encodings.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON
2 // available.
3 //
4 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All
5 // rights reserved.
6 //
7 // Licensed under the MIT License (the "License"); you may not use this file
8 // except in compliance with the License. You may obtain a copy of the License
9 // at
10 //
11 // http://opensource.org/licenses/MIT
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 // License for the specific language governing permissions and limitations under
17 // the License.
18 
19 #ifndef RAPIDJSON_ENCODINGS_H_
20 #define RAPIDJSON_ENCODINGS_H_
21 
22 #include "rapidjson.h"
23 
24 #if defined(_MSC_VER) && !defined(__clang__)
25 RAPIDJSON_DIAG_PUSH
26 RAPIDJSON_DIAG_OFF(
27  4244) // conversion from 'type1' to 'type2', possible loss of data
28 RAPIDJSON_DIAG_OFF(4702) // unreachable code
29 #elif defined(__GNUC__)
30 RAPIDJSON_DIAG_PUSH
31 RAPIDJSON_DIAG_OFF(effc++)
32 RAPIDJSON_DIAG_OFF(overflow)
33 #endif
34 
36 
38 // Encoding
39 
53 
60 
68 
74 
78 
82 
86 
92 // UTF8
94 
96 
101 template <typename CharType = char>
102 struct UTF8 {
103  typedef CharType Ch;
104 
105  enum { supportUnicode = 1 };
106 
107  template <typename OutputStream>
108  static void Encode(OutputStream &os, unsigned codepoint) {
109  if (codepoint <= 0x7F)
110  os.Put(static_cast<Ch>(codepoint & 0xFF));
111  else if (codepoint <= 0x7FF) {
112  os.Put(static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
113  os.Put(static_cast<Ch>(0x80 | ((codepoint & 0x3F))));
114  } else if (codepoint <= 0xFFFF) {
115  os.Put(static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
116  os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
117  os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
118  } else {
119  RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
120  os.Put(static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
121  os.Put(static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
122  os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
123  os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
124  }
125  }
126 
127  template <typename OutputStream>
128  static void EncodeUnsafe(OutputStream &os, unsigned codepoint) {
129  if (codepoint <= 0x7F)
130  PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));
131  else if (codepoint <= 0x7FF) {
132  PutUnsafe(os, static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
133  PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint & 0x3F))));
134  } else if (codepoint <= 0xFFFF) {
135  PutUnsafe(os, static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
136  PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
137  PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));
138  } else {
139  RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
140  PutUnsafe(os, static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
141  PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
142  PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
143  PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));
144  }
145  }
146 
147  template <typename InputStream>
148  static bool Decode(InputStream &is, unsigned *codepoint) {
149 #define RAPIDJSON_COPY() \
150  c = is.Take(); \
151  *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
152 #define RAPIDJSON_TRANS(mask) \
153  result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
154 #define RAPIDJSON_TAIL() \
155  RAPIDJSON_COPY(); \
156  RAPIDJSON_TRANS(0x70)
157  typename InputStream::Ch c = is.Take();
158  if (!(c & 0x80)) {
159  *codepoint = static_cast<unsigned char>(c);
160  return true;
161  }
162 
163  unsigned char type = GetRange(static_cast<unsigned char>(c));
164  if (type >= 32) {
165  *codepoint = 0;
166  } else {
167  *codepoint = (0xFFu >> type) & static_cast<unsigned char>(c);
168  }
169  bool result = true;
170  switch (type) {
171  case 2:
172  RAPIDJSON_TAIL();
173  return result;
174  case 3:
175  RAPIDJSON_TAIL();
176  RAPIDJSON_TAIL();
177  return result;
178  case 4:
179  RAPIDJSON_COPY();
180  RAPIDJSON_TRANS(0x50);
181  RAPIDJSON_TAIL();
182  return result;
183  case 5:
184  RAPIDJSON_COPY();
185  RAPIDJSON_TRANS(0x10);
186  RAPIDJSON_TAIL();
187  RAPIDJSON_TAIL();
188  return result;
189  case 6:
190  RAPIDJSON_TAIL();
191  RAPIDJSON_TAIL();
192  RAPIDJSON_TAIL();
193  return result;
194  case 10:
195  RAPIDJSON_COPY();
196  RAPIDJSON_TRANS(0x20);
197  RAPIDJSON_TAIL();
198  return result;
199  case 11:
200  RAPIDJSON_COPY();
201  RAPIDJSON_TRANS(0x60);
202  RAPIDJSON_TAIL();
203  RAPIDJSON_TAIL();
204  return result;
205  default:
206  return false;
207  }
208 #undef RAPIDJSON_COPY
209 #undef RAPIDJSON_TRANS
210 #undef RAPIDJSON_TAIL
211  }
212 
213  template <typename InputStream, typename OutputStream>
214  static bool Validate(InputStream &is, OutputStream &os) {
215 #define RAPIDJSON_COPY() os.Put(c = is.Take())
216 #define RAPIDJSON_TRANS(mask) \
217  result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
218 #define RAPIDJSON_TAIL() \
219  RAPIDJSON_COPY(); \
220  RAPIDJSON_TRANS(0x70)
221  Ch c;
222  RAPIDJSON_COPY();
223  if (!(c & 0x80)) return true;
224 
225  bool result = true;
226  switch (GetRange(static_cast<unsigned char>(c))) {
227  case 2:
228  RAPIDJSON_TAIL();
229  return result;
230  case 3:
231  RAPIDJSON_TAIL();
232  RAPIDJSON_TAIL();
233  return result;
234  case 4:
235  RAPIDJSON_COPY();
236  RAPIDJSON_TRANS(0x50);
237  RAPIDJSON_TAIL();
238  return result;
239  case 5:
240  RAPIDJSON_COPY();
241  RAPIDJSON_TRANS(0x10);
242  RAPIDJSON_TAIL();
243  RAPIDJSON_TAIL();
244  return result;
245  case 6:
246  RAPIDJSON_TAIL();
247  RAPIDJSON_TAIL();
248  RAPIDJSON_TAIL();
249  return result;
250  case 10:
251  RAPIDJSON_COPY();
252  RAPIDJSON_TRANS(0x20);
253  RAPIDJSON_TAIL();
254  return result;
255  case 11:
256  RAPIDJSON_COPY();
257  RAPIDJSON_TRANS(0x60);
258  RAPIDJSON_TAIL();
259  RAPIDJSON_TAIL();
260  return result;
261  default:
262  return false;
263  }
264 #undef RAPIDJSON_COPY
265 #undef RAPIDJSON_TRANS
266 #undef RAPIDJSON_TAIL
267  }
268 
269  static unsigned char GetRange(unsigned char c) {
270  // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
271  // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation
272  // can test multiple types.
273  static const unsigned char type[] = {
274  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
275  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
276  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
277  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
278  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
279  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
280  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
281  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
282  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
283  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
284  0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0x10, 0x10, 0x10,
285  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
286  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
287  0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
288  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
289  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
290  8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
291  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
292  2, 2, 2, 2, 2, 2, 2, 2, 10, 3, 3, 3,
293  3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3,
294  11, 6, 6, 6, 5, 8, 8, 8, 8, 8, 8, 8,
295  8, 8, 8, 8,
296  };
297  return type[c];
298  }
299 
300  template <typename InputByteStream>
301  static CharType TakeBOM(InputByteStream &is) {
302  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
303  typename InputByteStream::Ch c = Take(is);
304  if (static_cast<unsigned char>(c) != 0xEFu) return c;
305  c = is.Take();
306  if (static_cast<unsigned char>(c) != 0xBBu) return c;
307  c = is.Take();
308  if (static_cast<unsigned char>(c) != 0xBFu) return c;
309  c = is.Take();
310  return c;
311  }
312 
313  template <typename InputByteStream>
314  static Ch Take(InputByteStream &is) {
315  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
316  return static_cast<Ch>(is.Take());
317  }
318 
319  template <typename OutputByteStream>
320  static void PutBOM(OutputByteStream &os) {
321  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
322  os.Put(static_cast<typename OutputByteStream::Ch>(0xEFu));
323  os.Put(static_cast<typename OutputByteStream::Ch>(0xBBu));
324  os.Put(static_cast<typename OutputByteStream::Ch>(0xBFu));
325  }
326 
327  template <typename OutputByteStream>
328  static void Put(OutputByteStream &os, Ch c) {
329  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
330  os.Put(static_cast<typename OutputByteStream::Ch>(c));
331  }
332 };
333 
335 // UTF16
336 
338 
347 template <typename CharType = wchar_t>
348 struct UTF16 {
349  typedef CharType Ch;
350  RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2);
351 
352  enum { supportUnicode = 1 };
353 
354  template <typename OutputStream>
355  static void Encode(OutputStream &os, unsigned codepoint) {
356  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
357  if (codepoint <= 0xFFFF) {
359  codepoint < 0xD800 ||
360  codepoint > 0xDFFF); // Code point itself cannot be surrogate pair
361  os.Put(static_cast<typename OutputStream::Ch>(codepoint));
362  } else {
363  RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
364  unsigned v = codepoint - 0x10000;
365  os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
366  os.Put(static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));
367  }
368  }
369 
370  template <typename OutputStream>
371  static void EncodeUnsafe(OutputStream &os, unsigned codepoint) {
372  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
373  if (codepoint <= 0xFFFF) {
375  codepoint < 0xD800 ||
376  codepoint > 0xDFFF); // Code point itself cannot be surrogate pair
377  PutUnsafe(os, static_cast<typename OutputStream::Ch>(codepoint));
378  } else {
379  RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
380  unsigned v = codepoint - 0x10000;
381  PutUnsafe(os, static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
382  PutUnsafe(os,
383  static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));
384  }
385  }
386 
387  template <typename InputStream>
388  static bool Decode(InputStream &is, unsigned *codepoint) {
389  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
390  typename InputStream::Ch c = is.Take();
391  if (c < 0xD800 || c > 0xDFFF) {
392  *codepoint = static_cast<unsigned>(c);
393  return true;
394  } else if (c <= 0xDBFF) {
395  *codepoint = (static_cast<unsigned>(c) & 0x3FF) << 10;
396  c = is.Take();
397  *codepoint |= (static_cast<unsigned>(c) & 0x3FF);
398  *codepoint += 0x10000;
399  return c >= 0xDC00 && c <= 0xDFFF;
400  }
401  return false;
402  }
403 
404  template <typename InputStream, typename OutputStream>
405  static bool Validate(InputStream &is, OutputStream &os) {
406  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
407  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
408  typename InputStream::Ch c;
409  os.Put(static_cast<typename OutputStream::Ch>(c = is.Take()));
410  if (c < 0xD800 || c > 0xDFFF)
411  return true;
412  else if (c <= 0xDBFF) {
413  os.Put(c = is.Take());
414  return c >= 0xDC00 && c <= 0xDFFF;
415  }
416  return false;
417  }
418 };
419 
421 template <typename CharType = wchar_t>
422 struct UTF16LE : UTF16<CharType> {
423  template <typename InputByteStream>
424  static CharType TakeBOM(InputByteStream &is) {
425  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
426  CharType c = Take(is);
427  return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
428  }
429 
430  template <typename InputByteStream>
431  static CharType Take(InputByteStream &is) {
432  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
433  unsigned c = static_cast<uint8_t>(is.Take());
434  c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
435  return static_cast<CharType>(c);
436  }
437 
438  template <typename OutputByteStream>
439  static void PutBOM(OutputByteStream &os) {
440  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
441  os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
442  os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
443  }
444 
445  template <typename OutputByteStream>
446  static void Put(OutputByteStream &os, CharType c) {
447  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
448  os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) &
449  0xFFu));
450  os.Put(static_cast<typename OutputByteStream::Ch>(
451  (static_cast<unsigned>(c) >> 8) & 0xFFu));
452  }
453 };
454 
456 template <typename CharType = wchar_t>
457 struct UTF16BE : UTF16<CharType> {
458  template <typename InputByteStream>
459  static CharType TakeBOM(InputByteStream &is) {
460  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
461  CharType c = Take(is);
462  return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
463  }
464 
465  template <typename InputByteStream>
466  static CharType Take(InputByteStream &is) {
467  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
468  unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
469  c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));
470  return static_cast<CharType>(c);
471  }
472 
473  template <typename OutputByteStream>
474  static void PutBOM(OutputByteStream &os) {
475  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
476  os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
477  os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
478  }
479 
480  template <typename OutputByteStream>
481  static void Put(OutputByteStream &os, CharType c) {
482  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
483  os.Put(static_cast<typename OutputByteStream::Ch>(
484  (static_cast<unsigned>(c) >> 8) & 0xFFu));
485  os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) &
486  0xFFu));
487  }
488 };
489 
491 // UTF32
492 
494 
502 template <typename CharType = unsigned>
503 struct UTF32 {
504  typedef CharType Ch;
505  RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4);
506 
507  enum { supportUnicode = 1 };
508 
509  template <typename OutputStream>
510  static void Encode(OutputStream &os, unsigned codepoint) {
511  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);
512  RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
513  os.Put(codepoint);
514  }
515 
516  template <typename OutputStream>
517  static void EncodeUnsafe(OutputStream &os, unsigned codepoint) {
518  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);
519  RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
520  PutUnsafe(os, codepoint);
521  }
522 
523  template <typename InputStream>
524  static bool Decode(InputStream &is, unsigned *codepoint) {
525  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
526  Ch c = is.Take();
527  *codepoint = c;
528  return c <= 0x10FFFF;
529  }
530 
531  template <typename InputStream, typename OutputStream>
532  static bool Validate(InputStream &is, OutputStream &os) {
533  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
534  Ch c;
535  os.Put(c = is.Take());
536  return c <= 0x10FFFF;
537  }
538 };
539 
541 template <typename CharType = unsigned>
542 struct UTF32LE : UTF32<CharType> {
543  template <typename InputByteStream>
544  static CharType TakeBOM(InputByteStream &is) {
545  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
546  CharType c = Take(is);
547  return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;
548  }
549 
550  template <typename InputByteStream>
551  static CharType Take(InputByteStream &is) {
552  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
553  unsigned c = static_cast<uint8_t>(is.Take());
554  c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
555  c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
556  c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
557  return static_cast<CharType>(c);
558  }
559 
560  template <typename OutputByteStream>
561  static void PutBOM(OutputByteStream &os) {
562  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
563  os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
564  os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
565  os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
566  os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
567  }
568 
569  template <typename OutputByteStream>
570  static void Put(OutputByteStream &os, CharType c) {
571  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
572  os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
573  os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
574  os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
575  os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
576  }
577 };
578 
580 template <typename CharType = unsigned>
581 struct UTF32BE : UTF32<CharType> {
582  template <typename InputByteStream>
583  static CharType TakeBOM(InputByteStream &is) {
584  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
585  CharType c = Take(is);
586  return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;
587  }
588 
589  template <typename InputByteStream>
590  static CharType Take(InputByteStream &is) {
591  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
592  unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
593  c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
594  c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
595  c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));
596  return static_cast<CharType>(c);
597  }
598 
599  template <typename OutputByteStream>
600  static void PutBOM(OutputByteStream &os) {
601  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
602  os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
603  os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
604  os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
605  os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
606  }
607 
608  template <typename OutputByteStream>
609  static void Put(OutputByteStream &os, CharType c) {
610  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
611  os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
612  os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
613  os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
614  os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
615  }
616 };
617 
619 // ASCII
620 
622 
626 template <typename CharType = char>
627 struct ASCII {
628  typedef CharType Ch;
629 
630  enum { supportUnicode = 0 };
631 
632  template <typename OutputStream>
633  static void Encode(OutputStream &os, unsigned codepoint) {
634  RAPIDJSON_ASSERT(codepoint <= 0x7F);
635  os.Put(static_cast<Ch>(codepoint & 0xFF));
636  }
637 
638  template <typename OutputStream>
639  static void EncodeUnsafe(OutputStream &os, unsigned codepoint) {
640  RAPIDJSON_ASSERT(codepoint <= 0x7F);
641  PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));
642  }
643 
644  template <typename InputStream>
645  static bool Decode(InputStream &is, unsigned *codepoint) {
646  uint8_t c = static_cast<uint8_t>(is.Take());
647  *codepoint = c;
648  return c <= 0X7F;
649  }
650 
651  template <typename InputStream, typename OutputStream>
652  static bool Validate(InputStream &is, OutputStream &os) {
653  uint8_t c = static_cast<uint8_t>(is.Take());
654  os.Put(static_cast<typename OutputStream::Ch>(c));
655  return c <= 0x7F;
656  }
657 
658  template <typename InputByteStream>
659  static CharType TakeBOM(InputByteStream &is) {
660  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
661  uint8_t c = static_cast<uint8_t>(Take(is));
662  return static_cast<Ch>(c);
663  }
664 
665  template <typename InputByteStream>
666  static Ch Take(InputByteStream &is) {
667  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
668  return static_cast<Ch>(is.Take());
669  }
670 
671  template <typename OutputByteStream>
672  static void PutBOM(OutputByteStream &os) {
673  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
674  (void)os;
675  }
676 
677  template <typename OutputByteStream>
678  static void Put(OutputByteStream &os, Ch c) {
679  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
680  os.Put(static_cast<typename OutputByteStream::Ch>(c));
681  }
682 };
683 
685 // AutoUTF
686 
688 enum UTFType {
689  kUTF8 = 0,
690  kUTF16LE = 1,
691  kUTF16BE = 2,
692  kUTF32LE = 3,
693  kUTF32BE = 4
694 };
695 
698 
701 template <typename CharType>
702 struct AutoUTF {
703  typedef CharType Ch;
704 
705  enum { supportUnicode = 1 };
706 
707 #define RAPIDJSON_ENCODINGS_FUNC(x) \
708  UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
709 
710  template <typename OutputStream>
711  static RAPIDJSON_FORCEINLINE void Encode(OutputStream &os,
712  unsigned codepoint) {
713  typedef void (*EncodeFunc)(OutputStream &, unsigned);
714  static const EncodeFunc f[] = {RAPIDJSON_ENCODINGS_FUNC(Encode)};
715  (*f[os.GetType()])(os, codepoint);
716  }
717 
718  template <typename OutputStream>
719  static RAPIDJSON_FORCEINLINE void EncodeUnsafe(OutputStream &os,
720  unsigned codepoint) {
721  typedef void (*EncodeFunc)(OutputStream &, unsigned);
722  static const EncodeFunc f[] = {RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe)};
723  (*f[os.GetType()])(os, codepoint);
724  }
725 
726  template <typename InputStream>
727  static RAPIDJSON_FORCEINLINE bool Decode(InputStream &is,
728  unsigned *codepoint) {
729  typedef bool (*DecodeFunc)(InputStream &, unsigned *);
730  static const DecodeFunc f[] = {RAPIDJSON_ENCODINGS_FUNC(Decode)};
731  return (*f[is.GetType()])(is, codepoint);
732  }
733 
734  template <typename InputStream, typename OutputStream>
735  static RAPIDJSON_FORCEINLINE bool Validate(InputStream &is,
736  OutputStream &os) {
737  typedef bool (*ValidateFunc)(InputStream &, OutputStream &);
738  static const ValidateFunc f[] = {RAPIDJSON_ENCODINGS_FUNC(Validate)};
739  return (*f[is.GetType()])(is, os);
740  }
741 
742 #undef RAPIDJSON_ENCODINGS_FUNC
743 };
744 
746 // Transcoder
747 
749 template <typename SourceEncoding, typename TargetEncoding>
750 struct Transcoder {
753  template <typename InputStream, typename OutputStream>
754  static RAPIDJSON_FORCEINLINE bool Transcode(InputStream &is,
755  OutputStream &os) {
756  unsigned codepoint;
757  if (!SourceEncoding::Decode(is, &codepoint)) return false;
758  TargetEncoding::Encode(os, codepoint);
759  return true;
760  }
761 
762  template <typename InputStream, typename OutputStream>
763  static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream &is,
764  OutputStream &os) {
765  unsigned codepoint;
766  if (!SourceEncoding::Decode(is, &codepoint)) return false;
767  TargetEncoding::EncodeUnsafe(os, codepoint);
768  return true;
769  }
770 
772  template <typename InputStream, typename OutputStream>
773  static RAPIDJSON_FORCEINLINE bool Validate(InputStream &is,
774  OutputStream &os) {
775  return Transcode(
776  is, os); // Since source/target encoding is different, must transcode.
777  }
778 };
779 
780 // Forward declaration.
781 template <typename Stream>
782 inline void PutUnsafe(Stream &stream, typename Stream::Ch c);
783 
785 template <typename Encoding>
786 struct Transcoder<Encoding, Encoding> {
787  template <typename InputStream, typename OutputStream>
788  static RAPIDJSON_FORCEINLINE bool Transcode(InputStream &is,
789  OutputStream &os) {
790  os.Put(is.Take()); // Just copy one code unit. This semantic is different
791  // from primary template class.
792  return true;
793  }
794 
795  template <typename InputStream, typename OutputStream>
796  static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream &is,
797  OutputStream &os) {
798  PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is
799  // different from primary template class.
800  return true;
801  }
802 
803  template <typename InputStream, typename OutputStream>
804  static RAPIDJSON_FORCEINLINE bool Validate(InputStream &is,
805  OutputStream &os) {
806  return Encoding::Validate(is, os); // source/target encoding are the same
807  }
808 };
809 
811 
812 #if defined(__GNUC__) || (defined(_MSC_VER) && !defined(__clang__))
813 RAPIDJSON_DIAG_POP
814 #endif
815 
816 #endif // RAPIDJSON_ENCODINGS_H_
static bool Decode(InputStream &is, unsigned *codepoint)
Definition: encodings.h:148
Encoding conversion.
Definition: encodings.h:750
static void Put(OutputByteStream &os, Ch c)
Definition: encodings.h:328
static CharType TakeBOM(InputByteStream &is)
Definition: encodings.h:544
UTFType
Runtime-specified UTF encoding type of a stream.
Definition: encodings.h:688
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:433
ASCII encoding.
Definition: encodings.h:627
f
static void Encode(OutputStream &os, unsigned codepoint)
Definition: encodings.h:633
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:131
static CharType TakeBOM(InputByteStream &is)
Definition: encodings.h:301
CharType Ch
Definition: encodings.h:103
static RAPIDJSON_FORCEINLINE void EncodeUnsafe(OutputStream &os, unsigned codepoint)
Definition: encodings.h:719
UTF-32 big endian.
Definition: encodings.h:693
UTF-16 little endian.
Definition: encodings.h:690
UTF-8.
Definition: encodings.h:689
static bool Validate(InputStream &is, OutputStream &os)
Definition: encodings.h:214
UTF-16 encoding.
Definition: encodings.h:348
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition: rapidjson.h:476
unsigned short uint16_t
Definition: stdint.h:126
static CharType TakeBOM(InputByteStream &is)
Definition: encodings.h:659
static void Put(OutputByteStream &os, Ch c)
Definition: encodings.h:678
unsigned char uint8_t
Definition: stdint.h:125
UTF-16 big endian.
Definition: encodings.h:691
static bool Validate(InputStream &is, OutputStream &os)
Definition: encodings.h:532
static bool Validate(InputStream &is, OutputStream &os)
Definition: encodings.h:652
static void PutBOM(OutputByteStream &os)
Definition: encodings.h:672
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:128
static void PutBOM(OutputByteStream &os)
Definition: encodings.h:320
CharType Ch
Definition: encodings.h:504
#define RAPIDJSON_ENCODINGS_FUNC(x)
Definition: encodings.h:707
static void Put(OutputByteStream &os, CharType c)
Definition: encodings.h:570
static Ch Take(InputByteStream &is)
Definition: encodings.h:314
static CharType Take(InputByteStream &is)
Definition: encodings.h:431
static void Put(OutputByteStream &os, CharType c)
Definition: encodings.h:446
static CharType TakeBOM(InputByteStream &is)
Definition: encodings.h:424
static CharType Take(InputByteStream &is)
Definition: encodings.h:466
static CharType Take(InputByteStream &is)
Definition: encodings.h:551
UTF-8 encoding.
Definition: encodings.h:102
static bool Decode(InputStream &is, unsigned *codepoint)
Definition: encodings.h:645
static CharType Take(InputByteStream &is)
Definition: encodings.h:590
static Ch Take(InputByteStream &is)
Definition: encodings.h:666
static RAPIDJSON_FORCEINLINE bool Transcode(InputStream &is, OutputStream &os)
Definition: encodings.h:754
unsigned int uint32_t
Definition: stdint.h:127
static void Put(OutputByteStream &os, CharType c)
Definition: encodings.h:481
static unsigned char GetRange(unsigned char c)
Definition: encodings.h:269
static void PutBOM(OutputByteStream &os)
Definition: encodings.h:439
static void EncodeUnsafe(OutputStream &os, unsigned codepoint)
Definition: encodings.h:128
UTF-32 encoding.
Definition: encodings.h:503
CharType Ch
Definition: encodings.h:349
#define RAPIDJSON_TAIL()
UTF-16 big endian encoding.
Definition: encodings.h:457
static RAPIDJSON_FORCEINLINE bool Transcode(InputStream &is, OutputStream &os)
Definition: encodings.h:788
static void Encode(OutputStream &os, unsigned codepoint)
Definition: encodings.h:510
UTF-32 big endian encoding.
Definition: encodings.h:581
CharType Ch
Definition: encodings.h:703
static void Encode(OutputStream &os, unsigned codepoint)
Definition: encodings.h:355
#define RAPIDJSON_COPY()
static RAPIDJSON_FORCEINLINE bool Decode(InputStream &is, unsigned *codepoint)
Definition: encodings.h:727
static bool Decode(InputStream &is, unsigned *codepoint)
Definition: encodings.h:388
common definitions and configuration
static RAPIDJSON_FORCEINLINE void Encode(OutputStream &os, unsigned codepoint)
Definition: encodings.h:711
static RAPIDJSON_FORCEINLINE bool Validate(InputStream &is, OutputStream &os)
Validate one Unicode codepoint from an encoded stream.
Definition: encodings.h:773
static CharType TakeBOM(InputByteStream &is)
Definition: encodings.h:583
static void Put(OutputByteStream &os, CharType c)
Definition: encodings.h:609
static RAPIDJSON_FORCEINLINE bool Validate(InputStream &is, OutputStream &os)
Definition: encodings.h:804
void PutUnsafe(Stream &stream, typename Stream::Ch c)
Write character to a stream, presuming buffer is reserved.
Definition: stream.h:98
static void PutBOM(OutputByteStream &os)
Definition: encodings.h:561
static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream &is, OutputStream &os)
Definition: encodings.h:796
static void EncodeUnsafe(OutputStream &os, unsigned codepoint)
Definition: encodings.h:371
UTF-32 little endian.
Definition: encodings.h:692
static bool Decode(InputStream &is, unsigned *codepoint)
Definition: encodings.h:524
CharType Ch
Definition: encodings.h:628
static void PutBOM(OutputByteStream &os)
Definition: encodings.h:600
static void Encode(OutputStream &os, unsigned codepoint)
Definition: encodings.h:108
static void EncodeUnsafe(OutputStream &os, unsigned codepoint)
Definition: encodings.h:639
static void PutBOM(OutputByteStream &os)
Definition: encodings.h:474
#define RAPIDJSON_TRANS(mask)
UTF-16 little endian encoding.
Definition: encodings.h:422
static bool Validate(InputStream &is, OutputStream &os)
Definition: encodings.h:405
static CharType TakeBOM(InputByteStream &is)
Definition: encodings.h:459
UTF-32 little endian enocoding.
Definition: encodings.h:542
static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream &is, OutputStream &os)
Definition: encodings.h:763
static RAPIDJSON_FORCEINLINE bool Validate(InputStream &is, OutputStream &os)
Definition: encodings.h:735
static void EncodeUnsafe(OutputStream &os, unsigned codepoint)
Definition: encodings.h:517


livox_ros_driver
Author(s): Livox Dev Team
autogenerated on Mon Mar 15 2021 02:40:46