1 /* string.c++ -- written by Alexis WILKE for Made to Order Software Corp. (c) 2005-2009 */
2
3 /*
4
5 Copyright (c) 2005-2009 Made to Order Software Corp.
6
7 Permission is hereby granted, free of charge, to any
8 person obtaining a copy of this software and
9 associated documentation files (the "Software"), to
10 deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify,
12 merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom
14 the Software is furnished to do so, subject to the
15 following conditions:
16
17 The above copyright notice and this permission notice
18 shall be included in all copies or substantial
19 portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
22 ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
23 LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
24 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
25 EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 SOFTWARE.
31
32 */
33
34 #include "compiler.h"
35
36
37 namespace sswf
38 {
39 namespace as
40 {
41
42
43
44
String(void)45 String::String(void)
46 {
47 f_len = 0;
48 f_max = 0;
49 f_str = 0;
50 }
String(const String & string)51 String::String(const String& string)
52 {
53 f_len = 0;
54 f_max = 0;
55 f_str = 0;
56 Set(string.f_str, string.f_len);
57 }
String(const char * str)58 String::String(const char *str)
59 {
60 f_len = 0;
61 f_max = 0;
62 f_str = 0;
63 operator += (str);
64 }
~String()65 String::~String()
66 {
67 delete [] f_str;
68 }
69
operator =(const String & string)70 String& String::operator = (const String& string)
71 {
72 Set(string.f_str, string.f_len);
73 return *this;
74 }
75
76 // Assume ISO-8859-1 as input
operator =(const char * str)77 String& String::operator = (const char *str)
78 {
79 Empty();
80 return operator += (str);
81 }
82
operator ==(const String & string) const83 bool String::operator == (const String& string) const
84 {
85 if(f_len != string.f_len) {
86 return false;
87 }
88
89 return memcmp(f_str, string.f_str, sizeof(long) * f_len) == 0;
90 }
91
operator !=(const String & string) const92 bool String::operator != (const String& string) const
93 {
94 return !operator == (string);
95 }
96
operator ==(const char * str) const97 bool String::operator == (const char *str) const
98 {
99 long idx = 0;
100
101 while(*str != '\0' && idx < f_len) {
102 if(*str != f_str[idx]) {
103 return false;
104 }
105 str++;
106 idx++;
107 }
108
109 return *str == '\0' && idx == f_len;
110 }
111
operator !=(const char * str) const112 bool String::operator != (const char *str) const
113 {
114 return !operator == (str);
115 }
116
Compare(const String & string) const117 int String::Compare(const String& string) const
118 {
119 long idx = 0;
120 long max = f_len < string.f_len ? f_len : string.f_len;
121 while(idx < max) {
122 long r = f_str[idx] - string.f_str[idx];
123 if(r != 0) {
124 return r < 0 ? -1 : 1;
125 }
126 idx++;
127 }
128 if(max == f_len) {
129 return max == string.f_len ? 0 : -1;
130 }
131 return 1;
132 }
133
Compare(const char * string) const134 int String::Compare(const char *string) const
135 {
136 if(string == 0) {
137 if(f_len == 0) {
138 return 0;
139 }
140 return 1;
141 }
142 long idx = 0;
143 long len = strlen(string);
144 long max = f_len < len ? f_len : len;
145 while(idx < max) {
146 long r = f_str[idx] - ((const unsigned char *) string)[idx];
147 if(r != 0) {
148 return r < 0 ? -1 : 1;
149 }
150 idx++;
151 }
152 if(max == f_len) {
153 return max == len ? 0 : -1;
154 }
155 return 1;
156 }
157
IsEmpty(void) const158 bool String::IsEmpty(void) const
159 {
160 return f_len == 0;
161 }
Empty(void)162 void String::Empty(void)
163 {
164 f_len = 0;
165 }
166
GetLength(void) const167 long String::GetLength(void) const
168 {
169 return f_len;
170 }
Get(void) const171 const long *String::Get(void) const
172 {
173 return f_str;
174 }
Set(const long * str,long size)175 void String::Set(const long *str, long size)
176 {
177 if(size > 0 && size < f_max) {
178 f_len = size;
179 memcpy(f_str, str, f_len * sizeof(long));
180 }
181 else {
182 delete [] f_str;
183 if(size <= 0) {
184 f_len = 0;
185 f_max = 0;
186 f_str = 0;
187 }
188 else {
189 f_len = size;
190 f_max = (size + 255) & -256;
191 f_str = new long[f_max];
192 memcpy(f_str, str, f_len * sizeof(long));
193 }
194 }
195 }
196
AppendChar(long c)197 void String::AppendChar(long c)
198 {
199 if(f_len >= f_max) {
200 f_max += 256;
201 long *s = new long[f_max];
202 memcpy(s, f_str, f_len * sizeof(long));
203 delete [] f_str;
204 f_str = s;
205 }
206
207 f_str[f_len] = c;
208 ++f_len;
209 }
210
AppendStr(const long * str,long len)211 String& String::AppendStr(const long *str, long len)
212 {
213 if(len == 0) {
214 return *this;
215 }
216
217 if(f_len + len > f_max) {
218 f_max = (f_len + len + 255) & -256;
219 long *s = new long[f_max];
220 memcpy(s, f_str, f_len * sizeof(long));
221 memcpy(s + f_len, str, len * sizeof(long));
222 delete [] f_str;
223 f_str = s;
224 }
225 else {
226 memcpy(f_str + f_len, str, len * sizeof(long));
227 }
228 f_len += len;
229
230 return *this;
231 }
232
operator +=(const String & string)233 String& String::operator += (const String& string)
234 {
235 if(string.f_len == 0) {
236 return *this;
237 }
238
239 if(f_len + string.f_len > f_max) {
240 f_max = (f_len + string.f_len + 255) & -256;
241 long *s = new long[f_max];
242 if(f_len > 0) {
243 memcpy(s, f_str, f_len * sizeof(long));
244 }
245 memcpy(s + f_len, string.f_str, string.f_len * sizeof(long));
246 delete [] f_str;
247 f_str = s;
248 }
249 else {
250 memcpy(f_str + f_len, string.f_str, string.f_len * sizeof(long));
251 }
252 f_len += string.f_len;
253
254 return *this;
255 }
256
257 // Assume ISO-8859-1 as input
operator +=(const char * str)258 String& String::operator += (const char *str)
259 {
260 if(str == 0) {
261 return *this;
262 }
263 long l = strlen(str);
264 if(l == 0) {
265 return *this;
266 }
267
268 long idx;
269 if(f_len + l > f_max) {
270 f_max = (f_len + l + 255) & -256;
271 long *s = new long[f_max];
272 if(f_len > 0) {
273 memcpy(s, f_str, f_len * sizeof(long));
274 }
275 for(idx = 0; idx < l; ++idx) {
276 s[f_len + idx] = str[idx];
277 }
278 delete [] f_str;
279 f_str = s;
280 }
281 else {
282 for(idx = 0; idx < l; ++idx) {
283 f_str[f_len + idx] = str[idx];
284 }
285 }
286 f_len += l;
287
288 return *this;
289 }
290
291
292
293
GetUTF8Length(void) const294 int String::GetUTF8Length(void) const
295 {
296 size_t r, l, wc_len;
297 long *wc, c;
298
299 // make sure we always have a null at the end...
300 r = 0;
301
302 wc_len = f_len;
303 wc = f_str;
304 while(wc_len > 0) {
305 /* get one wide character */
306 c = *wc++;
307 wc_len--;
308 /* encode in temp buffer */
309 if(c < 0x80) {
310 /* this will also encode '\0'... */
311 l = 1;
312 }
313 else if(c < 0x800) {
314 l = 2;
315 }
316 else if(c < 0x10000) {
317 l = 3;
318 }
319 else if(c < 0x200000) {
320 l = 4;
321 }
322 else if(c < 0x4000000) {
323 l = 5;
324 }
325 else if(c > 0) {
326 l = 6;
327 }
328 else {
329 /* an invalid wide character (negative!) */
330 return -1;
331 }
332 r += l;
333 }
334
335 return r;
336 }
337
ToUTF8(char * mb,size_t & mb_len) const338 int String::ToUTF8(char *mb, size_t& mb_len) const
339 {
340 char buf[6];
341 size_t l, wc_len;
342 long *wc, c;
343
344 // make sure we always have a null at the end...
345 mb_len--;
346 mb[mb_len] = '\0';
347
348 wc_len = f_len;
349 wc = f_str;
350 while(wc_len > 0) {
351 /* get one wide character */
352 c = *wc++;
353 wc_len--;
354 /* encode in temp buffer */
355 if(c < 0x80) {
356 /* this will also encode '\0'... */
357 buf[0] = (char) c;
358 l = 1;
359 }
360 else if(c < 0x800) {
361 buf[0] = (c >> 6) | 0xC0;
362 buf[1] = (c & 0x3F) | 0x80;
363 l = 2;
364 }
365 else if(c < 0x10000) {
366 buf[0] = (c >> 12) | 0xE0;
367 buf[1] = ((c >> 6) & 0x3F) | 0x80;
368 buf[2] = (c & 0x3F) | 0x80;
369 l = 3;
370 }
371 else if(c < 0x200000) {
372 buf[0] = (c >> 18) | 0xF0;
373 buf[1] = ((c >> 12) & 0x3F) | 0x80;
374 buf[2] = ((c >> 6) & 0x3F) | 0x80;
375 buf[3] = (c & 0x3F) | 0x80;
376 l = 4;
377 }
378 else if(c < 0x4000000) {
379 buf[0] = (c >> 24) | 0xF8;
380 buf[1] = ((c >> 18) & 0x3F) | 0x80;
381 buf[2] = ((c >> 12) & 0x3F) | 0x80;
382 buf[3] = ((c >> 6) & 0x3F) | 0x80;
383 buf[4] = (c & 0x3F) | 0x80;
384 l = 5;
385 }
386 else if(c > 0) { // <=> (signed long) c < 0x80000000
387 buf[0] = (c >> 30) | 0xFC;
388 buf[1] = ((c >> 24) & 0x3F) | 0x80;
389 buf[2] = ((c >> 18) & 0x3F) | 0x80;
390 buf[3] = ((c >> 12) & 0x3F) | 0x80;
391 buf[4] = ((c >> 6) & 0x3F) | 0x80;
392 buf[5] = (c & 0x3F) | 0x80;
393 l = 6;
394 }
395 else {
396 /* an invalid wide character (negative!) */
397 return -1;
398 }
399 if(l < mb_len) {
400 mb_len -= l;
401 memcpy(mb, buf, l);
402 mb += l;
403 }
404 else {
405 /* overflow error */
406 return -1;
407 }
408 }
409
410 *mb = '\0';
411
412 mb_len++; // put the '\0' back in what's left
413
414 return 0;
415 }
416
417
418 // WARNING: this function appends the string mb to
419 // the current string in this object
FromUTF8(const char * mb,size_t mb_len)420 int String::FromUTF8(const char *mb, size_t mb_len)
421 {
422 unsigned char c;
423 long w;
424 size_t l;
425
426 while(mb_len > 0) {
427 mb_len--;
428 c = (unsigned char) *mb++;
429 if(c < 0x80) {
430 w = c;
431 }
432 else {
433 if(c >= 0xC0 && c <= 0xDF) {
434 l = 1;
435 w = c & 0x1F;
436 }
437 else if(c >= 0xE0 && c <= 0xEF) {
438 l = 2;
439 w = c & 0x0F;
440 }
441 else if(c >= 0xF0 && c <= 0xF7) {
442 l = 3;
443 w = c & 0x07;
444 }
445 else if(c >= 0xF8 && c <= 0xFB) {
446 l = 4;
447 w = c & 0x03;
448 }
449 else if(c >= 0xFC && c <= 0xFD) {
450 l = 5;
451 w = c & 0x01;
452 }
453 else {
454 return -1;
455 }
456 if(mb_len < l) {
457 return -1;
458 }
459 mb_len -= l;
460 while(l > 0) {
461 c = (unsigned char) *mb++;
462 if(c < 0x80 || c > 0xBF) {
463 return -1;
464 }
465 l--;
466 w = (w << 6) | (c & 0x3F);
467 }
468 }
469 AppendChar(w);
470 }
471
472 return 0;
473 }
474
475
GetUTF8(void) const476 char *String::GetUTF8(void) const
477 {
478 size_t len = GetUTF8Length() + 2;
479 char *str = new char[len];
480 ToUTF8(str, len);
481 return str;
482 }
483
484
485
486 }; // namespace as
487 }; // namespace sswf
488