git repos / blockattack-game

blame: source/code/Libs/include/utf8/core.h

normal view · raw

9f5ec0cc sago007 2015-12-05 08:01 1
// Copyright 2006 Nemanja Trifunovic
9f5ec0cc sago007 2015-12-05 08:01 2
9f5ec0cc sago007 2015-12-05 08:01 3
/*
9f5ec0cc sago007 2015-12-05 08:01 4
Permission is hereby granted, free of charge, to any person or organization
9f5ec0cc sago007 2015-12-05 08:01 5
obtaining a copy of the software and accompanying documentation covered by
9f5ec0cc sago007 2015-12-05 08:01 6
this license (the "Software") to use, reproduce, display, distribute,
9f5ec0cc sago007 2015-12-05 08:01 7
execute, and transmit the Software, and to prepare derivative works of the
9f5ec0cc sago007 2015-12-05 08:01 8
Software, and to permit third-parties to whom the Software is furnished to
9f5ec0cc sago007 2015-12-05 08:01 9
do so, all subject to the following:
9f5ec0cc sago007 2015-12-05 08:01 10
9f5ec0cc sago007 2015-12-05 08:01 11
The copyright notices in the Software and this entire statement, including
9f5ec0cc sago007 2015-12-05 08:01 12
the above license grant, this restriction and the following disclaimer,
9f5ec0cc sago007 2015-12-05 08:01 13
must be included in all copies of the Software, in whole or in part, and
9f5ec0cc sago007 2015-12-05 08:01 14
all derivative works of the Software, unless such copies or derivative
9f5ec0cc sago007 2015-12-05 08:01 15
works are solely in the form of machine-executable object code generated by
9f5ec0cc sago007 2015-12-05 08:01 16
a source language processor.
9f5ec0cc sago007 2015-12-05 08:01 17
9f5ec0cc sago007 2015-12-05 08:01 18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9f5ec0cc sago007 2015-12-05 08:01 19
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9f5ec0cc sago007 2015-12-05 08:01 20
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
9f5ec0cc sago007 2015-12-05 08:01 21
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
9f5ec0cc sago007 2015-12-05 08:01 22
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
9f5ec0cc sago007 2015-12-05 08:01 23
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
9f5ec0cc sago007 2015-12-05 08:01 24
DEALINGS IN THE SOFTWARE.
9f5ec0cc sago007 2015-12-05 08:01 25
*/
9f5ec0cc sago007 2015-12-05 08:01 26
9f5ec0cc sago007 2015-12-05 08:01 27
9f5ec0cc sago007 2015-12-05 08:01 28
#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
9f5ec0cc sago007 2015-12-05 08:01 29
#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
9f5ec0cc sago007 2015-12-05 08:01 30
9f5ec0cc sago007 2015-12-05 08:01 31
#include <iterator>
9f5ec0cc sago007 2015-12-05 08:01 32
9f5ec0cc sago007 2015-12-05 08:01 33
namespace utf8
9f5ec0cc sago007 2015-12-05 08:01 34
{
9f5ec0cc sago007 2015-12-05 08:01 35
    // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
9f5ec0cc sago007 2015-12-05 08:01 36
    // You may need to change them to match your system.
9f5ec0cc sago007 2015-12-05 08:01 37
    // These typedefs have the same names as ones from cstdint, or boost/cstdint
9f5ec0cc sago007 2015-12-05 08:01 38
    typedef unsigned char   uint8_t;
9f5ec0cc sago007 2015-12-05 08:01 39
    typedef unsigned short  uint16_t;
9f5ec0cc sago007 2015-12-05 08:01 40
    typedef unsigned int    uint32_t;
9f5ec0cc sago007 2015-12-05 08:01 41
9f5ec0cc sago007 2015-12-05 08:01 42
// Helper code - not intended to be directly called by the library users. May be changed at any time
9f5ec0cc sago007 2015-12-05 08:01 43
namespace internal
9f5ec0cc sago007 2015-12-05 08:01 44
{
9f5ec0cc sago007 2015-12-05 08:01 45
    // Unicode constants
9f5ec0cc sago007 2015-12-05 08:01 46
    // Leading (high) surrogates: 0xd800 - 0xdbff
9f5ec0cc sago007 2015-12-05 08:01 47
    // Trailing (low) surrogates: 0xdc00 - 0xdfff
9f5ec0cc sago007 2015-12-05 08:01 48
    const uint16_t LEAD_SURROGATE_MIN  = 0xd800u;
9f5ec0cc sago007 2015-12-05 08:01 49
    const uint16_t LEAD_SURROGATE_MAX  = 0xdbffu;
9f5ec0cc sago007 2015-12-05 08:01 50
    const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
9f5ec0cc sago007 2015-12-05 08:01 51
    const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
9f5ec0cc sago007 2015-12-05 08:01 52
    const uint16_t LEAD_OFFSET         = LEAD_SURROGATE_MIN - (0x10000 >> 10);
9f5ec0cc sago007 2015-12-05 08:01 53
    const uint32_t SURROGATE_OFFSET    = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN;
9f5ec0cc sago007 2015-12-05 08:01 54
9f5ec0cc sago007 2015-12-05 08:01 55
    // Maximum valid value for a Unicode code point
9f5ec0cc sago007 2015-12-05 08:01 56
    const uint32_t CODE_POINT_MAX      = 0x0010ffffu;
9f5ec0cc sago007 2015-12-05 08:01 57
9f5ec0cc sago007 2015-12-05 08:01 58
    template<typename octet_type>
9f5ec0cc sago007 2015-12-05 08:01 59
    inline uint8_t mask8(octet_type oc)
9f5ec0cc sago007 2015-12-05 08:01 60
    {
9f5ec0cc sago007 2015-12-05 08:01 61
        return static_cast<uint8_t>(0xff & oc);
9f5ec0cc sago007 2015-12-05 08:01 62
    }
9f5ec0cc sago007 2015-12-05 08:01 63
    template<typename u16_type>
9f5ec0cc sago007 2015-12-05 08:01 64
    inline uint16_t mask16(u16_type oc)
9f5ec0cc sago007 2015-12-05 08:01 65
    {
9f5ec0cc sago007 2015-12-05 08:01 66
        return static_cast<uint16_t>(0xffff & oc);
9f5ec0cc sago007 2015-12-05 08:01 67
    }
9f5ec0cc sago007 2015-12-05 08:01 68
    template<typename octet_type>
9f5ec0cc sago007 2015-12-05 08:01 69
    inline bool is_trail(octet_type oc)
9f5ec0cc sago007 2015-12-05 08:01 70
    {
9f5ec0cc sago007 2015-12-05 08:01 71
        return ((utf8::internal::mask8(oc) >> 6) == 0x2);
9f5ec0cc sago007 2015-12-05 08:01 72
    }
9f5ec0cc sago007 2015-12-05 08:01 73
9f5ec0cc sago007 2015-12-05 08:01 74
    template <typename u16>
9f5ec0cc sago007 2015-12-05 08:01 75
    inline bool is_lead_surrogate(u16 cp)
9f5ec0cc sago007 2015-12-05 08:01 76
    {
9f5ec0cc sago007 2015-12-05 08:01 77
        return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
9f5ec0cc sago007 2015-12-05 08:01 78
    }
9f5ec0cc sago007 2015-12-05 08:01 79
9f5ec0cc sago007 2015-12-05 08:01 80
    template <typename u16>
9f5ec0cc sago007 2015-12-05 08:01 81
    inline bool is_trail_surrogate(u16 cp)
9f5ec0cc sago007 2015-12-05 08:01 82
    {
9f5ec0cc sago007 2015-12-05 08:01 83
        return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
9f5ec0cc sago007 2015-12-05 08:01 84
    }
9f5ec0cc sago007 2015-12-05 08:01 85
9f5ec0cc sago007 2015-12-05 08:01 86
    template <typename u16>
9f5ec0cc sago007 2015-12-05 08:01 87
    inline bool is_surrogate(u16 cp)
9f5ec0cc sago007 2015-12-05 08:01 88
    {
9f5ec0cc sago007 2015-12-05 08:01 89
        return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
9f5ec0cc sago007 2015-12-05 08:01 90
    }
9f5ec0cc sago007 2015-12-05 08:01 91
9f5ec0cc sago007 2015-12-05 08:01 92
    template <typename u32>
9f5ec0cc sago007 2015-12-05 08:01 93
    inline bool is_code_point_valid(u32 cp)
9f5ec0cc sago007 2015-12-05 08:01 94
    {
9f5ec0cc sago007 2015-12-05 08:01 95
        return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));
9f5ec0cc sago007 2015-12-05 08:01 96
    }
