Maxim Integrated / Mbed OS MAXREFDES155#

Dependencies:   MaximInterface

Committer:
IanBenzMaxim
Date:
Fri Oct 04 12:10:11 2019 -0500
Revision:
17:5926077e5345
Parent:
16:a004191a79ab
Set pin maps through the mbed configuration system. Added support for MAX32625MBED target. Updated mbed-os to version 5.7.7 for MAX32625 I2C fixes. Consolidated simplelink hook definitions.

Who changed what in which revision?

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