| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1 |
// Tencent is pleased to support the open source community by making RapidJSON available. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
2 |
// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
3 |
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
4 |
// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
5 |
// Licensed under the MIT License (the "License"); you may not use this file except |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
6 |
// in compliance with the License. You may obtain a copy of the License at |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
7 |
// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
8 |
// http://opensource.org/licenses/MIT |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
9 |
// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
10 |
// Unless required by applicable law or agreed to in writing, software distributed |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
11 |
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
12 |
// CONDITIONS OF ANY KIND, either express or implied. See the License for the |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
13 |
// specific language governing permissions and limitations under the License. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
14 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
15 |
#ifndef CEREAL_RAPIDJSON_ENCODINGS_H_ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
16 |
#define CEREAL_RAPIDJSON_ENCODINGS_H_ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
17 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
18 |
#include "rapidjson.h" |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
19 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
20 |
#ifdef _MSC_VER |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
21 |
CEREAL_RAPIDJSON_DIAG_PUSH |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
22 |
CEREAL_RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
23 |
CEREAL_RAPIDJSON_DIAG_OFF(4702) // unreachable code |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
24 |
#elif defined(__GNUC__) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
25 |
CEREAL_RAPIDJSON_DIAG_PUSH |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
26 |
CEREAL_RAPIDJSON_DIAG_OFF(effc++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
27 |
CEREAL_RAPIDJSON_DIAG_OFF(overflow) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
28 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
29 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
30 |
CEREAL_RAPIDJSON_NAMESPACE_BEGIN |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
31 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
32 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
33 |
// Encoding |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
34 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
35 |
/*! \class rapidjson::Encoding |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
36 |
\brief Concept for encoding of Unicode characters. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
37 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
38 |
\code |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
39 |
concept Encoding { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
40 |
typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
41 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
42 |
enum { supportUnicode = 1 }; // or 0 if not supporting unicode |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
43 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
44 |
//! \brief Encode a Unicode codepoint to an output stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
45 |
//! \param os Output stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
46 |
//! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
47 |
template<typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
48 |
static void Encode(OutputStream& os, unsigned codepoint); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
49 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
50 |
//! \brief Decode a Unicode codepoint from an input stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
51 |
//! \param is Input stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
52 |
//! \param codepoint Output of the unicode codepoint. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
53 |
//! \return true if a valid codepoint can be decoded from the stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
54 |
template <typename InputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
55 |
static bool Decode(InputStream& is, unsigned* codepoint); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
56 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
57 |
//! \brief Validate one Unicode codepoint from an encoded stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
58 |
//! \param is Input stream to obtain codepoint. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
59 |
//! \param os Output for copying one codepoint. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
60 |
//! \return true if it is valid. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
61 |
//! \note This function just validating and copying the codepoint without actually decode it. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
62 |
template <typename InputStream, typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
63 |
static bool Validate(InputStream& is, OutputStream& os); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
64 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
65 |
// The following functions are deal with byte streams. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
66 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
67 |
//! Take a character from input byte stream, skip BOM if exist. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
68 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
69 |
static CharType TakeBOM(InputByteStream& is); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
70 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
71 |
//! Take a character from input byte stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
72 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
73 |
static Ch Take(InputByteStream& is); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
74 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
75 |
//! Put BOM to output byte stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
76 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
77 |
static void PutBOM(OutputByteStream& os); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
78 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
79 |
//! Put a character to output byte stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
80 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
81 |
static void Put(OutputByteStream& os, Ch c); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
82 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
83 |
\endcode |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
84 |
*/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
85 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
86 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
87 |
// UTF8 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
88 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
89 |
//! UTF-8 encoding. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
90 |
/*! http://en.wikipedia.org/wiki/UTF-8 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
91 |
http://tools.ietf.org/html/rfc3629 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
92 |
\tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
93 |
\note implements Encoding concept |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
94 |
*/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
95 |
template<typename CharType = char> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
96 |
struct UTF8 { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
97 |
typedef CharType Ch; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
98 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
99 |
enum { supportUnicode = 1 }; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
100 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
101 |
template<typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
102 |
static void Encode(OutputStream& os, unsigned codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
103 |
if (codepoint <= 0x7F) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
104 |
os.Put(static_cast<Ch>(codepoint & 0xFF)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
105 |
else if (codepoint <= 0x7FF) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
106 |
os.Put(static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
107 |
os.Put(static_cast<Ch>(0x80 | ((codepoint & 0x3F)))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
108 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
109 |
else if (codepoint <= 0xFFFF) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
110 |
os.Put(static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
111 |
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
112 |
os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
113 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
114 |
else { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
115 |
CEREAL_RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
116 |
os.Put(static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
117 |
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
118 |
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
119 |
os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
120 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
121 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
122 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
123 |
template<typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
124 |
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
125 |
if (codepoint <= 0x7F) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
126 |
PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
127 |
else if (codepoint <= 0x7FF) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
128 |
PutUnsafe(os, static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
129 |
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint & 0x3F)))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
130 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
131 |
else if (codepoint <= 0xFFFF) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
132 |
PutUnsafe(os, static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
133 |
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
134 |
PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
135 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
136 |
else { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
137 |
CEREAL_RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
138 |
PutUnsafe(os, static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
139 |
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
140 |
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
141 |
PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
142 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
143 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
144 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
145 |
template <typename InputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
146 |
static bool Decode(InputStream& is, unsigned* codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
147 |
#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
148 |
#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
149 |
#define TAIL() COPY(); TRANS(0x70) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
150 |
typename InputStream::Ch c = is.Take(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
151 |
if (!(c & 0x80)) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
152 |
*codepoint = static_cast<unsigned char>(c); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
153 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
154 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
155 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
156 |
unsigned char type = GetRange(static_cast<unsigned char>(c)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
157 |
if (type >= 32) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
158 |
*codepoint = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
159 |
} else { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
160 |
*codepoint = (0xFF >> type) & static_cast<unsigned char>(c); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
161 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
162 |
bool result = true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
163 |
switch (type) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
164 |
case 2: TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
165 |
case 3: TAIL(); TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
166 |
case 4: COPY(); TRANS(0x50); TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
167 |
case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
168 |
case 6: TAIL(); TAIL(); TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
169 |
case 10: COPY(); TRANS(0x20); TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
170 |
case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
171 |
default: return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
172 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
173 |
#undef COPY |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
174 |
#undef TRANS |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
175 |
#undef TAIL |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
176 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
177 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
178 |
template <typename InputStream, typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
179 |
static bool Validate(InputStream& is, OutputStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
180 |
#define COPY() os.Put(c = is.Take()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
181 |
#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
182 |
#define TAIL() COPY(); TRANS(0x70) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
183 |
Ch c; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
184 |
COPY(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
185 |
if (!(c & 0x80)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
186 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
187 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
188 |
bool result = true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
189 |
switch (GetRange(static_cast<unsigned char>(c))) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
190 |
case 2: TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
191 |
case 3: TAIL(); TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
192 |
case 4: COPY(); TRANS(0x50); TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
193 |
case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
194 |
case 6: TAIL(); TAIL(); TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
195 |
case 10: COPY(); TRANS(0x20); TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
196 |
case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
197 |
default: return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
198 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
199 |
#undef COPY |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
200 |
#undef TRANS |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
201 |
#undef TAIL |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
202 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
203 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
204 |
static unsigned char GetRange(unsigned char c) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
205 |
// Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
206 |
// With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
207 |
static const unsigned char type[] = { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
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, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
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, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
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, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
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, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
212 |
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
213 |
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
214 |
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
215 |
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
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, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
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, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
218 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
219 |
return type[c]; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
220 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
221 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
222 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
223 |
static CharType TakeBOM(InputByteStream& is) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
224 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
225 |
typename InputByteStream::Ch c = Take(is); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
226 |
if (static_cast<unsigned char>(c) != 0xEFu) return c; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
227 |
c = is.Take(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
228 |
if (static_cast<unsigned char>(c) != 0xBBu) return c; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
229 |
c = is.Take(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
230 |
if (static_cast<unsigned char>(c) != 0xBFu) return c; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
231 |
c = is.Take(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
232 |
return c; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
233 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
234 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
235 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
236 |
static Ch Take(InputByteStream& is) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
237 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
238 |
return static_cast<Ch>(is.Take()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
239 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
240 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
241 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
242 |
static void PutBOM(OutputByteStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
243 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
244 |
os.Put(static_cast<typename OutputByteStream::Ch>(0xEFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
245 |
os.Put(static_cast<typename OutputByteStream::Ch>(0xBBu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
246 |
os.Put(static_cast<typename OutputByteStream::Ch>(0xBFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
247 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
248 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
249 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
250 |
static void Put(OutputByteStream& os, Ch c) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
251 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
252 |
os.Put(static_cast<typename OutputByteStream::Ch>(c)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
253 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
254 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
255 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
256 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
257 |
// UTF16 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
258 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
259 |
//! UTF-16 encoding. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
260 |
/*! http://en.wikipedia.org/wiki/UTF-16 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
261 |
http://tools.ietf.org/html/rfc2781 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
262 |
\tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
263 |
\note implements Encoding concept |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
264 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
265 |
\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
266 |
For streaming, use UTF16LE and UTF16BE, which handle endianness. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
267 |
*/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
268 |
template<typename CharType = wchar_t> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
269 |
struct UTF16 { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
270 |
typedef CharType Ch; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
271 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
272 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
273 |
enum { supportUnicode = 1 }; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
274 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
275 |
template<typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
276 |
static void Encode(OutputStream& os, unsigned codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
277 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
278 |
if (codepoint <= 0xFFFF) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
279 |
CEREAL_RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
280 |
os.Put(static_cast<typename OutputStream::Ch>(codepoint)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
281 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
282 |
else { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
283 |
CEREAL_RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
284 |
unsigned v = codepoint - 0x10000; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
285 |
os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
286 |
os.Put((v & 0x3FF) | 0xDC00); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
287 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
288 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
289 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
290 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
291 |
template<typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
292 |
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
293 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
294 |
if (codepoint <= 0xFFFF) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
295 |
CEREAL_RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
296 |
PutUnsafe(os, static_cast<typename OutputStream::Ch>(codepoint)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
297 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
298 |
else { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
299 |
CEREAL_RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
300 |
unsigned v = codepoint - 0x10000; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
301 |
PutUnsafe(os, static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
302 |
PutUnsafe(os, (v & 0x3FF) | 0xDC00); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
303 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
304 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
305 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
306 |
template <typename InputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
307 |
static bool Decode(InputStream& is, unsigned* codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
308 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
309 |
typename InputStream::Ch c = is.Take(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
310 |
if (c < 0xD800 || c > 0xDFFF) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
311 |
*codepoint = static_cast<unsigned>(c); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
312 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
313 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
314 |
else if (c <= 0xDBFF) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
315 |
*codepoint = (static_cast<unsigned>(c) & 0x3FF) << 10; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
316 |
c = is.Take(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
317 |
*codepoint |= (static_cast<unsigned>(c) & 0x3FF); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
318 |
*codepoint += 0x10000; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
319 |
return c >= 0xDC00 && c <= 0xDFFF; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
320 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
321 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
322 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
323 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
324 |
template <typename InputStream, typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
325 |
static bool Validate(InputStream& is, OutputStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
326 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
327 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
328 |
typename InputStream::Ch c; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
329 |
os.Put(static_cast<typename OutputStream::Ch>(c = is.Take())); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
330 |
if (c < 0xD800 || c > 0xDFFF) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
331 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
332 |
else if (c <= 0xDBFF) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
333 |
os.Put(c = is.Take()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
334 |
return c >= 0xDC00 && c <= 0xDFFF; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
335 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
336 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
337 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
338 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
339 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
340 |
//! UTF-16 little endian encoding. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
341 |
template<typename CharType = wchar_t> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
342 |
struct UTF16LE : UTF16<CharType> { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
343 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
344 |
static CharType TakeBOM(InputByteStream& is) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
345 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
346 |
CharType c = Take(is); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
347 |
return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
348 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
349 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
350 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
351 |
static CharType Take(InputByteStream& is) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
352 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
353 |
unsigned c = static_cast<uint8_t>(is.Take()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
354 |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
355 |
return static_cast<CharType>(c); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
356 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
357 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
358 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
359 |
static void PutBOM(OutputByteStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
360 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
361 |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
362 |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
363 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
364 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
365 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
366 |
static void Put(OutputByteStream& os, CharType c) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
367 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
368 |
os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
369 |
os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
370 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
371 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
372 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
373 |
//! UTF-16 big endian encoding. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
374 |
template<typename CharType = wchar_t> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
375 |
struct UTF16BE : UTF16<CharType> { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
376 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
377 |
static CharType TakeBOM(InputByteStream& is) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
378 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
379 |
CharType c = Take(is); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
380 |
return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
381 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
382 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
383 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
384 |
static CharType Take(InputByteStream& is) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
385 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
386 |
unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
387 |
c |= static_cast<uint8_t>(is.Take()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
388 |
return static_cast<CharType>(c); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
389 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
390 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
391 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
392 |
static void PutBOM(OutputByteStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
393 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
394 |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
395 |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
396 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
397 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
398 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
399 |
static void Put(OutputByteStream& os, CharType c) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
400 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
401 |
os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
402 |
os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
403 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
404 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
405 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
406 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
407 |
// UTF32 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
408 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
409 |
//! UTF-32 encoding. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
410 |
/*! http://en.wikipedia.org/wiki/UTF-32 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
411 |
\tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
412 |
\note implements Encoding concept |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
413 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
414 |
\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
415 |
For streaming, use UTF32LE and UTF32BE, which handle endianness. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
416 |
*/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
417 |
template<typename CharType = unsigned> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
418 |
struct UTF32 { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
419 |
typedef CharType Ch; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
420 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
421 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
422 |
enum { supportUnicode = 1 }; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
423 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
424 |
template<typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
425 |
static void Encode(OutputStream& os, unsigned codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
426 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
427 |
CEREAL_RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
428 |
os.Put(codepoint); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
429 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
430 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
431 |
template<typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
432 |
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
433 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
434 |
CEREAL_RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
435 |
PutUnsafe(os, codepoint); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
436 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
437 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
438 |
template <typename InputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
439 |
static bool Decode(InputStream& is, unsigned* codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
440 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
441 |
Ch c = is.Take(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
442 |
*codepoint = c; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
443 |
return c <= 0x10FFFF; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
444 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
445 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
446 |
template <typename InputStream, typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
447 |
static bool Validate(InputStream& is, OutputStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
448 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
449 |
Ch c; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
450 |
os.Put(c = is.Take()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
451 |
return c <= 0x10FFFF; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
452 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
453 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
454 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
455 |
//! UTF-32 little endian enocoding. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
456 |
template<typename CharType = unsigned> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
457 |
struct UTF32LE : UTF32<CharType> { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
458 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
459 |
static CharType TakeBOM(InputByteStream& is) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
460 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
461 |
CharType c = Take(is); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
462 |
return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
463 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
464 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
465 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
466 |
static CharType Take(InputByteStream& is) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
467 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
468 |
unsigned c = static_cast<uint8_t>(is.Take()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
469 |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
470 |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
471 |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
472 |
return static_cast<CharType>(c); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
473 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
474 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
475 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
476 |
static void PutBOM(OutputByteStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
477 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
478 |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
479 |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
480 |
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
481 |
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
482 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
483 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
484 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
485 |
static void Put(OutputByteStream& os, CharType c) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
486 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
487 |
os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
488 |
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
489 |
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
490 |
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
491 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
492 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
493 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
494 |
//! UTF-32 big endian encoding. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
495 |
template<typename CharType = unsigned> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
496 |
struct UTF32BE : UTF32<CharType> { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
497 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
498 |
static CharType TakeBOM(InputByteStream& is) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
499 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
500 |
CharType c = Take(is); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
501 |
return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
502 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
503 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
504 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
505 |
static CharType Take(InputByteStream& is) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
506 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
507 |
unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
508 |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
509 |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
510 |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
511 |
return static_cast<CharType>(c); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
512 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
513 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
514 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
515 |
static void PutBOM(OutputByteStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
516 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
517 |
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
518 |
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
519 |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
520 |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
521 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
522 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
523 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
524 |
static void Put(OutputByteStream& os, CharType c) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
525 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
526 |
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
527 |
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
528 |
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
529 |
os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
530 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
531 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
532 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
533 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
534 |
// ASCII |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
535 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
536 |
//! ASCII encoding. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
537 |
/*! http://en.wikipedia.org/wiki/ASCII |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
538 |
\tparam CharType Code unit for storing 7-bit ASCII data. Default is char. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
539 |
\note implements Encoding concept |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
540 |
*/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
541 |
template<typename CharType = char> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
542 |
struct ASCII { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
543 |
typedef CharType Ch; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
544 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
545 |
enum { supportUnicode = 0 }; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
546 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
547 |
template<typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
548 |
static void Encode(OutputStream& os, unsigned codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
549 |
CEREAL_RAPIDJSON_ASSERT(codepoint <= 0x7F); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
550 |
os.Put(static_cast<Ch>(codepoint & 0xFF)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
551 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
552 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
553 |
template<typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
554 |
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
555 |
CEREAL_RAPIDJSON_ASSERT(codepoint <= 0x7F); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
556 |
PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
557 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
558 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
559 |
template <typename InputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
560 |
static bool Decode(InputStream& is, unsigned* codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
561 |
uint8_t c = static_cast<uint8_t>(is.Take()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
562 |
*codepoint = c; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
563 |
return c <= 0X7F; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
564 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
565 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
566 |
template <typename InputStream, typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
567 |
static bool Validate(InputStream& is, OutputStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
568 |
uint8_t c = static_cast<uint8_t>(is.Take()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
569 |
os.Put(static_cast<typename OutputStream::Ch>(c)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
570 |
return c <= 0x7F; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
571 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
572 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
573 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
574 |
static CharType TakeBOM(InputByteStream& is) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
575 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
576 |
uint8_t c = static_cast<uint8_t>(Take(is)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
577 |
return static_cast<Ch>(c); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
578 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
579 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
580 |
template <typename InputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
581 |
static Ch Take(InputByteStream& is) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
582 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
583 |
return static_cast<Ch>(is.Take()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
584 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
585 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
586 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
587 |
static void PutBOM(OutputByteStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
588 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
589 |
(void)os; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
590 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
591 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
592 |
template <typename OutputByteStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
593 |
static void Put(OutputByteStream& os, Ch c) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
594 |
CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
595 |
os.Put(static_cast<typename OutputByteStream::Ch>(c)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
596 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
597 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
598 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
599 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
600 |
// AutoUTF |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
601 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
602 |
//! Runtime-specified UTF encoding type of a stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
603 |
enum UTFType { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
604 |
kUTF8 = 0, //!< UTF-8. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
605 |
kUTF16LE = 1, //!< UTF-16 little endian. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
606 |
kUTF16BE = 2, //!< UTF-16 big endian. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
607 |
kUTF32LE = 3, //!< UTF-32 little endian. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
608 |
kUTF32BE = 4 //!< UTF-32 big endian. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
609 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
610 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
611 |
//! Dynamically select encoding according to stream's runtime-specified UTF encoding type. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
612 |
/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType(). |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
613 |
*/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
614 |
template<typename CharType> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
615 |
struct AutoUTF { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
616 |
typedef CharType Ch; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
617 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
618 |
enum { supportUnicode = 1 }; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
619 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
620 |
#define CEREAL_RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
621 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
622 |
template<typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
623 |
CEREAL_RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
624 |
typedef void (*EncodeFunc)(OutputStream&, unsigned); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
625 |
static const EncodeFunc f[] = { CEREAL_RAPIDJSON_ENCODINGS_FUNC(Encode) }; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
626 |
(*f[os.GetType()])(os, codepoint); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
627 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
628 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
629 |
template<typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
630 |
CEREAL_RAPIDJSON_FORCEINLINE static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
631 |
typedef void (*EncodeFunc)(OutputStream&, unsigned); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
632 |
static const EncodeFunc f[] = { CEREAL_RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) }; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
633 |
(*f[os.GetType()])(os, codepoint); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
634 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
635 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
636 |
template <typename InputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
637 |
CEREAL_RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
638 |
typedef bool (*DecodeFunc)(InputStream&, unsigned*); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
639 |
static const DecodeFunc f[] = { CEREAL_RAPIDJSON_ENCODINGS_FUNC(Decode) }; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
640 |
return (*f[is.GetType()])(is, codepoint); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
641 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
642 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
643 |
template <typename InputStream, typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
644 |
CEREAL_RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
645 |
typedef bool (*ValidateFunc)(InputStream&, OutputStream&); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
646 |
static const ValidateFunc f[] = { CEREAL_RAPIDJSON_ENCODINGS_FUNC(Validate) }; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
647 |
return (*f[is.GetType()])(is, os); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
648 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
649 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
650 |
#undef CEREAL_RAPIDJSON_ENCODINGS_FUNC |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
651 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
652 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
653 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
654 |
// Transcoder |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
655 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
656 |
//! Encoding conversion. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
657 |
template<typename SourceEncoding, typename TargetEncoding> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
658 |
struct Transcoder { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
659 |
//! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
660 |
template<typename InputStream, typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
661 |
CEREAL_RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
662 |
unsigned codepoint; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
663 |
if (!SourceEncoding::Decode(is, &codepoint)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
664 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
665 |
TargetEncoding::Encode(os, codepoint); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
666 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
667 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
668 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
669 |
template<typename InputStream, typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
670 |
CEREAL_RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
671 |
unsigned codepoint; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
672 |
if (!SourceEncoding::Decode(is, &codepoint)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
673 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
674 |
TargetEncoding::EncodeUnsafe(os, codepoint); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
675 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
676 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
677 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
678 |
//! Validate one Unicode codepoint from an encoded stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
679 |
template<typename InputStream, typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
680 |
CEREAL_RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
681 |
return Transcode(is, os); // Since source/target encoding is different, must transcode. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
682 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
683 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
684 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
685 |
// Forward declaration. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
686 |
template<typename Stream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
687 |
inline void PutUnsafe(Stream& stream, typename Stream::Ch c); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
688 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
689 |
//! Specialization of Transcoder with same source and target encoding. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
690 |
template<typename Encoding> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
691 |
struct Transcoder<Encoding, Encoding> { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
692 |
template<typename InputStream, typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
693 |
CEREAL_RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
694 |
os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
695 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
696 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
697 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
698 |
template<typename InputStream, typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
699 |
CEREAL_RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
700 |
PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
701 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
702 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
703 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
704 |
template<typename InputStream, typename OutputStream> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
705 |
CEREAL_RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
706 |
return Encoding::Validate(is, os); // source/target encoding are the same |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
707 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
708 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
709 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
710 |
CEREAL_RAPIDJSON_NAMESPACE_END |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
711 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
712 |
#if defined(__GNUC__) || defined(_MSC_VER) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
713 |
CEREAL_RAPIDJSON_DIAG_POP |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
714 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
715 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
716 |
#endif // CEREAL_RAPIDJSON_ENCODINGS_H_ |
|
|
1970-01-01 00:00 |
717 |
|