~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/utf8/unchecked.h

  • Committer: Monty Taylor
  • Date: 2009-02-13 01:00:48 UTC
  • mto: This revision was merged to the branch mainline in revision 885.
  • Revision ID: mordred@inaugust.com-20090213010048-cts7nl40flsmqd19
Added in utf8cpp. We want this to be an external lib, but it needs packaged.
Since it's just 4 header files, for now we'll do this and see how it goes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2006 Nemanja Trifunovic
 
2
 
 
3
/*
 
4
Permission is hereby granted, free of charge, to any person or organization
 
5
obtaining a copy of the software and accompanying documentation covered by
 
6
this license (the "Software") to use, reproduce, display, distribute,
 
7
execute, and transmit the Software, and to prepare derivative works of the
 
8
Software, and to permit third-parties to whom the Software is furnished to
 
9
do so, all subject to the following:
 
10
 
 
11
The copyright notices in the Software and this entire statement, including
 
12
the above license grant, this restriction and the following disclaimer,
 
13
must be included in all copies of the Software, in whole or in part, and
 
14
all derivative works of the Software, unless such copies or derivative
 
15
works are solely in the form of machine-executable object code generated by
 
16
a source language processor.
 
17
 
 
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
19
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
20
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 
21
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 
22
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 
23
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
24
DEALINGS IN THE SOFTWARE.
 
25
*/
 
26
 
 
27
 
 
28
#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
 
29
#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
 
30
 
 
31
#include "drizzled/utf8/core.h"
 
32
 
 
33
namespace utf8
 