9f5ec0cc sago007 2015-12-05 08:01 97
9f5ec0cc sago007 2015-12-05 08:01 98
    template <typename octet_iterator>
9f5ec0cc sago007 2015-12-05 08:01 99
    inline typename std::iterator_traits<octet_iterator>::difference_type
9f5ec0cc sago007 2015-12-05 08:01 100
    sequence_length(octet_iterator lead_it)
9f5ec0cc sago007 2015-12-05 08:01 101
    {
9f5ec0cc sago007 2015-12-05 08:01 102
        uint8_t lead = utf8::internal::mask8(*lead_it);
9f5ec0cc sago007 2015-12-05 08:01 103
        if (lead < 0x80)
9f5ec0cc sago007 2015-12-05 08:01 104
            return 1;
9f5ec0cc sago007 2015-12-05 08:01 105
        else if ((lead >> 5) == 0x6)
9f5ec0cc sago007 2015-12-05 08:01 106
            return 2;
9f5ec0cc sago007 2015-12-05 08:01 107
        else if ((lead >> 4) == 0xe)
9f5ec0cc sago007 2015-12-05 08:01 108
            return 3;
9f5ec0cc sago007 2015-12-05 08:01 109
        else if ((lead >> 3) == 0x1e)
9f5ec0cc sago007 2015-12-05 08:01 110
            return 4;
9f5ec0cc sago007 2015-12-05 08:01 111
        else
9f5ec0cc sago007 2015-12-05 08:01 112
            return 0;
9f5ec0cc sago007 2015-12-05 08:01 113
    }
