~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSUTF8.cc

  • Committer: Monty Taylor
  • Date: 2010-07-04 20:02:43 UTC
  • mfrom: (1548.2.40 drizzle_pbms)
  • mto: This revision was merged to the branch mainline in revision 1644.
  • Revision ID: mordred@inaugust.com-20100704200243-2vkq9gi6ysauj2tb
Merge PBMS from Barry.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2008 PrimeBase Technologies GmbH, Germany
 
2
 *
 
3
 * PrimeBase Media Stream for MySQL
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
18
 *
 
19
 * Original author: Paul McCullagh (H&G2JCtL)
 
20
 * Continued development: Barry Leslie
 
21
 *
 
22
 * 2007-06-14
 
23
 *
 
24
 * CORE SYSTEM:
 
25
 * Unicode / UTF-8 convertion
 
26
 *
 
27
 */
 
28
 
 
29
#include "CSConfig.h"
 
30
 
 
31
#include <assert.h>
 
32
#include <string.h>
 
33
 
 
34
#include "CSUTF8.h"
 
35
#include "CSMemory.h"
 
36
#include "CSGlobal.h"
 
37
 
 
38
size_t cs_utf_to_uni_char(const u_char *in_string, uint32_t *ret_value)
 
39
{
 
40
        const u_char *i_string =  in_string;
 
41
        size_t  s_len = strlen((char*)in_string);
 
42
        u_char  ch;
 
43
        uint32_t        val;
 
44
        size_t  clen;
 
45
 
 
46
        ch = *i_string;
 
47
        if ((ch & 0x80) == 0x00) {
 
48
                val = (uint32_t) ch & 0x0000007F;
 
49
                clen = 1;
 
50
        }
 
51
        else if ((ch & 0xE0) == 0xC0) {
 
52
                if (s_len > 1) {
 
53
                        val = ((i_string[0] & 0x0000001F) << 6) |
 
54
                                                (i_string[1] & 0x0000003F);
 
55
                        if (val < 0x00000080)
 
56
                                val = '?';
 
57
                        clen = 2;
 
58
                }
 
59
                else {
 
60
                        val = '?';
 
61
                        clen = s_len;
 
62
                }
 
63
        }
 
64
        else if ((ch & 0xF0) == 0xE0) {
 
65
                if (s_len > 2) {
 
66
                        val = ((i_string[0] & 0x0000000F) << 12) |
 
67
                                                ((i_string[1] & 0x0000003F) << 6) |
 
68
                                                (i_string[2] & 0x0000003F);
 
69
                        if (val < 0x000000800)
 
70
                                val = '?';
 
71
                        clen = 3;
 
72
                }
 
73
                else {
 
74
                        val = '?';
 
75
                        clen = s_len;
 
76
                }
 
77
        }
 
78
        else if ((ch & 0xF8) == 0xF0) {
 
79
                if (s_len > 3) {
 
80
                        val = ((i_string[0] & 0x00000007) << 18) |
 
81
                                                ((i_string[1] & 0x0000003F) << 12) |
 
82
                                                ((i_string[2] & 0x0000003F) << 6) |
 
83
                                                (i_string[3] & 0x0000003F);
 
84
                        if (val < 0x00010000)
 
85
                                val = '?';
 
86
                        clen = 4;
 
87
                }
 
88
                else {
 
89
                        val = '?';
 
90
                        clen = s_len;
 
91
                }
 
92
        }
 
93
        else if ((ch & 0xFC) == 0xF8) {
 
94
                if (s_len > 4) {
 
95
                        val = ((i_string[0] & 0x00000003) << 24) |
 
96
                                                ((i_string[1] & 0x0000003F) << 18) |
 
97
                                                ((i_string[2] & 0x0000003F) << 12) |
 
98
                                                ((i_string[3] & 0x0000003F) << 6) |
 
99
                                                (i_string[4] & 0x0000003F);
 
100
                        if (val < 0x00200000)
 
101
                                val = '?';
 
102
                        clen = 5;
 
103
                }
 
104
                else {
 
105
                        val = '?';
 
106
                        clen = s_len;
 
107
                }
 
108
        }
 
109
        else if ((ch & 0xFE) == 0xFC) {
 
110
                if (s_len > 5) {
 
111
                        val = ((i_string[0] & 0x00000001) << 30) |
 
112
                                                ((i_string[1] & 0x0000003F) << 24) |
 
113
                                                ((i_string[2] & 0x0000003F) << 18) |
 
114
                                                ((i_string[3] & 0x0000003F) << 12) |
 
115
                                                ((i_string[4] & 0x0000003F) << 6) |
 
116
                                                (i_string[5] & 0x0000003F);
 
117
                        if (val < 0x04000000)
 
118
                                val = '?';
 
119
                        clen = 6;
 
120
                }
 
121
                else {
 
122
                        val = '?';
 
123
                        clen = s_len;
 
124
                }
 
125
        }
 
126
        else {
 
127
                // Should not happen!
 
128
                val = '?';
 
129
                clen = 1;
 
130
        }
 
131
        *ret_value = val;
 
132
        return(clen);
 
133
}
 
134
 
 
135
void cs_utf8_to_uni(size_t out_len, unichar *out_string, const u_char *in_string)
 
