~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/utf8/unchecked.h

Merged Drizzle's Trunk.

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 DRIZZLED_UTF8_UNCHECKED_H
29
 
#define DRIZZLED_UTF8_UNCHECKED_H
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 /* DRIZZLED_UTF8_UNCHECKED_H */
228