9f5ec0cc sago007 2015-12-05 08:01 114
9f5ec0cc sago007 2015-12-05 08:01 115
    template <typename octet_difference_type>
9f5ec0cc sago007 2015-12-05 08:01 116
    inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
9f5ec0cc sago007 2015-12-05 08:01 117
    {
9f5ec0cc sago007 2015-12-05 08:01 118
        if (cp < 0x80) {
9f5ec0cc sago007 2015-12-05 08:01 119
            if (length != 1) 
9f5ec0cc sago007 2015-12-05 08:01 120
                return true;
9f5ec0cc sago007 2015-12-05 08:01 121
        }
9f5ec0cc sago007 2015-12-05 08:01 122
        else if (cp < 0x800) {
9f5ec0cc sago007 2015-12-05 08:01 123
            if (length != 2) 
9f5ec0cc sago007 2015-12-05 08:01 124
                return true;
9f5ec0cc sago007 2015-12-05 08:01 125
        }
9f5ec0cc sago007 2015-12-05 08:01 126
        else if (cp < 0x10000) {
9f5ec0cc sago007 2015-12-05 08:01 127
            if (length != 3) 
9f5ec0cc sago007 2015-12-05 08:01 128
                return true;
9f5ec0cc sago007 2015-12-05 08:01 129
        }
9f5ec0cc sago007 2015-12-05 08:01 130
9f5ec0cc sago007 2015-12-05 08:01 131
        return false;
9f5ec0cc sago007 2015-12-05 08:01 132
    }
9f5ec0cc sago007 2015-12-05 08:01 133
9f5ec0cc sago007 2015-12-05 08:01 134
    enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
9f5ec0cc sago007 2015-12-05 08:01 135
9f5ec0cc sago007 2015-12-05 08:01 136
    /// Helper for get_sequence_x
9f5ec0cc sago007 2015-12-05 08:01 137
    template <typename octet_iterator>