136
{
 
137
        uint32_t        utf_value;
 
138
 
 
139
        out_len--;  // Space for zero terminator
 
140
        while (*in_string) {
 
141
                in_string += cs_utf_to_uni_char(in_string, &utf_value);
 
142
                if (out_len == 0)
 
143
                        break;
 
144
                if (utf_value > 0x0000FFFF)
 
145
                        *out_string = (unichar) '?';
 
146
                else
 
147
                        *out_string = (unichar) utf_value;
 
148
                out_string++;
 
149
                out_len--;
 
150
        }
 
151
        *out_string = 0;
 
152
}
 
153
 
 
154
void cs_utf8_to_uni_no_term(size_t out_len, unichar *out_string, const u_char *in_string)
 
155
{
 
156
        uint32_t        utf_value;
 
157
 
 
158
        while (*in_string) {
 
159
                in_string += cs_utf_to_uni_char(in_string, &utf_value);
 
160
                if (out_len == 0)
 
161
                        break;
 
162
                if (utf_value > 0x0000FFFF)
 
163
                        *out_string = (unichar) '?';
 
164
                else
 
165
                        *out_string = (unichar) utf_value;
 
166
                out_string++;
 
167
                out_len--;
 
168
        }
 
169
}
 
170
 
 
171
void cs_uni_to_utf8(size_t out_len, char *out_string, const unichar *in_string)
 
172
{
 
173
        out_len--;  // Space for zero terminator
 
174
        while (*in_string) {
 
175
                if (*in_string <= 0x007F) {
 
176
                        if (out_len < 1)
 
177
                                break;
 
178
                        *out_string++ = (char) (u_char) *in_string;
 
179
                        out_len--;
 
180
                }
 
181
                else if (*in_string <= 0x07FF) {
 
182
                        if (out_len < 3)
 
183
                                break;
 
184
                        *out_string++ = (char) (u_char) ((0x00C0) | ((*in_string >> 6) & 0x001F));
 
185
                        *out_string++ = (char) (u_char) ((0x0080) | (*in_string & 0x003F));
 
186
                        out_len -= 2;
 
187
                }
 
188
                else /* <= 0xFFFF */ {
 
189
                        if (out_len < 3)
 
190
                                break;
 
191
                        *out_string++ = (char) (u_char) ((0x00E0) | ((*in_string >> 12) & 0x000F));
 
192
                        *out_string++ = (char) (u_char) ((0x0080) | ((*in_string >> 6) & 0x003F));
 
193
                        *out_string++ = (char) (u_char) ((0x0080) | (*in_string & 0x003F));
 
194
                        out_len -= 3;
 
195
                }
 
196
                in_string++;
 
197
        }
 
198
        *out_string = 0;
 
199
}
 
200
 
 
201
void cs_uni_to_utf8(size_t out_len, char *out_string, const unichar *in_string, s_int in_len)
 
202
{
 
203
        out_len--;  // Space for zero terminator
 
204
        while (in_len--) {
 
205
                if (*in_string <= 0x007F) {
 
206
                        if (out_len < 1)
 
207
                                break;
 
208
                        *out_string++ = (char) (u_char) *in_string;
 
209
                        out_len--;
 
210
                }
 
211
                else if (*in_string <= 0x07FF) {
 
212
                        if (out_len < 3)
 
213
                                break;
 
214
                        *out_string++ = (char) (u_char) ((0x00C0) | ((*in_string >> 6) & 0x001F));
 
215
                        *out_string++ = (char) (u_char) ((0x0080) | (*in_string & 0x003F));
 
216
                        out_len -= 2;
 
217
                }
 
218
                else /* <= 0xFFFF */ {
 
219
                        if (out_len < 3)
 
220
                                break;
 
221
                        *out_string++ = (char) (u_char) ((0x00E0) | ((*in_string >> 12) & 0x000F));
 
222
                        *out_string++ = (char) (u_char) ((0x0080) | ((*in_string >> 6) & 0x003F));
 
223
                        *out_string++ = (char) (u_char) ((0x0080) | (*in_string & 0x003F));
 
224
                        out_len -= 3;
 
225
                }
 
226
                in_string++;
 
227
        }
 
228
        *out_string = 0;
 
229
}
 
230
 
 
231
size_t cs_utf8_to_uni_len(const char *in_string)
 
232
{
 
233
        size_t slen = 0;
 
234
 
 
235
        while (*in_string) {
 
236
                if ((*((u_char *) in_string) & 0xC0) == 0x80)
 
237
                        // These are char data bytes (10xxxxxx)
 
238
                        ;
 
239
                else
 
240
                        // These are single char (00xxxxx, 01xxxxx), or char start bytes (11xxxxxx)
 
241
                        slen++;
 
242
                in_string++;
 
243
        }
 
244
        return slen;
 
245
}
 
246
 
 
247
size_t cs_uni_to_utf8_len(const unichar *in_string, s_int in_len)
 
248
{
 
249
        size_t slen = 0;
 
250
 
 
251
        while (in_len--) {
 
252
                if (*in_string <= 0x000007F) {
 
253
                        slen++;
 
254
                }
 
255
                else if (*in_string <= 0x00007FF)
 
256
                        slen += 2;
 
257
                else /* <= 0xFFFF */
 
258
                        slen += 3;
 
259
                in_string++;
 
260
        }
 
261
        return slen;
 
262
}
 
263
 
 
264
/*
 
265
size_t cs_uni_len(const unichar *in_string)
 
266
{
 
267
        size_t len = 0;
 
268
        
 
269
        while (*in_string++) len++;
 
270
        return len;
 
271
}
 
272
*/
 
273