34
{
 
35
    namespace unchecked 
 
36
    {
 
37
        template <typename octet_iterator>
 
38
        octet_iterator append(uint32_t cp, octet_iterator result)
 
39
        {
 
40
            if (cp < 0x80)                        // one octet
 
41
                *(result++) = static_cast<uint8_t>(cp);  
 
42
            else if (cp < 0x800) {                // two octets
 
43
                *(result++) = static_cast<uint8_t>((cp >> 6)          | 0xc0);
 
44
                *(result++) = static_cast<uint8_t>((cp & 0x3f)        | 0x80);
 
45
            }
 
46
            else if (cp < 0x10000) {              // three octets
 
47
                *(result++) = static_cast<uint8_t>((cp >> 12)         | 0xe0);
 
48
                *(result++) = static_cast<uint8_t>((cp >> 6) & 0x3f   | 0x80);
 
49
                *(result++) = static_cast<uint8_t>((cp & 0x3f)        | 0x80);
 
50
            }
 
51
            else {                                // four octets
 
52
                *(result++) = static_cast<uint8_t>((cp >> 18)         | 0xf0);
 
53
                *(result++) = static_cast<uint8_t>((cp >> 12)& 0x3f   | 0x80);
 
54
                *(result++) = static_cast<uint8_t>((cp >> 6) & 0x3f   | 0x80);
 
55
                *(result++) = static_cast<uint8_t>((cp & 0x3f)        | 0x80);
 
56
            }
 
57
            return result;
 
58
        }
 
59
 
 
60
        template <typename octet_iterator>
 
61
        uint32_t next(octet_iterator& it)
 
62
        {
 
63
            uint32_t cp = internal::mask8(*it);
 
64
            typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
 
65
            switch (length) {
 
66
                case 1:
 
67
                    break;
 
68
                case 2:
 
69
                    it++;
 
70
                    cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
 
71
                    break;
 
72
                case 3:
 
73
                    ++it; 
 
74
                    cp = ((cp << 12) & 0xffff) + ((internal::mask8(*it) << 6) & 0xfff);
 
75
                    ++it;
 
76
                    cp += (*it) & 0x3f;
 
77
                    break;
 
78
                case 4:
 
79
                    ++it;
 
80
                    cp = ((cp << 18) & 0x1fffff) + ((internal::mask8(*it) << 12) & 0x3ffff);                
 
81
                    ++it;
 
82
                    cp += (internal::mask8(*it) << 6) & 0xfff;
 
83
                    ++it;
 
84
                    cp += (*it) & 0x3f; 
 
85
                    break;
 
86
            }
 
87
            ++it;
 
88
            return cp;        
 
89
        }
 
90
 
 
91
        template <typename octet_iterator>
 
92
        uint32_t peek_next(octet_iterator it)
 
93
        {
 
94
            return next(it);    
 
95
        }
 
96
 
 
97
        template <typename octet_iterator>
 
98
        uint32_t prior(octet_iterator& it)
 
99
        {
 
100
            while (internal::is_trail(*(--it))) ;
 
101
            octet_iterator temp = it;
 
102
            return next(temp);
 
103
        }
 
104
 
 
105
        // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous)
 
106
        template <typename octet_iterator>
 
107
        inline uint32_t previous(octet_iterator& it)
 
108
        {
 
109
            return prior(it);
 
110
        }
 
111
 
 
112
        template <typename octet_iterator, typename distance_type>
 
113
        void advance (octet_iterator& it, distance_type n)
 
114
        {
 
115
            for (distance_type i = 0; i < n; ++i)
 
116
                next(it);
 
117
        }
 
118
 
 
119
        template <typename octet_iterator>
 
120
        typename std::iterator_traits<octet_iterator>::difference_type
 
121
        distance (octet_iterator first, octet_iterator last)
 
122
        {
 
123
            typename std::iterator_traits<octet_iterator>::difference_type dist;
 
124
            for (dist = 0; first < last; ++dist) 
 
125
                next(first);
 
126
            return dist;
 
127
        }
 
128
 
 
129
        template <typename u16bit_iterator, typename octet_iterator>
 
130
        octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
 
131
        {       
 
132
            while (start != end) {
 
133
                uint32_t cp = internal::mask16(*start++);
 
134
            // Take care of surrogate pairs first
 
135
                if (internal::is_surrogate(cp)) {
 
136
                    uint32_t trail_surrogate = internal::mask16(*start++);
 
137
                    cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
 
138
                }
 
139
                result = append(cp, result);
 
140
            }
 
141
            return result;         
 
142
        }
 
143
 
 
144
        template <typename u16bit_iterator, typename octet_iterator>
 
145
        u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
 
146
        {
 
147
            while (start != end) {
 
148
                uint32_t cp = next(start);
 
149
                if (cp > 0xffff) { //make a surrogate pair
 
150
                    *result++ = static_cast<uint16_t>((cp >> 10)   + internal::LEAD_OFFSET);
 
151
                    *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
 
152
                }
 
153
                else
 
154
                    *result++ = static_cast<uint16_t>(cp);
 
155
            }
 
156
            return result;
 
157
        }
 
158
 
 
159
        template <typename octet_iterator, typename u32bit_iterator>
 
160
        octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
 
161
        {
 
162
            while (start != end)
 
163
                result = append(*(start++), result);
 
164
 
 
165
            return result;
 
166
        }
 
167
 
 
168
        template <typename octet_iterator, typename u32bit_iterator>
 
169
        u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
 
170
        {
 
171
            while (start < end)
 
172
                (*result++) = next(start);
 
173
 
 
174
            return result;
 
175
        }
 
176
 
 
177
        // The iterator class
 
178
        template <typename octet_iterator>
 
179
          class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> { 
 
180
            octet_iterator it;
 
181
            public:
 
182
            iterator () {};
 
183
            explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
 
184
            // the default "big three" are OK
 
185
            octet_iterator base () const { return it; }
 
186
            uint32_t operator * () const
 
187
            {
 
188
                octet_iterator temp = it;
 
189
                return next(temp);
 
190
            }
 
191
            bool operator == (const iterator& rhs) const 
 
192
            { 
 
193
                return (it == rhs.it);
 
194
            }
 
195
            bool operator != (const iterator& rhs) const
 
196
            {
 
197
                return !(operator == (rhs));
 
198
            }
 
199
            iterator& operator ++ () 
 
200
            {
 
201
                std::advance(it, internal::sequence_length(it));
 
202
                return *this;
 
203
            }
 
204
            iterator operator ++ (int)
 
205
            {
 
206
                iterator temp = *this;
 
207
                std::advance(it, internal::sequence_length(it));
 
208
                return temp;
 
209
            }  
 
210
            iterator& operator -- ()
 
211
            {
 
212
                prior(it);
 
213
                return *this;
 
214
            }
 
215
            iterator operator -- (int)
 
216
            {
 
217
                iterator temp = *this;
 
218
                prior(it);
 
219
                return temp;
 
220
            }
 
221
          }; // class iterator
 
222
 
 
223
    } // namespace utf8::unchecked
 
224
} // namespace utf8 
 
225
 
 
226
 
 
227
#endif // header guard
 
228