9f5ec0cc sago007 2015-12-05 08:01 138
    utf_error increase_safely(octet_iterator& it, octet_iterator end)
9f5ec0cc sago007 2015-12-05 08:01 139
    {
9f5ec0cc sago007 2015-12-05 08:01 140
        if (++it == end)
9f5ec0cc sago007 2015-12-05 08:01 141
            return NOT_ENOUGH_ROOM;
9f5ec0cc sago007 2015-12-05 08:01 142
9f5ec0cc sago007 2015-12-05 08:01 143
        if (!utf8::internal::is_trail(*it))
9f5ec0cc sago007 2015-12-05 08:01 144
            return INCOMPLETE_SEQUENCE;
9f5ec0cc sago007 2015-12-05 08:01 145
        
9f5ec0cc sago007 2015-12-05 08:01 146
        return UTF8_OK;
9f5ec0cc sago007 2015-12-05 08:01 147
    }
9f5ec0cc sago007 2015-12-05 08:01 148
9f5ec0cc sago007 2015-12-05 08:01 149
    #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}    
9f5ec0cc sago007 2015-12-05 08:01 150
9f5ec0cc sago007 2015-12-05 08:01 151
    /// get_sequence_x functions decode utf-8 sequences of the length x
9f5ec0cc sago007 2015-12-05 08:01 152
    template <typename octet_iterator>
9f5ec0cc sago007 2015-12-05 08:01 153
    utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)
9f5ec0cc sago007 2015-12-05 08:01 154
    {
9f5ec0cc sago007 2015-12-05 08:01 155
        if (it == end)
9f5ec0cc sago007 2015-12-05 08:01 156
            return NOT_ENOUGH_ROOM;
9f5ec0cc sago007 2015-12-05 08:01 157
9f5ec0cc sago007 2015-12-05 08:01 158
        code_point = utf8::internal::mask8(*it);
9f5ec0cc sago007 2015-12-05 08:01 159
9f5ec0cc sago007 2015-12-05 08:01 160
        return UTF8_OK;
9f5ec0cc sago007 2015-12-05 08:01 161
    }
9f5ec0cc sago007 2015-12-05 08:01 162
9f5ec0cc sago007 2015-12-05 08:01 163
    template <typename octet_iterator>
9f5ec0cc sago007 2015-12-05 08:01 164
    utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)
9f5ec0cc sago007 2015-12-05 08:01 165
    {
9f5ec0cc sago007 2015-12-05 08:01 166
        if (it == end) 
9f5ec0cc sago007 2015-12-05 08:01 167
            return NOT_ENOUGH_ROOM;
9f5ec0cc sago007 2015-12-05 08:01 168
        
9f5ec0cc sago007 2015-12-05 08:01 169
        code_point = utf8::internal::mask8(*it);
9f5ec0cc sago007 2015-12-05 08:01 170
9f5ec0cc sago007 2015-12-05 08:01 171
        UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
9f5ec0cc sago007 2015-12-05 08:01 172
9f5ec0cc sago007 2015-12-05 08:01 173
        code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);
9f5ec0cc sago007 2015-12-05 08:01 174
9f5ec0cc sago007 2015-12-05 08:01 175
        return UTF8_OK;
9f5ec0cc sago007 2015-12-05 08:01 176
    }
9f5ec0cc sago007 2015-12-05 08:01 177
9f5ec0cc sago007 2015-12-05 08:01 178
    template <typename octet_iterator>
9f5ec0cc sago007 2015-12-05 08:01 179
    utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)
