99 enum { supportUnicode = 1 };
101 template<
typename OutputStream>
102 static void Encode(OutputStream& os,
unsigned codepoint) {
103 if (codepoint <= 0x7F)
104 os.Put(
static_cast<Ch
>(codepoint & 0xFF));
105 else if (codepoint <= 0x7FF) {
106 os.Put(
static_cast<Ch
>(0xC0 | ((codepoint >> 6) & 0xFF)));
107 os.Put(
static_cast<Ch
>(0x80 | ((codepoint & 0x3F))));
109 else if (codepoint <= 0xFFFF) {
110 os.Put(
static_cast<Ch
>(0xE0 | ((codepoint >> 12) & 0xFF)));
111 os.Put(
static_cast<Ch
>(0x80 | ((codepoint >> 6) & 0x3F)));
112 os.Put(
static_cast<Ch
>(0x80 | (codepoint & 0x3F)));
116 os.Put(
static_cast<Ch
>(0xF0 | ((codepoint >> 18) & 0xFF)));
117 os.Put(
static_cast<Ch
>(0x80 | ((codepoint >> 12) & 0x3F)));
118 os.Put(
static_cast<Ch
>(0x80 | ((codepoint >> 6) & 0x3F)));
119 os.Put(
static_cast<Ch
>(0x80 | (codepoint & 0x3F)));
123 template<
typename OutputStream>
124 static void EncodeUnsafe(OutputStream& os,
unsigned codepoint) {
125 if (codepoint <= 0x7F)
126 PutUnsafe(os,
static_cast<Ch
>(codepoint & 0xFF));
127 else if (codepoint <= 0x7FF) {
128 PutUnsafe(os,
static_cast<Ch
>(0xC0 | ((codepoint >> 6) & 0xFF)));
129 PutUnsafe(os,
static_cast<Ch
>(0x80 | ((codepoint & 0x3F))));
131 else if (codepoint <= 0xFFFF) {
132 PutUnsafe(os,
static_cast<Ch
>(0xE0 | ((codepoint >> 12) & 0xFF)));
133 PutUnsafe(os,
static_cast<Ch
>(0x80 | ((codepoint >> 6) & 0x3F)));
134 PutUnsafe(os,
static_cast<Ch
>(0x80 | (codepoint & 0x3F)));
138 PutUnsafe(os,
static_cast<Ch
>(0xF0 | ((codepoint >> 18) & 0xFF)));
139 PutUnsafe(os,
static_cast<Ch
>(0x80 | ((codepoint >> 12) & 0x3F)));
140 PutUnsafe(os,
static_cast<Ch
>(0x80 | ((codepoint >> 6) & 0x3F)));
141 PutUnsafe(os,
static_cast<Ch
>(0x80 | (codepoint & 0x3F)));
145 template <
typename InputStream>
146 static bool Decode(InputStream& is,
unsigned* codepoint) {
147#define RAPIDJSON_COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
148#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
149#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
150 typename InputStream::Ch c = is.Take();
152 *codepoint =
static_cast<unsigned char>(c);
156 unsigned char type = GetRange(
static_cast<unsigned char>(c));
160 *codepoint = (0xFFu >> type) &
static_cast<unsigned char>(c);
164 case 2: RAPIDJSON_TAIL();
return result;
165 case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
166 case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL();
return result;
167 case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
168 case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
169 case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL();
return result;
170 case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
171 default:
return false;
174#undef RAPIDJSON_TRANS
178 template <
typename InputStream,
typename OutputStream>
179 static bool Validate(InputStream& is, OutputStream& os) {
180#define RAPIDJSON_COPY() os.Put(c = is.Take())
181#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
182#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
189 switch (GetRange(
static_cast<unsigned char>(c))) {
190 case 2: RAPIDJSON_TAIL();
return result;
191 case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
192 case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL();
return result;
193 case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
194 case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
195 case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL();
return result;
196 case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
197 default:
return false;
200#undef RAPIDJSON_TRANS
204 static unsigned char GetRange(
unsigned char c) {
207 static const unsigned char type[] = {
208 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,
209 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,
210 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,
211 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,
212 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
213 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
214 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
215 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
216 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,
217 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,
222 template <
typename InputByteStream>
223 static CharType TakeBOM(InputByteStream& is) {
225 typename InputByteStream::Ch c = Take(is);
226 if (
static_cast<unsigned char>(c) != 0xEFu)
return c;
228 if (
static_cast<unsigned char>(c) != 0xBBu)
return c;
230 if (
static_cast<unsigned char>(c) != 0xBFu)
return c;
235 template <
typename InputByteStream>
236 static Ch Take(InputByteStream& is) {
238 return static_cast<Ch
>(is.Take());
241 template <
typename OutputByteStream>
242 static void PutBOM(OutputByteStream& os) {
244 os.Put(
static_cast<typename OutputByteStream::Ch
>(0xEFu));
245 os.Put(
static_cast<typename OutputByteStream::Ch
>(0xBBu));
246 os.Put(
static_cast<typename OutputByteStream::Ch
>(0xBFu));
249 template <
typename OutputByteStream>
250 static void Put(OutputByteStream& os, Ch c) {
252 os.Put(
static_cast<typename OutputByteStream::Ch
>(c));