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