9f5ec0cc sago007 2015-12-05 08:01 180
    {
9f5ec0cc sago007 2015-12-05 08:01 181
        if (it == end)
9f5ec0cc sago007 2015-12-05 08:01 182
            return NOT_ENOUGH_ROOM;
9f5ec0cc sago007 2015-12-05 08:01 183
            
9f5ec0cc sago007 2015-12-05 08:01 184
        code_point = utf8::internal::mask8(*it);
9f5ec0cc sago007 2015-12-05 08:01 185
9f5ec0cc sago007 2015-12-05 08:01 186
        UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
9f5ec0cc sago007 2015-12-05 08:01 187
9f5ec0cc sago007 2015-12-05 08:01 188
        code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
9f5ec0cc sago007 2015-12-05 08:01 189
9f5ec0cc sago007 2015-12-05 08:01 190
        UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
9f5ec0cc sago007 2015-12-05 08:01 191
9f5ec0cc sago007 2015-12-05 08:01 192
        code_point += (*it) & 0x3f;
9f5ec0cc sago007 2015-12-05 08:01 193
9f5ec0cc sago007 2015-12-05 08:01 194
        return UTF8_OK;
9f5ec0cc sago007 2015-12-05 08:01 195
    }
9f5ec0cc sago007 2015-12-05 08:01 196
9f5ec0cc sago007 2015-12-05 08:01 197
    template <typename octet_iterator>
9f5ec0cc sago007 2015-12-05 08:01 198
    utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)
9f5ec0cc sago007 2015-12-05 08:01 199
    {
9f5ec0cc sago007 2015-12-05 08:01 200
        if (it == end)
9f5ec0cc sago007 2015-12-05 08:01 201
           return NOT_ENOUGH_ROOM;
9f5ec0cc sago007 2015-12-05 08:01 202
9f5ec0cc sago007 2015-12-05 08:01 203
        code_point = utf8::internal::mask8(*it);
9f5ec0cc sago007 2015-12-05 08:01 204
9f5ec0cc sago007 2015-12-05 08:01 205
        UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
9f5ec0cc sago007 2015-12-05 08:01 206
9f5ec0cc sago007 2015-12-05 08:01 207
        code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
9f5ec0cc sago007 2015-12-05 08:01 208
9f5ec0cc sago007 2015-12-05 08:01 209
        UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
9f5ec0cc sago007 2015-12-05 08:01 210
9f5ec0cc sago007 2015-12-05 08:01 211
        code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;
9f5ec0cc sago007 2015-12-05 08:01 212
9f5ec0cc sago007 2015-12-05 08:01 213
        UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
9f5ec0cc sago007 2015-12-05 08:01 214
9f5ec0cc sago007 2015-12-05 08:01 215
        code_point += (*it) & 0x3f;
9f5ec0cc sago007 2015-12-05 08:01 216
9f5ec0cc sago007 2015-12-05 08:01 217
        return UTF8_OK;
9f5ec0cc sago007 2015-12-05 08:01 218
    }
9f5ec0cc sago007 2015-12-05 08:01 219
9f5ec0cc sago007 2015-12-05 08:01 220
    #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR
9f5ec0cc sago007 2015-12-05 08:01 221
9f5ec0cc sago007 2015-12-05 08:01 222
    template <typename octet_iterator>
9f5ec0cc sago007 2015-12-05 08:01 223
    utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
