~ubuntu-branches/ubuntu/trusty/codeblocks/trusty-proposed

« back to all changes in this revision

Viewing changes to src/sdk/wxscintilla/src/scintilla/src/UniConversion.cxx

  • Committer: Package Import Robot
  • Author(s): Vincent Cheng
  • Date: 2013-05-06 00:20:02 UTC
  • mfrom: (6.1.2 experimental)
  • Revision ID: package-import@ubuntu.com-20130506002002-ngc7bwkewnak8fja
Tags: 12.11-3
* Upload to unstable.
* Update watch file, thanks to Bart Martens.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// Scintilla source code edit control
2
2
/** @file UniConversion.cxx
3
 
 ** Functions to handle UFT-8 and UCS-2 strings.
 
3
 ** Functions to handle UTF-8 and UTF-16 strings.
4
4
 **/
5
5
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
6
6
// The License.txt file describes the conditions under which this software may be distributed.
61
61
        putf[len] = '\0';
62
62
}
63
63
 
 
64
unsigned int UTF8CharLength(unsigned char ch) {
 
65
        if (ch < 0x80) {
 
66
                return 1;
 
67
        } else if (ch < 0x80 + 0x40 + 0x20) {
 
68
                return 2;
 
69
        } else if (ch < 0x80 + 0x40 + 0x20 + 0x10) {
 
70
                return 3;
 
71
        } else {
 
72
                return 4;
 
73
        }
 
74
}
 
75
 
64
76
unsigned int UTF16Length(const char *s, unsigned int len) {
65
77
        unsigned int ulen = 0;
66
78
        unsigned int charLen;
67
 
        for (unsigned int i=0;i<len;) {
 
79
        for (unsigned int i=0; i<len;) {
68
80
                unsigned char ch = static_cast<unsigned char>(s[i]);
69
81
                if (ch < 0x80) {
70
82
                        charLen = 1;
117
129
        }
118
130
        return ui;
119
131
}
 
132
 
 
133
int UTF8BytesOfLead[256];
 
134
static bool initialisedBytesOfLead = false;
 
135
 
 
136
static int BytesFromLead(int leadByte) {
 
137
        if (leadByte < 0xC2) {
 
138
                // Single byte or invalid
 
139
                return 1;
 
140
        } else if (leadByte < 0xE0) {
 
141
                return 2;
 
142
        } else if (leadByte < 0xF0) {
 
143
                return 3;
 
144
        } else if (leadByte < 0xF5) {
 
145
                return 4;
 
146
        } else {
 
147
                // Characters longer than 4 bytes not possible in current UTF-8
 
148
                return 1;
 
149
        }
 
150
}
 
151
 
 
152
void UTF8BytesOfLeadInitialise() {
 
153
        if (!initialisedBytesOfLead) {
 
154
                for (int i=0;i<256;i++) {
 
155
                        UTF8BytesOfLead[i] = BytesFromLead(i);
 
156
                }
 
157
                initialisedBytesOfLead = true;
 
158
        }
 
159
}
 
160
 
 
161
// Return both the width of the first character in the string and a status
 
162
// saying whether it is valid or invalid.
 
163
// Most invalid sequences return a width of 1 so are treated as isolated bytes but
 
164
// the non-characters *FFFE, *FFFF and FDD0 .. FDEF return 3 or 4 as they can be
 
165
// reasonably treated as code points in some circumstances. They will, however,
 
166
// not have associated glyphs.
 
167
int UTF8Classify(const unsigned char *us, int len) {
 
168
        // For the rules: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 
169
        if (*us < 0x80) {
 
170
                // Single bytes easy
 
171
                return 1;
 
172
        } else if (*us > 0xf4) {
 
173
                // Characters longer than 4 bytes not possible in current UTF-8
 
174
                return UTF8MaskInvalid | 1;
 
175
        } else if (*us >= 0xf0) {
 
176
                // 4 bytes
 
177
                if (len < 4)
 
178
                        return UTF8MaskInvalid | 1;
 
179
                if (UTF8IsTrailByte(us[1]) && UTF8IsTrailByte(us[2]) && UTF8IsTrailByte(us[3])) {
 
180
                        if (((us[1] & 0xf) == 0xf) && (us[2] == 0xbf) && ((us[3] == 0xbe) || (us[3] == 0xbf))) {
 
181
                                // *FFFE or *FFFF non-character
 
182
                                return UTF8MaskInvalid | 4;
 
183
                        }
 
184
                        if (*us == 0xf4) {
 
185
                                // Check if encoding a value beyond the last Unicode character 10FFFF
 
186
                                if (us[1] > 0x8f) {
 
187
                                        return UTF8MaskInvalid | 1;
 
188
                                } else if (us[1] == 0x8f) {
 
189
                                        if (us[2] > 0xbf) {
 
190
                                                return UTF8MaskInvalid | 1;
 
191
                                        } else if (us[2] == 0xbf) {
 
192
                                                if (us[3] > 0xbf) {
 
193
                                                        return UTF8MaskInvalid | 1;
 
194
                                                }
 
195
                                        }
 
196
                                }
 
197
                        } else if ((*us == 0xf0) && ((us[1] & 0xf0) == 0x80)) {
 
198
                                // Overlong
 
199
                                return UTF8MaskInvalid | 1;
 
200
                        }
 
201
                        return 4;
 
202
                } else {
 
203
                        return UTF8MaskInvalid | 1;
 
204
                }
 
205
        } else if (*us >= 0xe0) {
 
206
                // 3 bytes
 
207
                if (len < 3)
 
208
                        return UTF8MaskInvalid | 1;
 
209
                if (UTF8IsTrailByte(us[1]) && UTF8IsTrailByte(us[2])) {
 
210
                        if ((*us == 0xe0) && ((us[1] & 0xe0) == 0x80)) {
 
211
                                // Overlong
 
212
                                return UTF8MaskInvalid | 1;
 
213
                        }
 
214
                        if ((*us == 0xed) && ((us[1] & 0xe0) == 0xa0)) {
 
215
                                // Surrogate
 
216
                                return UTF8MaskInvalid | 1;
 
217
                        }
 
218
                        if ((*us == 0xef) && (us[1] == 0xbf) && (us[2] == 0xbe)) {
 
219
                                // U+FFFE non-character - 3 bytes long
 
220
                                return UTF8MaskInvalid | 3;
 
221
                        }
 
222
                        if ((*us == 0xef) && (us[1] == 0xbf) && (us[2] == 0xbf)) {
 
223
                                // U+FFFF non-character - 3 bytes long
 
224
                                return UTF8MaskInvalid | 3;
 
225
                        }
 
226
                        if ((*us == 0xef) && (us[1] == 0xb7) && (((us[2] & 0xf0) == 0x90) || ((us[2] & 0xf0) == 0xa0))) {
 
227
                                // U+FDD0 .. U+FDEF
 
228
                                return UTF8MaskInvalid | 3;
 
229
                        }
 
230
                        return 3;
 
231
                } else {
 
232
                        return UTF8MaskInvalid | 1;
 
233
                }
 
234
        } else if (*us >= 0xc2) {
 
235
                // 2 bytes
 
236
                if (len < 2)
 
237
                        return UTF8MaskInvalid | 1;
 
238
                if (UTF8IsTrailByte(us[1])) {
 
239
                        return 2;
 
240
                } else {
 
241
                        return UTF8MaskInvalid | 1;
 
242
                }
 
243
        } else {
 
244
                // 0xc0 .. 0xc1 is overlong encoding
 
245
                // 0x80 .. 0xbf is trail byte
 
246
                return UTF8MaskInvalid | 1;
 
247
        }
 
248
}