ewmscp  ..
escapism.cpp
Go to the documentation of this file.
1 #include "escapism.h"
2 
3 
5 
6 static std::map<std::string, escapismFactoryClass*>& getEscapismFactoryMap() {
7  static std::remove_reference<decltype(getEscapismFactoryMap())>::type factoryMap;
8  return factoryMap;
9 }
11  public:
12  escapismFactoryClass(const std::string& name) {
13  getEscapismFactoryMap()[name] = this;
14  }
15  virtual const escapism* create() = 0;
16 };
17 template <class T> class escapismFactoryClassTemplate: public escapismFactoryClass {
18  public:
19  escapismFactoryClassTemplate(const std::string& name): escapismFactoryClass(name) {};
20  const escapism* create() override {
21  return new T();
22  }
23 };
24 
25 const escapism* escapism::newEscaper(const std::string& name) {
26  if (name == "None") {
27  return nullptr;
28  }
29  return getEscapismFactoryMap()[name]->create();
30 }
32  for (const auto& item : getEscapismFactoryMap()) {
33  option.fAddToRange(item.first);
34  }
35 }
37  const std::string& description,
38  const std::string& defaultValue) {
39  auto opt = new options::single<std::string>('\0', name, description, defaultValue);
41  if (defaultValue == "None") {
42  opt->fAddToRange(defaultValue);
43  }
44  return opt;
45 }
46 
47 class escapismUrl: public escapism {
50  charCodingBitPatternType codingPattern = {{0ull, 0ull, 0ull, 0ull}};
51  const char* ueChars = "0123456789.-~_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
52  for (const char *c = ueChars; *c; c++) {
54  }
55  return codingPattern;
56  }
57  virtual bool unencoded(char c) const {
58  static charCodingBitPatternType codingPattern = initCodeList();
59  return (codingPattern.bits[charCodingBitPatternType::index(c)] & charCodingBitPatternType::mask(c)) != 0ull;
60  }
61  void escape(const std::string& unEscaped, std::string& escaped) const override {
62  for (auto c : unEscaped) {
63  if (unencoded(c)) {
64  escaped.push_back(c);
65  } else {
66  static const char hexEncode[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
67  escaped.push_back('%');
68  // array indices are safe due to & 0x0f,
69  escaped.push_back(hexEncode[ (c >> 4) & 0x0F ]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
70  escaped.push_back(hexEncode[ c & 0x0F ]); // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
71  }
72  }
73  }
74  void deEscape(const std::string& escaped, std::string& unEscaped) const override {
75  unEscaped.reserve(escaped.size()); // de-Escaped is always smaller, so this always fits and saves time
76  std::remove_reference<decltype(unEscaped)>::type::value_type code;
77  enum {normal, firstNibble, secondNibble} state = normal;
78  for (auto c : escaped) {
79  if (state == normal) {
80  if (c == '%') {
81  state = firstNibble;
82  continue;
83  }
84  unEscaped.push_back(c);
85  } else {
86  decltype(code) nibble;
87  if (std::isdigit(c)) {
88  nibble = c - '0';
89  } else {
90  c = std::toupper(c);
91  if ('A' <= c && c <= 'F') {
92  nibble = c - 'A' + 10;
93  } else {
94  throw std::invalid_argument("bad encoding");
95  }
96  }
97  if (state == firstNibble) {
98  code = nibble << 4;
99  state = secondNibble;
100  continue;
101  } else {
102  code |= nibble;
103  unEscaped.push_back(code);
104  state = normal;
105  continue;
106  }
107  }
108  }
109 
110  if (state != normal) {
111  throw std::invalid_argument("bad encoding");
112  }
113  }
114 };
116 
117 
121  charCodingBitPatternType codingPattern = {{0ull, 0ull, 0ull, 0ull}};
122  const char* ueChars = "0123456789.-~_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/";
123  for (const char *c = ueChars; *c; c++) {
125  }
126  return codingPattern;
127  }
128  bool unencoded(char c) const override {
129  static charCodingBitPatternType codingPattern = initCodeList();
130  return (codingPattern.bits[charCodingBitPatternType::index(c)] & charCodingBitPatternType::mask(c)) != 0ull;
131  }
132 };
134 
135 
136 
137 class escapismC: public escapism {
139  static const std::map<char, char>& getEscapeMap() {
140  static std::remove_reference<decltype(getEscapeMap())>::type escapeMap{
141  {'\a', 'a'},
142  {'\b', 'b'},
143  {'\f', 'f'},
144  {'\n', 'n'},
145  {'\r', 'r'},
146  {'\v', 'v'},
147  {'\\', '\\'},
148  {' ', ' '},
149  {'\'', '\''},
150  {'"', '"'},
151  };
152  return escapeMap;
153  }
154  static const std::map<char, char> invertEscapeMap() {
155  std::map<char, char> map;
156  for (const auto& item : getEscapeMap()) {
157  map.emplace(item.second, item.first);
158  }
159  return map;
160  }
161  static const std::map<char, char>& getUnEscapeMap() {
162  static std::remove_reference<decltype(getUnEscapeMap())>::type unEscapeMap(invertEscapeMap());
163  return unEscapeMap;
164  }
165 
167  charCodingBitPatternType codingPattern = {{0ull, 0ull, 0ull, 0ull}};
168  for (char c = ' '; c < 127; c++) {
169  if (getEscapeMap().find(c) == getEscapeMap().end()) {
171  }
172  }
173  return codingPattern;
174  }
175  static bool unencoded(char c) {
176  static charCodingBitPatternType codingPattern = initCodeList();
177  return (codingPattern.bits[charCodingBitPatternType::index(c)] & charCodingBitPatternType::mask(c)) != 0ull;
178  }
179  void escape(const std::string& unEscaped, std::string& escaped) const override {
180  for (auto c : unEscaped) {
181  if (unencoded(c)) {
182  escaped.push_back(c);
183  } else {
184  escaped.push_back('\\');
185  auto enc = getEscapeMap().find(c);
186  if (enc != getEscapeMap().end()) {
187  escaped.push_back(enc->second);
188  } else {
189  escaped.push_back('0' + ((c >> 6) & 0x07));
190  escaped.push_back('0' + ((c >> 3) & 0x07));
191  escaped.push_back('0' + ((c >> 0) & 0x07));
192  }
193  }
194  }
195  }
196  void deEscape(const std::string& escaped, std::string& unEscaped) const override {
197  unEscaped.reserve(escaped.size()); // de-Escaped is always smaller, so this always fits and saves time
198  std::remove_reference<decltype(unEscaped)>::type::value_type code;
199  enum {normal, escaping, second3bits, last3bits} state = normal;
200  for (auto c : escaped) {
201  if (state == normal) {
202  if (c == '\\') {
203  state = escaping;
204  continue;
205  }
206  unEscaped.push_back(c);
207  } else if (state == escaping) {
208  auto enc = getUnEscapeMap().find(c);
209  if (enc != getUnEscapeMap().end()) {
210  unEscaped.push_back(enc->second);
211  state = normal;
212  continue;
213  }
214  if ('0' <= c && c <= '7') {
215  decltype(code) threeBits;
216  threeBits = c - '0';
217  code = threeBits << 6;
218  state = second3bits;
219  continue;
220  } else {
221  throw std::invalid_argument("bad encoding");
222  }
223  } else if (state == second3bits) {
224  if ('0' <= c && c <= '7') {
225  decltype(code) threeBits;
226  threeBits = c - '0';
227  code |= threeBits << 3;
228  state = last3bits;
229  continue;
230  } else {
231  throw std::invalid_argument("bad encoding");
232  }
233  } else if (state == last3bits) {
234  if ('0' <= c && c <= '7') {
235  decltype(code) threeBits;
236  threeBits = c - '0';
237  code |= threeBits << 0;
238  unEscaped.push_back(code);
239  state = normal;
240  continue;
241  } else {
242  throw std::invalid_argument("bad encoding");
243  }
244  }
245  }
246 
247  if (state != normal) {
248  throw std::invalid_argument("bad encoding");
249  }
250  }
251 };
escapismFactoryClass
Definition: escapism.cpp:10
escapismC::getEscapeMap
static const std::map< char, char > & getEscapeMap()
Definition: escapism.cpp:139
options::single< std::string >
escapismFactoryClassTemplate::escapismFactoryClassTemplate
escapismFactoryClassTemplate(const std::string &name)
Definition: escapism.cpp:19
escapismUrlsoft::factory
static escapismFactoryClassTemplate< escapismUrlsoft > factory
Definition: escapism.cpp:119
options::internal::typed_base::fAddToRange
virtual void fAddToRange(rangeValueType aValue)
add a value to the range of allowed values
Definition: Options.h:458
escapismFactoryClass::create
virtual const escapism * create()=0
escapismC::initCodeList
static charCodingBitPatternType initCodeList()
Definition: escapism.cpp:166
escapism
Definition: escapism.h:6
escapism::charCodingBitPatternType::bits
std::uint64_t bits[4]
Definition: escapism.h:10
escapismUrl::initCodeList
static charCodingBitPatternType initCodeList()
Definition: escapism.cpp:49
escapismUrl::deEscape
void deEscape(const std::string &escaped, std::string &unEscaped) const override
Definition: escapism.cpp:74
escapismC::unencoded
static bool unencoded(char c)
Definition: escapism.cpp:175
escapismUrl::escape
void escape(const std::string &unEscaped, std::string &escaped) const override
Definition: escapism.cpp:61
getEscapismFactoryMap
static std::map< std::string, escapismFactoryClass * > & getEscapismFactoryMap()
Definition: escapism.cpp:6
escapismFactoryClass::escapismFactoryClass
escapismFactoryClass(const std::string &name)
Definition: escapism.cpp:12
escapismC::invertEscapeMap
static const std::map< char, char > invertEscapeMap()
Definition: escapism.cpp:154
escapism.h
escapism::newEscaperOption
static options::single< std::string > * newEscaperOption(const std::string &name, const std::string &description, const std::string &defaultValue="Url")
Definition: escapism.cpp:36
escapism::charCodingBitPatternType::mask
static std::uint64_t mask(char c)
Definition: escapism.h:14
escapismUrlsoft::unencoded
bool unencoded(char c) const override
Definition: escapism.cpp:128
escapismC::escape
void escape(const std::string &unEscaped, std::string &escaped) const override
Definition: escapism.cpp:179
escapism::addAllowedNamesToOption
static void addAllowedNamesToOption(options::single< std::string > &option)
Definition: escapism.cpp:31
escapismUrl::factory
static escapismFactoryClassTemplate< escapismUrl > factory
Definition: escapism.cpp:48
escapism::newEscaper
static const escapism * newEscaper(const std::string &name)
Definition: escapism.cpp:25
escapismUrlsoft
Definition: escapism.cpp:118
escapismUrl::unencoded
virtual bool unencoded(char c) const
Definition: escapism.cpp:57
escapismC::factory
static escapismFactoryClassTemplate< escapismC > factory
Definition: escapism.cpp:138
escapismUrlsoft::initCodeList
static charCodingBitPatternType initCodeList()
Definition: escapism.cpp:120
escapism::charCodingBitPatternType::index
static int index(char c)
Definition: escapism.h:11
escapismFactoryClassTemplate::create
const escapism * create() override
Definition: escapism.cpp:20
escapismUrl
Definition: escapism.cpp:47
escapismC::getUnEscapeMap
static const std::map< char, char > & getUnEscapeMap()
Definition: escapism.cpp:161
escapismFactoryClassTemplate
Definition: escapism.cpp:17
escapism::charCodingBitPatternType
Definition: escapism.h:8
escapismC::deEscape
void deEscape(const std::string &escaped, std::string &unEscaped) const override
Definition: escapism.cpp:196
escapismC
Definition: escapism.cpp:137