9f5ec0cc sago007 2015-12-05 08:01 224
    {
9f5ec0cc sago007 2015-12-05 08:01 225
        // Save the original value of it so we can go back in case of failure
9f5ec0cc sago007 2015-12-05 08:01 226
        // Of course, it does not make much sense with i.e. stream iterators
9f5ec0cc sago007 2015-12-05 08:01 227
        octet_iterator original_it = it;
9f5ec0cc sago007 2015-12-05 08:01 228
9f5ec0cc sago007 2015-12-05 08:01 229
        uint32_t cp = 0;
9f5ec0cc sago007 2015-12-05 08:01 230
        // Determine the sequence length based on the lead octet
9f5ec0cc sago007 2015-12-05 08:01 231
        typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;
9f5ec0cc sago007 2015-12-05 08:01 232
        const octet_difference_type length = utf8::internal::sequence_length(it);
9f5ec0cc sago007 2015-12-05 08:01 233
9f5ec0cc sago007 2015-12-05 08:01 234
        // Get trail octets and calculate the code point
9f5ec0cc sago007 2015-12-05 08:01 235
        utf_error err = UTF8_OK;
9f5ec0cc sago007 2015-12-05 08:01 236
        switch (length) {
9f5ec0cc sago007 2015-12-05 08:01 237
            case 0: 
9f5ec0cc sago007 2015-12-05 08:01 238
                return INVALID_LEAD;
9f5ec0cc sago007 2015-12-05 08:01 239
            case 1:
9f5ec0cc sago007 2015-12-05 08:01 240
                err = utf8::internal::get_sequence_1(it, end, cp);
9f5ec0cc sago007 2015-12-05 08:01 241
                break;
9f5ec0cc sago007 2015-12-05 08:01 242
            case 2:
9f5ec0cc sago007 2015-12-05 08:01 243
                err = utf8::internal::get_sequence_2(it, end, cp);
9f5ec0cc sago007 2015-12-05 08:01 244
            break;
9f5ec0cc sago007 2015-12-05 08:01 245
            case 3:
9f5ec0cc sago007 2015-12-05 08:01 246
                err = utf8::internal::get_sequence_3(it, end, cp);
9f5ec0cc sago007 2015-12-05 08:01 247
            break;
9f5ec0cc sago007 2015-12-05 08:01 248
            case 4:
9f5ec0cc sago007 2015-12-05 08:01 249
                err = utf8::internal::get_sequence_4(it, end, cp);
9f5ec0cc sago007 2015-12-05 08:01 250
            break;
9f5ec0cc sago007 2015-12-05 08:01 251
        }
9f5ec0cc sago007 2015-12-05 08:01 252
9f5ec0cc sago007 2015-12-05 08:01 253
        if (err == UTF8_OK) {
9f5ec0cc sago007 2015-12-05 08:01 254
            // Decoding succeeded. Now, security checks...
9f5ec0cc sago007 2015-12-05 08:01 255
            if (utf8::internal::is_code_point_valid(cp)) {
9f5ec0cc sago007 2015-12-05 08:01 256
                if (!utf8::internal::is_overlong_sequence(cp, length)){
9f5ec0cc sago007 2015-12-05 08:01 257
                    // Passed! Return here.
9f5ec0cc sago007 2015-12-05 08:01 258
                    code_point = cp;
9f5ec0cc sago007 2015-12-05 08:01 259
                    ++it;
9f5ec0cc sago007 2015-12-05 08:01 260
                    return UTF8_OK;
9f5ec0cc sago007 2015-12-05 08:01 261
                }
9f5ec0cc sago007 2015-12-05 08:01 262
                else
9f5ec0cc sago007 2015-12-05 08:01 263
                    err = OVERLONG_SEQUENCE;
9f5ec0cc sago007 2015-12-05 08:01 264
            }
9f5ec0cc sago007 2015-12-05 08:01 265
            else 
9f5ec0cc sago007 2015-12-05 08:01 266
                err = INVALID_CODE_POINT;
9f5ec0cc sago007 2015-12-05 08:01 267
        }
9f5ec0cc sago007 2015-12-05 08:01 268
9f5ec0cc sago007 2015-12-05 08:01 269
        // Failure branch - restore the original value of the iterator
9f5ec0cc sago007 2015-12-05 08:01 270
        it = original_it;
9f5ec0cc sago007 2015-12-05 08:01 271
        return err;
9f5ec0cc sago007 2015-12-05 08:01 272
    }
9f5ec0cc sago007 2015-12-05 08:01 273
9f5ec0cc sago007 2015-12-05 08:01 274
    template <typename octet_iterator>
9f5ec0cc sago007 2015-12-05 08:01 275
    inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
9f5ec0cc sago007 2015-12-05 08:01 276
        uint32_t ignored;
9f5ec0cc sago007 2015-12-05 08:01 277
        return utf8::internal::validate_next(it, end, ignored);
9f5ec0cc sago007 2015-12-05 08:01 278
    }
9f5ec0cc sago007 2015-12-05 08:01 279
9f5ec0cc sago007 2015-12-05 08:01 280
} // namespace internal
9f5ec0cc sago007 2015-12-05 08:01 281
9f5ec0cc sago007 2015-12-05 08:01 282
    /// The library API - functions intended to be called by the users
9f5ec0cc sago007 2015-12-05 08:01 283
9f5ec0cc sago007 2015-12-05 08:01 284
    // Byte order mark
