git repos / blockattack-game

blame: source/code/Libs/include/cereal/external/rapidjson/encodings.h

normal view · raw

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