File indexing completed on 2025-02-21 10:13:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef RAPIDJSON_ENCODINGS_H_
0016 #define RAPIDJSON_ENCODINGS_H_
0017
0018 #include "rapidjson.h"
0019
0020 #if defined(_MSC_VER) && !defined(__clang__)
0021 RAPIDJSON_DIAG_PUSH
0022 RAPIDJSON_DIAG_OFF(4244)
0023 RAPIDJSON_DIAG_OFF(4702)
0024 #elif defined(__GNUC__)
0025 RAPIDJSON_DIAG_PUSH
0026 RAPIDJSON_DIAG_OFF(effc++)
0027 RAPIDJSON_DIAG_OFF(overflow)
0028 #endif
0029
0030 RAPIDJSON_NAMESPACE_BEGIN
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 template<typename CharType = char>
0096 struct UTF8 {
0097 typedef CharType Ch;
0098
0099 enum { supportUnicode = 1 };
0100
0101 template<typename OutputStream>
0102 static void Encode(OutputStream& os, unsigned codepoint) {
0103 if (codepoint <= 0x7F)
0104 os.Put(static_cast<Ch>(codepoint & 0xFF));
0105 else if (codepoint <= 0x7FF) {
0106 os.Put(static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
0107 os.Put(static_cast<Ch>(0x80 | ((codepoint & 0x3F))));
0108 }
0109 else if (codepoint <= 0xFFFF) {
0110 os.Put(static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
0111 os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
0112 os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
0113 }
0114 else {
0115 RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
0116 os.Put(static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
0117 os.Put(static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
0118 os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
0119 os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
0120 }
0121 }
0122
0123 template<typename OutputStream>
0124 static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
0125 if (codepoint <= 0x7F)
0126 PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));
0127 else if (codepoint <= 0x7FF) {
0128 PutUnsafe(os, static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
0129 PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint & 0x3F))));
0130 }
0131 else if (codepoint <= 0xFFFF) {
0132 PutUnsafe(os, static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
0133 PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
0134 PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));
0135 }
0136 else {
0137 RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
0138 PutUnsafe(os, static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
0139 PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
0140 PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
0141 PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));
0142 }
0143 }
0144
0145 template <typename InputStream>
0146 static bool Decode(InputStream& is, unsigned* codepoint) {
0147 #define RAPIDJSON_COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
0148 #define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
0149 #define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
0150 typename InputStream::Ch c = is.Take();
0151 if (!(c & 0x80)) {
0152 *codepoint = static_cast<unsigned char>(c);
0153 return true;
0154 }
0155
0156 unsigned char type = GetRange(static_cast<unsigned char>(c));
0157 if (type >= 32) {
0158 *codepoint = 0;
0159 } else {
0160 *codepoint = (0xFFu >> type) & static_cast<unsigned char>(c);
0161 }
0162 bool result = true;
0163 switch (type) {
0164 case 2: RAPIDJSON_TAIL(); return result;
0165 case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
0166 case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result;
0167 case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
0168 case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
0169 case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result;
0170 case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
0171 default: return false;
0172 }
0173 #undef RAPIDJSON_COPY
0174 #undef RAPIDJSON_TRANS
0175 #undef RAPIDJSON_TAIL
0176 }
0177
0178 template <typename InputStream, typename OutputStream>
0179 static bool Validate(InputStream& is, OutputStream& os) {
0180 #define RAPIDJSON_COPY() os.Put(c = is.Take())
0181 #define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
0182 #define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
0183 Ch c;
0184 RAPIDJSON_COPY();
0185 if (!(c & 0x80))
0186 return true;
0187
0188 bool result = true;
0189 switch (GetRange(static_cast<unsigned char>(c))) {
0190 case 2: RAPIDJSON_TAIL(); return result;
0191 case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
0192 case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result;
0193 case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
0194 case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
0195 case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result;
0196 case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
0197 default: return false;
0198 }
0199 #undef RAPIDJSON_COPY
0200 #undef RAPIDJSON_TRANS
0201 #undef RAPIDJSON_TAIL
0202 }
0203
0204 static unsigned char GetRange(unsigned char c) {
0205
0206
0207 static const unsigned char type[] = {
0208 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0209 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0210 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0211 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0212 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
0213 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0214 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0215 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0216 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
0217 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
0218 };
0219 return type[c];
0220 }
0221
0222 template <typename InputByteStream>
0223 static CharType TakeBOM(InputByteStream& is) {
0224 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
0225 typename InputByteStream::Ch c = Take(is);
0226 if (static_cast<unsigned char>(c) != 0xEFu) return c;
0227 c = is.Take();
0228 if (static_cast<unsigned char>(c) != 0xBBu) return c;
0229 c = is.Take();
0230 if (static_cast<unsigned char>(c) != 0xBFu) return c;
0231 c = is.Take();
0232 return c;
0233 }
0234
0235 template <typename InputByteStream>
0236 static Ch Take(InputByteStream& is) {
0237 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
0238 return static_cast<Ch>(is.Take());
0239 }
0240
0241 template <typename OutputByteStream>
0242 static void PutBOM(OutputByteStream& os) {
0243 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
0244 os.Put(static_cast<typename OutputByteStream::Ch>(0xEFu));
0245 os.Put(static_cast<typename OutputByteStream::Ch>(0xBBu));
0246 os.Put(static_cast<typename OutputByteStream::Ch>(0xBFu));
0247 }
0248
0249 template <typename OutputByteStream>
0250 static void Put(OutputByteStream& os, Ch c) {
0251 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
0252 os.Put(static_cast<typename OutputByteStream::Ch>(c));
0253 }
0254 };
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268 template<typename CharType = wchar_t>
0269 struct UTF16 {
0270 typedef CharType Ch;
0271 RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2);
0272
0273 enum { supportUnicode = 1 };
0274
0275 template<typename OutputStream>
0276 static void Encode(OutputStream& os, unsigned codepoint) {
0277 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
0278 if (codepoint <= 0xFFFF) {
0279 RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF);
0280 os.Put(static_cast<typename OutputStream::Ch>(codepoint));
0281 }
0282 else {
0283 RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
0284 unsigned v = codepoint - 0x10000;
0285 os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
0286 os.Put(static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));
0287 }
0288 }
0289
0290
0291 template<typename OutputStream>
0292 static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
0293 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
0294 if (codepoint <= 0xFFFF) {
0295 RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF);
0296 PutUnsafe(os, static_cast<typename OutputStream::Ch>(codepoint));
0297 }
0298 else {
0299 RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
0300 unsigned v = codepoint - 0x10000;
0301 PutUnsafe(os, static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
0302 PutUnsafe(os, static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));
0303 }
0304 }
0305
0306 template <typename InputStream>
0307 static bool Decode(InputStream& is, unsigned* codepoint) {
0308 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
0309 typename InputStream::Ch c = is.Take();
0310 if (c < 0xD800 || c > 0xDFFF) {
0311 *codepoint = static_cast<unsigned>(c);
0312 return true;
0313 }
0314 else if (c <= 0xDBFF) {
0315 *codepoint = (static_cast<unsigned>(c) & 0x3FF) << 10;
0316 c = is.Take();
0317 *codepoint |= (static_cast<unsigned>(c) & 0x3FF);
0318 *codepoint += 0x10000;
0319 return c >= 0xDC00 && c <= 0xDFFF;
0320 }
0321 return false;
0322 }
0323
0324 template <typename InputStream, typename OutputStream>
0325 static bool Validate(InputStream& is, OutputStream& os) {
0326 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
0327 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
0328 typename InputStream::Ch c;
0329 os.Put(static_cast<typename OutputStream::Ch>(c = is.Take()));
0330 if (c < 0xD800 || c > 0xDFFF)
0331 return true;
0332 else if (c <= 0xDBFF) {
0333 os.Put(c = is.Take());
0334 return c >= 0xDC00 && c <= 0xDFFF;
0335 }
0336 return false;
0337 }
0338 };
0339
0340
0341 template<typename CharType = wchar_t>
0342 struct UTF16LE : UTF16<CharType> {
0343 template <typename InputByteStream>
0344 static CharType TakeBOM(InputByteStream& is) {
0345 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
0346 CharType c = Take(is);
0347 return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
0348 }
0349
0350 template <typename InputByteStream>
0351 static CharType Take(InputByteStream& is) {
0352 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
0353 unsigned c = static_cast<uint8_t>(is.Take());
0354 c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
0355 return static_cast<CharType>(c);
0356 }
0357
0358 template <typename OutputByteStream>
0359 static void PutBOM(OutputByteStream& os) {
0360 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
0361 os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
0362 os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
0363 }
0364
0365 template <typename OutputByteStream>
0366 static void Put(OutputByteStream& os, CharType c) {
0367 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
0368 os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));
0369 os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));
0370 }
0371 };
0372
0373
0374 template<typename CharType = wchar_t>
0375 struct UTF16BE : UTF16<CharType> {
0376 template <typename InputByteStream>
0377 static CharType TakeBOM(InputByteStream& is) {
0378 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
0379 CharType c = Take(is);
0380 return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
0381 }
0382
0383 template <typename InputByteStream>
0384 static CharType Take(InputByteStream& is) {
0385 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
0386 unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
0387 c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));
0388 return static_cast<CharType>(c);
0389 }
0390
0391 template <typename OutputByteStream>
0392 static void PutBOM(OutputByteStream& os) {
0393 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
0394 os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
0395 os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
0396 }
0397
0398 template <typename OutputByteStream>
0399 static void Put(OutputByteStream& os, CharType c) {
0400 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
0401 os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));
0402 os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));
0403 }
0404 };
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417 template<typename CharType = unsigned>
0418 struct UTF32 {
0419 typedef CharType Ch;
0420 RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4);
0421
0422 enum { supportUnicode = 1 };
0423
0424 template<typename OutputStream>
0425 static void Encode(OutputStream& os, unsigned codepoint) {
0426 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);
0427 RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
0428 os.Put(codepoint);
0429 }
0430
0431 template<typename OutputStream>
0432 static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
0433 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);
0434 RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
0435 PutUnsafe(os, codepoint);
0436 }
0437
0438 template <typename InputStream>
0439 static bool Decode(InputStream& is, unsigned* codepoint) {
0440 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
0441 Ch c = is.Take();
0442 *codepoint = c;
0443 return c <= 0x10FFFF;
0444 }
0445
0446 template <typename InputStream, typename OutputStream>
0447 static bool Validate(InputStream& is, OutputStream& os) {
0448 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
0449 Ch c;
0450 os.Put(c = is.Take());
0451 return c <= 0x10FFFF;
0452 }
0453 };
0454
0455
0456 template<typename CharType = unsigned>
0457 struct UTF32LE : UTF32<CharType> {
0458 template <typename InputByteStream>
0459 static CharType TakeBOM(InputByteStream& is) {
0460 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
0461 CharType c = Take(is);
0462 return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;
0463 }
0464
0465 template <typename InputByteStream>
0466 static CharType Take(InputByteStream& is) {
0467 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
0468 unsigned c = static_cast<uint8_t>(is.Take());
0469 c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
0470 c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
0471 c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
0472 return static_cast<CharType>(c);
0473 }
0474
0475 template <typename OutputByteStream>
0476 static void PutBOM(OutputByteStream& os) {
0477 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
0478 os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
0479 os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
0480 os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
0481 os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
0482 }
0483
0484 template <typename OutputByteStream>
0485 static void Put(OutputByteStream& os, CharType c) {
0486 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
0487 os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
0488 os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
0489 os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
0490 os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
0491 }
0492 };
0493
0494
0495 template<typename CharType = unsigned>
0496 struct UTF32BE : UTF32<CharType> {
0497 template <typename InputByteStream>
0498 static CharType TakeBOM(InputByteStream& is) {
0499 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
0500 CharType c = Take(is);
0501 return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;
0502 }
0503
0504 template <typename InputByteStream>
0505 static CharType Take(InputByteStream& is) {
0506 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
0507 unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
0508 c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
0509 c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
0510 c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));
0511 return static_cast<CharType>(c);
0512 }
0513
0514 template <typename OutputByteStream>
0515 static void PutBOM(OutputByteStream& os) {
0516 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
0517 os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
0518 os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
0519 os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
0520 os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
0521 }
0522
0523 template <typename OutputByteStream>
0524 static void Put(OutputByteStream& os, CharType c) {
0525 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
0526 os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
0527 os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
0528 os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
0529 os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
0530 }
0531 };
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541 template<typename CharType = char>
0542 struct ASCII {
0543 typedef CharType Ch;
0544
0545 enum { supportUnicode = 0 };
0546
0547 template<typename OutputStream>
0548 static void Encode(OutputStream& os, unsigned codepoint) {
0549 RAPIDJSON_ASSERT(codepoint <= 0x7F);
0550 os.Put(static_cast<Ch>(codepoint & 0xFF));
0551 }
0552
0553 template<typename OutputStream>
0554 static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
0555 RAPIDJSON_ASSERT(codepoint <= 0x7F);
0556 PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));
0557 }
0558
0559 template <typename InputStream>
0560 static bool Decode(InputStream& is, unsigned* codepoint) {
0561 uint8_t c = static_cast<uint8_t>(is.Take());
0562 *codepoint = c;
0563 return c <= 0X7F;
0564 }
0565
0566 template <typename InputStream, typename OutputStream>
0567 static bool Validate(InputStream& is, OutputStream& os) {
0568 uint8_t c = static_cast<uint8_t>(is.Take());
0569 os.Put(static_cast<typename OutputStream::Ch>(c));
0570 return c <= 0x7F;
0571 }
0572
0573 template <typename InputByteStream>
0574 static CharType TakeBOM(InputByteStream& is) {
0575 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
0576 uint8_t c = static_cast<uint8_t>(Take(is));
0577 return static_cast<Ch>(c);
0578 }
0579
0580 template <typename InputByteStream>
0581 static Ch Take(InputByteStream& is) {
0582 RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
0583 return static_cast<Ch>(is.Take());
0584 }
0585
0586 template <typename OutputByteStream>
0587 static void PutBOM(OutputByteStream& os) {
0588 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
0589 (void)os;
0590 }
0591
0592 template <typename OutputByteStream>
0593 static void Put(OutputByteStream& os, Ch c) {
0594 RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
0595 os.Put(static_cast<typename OutputByteStream::Ch>(c));
0596 }
0597 };
0598
0599
0600
0601
0602
0603 enum UTFType {
0604 kUTF8 = 0,
0605 kUTF16LE = 1,
0606 kUTF16BE = 2,
0607 kUTF32LE = 3,
0608 kUTF32BE = 4
0609 };
0610
0611
0612
0613
0614 template<typename CharType>
0615 struct AutoUTF {
0616 typedef CharType Ch;
0617
0618 enum { supportUnicode = 1 };
0619
0620 #define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
0621
0622 template<typename OutputStream>
0623 static RAPIDJSON_FORCEINLINE void Encode(OutputStream& os, unsigned codepoint) {
0624 typedef void (*EncodeFunc)(OutputStream&, unsigned);
0625 static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) };
0626 (*f[os.GetType()])(os, codepoint);
0627 }
0628
0629 template<typename OutputStream>
0630 static RAPIDJSON_FORCEINLINE void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
0631 typedef void (*EncodeFunc)(OutputStream&, unsigned);
0632 static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) };
0633 (*f[os.GetType()])(os, codepoint);
0634 }
0635
0636 template <typename InputStream>
0637 static RAPIDJSON_FORCEINLINE bool Decode(InputStream& is, unsigned* codepoint) {
0638 typedef bool (*DecodeFunc)(InputStream&, unsigned*);
0639 static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) };
0640 return (*f[is.GetType()])(is, codepoint);
0641 }
0642
0643 template <typename InputStream, typename OutputStream>
0644 static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
0645 typedef bool (*ValidateFunc)(InputStream&, OutputStream&);
0646 static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) };
0647 return (*f[is.GetType()])(is, os);
0648 }
0649
0650 #undef RAPIDJSON_ENCODINGS_FUNC
0651 };
0652
0653
0654
0655
0656
0657 template<typename SourceEncoding, typename TargetEncoding>
0658 struct Transcoder {
0659
0660 template<typename InputStream, typename OutputStream>
0661 static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) {
0662 unsigned codepoint;
0663 if (!SourceEncoding::Decode(is, &codepoint))
0664 return false;
0665 TargetEncoding::Encode(os, codepoint);
0666 return true;
0667 }
0668
0669 template<typename InputStream, typename OutputStream>
0670 static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
0671 unsigned codepoint;
0672 if (!SourceEncoding::Decode(is, &codepoint))
0673 return false;
0674 TargetEncoding::EncodeUnsafe(os, codepoint);
0675 return true;
0676 }
0677
0678
0679 template<typename InputStream, typename OutputStream>
0680 static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
0681 return Transcode(is, os);
0682 }
0683 };
0684
0685
0686 template<typename Stream>
0687 inline void PutUnsafe(Stream& stream, typename Stream::Ch c);
0688
0689
0690 template<typename Encoding>
0691 struct Transcoder<Encoding, Encoding> {
0692 template<typename InputStream, typename OutputStream>
0693 static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) {
0694 os.Put(is.Take());
0695 return true;
0696 }
0697
0698 template<typename InputStream, typename OutputStream>
0699 static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
0700 PutUnsafe(os, is.Take());
0701 return true;
0702 }
0703
0704 template<typename InputStream, typename OutputStream>
0705 static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
0706 return Encoding::Validate(is, os);
0707 }
0708 };
0709
0710 RAPIDJSON_NAMESPACE_END
0711
0712 #if defined(__GNUC__) || (defined(_MSC_VER) && !defined(__clang__))
0713 RAPIDJSON_DIAG_POP
0714 #endif
0715
0716 #endif