9f5ec0cc sago007 2015-12-05 08:01 285
    const uint8_t bom[] = {0xef, 0xbb, 0xbf};
9f5ec0cc sago007 2015-12-05 08:01 286
9f5ec0cc sago007 2015-12-05 08:01 287
    template <typename octet_iterator>
9f5ec0cc sago007 2015-12-05 08:01 288
    octet_iterator find_invalid(octet_iterator start, octet_iterator end)
9f5ec0cc sago007 2015-12-05 08:01 289
    {
9f5ec0cc sago007 2015-12-05 08:01 290
        octet_iterator result = start;
9f5ec0cc sago007 2015-12-05 08:01 291
        while (result != end) {
9f5ec0cc sago007 2015-12-05 08:01 292
            utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);
9f5ec0cc sago007 2015-12-05 08:01 293
            if (err_code != internal::UTF8_OK)
9f5ec0cc sago007 2015-12-05 08:01 294
                return result;
9f5ec0cc sago007 2015-12-05 08:01 295
        }
9f5ec0cc sago007 2015-12-05 08:01 296
        return result;
9f5ec0cc sago007 2015-12-05 08:01 297
    }
9f5ec0cc sago007 2015-12-05 08:01 298
9f5ec0cc sago007 2015-12-05 08:01 299
    template <typename octet_iterator>
9f5ec0cc sago007 2015-12-05 08:01 300
    inline bool is_valid(octet_iterator start, octet_iterator end)
9f5ec0cc sago007 2015-12-05 08:01 301
    {
9f5ec0cc sago007 2015-12-05 08:01 302
        return (utf8::find_invalid(start, end) == end);
9f5ec0cc sago007 2015-12-05 08:01 303
    }
9f5ec0cc sago007 2015-12-05 08:01 304
9f5ec0cc sago007 2015-12-05 08:01 305
    template <typename octet_iterator>
9f5ec0cc sago007 2015-12-05 08:01 306
    inline bool starts_with_bom (octet_iterator it, octet_iterator end)
9f5ec0cc sago007 2015-12-05 08:01 307
    {
9f5ec0cc sago007 2015-12-05 08:01 308
        return (
9f5ec0cc sago007 2015-12-05 08:01 309
            ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&
9f5ec0cc sago007 2015-12-05 08:01 310
            ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&
9f5ec0cc sago007 2015-12-05 08:01 311
            ((it != end) && (utf8::internal::mask8(*it))   == bom[2])
9f5ec0cc sago007 2015-12-05 08:01 312
           );
9f5ec0cc sago007 2015-12-05 08:01 313
    }
9f5ec0cc sago007 2015-12-05 08:01 314
	
9f5ec0cc sago007 2015-12-05 08:01 315
    //Deprecated in release 2.3 
9f5ec0cc sago007 2015-12-05 08:01 316
    template <typename octet_iterator>
9f5ec0cc sago007 2015-12-05 08:01 317
    inline bool is_bom (octet_iterator it)
9f5ec0cc sago007 2015-12-05 08:01 318
    {
9f5ec0cc sago007 2015-12-05 08:01 319
        return (
9f5ec0cc sago007 2015-12-05 08:01 320
            (utf8::internal::mask8(*it++)) == bom[0] &&
9f5ec0cc sago007 2015-12-05 08:01 321
            (utf8::internal::mask8(*it++)) == bom[1] &&
9f5ec0cc sago007 2015-12-05 08:01 322
            (utf8::internal::mask8(*it))   == bom[2]
9f5ec0cc sago007 2015-12-05 08:01 323
           );
9f5ec0cc sago007 2015-12-05 08:01 324
    }
9f5ec0cc sago007 2015-12-05 08:01 325
} // namespace utf8
9f5ec0cc sago007 2015-12-05 08:01 326
9f5ec0cc sago007 2015-12-05 08:01 327
#endif // header guard
9f5ec0cc sago007 2015-12-05 08:01 328
9f5ec0cc sago007 2015-12-05 08:01 329
1970-01-01 00:00 330