100 enum { supportUnicode = 1 };
102 template<
typename OutputStream>
103 static void Encode(OutputStream& os,
unsigned codepoint) {
104 if (codepoint <= 0x7F)
105 os.Put(
static_cast<Ch
>(codepoint & 0xFF));
106 else if (codepoint <= 0x7FF) {
107 os.Put(
static_cast<Ch
>(0xC0 | ((codepoint >> 6) & 0xFF)));
108 os.Put(
static_cast<Ch
>(0x80 | ((codepoint & 0x3F))));
110 else if (codepoint <= 0xFFFF) {
111 os.Put(
static_cast<Ch
>(0xE0 | ((codepoint >> 12) & 0xFF)));
112 os.Put(
static_cast<Ch
>(0x80 | ((codepoint >> 6) & 0x3F)));
113 os.Put(
static_cast<Ch
>(0x80 | (codepoint & 0x3F)));
117 os.Put(
static_cast<Ch
>(0xF0 | ((codepoint >> 18) & 0xFF)));
118 os.Put(
static_cast<Ch
>(0x80 | ((codepoint >> 12) & 0x3F)));
119 os.Put(
static_cast<Ch
>(0x80 | ((codepoint >> 6) & 0x3F)));
120 os.Put(
static_cast<Ch
>(0x80 | (codepoint & 0x3F)));
124 template<
typename OutputStream>
125 static void EncodeUnsafe(OutputStream& os,
unsigned codepoint) {
126 if (codepoint <= 0x7F)
127 PutUnsafe(os,
static_cast<Ch
>(codepoint & 0xFF));
128 else if (codepoint <= 0x7FF) {
129 PutUnsafe(os,
static_cast<Ch
>(0xC0 | ((codepoint >> 6) & 0xFF)));
130 PutUnsafe(os,
static_cast<Ch
>(0x80 | ((codepoint & 0x3F))));
132 else if (codepoint <= 0xFFFF) {
133 PutUnsafe(os,
static_cast<Ch
>(0xE0 | ((codepoint >> 12) & 0xFF)));
134 PutUnsafe(os,
static_cast<Ch
>(0x80 | ((codepoint >> 6) & 0x3F)));
135 PutUnsafe(os,
static_cast<Ch
>(0x80 | (codepoint & 0x3F)));
139 PutUnsafe(os,
static_cast<Ch
>(0xF0 | ((codepoint >> 18) & 0xFF)));
140 PutUnsafe(os,
static_cast<Ch
>(0x80 | ((codepoint >> 12) & 0x3F)));
141 PutUnsafe(os,
static_cast<Ch
>(0x80 | ((codepoint >> 6) & 0x3F)));
142 PutUnsafe(os,
static_cast<Ch
>(0x80 | (codepoint & 0x3F)));
146 template <
typename InputStream>
147 static bool Decode(InputStream& is,
unsigned* codepoint) {
148#define RAPIDJSON_COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
149#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
150#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
151 typename InputStream::Ch c = is.Take();
153 *codepoint =
static_cast<unsigned char>(c);
157 unsigned char type = GetRange(
static_cast<unsigned char>(c));
161 *codepoint = (0xFFu >> type) &
static_cast<unsigned char>(c);
165 case 2: RAPIDJSON_TAIL();
return result;
166 case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
167 case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL();
return result;
168 case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
169 case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
170 case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL();
return result;
171 case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
172 default:
return false;
175#undef RAPIDJSON_TRANS
179 template <
typename InputStream,
typename OutputStream>
180 static bool Validate(InputStream& is, OutputStream& os) {
181#define RAPIDJSON_COPY() os.Put(c = is.Take())
182#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
183#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
190 switch (GetRange(
static_cast<unsigned char>(c))) {
191 case 2: RAPIDJSON_TAIL();
return result;
192 case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
193 case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL();
return result;
194 case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
195 case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
196 case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL();
return result;
197 case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL();
return result;
198 default:
return false;
201#undef RAPIDJSON_TRANS
205 static unsigned char GetRange(
unsigned char c) {
208 static const unsigned char type[] = {
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 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,
213 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
214 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
215 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
216 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
217 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,
218 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,
223 template <
typename InputByteStream>
224 static CharType TakeBOM(InputByteStream& is) {
226 typename InputByteStream::Ch c = Take(is);
227 if (
static_cast<unsigned char>(c) != 0xEFu)
return c;
229 if (
static_cast<unsigned char>(c) != 0xBBu)
return c;
231 if (
static_cast<unsigned char>(c) != 0xBFu)
return c;
236 template <
typename InputByteStream>
237 static Ch Take(InputByteStream& is) {
239 return static_cast<Ch
>(is.Take());
242 template <
typename OutputByteStream>
243 static void PutBOM(OutputByteStream& os) {
245 os.Put(
static_cast<typename OutputByteStream::Ch
>(0xEFu));
246 os.Put(
static_cast<typename OutputByteStream::Ch
>(0xBBu));
247 os.Put(
static_cast<typename OutputByteStream::Ch
>(0xBFu));
250 template <
typename OutputByteStream>
251 static void Put(OutputByteStream& os, Ch c) {
253 os.Put(
static_cast<typename OutputByteStream::Ch
>(c));