b311480e |
1 | // Copyright (c) 1993-1999 Matra Datavision |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
7fd59977 |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
d5f74e42 |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
7fd59977 |
14 | |
7fd59977 |
15 | #include <TCollection_ExtendedString.ixx> |
16 | #include <Standard.hxx> |
17 | #include <Standard_ExtString.hxx> |
18 | #include <Standard_NullObject.hxx> |
19 | #include <Standard_OutOfRange.hxx> |
7fd59977 |
20 | #include <TCollection_AsciiString.hxx> |
21 | |
971c281b |
22 | #include <cstdio> |
23 | #include <cctype> |
24 | |
7fd59977 |
25 | static |
26 | Standard_PExtCharacter Allocate(const Standard_Size aLength); |
27 | |
28 | static |
29 | Standard_PExtCharacter Reallocate(Standard_Address aAddr, |
29cb310a |
30 | const Standard_Size aLength); |
7fd59977 |
31 | |
32 | Standard_EXPORT short NULL_EXTSTRING[1] = {0}; |
33 | |
34 | //============================== input value have len = 2 bytes ==== |
35 | inline Standard_ExtCharacter ConvertToUnicode2B (unsigned char *p) |
36 | { |
37 | // *p, *(p+1) |
d9ff84e8 |
38 | // little endian |
7fd59977 |
39 | union { |
40 | struct { |
7fd59977 |
41 | unsigned char l; |
d9ff84e8 |
42 | unsigned char h; |
7fd59977 |
43 | } hl; |
44 | Standard_ExtCharacter chr; |
45 | } EL; |
46 | |
47 | unsigned char l = *(p+1); |
48 | l |= 0xC0; |
49 | unsigned char h = *p; |
50 | h <<= 6; |
51 | h |= 0x3F; |
52 | l &= h;// l is defined |
53 | h = *p; |
54 | h >>= 2; |
55 | h &= 0x07; |
56 | EL.hl.l = l; |
57 | EL.hl.h = h; |
58 | return EL.chr; |
59 | } |
60 | |
61 | //============================== input value have len = 3 bytes ==== |
62 | inline Standard_ExtCharacter ConvertToUnicode3B (unsigned char *p) |
63 | { |
64 | // *p, *(p+1), *(p+2) =>0 , 1, 2 |
d9ff84e8 |
65 | // little endian |
7fd59977 |
66 | union { |
67 | struct { |
7fd59977 |
68 | unsigned char l; |
d9ff84e8 |
69 | unsigned char h; |
7fd59977 |
70 | } hl; |
71 | Standard_ExtCharacter chr; |
72 | } EL; |
73 | |
74 | |
75 | unsigned char h = *(p+1);//h = 10yyyyyy |
76 | unsigned char l = *(p+2);//h = 10zzzzzz |
77 | |
78 | l |= 0xC0; |
79 | h <<= 6; //yy------ |
80 | h |= 0x3F; //yy111111 |
81 | l &= h; // yyzzzzzz - l is defined |
82 | EL.hl.l = l; |
83 | |
84 | unsigned char a = *p;// a = 1110xxxx |
85 | a <<= 4;//xxxx---- |
86 | a |= 0x0F;//a = xxxx1111 |
87 | h = *(p+1); |
88 | h >>= 2;//----yyyy |
89 | h |= 0xF0; //1111yyyy |
90 | a &= h; // a = xxxxyyyy |
91 | EL.hl.h = a; //h is defined |
92 | return EL.chr; |
93 | } |
94 | //============================== returns number of symbols in UTF8 string ==== |
95 | inline Standard_Integer nbSymbols(const Standard_CString aStr) { |
96 | Standard_Integer aLen = 0;// length in symbols |
97 | int i = 0; |
98 | while (aStr[i] != '\0') { |
99 | if((aStr[i] & 0x80) == 0x00) //1byte => 1 symb - Lat1 |
100 | {aLen++; i++;} |
101 | else if((aStr[i] & 0xE0) == 0xC0 && |
29cb310a |
102 | (aStr[i+1] && |
103 | (aStr[i+1] & 0xC0) == 0x80)) {//2 bytes => 1 symb |
7fd59977 |
104 | aLen++; |
105 | i += 2; |
106 | } else if((aStr[i] & 0xF0) == 0xE0 && |
29cb310a |
107 | ((aStr[i+1] && (aStr[i+1] & 0xC0) == 0x80)) && |
108 | (aStr[i+2] && (aStr[i+2] & 0xC0) == 0x80)) { |
7fd59977 |
109 | aLen++; |
110 | i += 3; |
111 | } else |
112 | i++; |
113 | } |
114 | return aLen; |
115 | } |
116 | |
117 | //----------------------------------------------------------------------------- |
118 | // Create an empty ExtendedString |
119 | // ---------------------------------------------------------------------------- |
120 | TCollection_ExtendedString::TCollection_ExtendedString() |
121 | { |
122 | // mystring = 0L; |
123 | mylength = 0; |
124 | mystring = Allocate((mylength+1)*2); |
125 | mystring[mylength] = '\0'; |
126 | } |
127 | |
128 | //---------------------------------------------------------------------------- |
129 | // Create an ExtendedString from a Standard_CString |
130 | //---------------------------------------------------------------------------- |
131 | TCollection_ExtendedString::TCollection_ExtendedString |
132 | (const Standard_CString astring, |
29cb310a |
133 | const Standard_Boolean isMultiByte) |
7fd59977 |
134 | { |
135 | if (astring) { |
136 | if(!isMultiByte) { |
105aae76 |
137 | mylength = (int)strlen( astring ); |
7fd59977 |
138 | mystring = Allocate((mylength+1)*2); |
139 | for (int i = 0 ; i < mylength ; i++) |
29cb310a |
140 | mystring[i] = ToExtCharacter(astring[i]); |
7fd59977 |
141 | mystring[mylength] = '\0'; |
142 | } |
143 | else { |
144 | mylength = nbSymbols(astring); |
29cb310a |
145 | mystring = Allocate( (mylength+1)*2 ); |
7fd59977 |
146 | if(!ConvertToUnicode (astring)) |
7f4c4756 |
147 | { |
d9ff84e8 |
148 | mylength = (int)strlen( astring ); |
149 | mystring = Reallocate(mystring, (mylength+1)*2); |
150 | for (int i = 0 ; i < mylength ; i++) |
151 | mystring[i] = ToExtCharacter(astring[i]); |
152 | mystring[mylength] = '\0'; |
7f4c4756 |
153 | } |
7fd59977 |
154 | } |
155 | } |
156 | else { |
157 | Standard_NullObject::Raise("TCollection_ExtendedString : " |
158 | "parameter 'astring'"); |
159 | } |
160 | } |
161 | |
162 | //--------------------------------------------------------------------------- |
163 | // Create an ExtendedString from an ExtString |
164 | //-------------------------------------------------------------------------- |
165 | TCollection_ExtendedString::TCollection_ExtendedString |
166 | (const Standard_ExtString astring) |
167 | { |
168 | |
169 | if (astring) { |
29cb310a |
170 | for ( mylength=0; astring[mylength]; ++mylength ); |
171 | const Standard_Integer size = (mylength+1)*2; |
172 | mystring = Allocate(size); |
173 | memcpy( mystring, astring, size ); |
7fd59977 |
174 | mystring[mylength] = '\0'; |
7fd59977 |
175 | } |
176 | else { |
177 | Standard_NullObject::Raise("TCollection_ExtendedString : null parameter "); |
178 | } |
179 | } |
180 | |
181 | // ---------------------------------------------------------------------------- |
182 | // Create an asciistring from a Standard_Character |
183 | // ---------------------------------------------------------------------------- |
184 | TCollection_ExtendedString::TCollection_ExtendedString |
185 | (const Standard_Character aChar) |
186 | { |
187 | if ( aChar != '\0' ) { |
188 | mylength = 1; |
189 | mystring = Allocate(2*2); |
190 | mystring[0] = ToExtCharacter(aChar); |
191 | mystring[1] = '\0'; |
192 | } |
193 | else { |
194 | // mystring = 0L; |
195 | mylength = 0; |
196 | mystring = Allocate((mylength+1)*2); |
197 | mystring[mylength] = '\0'; |
198 | } |
199 | } |
200 | |
201 | //-------------------------------------------------------------------------- |
202 | // Create a string from a ExtCharacter |
203 | // ---------------------------------------------------------------------------- |
204 | TCollection_ExtendedString::TCollection_ExtendedString |
205 | (const Standard_ExtCharacter aChar) |
206 | { |
207 | mylength = 1; |
208 | mystring = Allocate(2*2); |
209 | mystring[0] = aChar; |
210 | mystring[1] = '\0'; |
211 | } |
212 | |
213 | // ---------------------------------------------------------------------------- |
214 | // Create an AsciiString from a filler |
215 | // ---------------------------------------------------------------------------- |
216 | TCollection_ExtendedString::TCollection_ExtendedString |
217 | (const Standard_Integer length, |
218 | const Standard_ExtCharacter filler ) |
219 | { |
29cb310a |
220 | mystring = Allocate( (length+1)*2 ); |
7fd59977 |
221 | mylength = length; |
222 | for (int i = 0 ; i < length ; i++) mystring[i] = filler; |
223 | mystring[length] = '\0'; |
224 | } |
225 | |
226 | // ---------------------------------------------------------------------------- |
227 | // Create a String from an Integer |
228 | // ---------------------------------------------------------------------------- |
229 | TCollection_ExtendedString::TCollection_ExtendedString |
230 | (const Standard_Integer aValue) |
231 | { |
232 | union {int bid ; |
233 | char t [13];} CHN ; |
91322f44 |
234 | Sprintf(&CHN.t[0],"%d",aValue); |
105aae76 |
235 | mylength = (int)strlen(CHN.t); |
7fd59977 |
236 | mystring = Allocate((mylength+1)*2); |
237 | for (int i = 0 ; i < mylength ; i++) mystring[i] = ToExtCharacter(CHN.t[i]); |
238 | mystring[mylength] = '\0'; |
239 | } |
240 | |
241 | // ---------------------------------------------------------------------------- |
242 | // Create a String from a real |
243 | // ---------------------------------------------------------------------------- |
244 | TCollection_ExtendedString::TCollection_ExtendedString |
245 | (const Standard_Real aValue) |
246 | { |
247 | union {int bid ; |
248 | char t [50];} CHN ; |
91322f44 |
249 | Sprintf(&CHN.t[0],"%g",aValue); |
105aae76 |
250 | mylength = (int)strlen( CHN.t ); |
7fd59977 |
251 | mystring = Allocate((mylength+1)*2); |
252 | for (int i = 0 ; i < mylength ; i++) mystring[i] = ToExtCharacter(CHN.t[i]); |
253 | mystring[mylength] = '\0'; |
254 | } |
255 | |
256 | //----------------------------------------------------------------------------- |
257 | // create an extendedstring from an extendedstring |
258 | // ---------------------------------------------------------------------------- |
259 | TCollection_ExtendedString::TCollection_ExtendedString |
260 | (const TCollection_ExtendedString& astring) |
261 | { |
29cb310a |
262 | const Standard_Integer size = (astring.mylength+1)*2; |
7fd59977 |
263 | mylength = astring.mylength; |
29cb310a |
264 | mystring = Allocate(size); |
265 | memcpy( mystring, astring.mystring, size ); |
7fd59977 |
266 | mystring[mylength] = '\0'; |
7fd59977 |
267 | } |
268 | |
269 | //--------------------------------------------------------------------------- |
270 | // Create an extendedstring from an AsciiString |
271 | //--------------------------------------------------------------------------- |
272 | TCollection_ExtendedString::TCollection_ExtendedString |
273 | (const TCollection_AsciiString& astring) |
274 | { |
d9ff84e8 |
275 | mylength = nbSymbols(astring.ToCString()); |
7fd59977 |
276 | mystring = Allocate((mylength+1)*2); |
d9ff84e8 |
277 | if(!ConvertToUnicode (astring.ToCString())) |
278 | { |
279 | mylength = astring.Length(); |
280 | mystring = Reallocate(mystring, (mylength+1)*2); |
281 | Standard_CString aCString = astring.ToCString(); |
282 | for (Standard_Integer i = 0; i <= mylength ; i++) |
283 | mystring[i] = ToExtCharacter( aCString[i] ); |
284 | } |
7fd59977 |
285 | } |
286 | |
287 | // ---------------------------------------------------------------------------- |
288 | // AssignCat |
289 | // ---------------------------------------------------------------------------- |
290 | void TCollection_ExtendedString::AssignCat |
291 | (const TCollection_ExtendedString& other) |
292 | { |
293 | Standard_Integer otherlength = other.mylength; |
294 | if (otherlength) { |
295 | Standard_ExtString sother = other.mystring; |
29cb310a |
296 | Standard_Integer newlength = mylength + otherlength; |
7fd59977 |
297 | if (mystring) { |
547702a1 |
298 | mystring = Reallocate(mystring, (newlength+1)*2 ); |
29cb310a |
299 | memcpy( mystring + mylength, sother, (otherlength+1)*2 ); |
7fd59977 |
300 | } |
301 | else { |
29cb310a |
302 | mystring = Allocate( (newlength+1)*2 ); |
303 | memcpy( mystring, sother, (otherlength+1)*2 ); |
7fd59977 |
304 | } |
305 | mylength = newlength; |
7fd59977 |
306 | } |
307 | } |
308 | |
309 | // ---------------------------------------------------------------------------- |
310 | // Cat |
311 | // ---------------------------------------------------------------------------- |
312 | TCollection_ExtendedString TCollection_ExtendedString::Cat |
313 | (const TCollection_ExtendedString& other) const |
314 | { |
29cb310a |
315 | TCollection_ExtendedString res( mylength + other.mylength, 0 ); |
316 | if ( mylength > 0 ) |
317 | memcpy( res.mystring, mystring, mylength*2 ); |
318 | if ( other.mylength > 0 ) |
319 | memcpy( res.mystring + mylength, other.mystring, other.mylength*2 ); |
7fd59977 |
320 | return res; |
321 | } |
322 | |
323 | // ---------------------------------------------------------------------------- |
324 | // ChangeAll |
325 | // ---------------------------------------------------------------------------- |
326 | void TCollection_ExtendedString::ChangeAll(const Standard_ExtCharacter aChar, |
327 | const Standard_ExtCharacter NewChar) |
328 | { |
329 | for (int i = 0 ; i < mylength; i++) |
330 | if (mystring[i] == aChar) mystring[i] = NewChar; |
331 | } |
332 | |
333 | // ---------------------------------------------------------------------------- |
334 | // Clear |
335 | // ---------------------------------------------------------------------------- |
336 | void TCollection_ExtendedString::Clear() |
337 | { |
547702a1 |
338 | if (mystring) Standard::Free(mystring); |
7fd59977 |
339 | // mystring = 0L; |
340 | mylength = 0; |
341 | mystring = Allocate((mylength+1)*2); |
342 | mystring[mylength] = '\0'; |
343 | } |
344 | |
345 | // ---------------------------------------------------------------------------- |
346 | // Copy |
347 | // ---------------------------------------------------------------------------- |
348 | void TCollection_ExtendedString::Copy (const TCollection_ExtendedString& fromwhere) |
349 | { |
350 | |
351 | if (fromwhere.mystring) { |
29cb310a |
352 | const Standard_Integer newlength = fromwhere.mylength; |
353 | const Standard_Integer size = (newlength + 1) * 2; |
7fd59977 |
354 | if (mystring) { |
547702a1 |
355 | mystring = Reallocate(mystring, size ); |
7fd59977 |
356 | } |
357 | else { |
29cb310a |
358 | mystring = Allocate( size ); |
7fd59977 |
359 | } |
360 | mylength = newlength; |
29cb310a |
361 | memcpy( mystring, fromwhere.mystring, size ); |
7fd59977 |
362 | } |
363 | else { |
364 | if (mystring) { |
365 | mylength = 0; |
366 | mystring[mylength] = '\0'; |
367 | } |
368 | } |
369 | } |
370 | |
371 | // ---------------------------------------------------------------------------- |
372 | // Destroy |
373 | // ---------------------------------------------------------------------------- |
374 | void TCollection_ExtendedString::Destroy() |
375 | { |
547702a1 |
376 | if (mystring) Standard::Free(mystring); |
7fd59977 |
377 | mystring = 0L; |
378 | } |
379 | |
380 | //---------------------------------------------------------------------------- |
381 | // Insert a character before 'where'th character |
382 | // ---------------------------------------------------------------------------- |
383 | void TCollection_ExtendedString::Insert(const Standard_Integer where, |
384 | const Standard_ExtCharacter what) |
385 | { |
386 | if (where > mylength + 1 ) |
387 | Standard_OutOfRange::Raise("TCollection_ExtendedString::Insert : " |
388 | "Parameter where is too big"); |
389 | if (where < 0) |
390 | Standard_OutOfRange::Raise("TCollection_ExtendedString::Insert : " |
391 | "Parameter where is negative"); |
392 | |
393 | if (mystring) { |
547702a1 |
394 | mystring = Reallocate(mystring, (mylength+2)*2); |
7fd59977 |
395 | } |
396 | else { |
397 | mystring = Allocate((mylength+2)*2); |
398 | } |
399 | if (where != mylength +1) { |
400 | for (int i=mylength-1; i >= where-1; i--) |
401 | mystring[i+1] = mystring[i]; |
402 | } |
403 | mystring[where-1] = what; |
404 | mylength++; |
405 | mystring[mylength] = '\0'; |
406 | } |
407 | |
408 | // ---------------------------------------------------------------------------- |
409 | // Insert |
410 | // ---------------------------------------------------------------------------- |
411 | void TCollection_ExtendedString::Insert(const Standard_Integer where, |
412 | const TCollection_ExtendedString& what) |
413 | { |
414 | Standard_ExtString swhat = what.mystring; |
415 | if (where <= mylength + 1) { |
416 | Standard_Integer whatlength = what.mylength; |
417 | if(whatlength) { |
418 | Standard_Integer newlength = mylength + whatlength; |
419 | |
420 | if (mystring) { |
547702a1 |
421 | mystring = Reallocate(mystring,(newlength+1)*2); |
7fd59977 |
422 | } |
423 | else { |
424 | mystring = Allocate((newlength+1)*2); |
425 | } |
426 | if (where != mylength +1) { |
427 | for (int i=mylength-1; i >= where-1; i--) |
428 | mystring[i+whatlength] = mystring[i]; |
429 | } |
430 | for (int i=0; i < whatlength; i++) |
431 | mystring[where-1+i] = swhat[i]; |
432 | |
433 | mylength = newlength; |
434 | mystring[mylength] = '\0'; |
435 | } |
436 | } |
437 | else { |
438 | Standard_OutOfRange::Raise("TCollection_ExtendedString::Insert : " |
439 | "Parameter where is too big"); |
440 | } |
441 | } |
442 | |
7fd59977 |
443 | // ---------------------------------------------------------------------------- |
444 | // IsEqual |
445 | // ---------------------------------------------------------------------------- |
446 | Standard_Boolean TCollection_ExtendedString::IsEqual |
447 | (const Standard_ExtString other) const |
448 | { |
29cb310a |
449 | return ( memcmp( mystring, other, (mylength+1)*2 ) == 0 ); |
7fd59977 |
450 | } |
7fd59977 |
451 | |
452 | // ---------------------------------------------------------------------------- |
453 | // IsEqual |
454 | // ---------------------------------------------------------------------------- |
455 | Standard_Boolean TCollection_ExtendedString::IsEqual |
456 | (const TCollection_ExtendedString& other) const |
457 | { |
29cb310a |
458 | return ( memcmp( mystring, other.mystring, (mylength+1)*2 ) == 0 ); |
7fd59977 |
459 | } |
460 | |
7fd59977 |
461 | // ---------------------------------------------------------------------------- |
462 | // IsDifferent |
463 | // ---------------------------------------------------------------------------- |
464 | Standard_Boolean TCollection_ExtendedString::IsDifferent |
465 | (const Standard_ExtString other ) const |
466 | { |
29cb310a |
467 | return ( memcmp( mystring, other, (mylength+1)*2 ) != 0 ); |
7fd59977 |
468 | } |
7fd59977 |
469 | |
470 | // ---------------------------------------------------------------------------- |
471 | // IsDifferent |
472 | // ---------------------------------------------------------------------------- |
473 | Standard_Boolean TCollection_ExtendedString::IsDifferent |
474 | (const TCollection_ExtendedString& other) const |
475 | { |
29cb310a |
476 | return ( memcmp( mystring, other.mystring, (mylength+1)*2 ) != 0 ); |
7fd59977 |
477 | } |
478 | |
7fd59977 |
479 | // ---------------------------------------------------------------------------- |
480 | // IsLess |
481 | // ---------------------------------------------------------------------------- |
482 | Standard_Boolean TCollection_ExtendedString::IsLess |
483 | (const Standard_ExtString other) const |
484 | { |
29cb310a |
485 | return ( memcmp( mystring, other, (mylength+1)*2 ) < 0 ); |
7fd59977 |
486 | } |
7fd59977 |
487 | |
488 | // ---------------------------------------------------------------------------- |
489 | // IsLess |
490 | // ---------------------------------------------------------------------------- |
491 | Standard_Boolean TCollection_ExtendedString::IsLess |
492 | (const TCollection_ExtendedString& other) const |
493 | { |
29cb310a |
494 | return ( memcmp( mystring, other.mystring, (mylength+1)*2 ) < 0 ); |
7fd59977 |
495 | } |
496 | |
7fd59977 |
497 | // ---------------------------------------------------------------------------- |
498 | // IsGreater |
499 | // ---------------------------------------------------------------------------- |
500 | Standard_Boolean TCollection_ExtendedString::IsGreater |
501 | (const Standard_ExtString other) const |
502 | { |
29cb310a |
503 | return ( memcmp( mystring, other, (mylength+1)*2 ) > 0 ); |
7fd59977 |
504 | } |
7fd59977 |
505 | |
506 | // ---------------------------------------------------------------------------- |
507 | // IsGreater |
508 | // ---------------------------------------------------------------------------- |
509 | Standard_Boolean TCollection_ExtendedString::IsGreater |
510 | (const TCollection_ExtendedString& other) const |
511 | { |
29cb310a |
512 | return ( memcmp( mystring, other.mystring, (mylength+1)*2 ) > 0 ); |
7fd59977 |
513 | } |
514 | |
515 | // ---------------------------------------------------------------------------- |
516 | // IsAscii |
517 | // ---------------------------------------------------------------------------- |
518 | Standard_Boolean TCollection_ExtendedString::IsAscii() const |
519 | { |
520 | for( Standard_Integer i = 0 ; i < mylength ; i++) |
521 | if (!IsAnAscii(mystring[i])) return Standard_False; |
522 | return Standard_True; |
523 | } |
524 | |
525 | //------------------------------------------------------------------------ |
526 | // Length |
527 | // ---------------------------------------------------------------------------- |
528 | Standard_Integer TCollection_ExtendedString::Length() const |
529 | { |
530 | return mylength; |
531 | } |
532 | |
533 | // ---------------------------------------------------------------------------- |
534 | // Print |
535 | // ---------------------------------------------------------------------------- |
536 | void TCollection_ExtendedString::Print(Standard_OStream& astream) const |
537 | { |
538 | // ASCII symbols (including extended Ascii) are printed as is; |
539 | // other Unicode characters are encoded as SGML numeric character references |
540 | for (Standard_Integer i = 0 ; i < mylength ; i++) { |
541 | Standard_ExtCharacter c = mystring[i]; |
542 | if ( IsAnAscii(c) ) |
543 | astream << ToCharacter(c); |
544 | else |
545 | astream << "&#" << c << ";"; |
546 | } |
547 | } |
548 | |
549 | |
550 | // ---------------------------------------------------------------------------- |
551 | Standard_OStream& operator << (Standard_OStream& astream, |
552 | const TCollection_ExtendedString& astring) |
553 | { |
554 | astring.Print(astream); |
555 | return astream; |
556 | } |
557 | |
558 | // ---------------------------------------------------------------------------- |
559 | // RemoveAll |
560 | // ---------------------------------------------------------------------------- |
561 | void TCollection_ExtendedString::RemoveAll(const Standard_ExtCharacter what) |
562 | |
563 | { |
564 | if (mylength == 0) return; |
565 | int c = 0; |
566 | for (int i=0; i < mylength; i++) |
567 | if (mystring[i] != what) mystring[c++] = mystring[i]; |
568 | mylength = c; |
569 | mystring[mylength] = '\0'; |
570 | } |
571 | |
572 | // ---------------------------------------------------------------------------- |
573 | // Remove |
574 | // ---------------------------------------------------------------------------- |
575 | void TCollection_ExtendedString::Remove (const Standard_Integer where, |
576 | const Standard_Integer ahowmany) |
577 | { |
578 | if (where+ahowmany <= mylength+1) { |
579 | int i,j; |
580 | for (i = where+ahowmany-1, j = where-1; i < mylength; i++, j++) |
581 | mystring[j] = mystring[i]; |
582 | mylength -= ahowmany; |
583 | mystring[mylength] = '\0'; |
584 | } |
585 | else |
586 | Standard_OutOfRange::Raise("TCollection_ExtendedString::Remove: " |
587 | "Too many characters to erase or " |
588 | "invalid starting value."); |
589 | } |
590 | |
591 | // ---------------------------------------------------------------------------- |
592 | // Search |
593 | // ---------------------------------------------------------------------------- |
594 | Standard_Integer TCollection_ExtendedString::Search |
595 | (const TCollection_ExtendedString& what) const |
596 | { |
597 | Standard_Integer size = what.mylength; |
598 | Standard_ExtString swhat = what.mystring; |
599 | if (size) { |
600 | int k,j; |
601 | int i = 0; |
602 | Standard_Boolean find = Standard_False; |
603 | while ( i < mylength-size+1 && !find) { |
604 | k = i++; |
605 | j = 0; |
606 | while (j < size && mystring[k++] == swhat[j++]) |
607 | if (j == size) find = Standard_True; |
608 | } |
609 | if (find) return i; |
610 | } |
611 | return -1; |
612 | } |
613 | |
614 | // ---------------------------------------------------------------------------- |
615 | // SearchFromEnd |
616 | // ---------------------------------------------------------------------------- |
617 | Standard_Integer TCollection_ExtendedString::SearchFromEnd |
618 | (const TCollection_ExtendedString& what) const |
619 | { |
620 | Standard_Integer size = what.mylength; |
621 | if (size) { |
622 | Standard_ExtString swhat = what.mystring; |
623 | int k,j; |
624 | int i = mylength-1; |
625 | Standard_Boolean find = Standard_False; |
626 | while ( i >= size-1 && !find) { |
627 | k = i--; |
628 | j = size-1; |
629 | while (j >= 0 && mystring[k--] == swhat[j--]) |
630 | if (j == -1) find = Standard_True; |
631 | } |
632 | if (find) return i-size+3; |
633 | } |
634 | return -1; |
635 | } |
636 | |
637 | // ---------------------------------------------------------------------------- |
638 | // SetValue |
639 | // ---------------------------------------------------------------------------- |
640 | void TCollection_ExtendedString::SetValue(const Standard_Integer where, |
641 | const Standard_ExtCharacter what) |
642 | { |
643 | if (where > 0 && where <= mylength) { |
644 | mystring[where-1] = what; |
645 | } |
646 | else { |
647 | Standard_OutOfRange::Raise("TCollection_ExtendedString::SetValue : parameter where"); |
648 | } |
649 | } |
650 | |
651 | // ---------------------------------------------------------------------------- |
652 | // SetValue |
653 | // ---------------------------------------------------------------------------- |
654 | void TCollection_ExtendedString::SetValue |
655 | (const Standard_Integer where, |
656 | const TCollection_ExtendedString& what) |
657 | { |
658 | if (where > 0 && where <= mylength+1) { |
659 | Standard_Integer size = what.mylength; |
660 | Standard_ExtString swhat = what.mystring; |
661 | size += (where - 1); |
662 | if (size >= mylength){ |
663 | if (mystring) { |
547702a1 |
664 | mystring = Reallocate (mystring,(size+1)*2); |
7fd59977 |
665 | } |
666 | else { |
667 | mystring = Allocate((size+1)*2); |
668 | } |
669 | mylength = size; |
670 | } |
671 | for (int i = where-1; i < size; i++) |
672 | mystring[i] = swhat[i-(where-1)]; |
673 | mystring[mylength] = '\0'; |
674 | } |
675 | else |
676 | Standard_OutOfRange::Raise("TCollection_ExtendedString::SetValue : " |
677 | "parameter where"); |
678 | } |
679 | |
680 | // ---------------------------------------------------------------------------- |
681 | // Split |
682 | // ---------------------------------------------------------------------------- |
683 | TCollection_ExtendedString TCollection_ExtendedString::Split |
684 | (const Standard_Integer where) |
685 | { |
686 | if (where >= 0 && where < mylength) { |
687 | TCollection_ExtendedString res(&mystring[where]); |
688 | Trunc(where); |
689 | return res; |
690 | } |
691 | Standard_OutOfRange::Raise("TCollection_ExtendedString::Split index"); |
692 | TCollection_ExtendedString res; |
693 | return res; |
694 | } |
695 | |
696 | // ---------------------------------------------------------------------------- |
697 | // Token |
698 | // ---------------------------------------------------------------------------- |
699 | TCollection_ExtendedString TCollection_ExtendedString::Token |
700 | (const Standard_ExtString separators, |
701 | const Standard_Integer whichone) const |
702 | { |
29cb310a |
703 | TCollection_ExtendedString res; |
7fd59977 |
704 | if (!separators) |
705 | Standard_NullObject::Raise("TCollection_ExtendedString::Token : " |
706 | "parameter 'separators'"); |
707 | |
708 | int i,j,k,l; |
709 | Standard_PExtCharacter buftmp = Allocate((mylength+1)*2); |
710 | Standard_ExtCharacter aSep; |
711 | |
712 | Standard_Boolean isSepFound = Standard_False, otherSepFound; |
713 | |
714 | j = 0; |
715 | |
716 | for (i = 0; i < whichone && j < mylength; i++) { |
717 | isSepFound = Standard_False; |
718 | k = 0; |
719 | buftmp[0] = 0; |
720 | |
721 | // Avant de commencer il faut virer les saloperies devant |
722 | // |
723 | otherSepFound = Standard_True; |
724 | while (j < mylength && otherSepFound) { |
725 | l = 0; |
726 | otherSepFound = Standard_False; |
727 | aSep = separators[l]; |
728 | while(aSep != 0) { |
729 | if (aSep == mystring[j]) { |
730 | aSep = 0; |
731 | otherSepFound = Standard_True; |
732 | } |
733 | else { |
734 | aSep = separators[l++]; |
735 | } |
736 | } |
737 | if (otherSepFound) j++; |
738 | } |
739 | |
740 | while (!isSepFound && k < mylength && j<mylength ) { |
741 | l = 0; |
742 | aSep = separators[l]; |
743 | |
744 | while (aSep != 0 && !isSepFound) { |
745 | if (aSep == mystring[j]) { |
746 | buftmp[k] = 0; |
747 | isSepFound = Standard_True; |
748 | } |
749 | else { |
750 | buftmp[k] = mystring[j]; |
751 | } |
752 | l++; |
753 | aSep = separators[l]; |
754 | } |
755 | j++; k++; |
756 | if(j==mylength) buftmp[k] = 0; |
757 | } |
758 | } |
759 | |
760 | if (i < whichone) { |
761 | buftmp[0] = 0; |
547702a1 |
762 | Standard::Free(buftmp); |
7fd59977 |
763 | } |
764 | else { |
547702a1 |
765 | Standard::Free(res.mystring); |
7fd59977 |
766 | res.mystring = buftmp; |
29cb310a |
767 | for ( res.mylength=0; buftmp[res.mylength]; ++res.mylength ); |
7fd59977 |
768 | } |
769 | return res; |
770 | } |
771 | |
772 | // ---------------------------------------------------------------------------- |
773 | // ToExtString |
774 | // ---------------------------------------------------------------------------- |
775 | const Standard_ExtString TCollection_ExtendedString::ToExtString() const |
776 | { |
777 | if(mystring) return mystring; |
778 | return NULL_EXTSTRING; |
779 | } |
780 | |
781 | // ---------------------------------------------------------------------------- |
782 | // Trunc |
783 | // ---------------------------------------------------------------------------- |
784 | void TCollection_ExtendedString::Trunc(const Standard_Integer ahowmany) |
785 | { |
786 | if (ahowmany < 0 || ahowmany > mylength) |
787 | Standard_OutOfRange::Raise("TCollection_ExtendedString::Trunc : " |
788 | "parameter 'ahowmany'"); |
789 | mylength = ahowmany; |
790 | mystring[mylength] = '\0'; |
791 | } |
792 | |
793 | // ---------------------------------------------------------------------------- |
794 | // Value |
795 | // ---------------------------------------------------------------------------- |
796 | Standard_ExtCharacter TCollection_ExtendedString::Value |
797 | (const Standard_Integer where) const |
798 | { |
799 | if (where > 0 && where <= mylength) { |
800 | if(mystring) return mystring[where-1]; |
801 | else return 0; |
802 | } |
803 | Standard_OutOfRange::Raise("TCollection_ExtendedString::Value : " |
804 | "parameter where"); |
805 | return 0; |
806 | } |
807 | |
808 | |
7fd59977 |
809 | //---------------------------------------------------------------------------- |
810 | // Convert CString (including multibyte case) to UniCode representation |
811 | //---------------------------------------------------------------------------- |
812 | Standard_Boolean TCollection_ExtendedString::ConvertToUnicode |
813 | (const Standard_CString aStr) |
814 | { |
815 | Standard_Boolean aRes = Standard_True; |
816 | short * p = mystring; |
817 | int i = 0; |
818 | while (aStr[i] != '\0') { |
819 | if((aStr[i] & 0x80) == 0x00) //1byte => 1 symb - Lat1 |
820 | {*p++ = ToExtCharacter(aStr[i]); i++;} |
821 | else if((aStr[i] & 0xE0) == 0xC0 && |
29cb310a |
822 | (aStr[i+1] && |
823 | (aStr[i+1] & 0xC0) == 0x80)) {//2 bytes => 1 symb |
7fd59977 |
824 | *p++ = ConvertToUnicode2B((unsigned char*)&aStr[i]); |
825 | i += 2; |
826 | } else if((aStr[i] & 0xF0) == 0xE0 && |
29cb310a |
827 | ((aStr[i+1] && (aStr[i+1] & 0xC0) == 0x80)) && |
828 | (aStr[i+2] && (aStr[i+2] & 0xC0) == 0x80)) { |
7fd59977 |
829 | *p++ = ConvertToUnicode3B((unsigned char*)&aStr[i]); |
830 | i += 3; |
831 | } else { //unsupported case ==> not UTF8 |
832 | aRes = Standard_False; |
833 | break; |
834 | } |
835 | } |
836 | *p = 0x0000; |
837 | return aRes; |
838 | } |
839 | //---------------------------------------------------------------------------- |
840 | // Returns expected CString length in UTF8 coding. |
841 | //---------------------------------------------------------------------------- |
842 | Standard_Integer TCollection_ExtendedString::LengthOfCString() const |
843 | { |
844 | Standard_Integer i=0, aLen=0; |
845 | while(mystring[i]) { |
846 | if((mystring[i] & 0xFF80) == 0) |
847 | aLen++; |
848 | else if((mystring[i] & 0xF800) == 0) |
849 | aLen +=2; |
850 | else |
851 | aLen += 3; |
852 | i++; |
853 | } |
854 | return aLen; |
855 | } |
856 | |
857 | //---------------------------------------------------------------------------- |
858 | // Converts the internal <mystring> to UTF8 coding and returns length of the |
859 | // out CString. |
860 | //---------------------------------------------------------------------------- |
861 | Standard_Integer TCollection_ExtendedString::ToUTF8CString(Standard_PCharacter& theCString) const |
862 | { |
863 | Standard_Integer i=0, j=0; |
864 | unsigned char a,b,c; |
865 | while(mystring[i]) { |
866 | if((mystring[i] & 0xFF80) == 0) { |
867 | theCString[j++] = (char)mystring[i]; |
868 | } |
869 | else if((mystring[i] & 0xF800) == 0) { |
870 | b = (unsigned char)mystring[i];//yyzzzzzz |
871 | c = (unsigned char)mystring[i];//yyzzzzzz |
872 | a = (unsigned char)(mystring[i]>>8);//00000yyy |
873 | b &= 0x3F; |
874 | b |= 0x80; |
875 | a <<=2; |
876 | a |= 0xC0;//110yyy00; |
877 | c >>=6; |
878 | c &= 0x03; |
879 | a |=c; |
880 | theCString[j++] = a; |
881 | theCString[j++] = b; |
882 | } else { |
883 | b = (unsigned char)mystring[i];//yyzzzzzz |
884 | c = (unsigned char)mystring[i];//yyzzzzzz |
885 | unsigned char d = a = (unsigned char)(mystring[i]>>8);//xxxxyyyy |
886 | c &= 0x3F; |
887 | c |= 0x80;//10zzzzzz |
888 | b >>= 6; //000000yy |
889 | d <<= 2;//xxyyyy00; |
890 | b |= d; |
891 | b = (b & 0x3F) | 0x80;//10yyyyyy |
892 | a >>= 4; //0000xxxx |
893 | a |= 0xE0;//1110xxxx |
894 | theCString[j++] = a; |
895 | theCString[j++] = b; |
896 | theCString[j++] = c; |
897 | } |
898 | i++; |
899 | } |
900 | theCString[j] = 0x00; |
901 | return j; |
902 | } |
903 | //======================================================================= |
904 | //function : Allocate |
905 | //purpose : |
906 | //======================================================================= |
907 | Standard_PExtCharacter Allocate(const Standard_Size aLength) |
908 | { |
909 | Standard_PExtCharacter pChar; |
910 | // |
911 | pChar=(Standard_PExtCharacter)Standard::Allocate(aLength); |
912 | // |
913 | return pChar; |
914 | } |
915 | //======================================================================= |
916 | //function : Reallocate |
917 | //purpose : |
918 | //======================================================================= |
919 | Standard_PExtCharacter Reallocate(Standard_Address aAddr, |
29cb310a |
920 | const Standard_Size aLength) |
7fd59977 |
921 | { |
547702a1 |
922 | return (Standard_PExtCharacter)Standard::Reallocate(aAddr, aLength); |
7fd59977 |
923 | } |