0027585: It is not possible to store OCAF documents to paths with special characters...
[occt.git] / src / TCollection / TCollection_AsciiString.cxx
1 // Copyright (c) 1993-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
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
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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <TCollection_AsciiString.hxx>
16
17 #include <NCollection_UtfIterator.hxx>
18 #include <Standard.hxx>
19 #include <Standard_NegativeValue.hxx>
20 #include <Standard_NullObject.hxx>
21 #include <Standard_NumericError.hxx>
22 #include <Standard_OutOfRange.hxx>
23 #include <TCollection_ExtendedString.hxx>
24 #include <TCollection_HAsciiString.hxx>
25
26 #include <cctype>
27 #include <cstdio>
28 #include <cstring>
29 // Shortcuts to standard allocate and reallocate functions
30 static inline Standard_PCharacter Allocate(const Standard_Size aLength)
31 {
32   return (Standard_PCharacter)Standard::Allocate (aLength);
33 }
34 static inline Standard_PCharacter Reallocate (Standard_Address aAddr,
35                                               const Standard_Size aLength)
36 {
37   return (Standard_PCharacter)Standard::Reallocate (aAddr, aLength);
38 }
39 static inline void Free (Standard_PCharacter aAddr)
40 {
41   Standard_Address aPtr = aAddr;
42   Standard::Free (aPtr);
43 }
44
45 // ----------------------------------------------------------------------------
46 // Create an empty AsciiString
47 // ----------------------------------------------------------------------------
48 TCollection_AsciiString::TCollection_AsciiString()
49 {
50   mylength = 0;
51   
52   mystring = Allocate(mylength+1);
53   mystring[mylength] = '\0';
54 }
55
56
57 // ----------------------------------------------------------------------------
58 // Create an asciistring from a Standard_CString
59 // ----------------------------------------------------------------------------
60 TCollection_AsciiString::TCollection_AsciiString(const Standard_CString astring)
61   : mystring(0), mylength(0)
62 {
63   if (astring) {
64     mylength = Standard_Integer( strlen(astring) );
65     mystring = Allocate(mylength+1);
66     strncpy(mystring,astring,mylength);
67     mystring[mylength] = '\0';
68   }
69   else {
70     Standard_NullObject::Raise("TCollection_AsciiString : parameter 'astring'");
71   }
72 }
73
74 // ----------------------------------------------------------------------------
75 // Create an asciistring from a Standard_CString
76 // ----------------------------------------------------------------------------
77 TCollection_AsciiString::TCollection_AsciiString(const Standard_CString astring,
78                                                  const Standard_Integer aLen )
79   : mystring(0), mylength(aLen)
80 {
81   if (astring) {
82     mystring = Allocate(mylength+1);
83     strncpy( mystring , astring , mylength );
84     mystring [ mylength ] = '\0' ;
85   }
86   else {
87     Standard_NullObject::Raise("TCollection_AsciiString : parameter 'astring'");
88   }
89 }
90
91 // ----------------------------------------------------------------------------
92 // Create an asciistring from a Standard_Character
93 // ----------------------------------------------------------------------------
94 TCollection_AsciiString::TCollection_AsciiString(const Standard_Character aChar)
95      : mystring(0)
96 {
97   if ( aChar != '\0' ) {
98     mylength    = 1;
99     mystring    = Allocate(2);
100     mystring[0] = aChar;
101     mystring[1] = '\0';
102   }
103   else {
104     mylength = 0;
105     mystring = Allocate(mylength+1);
106     mystring[mylength] = '\0';
107   }
108 }
109
110 // ----------------------------------------------------------------------------
111 // Create an AsciiString from a filler
112 // ----------------------------------------------------------------------------
113 TCollection_AsciiString::TCollection_AsciiString(const Standard_Integer length,
114                                                  const Standard_Character filler )
115 {
116   mystring = Allocate(length+1);
117   mylength = length;
118   for (int i = 0 ; i < length ; i++) mystring[i] = filler;
119   mystring[length] = '\0';
120 }
121
122 // ----------------------------------------------------------------------------
123 // Create an AsciiString from an Integer
124 // ----------------------------------------------------------------------------
125 TCollection_AsciiString::TCollection_AsciiString(const Standard_Integer aValue)
126      : mystring(0)
127 {
128   char t [13];
129   mylength = Sprintf( t,"%d",aValue);
130   mystring = Allocate(mylength+1);
131   strncpy( mystring , t , mylength );
132   mystring[mylength] = '\0';
133 }
134
135 // ----------------------------------------------------------------------------
136 // Create an asciistring from a real
137 // ----------------------------------------------------------------------------
138 TCollection_AsciiString::TCollection_AsciiString(const Standard_Real aValue)
139      : mystring(0)
140 {
141   char t [50];
142   mylength = Sprintf( t,"%g",aValue);
143   mystring = Allocate(mylength+1);
144   strncpy( mystring , t , mylength );
145   mystring[mylength] = '\0';
146 }
147
148 // ----------------------------------------------------------------------------
149 // Create an asciistring from an asciistring
150 // ----------------------------------------------------------------------------
151 TCollection_AsciiString::TCollection_AsciiString(const TCollection_AsciiString& astring)
152      : mystring(0)
153 {
154   mylength = astring.mylength;
155   mystring = Allocate(mylength+1);
156   if ( mylength )
157     strncpy(mystring,astring.mystring,mylength);
158   mystring[mylength] = '\0';
159 }
160
161 // ----------------------------------------------------------------------------
162 // Create an asciistring from a character
163 // ----------------------------------------------------------------------------
164 TCollection_AsciiString::TCollection_AsciiString(
165                          const TCollection_AsciiString& astring ,
166                          const Standard_Character other )
167      : mystring(0)
168 {
169   mylength = astring.mylength + 1 ;
170   mystring = Allocate(mylength+1);
171   if ( astring.mylength ) {
172     strncpy( mystring , astring.mystring , astring.mylength ) ;
173   }
174   mystring[mylength-1] = other ;
175   mystring[mylength] = '\0' ;
176 }
177
178 // ----------------------------------------------------------------------------
179 // Create an asciistring from an asciistring
180 // ----------------------------------------------------------------------------
181 TCollection_AsciiString::TCollection_AsciiString(
182                          const TCollection_AsciiString& astring ,
183                          const Standard_CString other )
184      : mystring(0)
185 {
186   Standard_Integer otherlength = Standard_Integer( other ? strlen( other ) : 0 );
187   mylength = astring.mylength + otherlength ;
188   mystring = Allocate(mylength+1);
189   if ( astring.mylength ) {
190     strncpy( mystring , astring.mystring , astring.mylength ) ;
191   }
192   if ( otherlength ) {
193     strncpy( mystring + astring.mylength, other, otherlength );
194   }
195   mystring[ mylength ] = '\0';
196 }
197
198 // ----------------------------------------------------------------------------
199 // Create an asciistring from an asciistring
200 // ----------------------------------------------------------------------------
201 TCollection_AsciiString::TCollection_AsciiString(
202                          const TCollection_AsciiString& astring ,
203                          const TCollection_AsciiString& other )
204      : mystring(0)
205 {
206   mylength = astring.mylength + other.mylength ;
207   mystring = Allocate(mylength+1);
208   if ( astring.mylength ) {
209     strncpy( mystring , astring.mystring , astring.mylength ) ;
210   }
211   if ( other.mylength ) {
212     strncpy( mystring + astring.mylength, other.mystring , other.mylength ) ;
213   }
214   mystring[mylength] = '\0' ;
215 }
216
217 //---------------------------------------------------------------------------
218 //  Create an asciistring from an ExtendedString 
219 //---------------------------------------------------------------------------
220 TCollection_AsciiString::TCollection_AsciiString(const TCollection_ExtendedString& astring,
221                                                  const Standard_Character replaceNonAscii) 
222 : mystring (0)
223 {
224   if (replaceNonAscii)
225   {
226     mylength = astring.Length(); 
227     mystring = Allocate(mylength+1);
228     for(int i = 0; i < mylength; i++) {
229       Standard_ExtCharacter c = astring.Value(i+1);
230       mystring[i] = ( IsAnAscii(c) ? ToCharacter(c) : replaceNonAscii );
231     }
232     mystring[mylength] = '\0';
233   }
234   else {
235     // create UTF-8 string
236     mylength = astring.LengthOfCString();
237     mystring = Allocate(mylength+1);
238     astring.ToUTF8CString(mystring);
239   }
240 }
241
242 //---------------------------------------------------------------------------
243 //  Create an TCollection_AsciiString from a Standard_WideChar
244 //---------------------------------------------------------------------------
245 TCollection_AsciiString::TCollection_AsciiString (const Standard_WideChar* theStringUtf)
246 : mystring (NULL),
247   mylength (0)
248 {
249   for (NCollection_UtfWideIter anIter (theStringUtf); *anIter != 0; ++anIter)
250   {
251     mylength += anIter.AdvanceBytesUtf8();
252   }
253
254   mystring = Allocate (mylength + 1);
255   mystring[mylength] = '\0';
256   NCollection_UtfWideIter anIterRead (theStringUtf);
257   for (Standard_Utf8Char* anIterWrite = mystring; *anIterRead != 0; ++anIterRead)
258   {
259     anIterWrite = anIterRead.GetUtf(anIterWrite);
260   }
261 }
262
263 // ----------------------------------------------------------------------------
264 // AssignCat
265 // ----------------------------------------------------------------------------
266 void TCollection_AsciiString::AssignCat(const Standard_Integer other)
267 {
268
269   AssignCat(TCollection_AsciiString(other));
270
271 }
272
273 // ----------------------------------------------------------------------------
274 // AssignCat
275 // ----------------------------------------------------------------------------
276 void TCollection_AsciiString::AssignCat(const Standard_Real other)
277 {
278
279   AssignCat(TCollection_AsciiString(other));
280
281 }
282
283 // ----------------------------------------------------------------------------
284 // AssignCat
285 // ----------------------------------------------------------------------------
286 void TCollection_AsciiString::AssignCat(const Standard_Character other)
287 {
288   if (other != '\0') {
289     mystring = Reallocate (mystring, mylength + 2);
290     mystring[mylength] = other ;
291     mylength += 1;
292     mystring[mylength] = '\0';
293   }
294 }
295
296 // ----------------------------------------------------------------------------
297 // AssignCat
298 // ----------------------------------------------------------------------------
299 void TCollection_AsciiString::AssignCat(const Standard_CString other)
300 {
301   if (other) {
302     Standard_Integer otherlength = Standard_Integer( strlen( other ));
303     if ( otherlength ) {
304       Standard_Integer newlength = mylength+otherlength;
305       mystring = Reallocate (mystring, newlength + 1);
306       strncpy( mystring + mylength, other, otherlength+1 );
307       mylength = newlength;
308     }
309   }
310   else {
311     Standard_NullObject::Raise("TCollection_AsciiString::Operator += parameter other");
312   }
313 }
314
315 // ----------------------------------------------------------------------------
316 // AssignCat
317 // ----------------------------------------------------------------------------
318 void TCollection_AsciiString::AssignCat(const TCollection_AsciiString& other)
319 {
320
321   if (other.mylength) {
322     Standard_Integer newlength = mylength+other.mylength;
323     mystring = Reallocate (mystring, newlength + 1);
324     strncpy( mystring + mylength, other.mystring, other.mylength+1 );
325     mylength = newlength;
326   }
327 }
328
329 // ---------------------------------------------------------------------------
330 // Capitalize
331 // ----------------------------------------------------------------------------
332 void TCollection_AsciiString::Capitalize()
333 {
334   if ( mylength ) mystring[0] = ::UpperCase(mystring[0]);
335   for (int i = 1; i < mylength; i++ )
336     mystring[i] = ::LowerCase(mystring[i]);
337 }
338
339 // ---------------------------------------------------------------------------
340 // Center
341 // ----------------------------------------------------------------------------
342 void TCollection_AsciiString::Center(const Standard_Integer Width ,
343                                      const Standard_Character Filler) 
344 {
345   if(Width > mylength) {
346     Standard_Integer newlength = mylength + ((Width - mylength)/2);
347     LeftJustify(newlength,Filler);
348     RightJustify(Width,Filler);
349   }
350   else if (Width < 0) {
351     Standard_NegativeValue::Raise();
352   }
353 }
354
355 // ----------------------------------------------------------------------------
356 // ChangeAll
357 // ----------------------------------------------------------------------------
358 void TCollection_AsciiString::ChangeAll(const Standard_Character aChar,
359                                         const Standard_Character NewChar,
360                                         const Standard_Boolean CaseSensitive)
361 {
362   if (CaseSensitive){
363     for (int i=0; i < mylength; i++)
364       if (mystring[i] == aChar) mystring[i] = NewChar;
365   }
366   else{
367     Standard_Character anUpperChar = ::UpperCase(aChar);
368     for (int i=0; i < mylength; i++)
369       if (::UpperCase(mystring[i]) == anUpperChar) mystring[i] = NewChar;
370   }
371 }
372
373 // ----------------------------------------------------------------------------
374 // Clear
375 // ----------------------------------------------------------------------------
376 void TCollection_AsciiString::Clear()
377 {
378   if ( mylength > 0 )
379   {
380     Free (mystring);
381     mylength = 0;
382     mystring = Allocate(mylength+1);
383     mystring[mylength] = '\0';
384   }
385 }
386
387 // ----------------------------------------------------------------------------
388 // Copy
389 // ----------------------------------------------------------------------------
390 void TCollection_AsciiString::Copy(const Standard_CString fromwhere)
391 {
392   if (fromwhere) {
393     mylength = Standard_Integer( strlen( fromwhere ));
394     mystring = Reallocate (mystring, mylength + 1);
395     strncpy( mystring, fromwhere, mylength+1 );
396   }
397   else {
398     mylength = 0;
399     mystring[mylength] = '\0';
400   }
401 }
402
403 // ----------------------------------------------------------------------------
404 // Copy
405 // ----------------------------------------------------------------------------
406 void TCollection_AsciiString::Copy(const TCollection_AsciiString& fromwhere)
407 {
408   if (fromwhere.mystring) {
409     mylength = fromwhere.mylength;
410     mystring = Reallocate (mystring, mylength + 1);
411     strncpy( mystring, fromwhere.mystring, mylength+1 );
412   }
413   else {
414     mylength = 0;
415     mystring[mylength] = '\0';
416   }
417 }
418
419 // ----------------------------------------------------------------------------
420 // Destroy
421 // ----------------------------------------------------------------------------
422 TCollection_AsciiString::~TCollection_AsciiString()
423 {
424   if (mystring) 
425     Free (mystring);
426   mystring = 0L;
427 }
428
429 // ----------------------------------------------------------------------------
430 // FirstLocationInSet
431 // ----------------------------------------------------------------------------
432 Standard_Integer TCollection_AsciiString::FirstLocationInSet
433                                 (const TCollection_AsciiString& Set,
434                                  const Standard_Integer         FromIndex,
435                                  const Standard_Integer         ToIndex) const
436 {
437   if (mylength == 0 || Set.mylength == 0) return 0;
438   if (FromIndex > 0 && ToIndex <= mylength && FromIndex <= ToIndex ) {
439     for(int i = FromIndex-1 ; i < ToIndex; i++)
440       for(int j = 0; j < Set.mylength; j++) 
441         if (mystring[i] == Set.mystring[j]) return i+1;
442     return 0;
443   }
444   Standard_OutOfRange::Raise();
445   return 0;
446 }
447
448 // ----------------------------------------------------------------------------
449 // FirstLocationNotInSet
450 // ----------------------------------------------------------------------------
451 Standard_Integer TCollection_AsciiString::FirstLocationNotInSet
452                                  (const TCollection_AsciiString& Set,
453                                   const Standard_Integer         FromIndex,
454                                   const Standard_Integer         ToIndex) const
455 {
456   if (mylength == 0 || Set.mylength == 0) return 0;
457   if (FromIndex > 0 && ToIndex <= mylength && FromIndex <= ToIndex ) {
458     Standard_Boolean find;
459     for (int i = FromIndex-1 ; i < ToIndex; i++) {
460       find = Standard_False;
461       for(int j = 0; j < Set.mylength; j++)  
462         if (mystring[i] == Set.mystring[j]) find = Standard_True;
463       if (!find)  return i+1;
464     }
465     return 0;
466   }
467   Standard_OutOfRange::Raise();
468   return 0;
469 }
470
471 //----------------------------------------------------------------------------
472 // Insert a character before 'where'th character
473 // ----------------------------------------------------------------------------
474 void TCollection_AsciiString::Insert(const Standard_Integer where,
475                                      const Standard_Character what)
476 {
477   if (where > mylength + 1 ) Standard_OutOfRange::Raise
478         ("TCollection_AsciiString::Insert : Parameter where is too big");
479   if (where < 1)             Standard_OutOfRange::Raise
480         ("TCollection_AsciiString::Insert : Parameter where is too small");
481   
482   mystring = Reallocate (mystring, mylength + 2);
483   if (where != mylength +1) {
484     for (int i=mylength-1; i >= where-1; i--)
485       mystring[i+1] = mystring[i];
486   }
487   mystring[where-1] = what;
488   mylength++;
489   mystring[mylength] = '\0';
490 }
491
492 // ----------------------------------------------------------------------------
493 // Insert
494 // ----------------------------------------------------------------------------
495 void TCollection_AsciiString::Insert(const Standard_Integer where,
496                                      const Standard_CString what)
497 {
498   if (where <= mylength + 1 && where > 0) {
499     if(what) {
500       Standard_Integer whatlength = Standard_Integer( strlen( what ) );
501       Standard_Integer newlength = mylength + whatlength;
502       
503       mystring = Reallocate (mystring, newlength + 1);
504       if (where != mylength +1) {
505         for (int i=mylength-1; i >= where-1; i--)
506           mystring[i+whatlength] = mystring[i];
507       }
508       for (int i=0; i < whatlength; i++)
509         mystring[where-1+i] = what[i];
510       
511       mylength = newlength;
512       mystring[mylength] = '\0';
513     }
514   }
515   else {
516     Standard_OutOfRange::Raise("TCollection_AsciiString::Insert : "
517                                "Parameter where is invalid");
518   }
519 }
520
521 // ----------------------------------------------------------------------------
522 // Insert
523 // ----------------------------------------------------------------------------
524 void TCollection_AsciiString::Insert(const Standard_Integer where,
525                                      const TCollection_AsciiString& what)
526 {
527   Standard_CString swhat = what.mystring;
528   if (where <= mylength + 1) {
529     Standard_Integer whatlength = what.mylength;
530     if(whatlength) {
531       Standard_Integer newlength = mylength + whatlength;
532       
533       mystring = Reallocate (mystring, newlength + 1);
534
535       if (where != mylength +1) {
536         for (int i=mylength-1; i >= where-1; i--)
537           mystring[i+whatlength] = mystring[i];
538       }
539       for (int i=0; i < whatlength; i++)
540         mystring[where-1+i] = swhat[i];
541       
542       mylength = newlength;
543       mystring[mylength] = '\0';
544     }
545   }
546   else {
547     Standard_OutOfRange::Raise("TCollection_AsciiString::Insert : "
548                                "Parameter where is too big");
549   }
550 }
551
552 //------------------------------------------------------------------------
553 //  InsertAfter
554 //------------------------------------------------------------------------
555 void TCollection_AsciiString::InsertAfter(const Standard_Integer Index,
556                                           const TCollection_AsciiString& what)
557 {
558    if (Index < 0 || Index > mylength) Standard_OutOfRange::Raise();
559    Insert(Index+1,what);
560 }
561
562 //------------------------------------------------------------------------
563 //  InsertBefore
564 //------------------------------------------------------------------------
565 void TCollection_AsciiString::InsertBefore(const Standard_Integer Index,
566                                            const TCollection_AsciiString& what)
567 {
568    if (Index < 1 || Index > mylength) Standard_OutOfRange::Raise();
569    Insert(Index,what);
570 }
571
572 // ----------------------------------------------------------------------------
573 // IsEqual
574 // ----------------------------------------------------------------------------
575 Standard_Boolean TCollection_AsciiString::IsEqual
576                                         (const Standard_CString other)const
577 {
578   if (other) {
579     return ( strncmp( other, mystring, mylength+1 ) == 0 );
580   }
581   Standard_NullObject::Raise("TCollection_AsciiString::Operator == "
582                              "Parameter 'other'");
583   return Standard_False;
584 }
585
586 // ----------------------------------------------------------------------------
587 // IsEqual
588 // ----------------------------------------------------------------------------
589 Standard_Boolean TCollection_AsciiString::IsEqual
590                                 (const TCollection_AsciiString& other)const
591 {
592   if (mylength != other.mylength) return Standard_False;
593   return ( strncmp( other.mystring, mystring, mylength ) == 0 );
594 }
595
596 // ----------------------------------------------------------------------------
597 // IsSameString
598 // ----------------------------------------------------------------------------
599 Standard_Boolean TCollection_AsciiString::IsSameString (const TCollection_AsciiString& theString1,
600                                                         const TCollection_AsciiString& theString2,
601                                                         const Standard_Boolean theIsCaseSensitive)
602 {
603   const Standard_Integer aSize1 = theString1.Length();
604   if (aSize1 != theString2.Length())
605   {
606     return Standard_False;
607   }
608
609   if (theIsCaseSensitive)
610   {
611     return (strncmp (theString1.ToCString(), theString2.ToCString(), aSize1) == 0);
612   }
613
614   for (Standard_Integer aCharIter = 1; aCharIter <= aSize1; ++aCharIter)
615   {
616     if (toupper (theString1.Value (aCharIter)) != toupper (theString2.Value (aCharIter)))
617     {
618       return Standard_False;
619     }
620   }
621   return Standard_True;
622 }
623
624 // ----------------------------------------------------------------------------
625 // IsDifferent
626 // ----------------------------------------------------------------------------
627 Standard_Boolean TCollection_AsciiString::IsDifferent
628                                         (const Standard_CString other)const
629 {
630   if (other) {
631     return ( strncmp( other, mystring, mylength+1 ) != 0 );
632   }
633   Standard_NullObject::Raise("TCollection_AsciiString::Operator != "
634                             "Parameter 'other'");
635   return Standard_False;
636 }
637
638 // ----------------------------------------------------------------------------
639 // IsDifferent
640 // ----------------------------------------------------------------------------
641 Standard_Boolean TCollection_AsciiString::IsDifferent
642                                 (const TCollection_AsciiString& other)const
643 {
644
645   if (mylength != other.mylength) return Standard_True;
646   return ( strncmp( other.mystring, mystring, mylength ) != 0 );
647 }
648
649 // ----------------------------------------------------------------------------
650 // IsLess
651 // ----------------------------------------------------------------------------
652 Standard_Boolean TCollection_AsciiString::IsLess
653                                         (const Standard_CString other)const
654 {
655   if (other) {
656     return ( strncmp( mystring, other, mylength+1 ) < 0 );
657   }
658   Standard_NullObject::Raise("TCollection_AsciiString::Operator < "
659                              "Parameter 'other'");
660   return Standard_False;
661 }
662
663 // ----------------------------------------------------------------------------
664 // IsLess
665 // ----------------------------------------------------------------------------
666 Standard_Boolean TCollection_AsciiString::IsLess
667                                 (const TCollection_AsciiString& other)const
668 {
669   return ( strncmp( mystring, other.mystring, mylength+1 ) < 0 );
670 }
671
672 // ----------------------------------------------------------------------------
673 // IsGreater
674 // ----------------------------------------------------------------------------
675 Standard_Boolean TCollection_AsciiString::IsGreater
676                                         (const Standard_CString other)const
677 {
678   if (other) {
679     return ( strncmp( mystring, other, mylength+1 ) > 0 );
680   }
681   Standard_NullObject::Raise("TCollection_AsciiString::Operator > "
682                              "Parameter 'other'");
683   return Standard_False;
684 }
685
686 // ----------------------------------------------------------------------------
687 // IsGreater
688 // ----------------------------------------------------------------------------
689 Standard_Boolean TCollection_AsciiString::IsGreater
690                                 (const TCollection_AsciiString& other)const
691 {
692   return ( strncmp( mystring, other.mystring, mylength+1 ) > 0 );
693 }
694
695 // ----------------------------------------------------------------------------
696 // StartsWith
697 // ----------------------------------------------------------------------------
698 Standard_Boolean TCollection_AsciiString::StartsWith (const TCollection_AsciiString& theStartString) const
699 {
700   if (this == &theStartString)
701   {
702     return true;
703   }
704
705   return mylength >= theStartString.mylength
706       && strncmp (theStartString.mystring, mystring, theStartString.mylength) == 0;
707 }
708
709 // ----------------------------------------------------------------------------
710 // EndsWith
711 // ----------------------------------------------------------------------------
712 Standard_Boolean TCollection_AsciiString::EndsWith (const TCollection_AsciiString& theEndString) const
713 {
714   if (this == &theEndString)
715   {
716     return true;
717   }
718
719   return mylength >= theEndString.mylength
720       && strncmp (theEndString.mystring, mystring + mylength - theEndString.mylength, theEndString.mylength) == 0;
721 }
722
723 // ----------------------------------------------------------------------------
724 // IntegerValue
725 // ----------------------------------------------------------------------------
726 Standard_Integer TCollection_AsciiString::IntegerValue()const
727 {
728   char *ptr;
729   Standard_Integer value = (Standard_Integer)strtol(mystring,&ptr,10); 
730   if (ptr != mystring) return value;
731
732   Standard_NumericError::Raise("TCollection_AsciiString::IntegerValue");
733   return 0;
734 }
735
736 // ----------------------------------------------------------------------------
737 // IsIntegerValue
738 // ----------------------------------------------------------------------------
739 Standard_Boolean TCollection_AsciiString::IsIntegerValue()const
740 {
741   char *ptr;
742   strtol(mystring,&ptr,10);
743
744   if (ptr != mystring) {
745     for (int i=int(ptr-mystring); i < mylength; i++) {
746       if (mystring[i] == '.') return Standard_False; // what about 'e','x',etc ???
747     }
748     return Standard_True;
749   }
750   return Standard_False;
751 }
752
753 // ----------------------------------------------------------------------------
754 // IsRealValue
755 // ----------------------------------------------------------------------------
756 Standard_Boolean TCollection_AsciiString::IsRealValue()const
757 {
758   char *ptr;
759   Strtod(mystring,&ptr);
760   return (ptr != mystring);
761 }
762
763 // ----------------------------------------------------------------------------
764 // IsAscii
765 // ----------------------------------------------------------------------------
766 Standard_Boolean TCollection_AsciiString::IsAscii()const
767 {
768 // LD : Debuggee le 26/11/98
769 //      Cette fonction retournait TOUJOURS Standard_True !
770   for (int i=0; i < mylength; i++)
771     if (mystring[i] >= 127 || mystring[i] < ' ') return Standard_False;
772   return Standard_True;
773 }
774
775 //------------------------------------------------------------------------
776 //  LeftAdjust
777 //------------------------------------------------------------------------
778 void TCollection_AsciiString::LeftAdjust ()
779 {
780    Standard_Integer i ;
781    for( i = 0 ; i < mylength ; i ++) if(!IsSpace(mystring[i])) break;
782    if( i > 0 ) Remove(1,i);
783 }
784
785 //------------------------------------------------------------------------
786 //  LeftJustify
787 //------------------------------------------------------------------------
788 void TCollection_AsciiString::LeftJustify(const Standard_Integer Width,
789                                           const Standard_Character Filler)
790 {
791    if (Width > mylength) {
792        mystring = Reallocate (mystring, Width + 1);
793      for (int i = mylength; i < Width ; i++) mystring[i] = Filler;
794      mylength = Width;
795      mystring[mylength] = '\0';
796    }
797    else if (Width < 0) {
798      Standard_NegativeValue::Raise();
799    }
800 }
801
802 //------------------------------------------------------------------------
803 //  Location
804 //------------------------------------------------------------------------
805 Standard_Integer TCollection_AsciiString::Location
806                                    (const Standard_Integer   N        ,
807                                     const Standard_Character C        ,
808                                     const Standard_Integer   FromIndex,
809                                     const Standard_Integer   ToIndex  ) const
810 {
811    if (FromIndex > 0 && ToIndex <= mylength && FromIndex <= ToIndex ) {
812      for(int i = FromIndex-1, count = 0; i <= ToIndex-1; i++) {
813        if(mystring[i] == C) {
814          count++;
815          if ( count == N ) return i+1;
816        }
817      }
818      return 0 ;
819    }
820    Standard_OutOfRange::Raise();
821    return 0 ;
822 }
823
824 //------------------------------------------------------------------------
825 //  Location
826 //------------------------------------------------------------------------
827 Standard_Integer TCollection_AsciiString::Location
828                                 (const TCollection_AsciiString& what,
829                                  const Standard_Integer         FromIndex,
830                                  const Standard_Integer         ToIndex) const
831 {
832   if (mylength == 0 || what.mylength == 0) return 0;
833   if (ToIndex <= mylength && FromIndex > 0 && FromIndex <= ToIndex ) {
834     Standard_Integer i = FromIndex-1;
835     Standard_Integer k = 1;
836     Standard_Integer l = FromIndex-2;
837     Standard_Boolean Find = Standard_False; 
838     while (!Find && i < ToIndex)  {
839       if (mystring[i] == what.Value(k)) {
840         k++;
841         if ( k > what.mylength) Find = Standard_True;
842       }
843       else {
844         if (k > 1) i--;    // si on est en cours de recherche 
845         k = 1;
846         l = i;
847       }
848       i++;
849     }
850     if (Find) return l+2;
851     else      return 0;
852   }
853   Standard_OutOfRange::Raise();
854   return 0;
855 }
856
857 // ----------------------------------------------------------------------------
858 // LowerCase
859 // ----------------------------------------------------------------------------
860 void TCollection_AsciiString::LowerCase()
861 {
862   for (int i=0; i < mylength; i++)
863     mystring[i] = ::LowerCase(mystring[i]);
864 }
865
866 //------------------------------------------------------------------------
867 //  Prepend
868 //------------------------------------------------------------------------
869 void TCollection_AsciiString::Prepend(const TCollection_AsciiString& what)
870 {
871   Insert(1,what);
872 }
873
874 // ----------------------------------------------------------------------------
875 // RealValue
876 // ----------------------------------------------------------------------------
877 Standard_Real TCollection_AsciiString::RealValue()const
878 {
879   char *ptr;
880   Standard_Real value = Strtod(mystring,&ptr);
881   if (ptr != mystring) return value;
882
883   Standard_NumericError::Raise("TCollection_AsciiString::RealValue");
884   return value;
885 }
886
887 // ----------------------------------------------------------------------------
888 // Read
889 //--------------------------------------------------------------------------
890 void TCollection_AsciiString::Read(Standard_IStream& astream)
891 {
892   // get characters from astream
893   const Standard_Integer bufSize = 8190;
894   Standard_Character buffer[bufSize];
895   std::streamsize oldWidth = astream.width (bufSize);
896   astream >> buffer;
897   astream.width( oldWidth );
898
899   // put to string
900   mylength = Standard_Integer( strlen( buffer ));
901   mystring = Reallocate (mystring, mylength + 1);
902   strncpy(mystring,buffer,mylength);
903   mystring[mylength] = '\0';
904 }
905
906
907 //---------------------------------------------------------------------------
908 Standard_IStream& operator >> (Standard_IStream& astream,
909                                TCollection_AsciiString& astring)
910 {
911   astring.Read(astream);
912   return astream;
913 }
914
915
916 // ----------------------------------------------------------------------------
917 // Print
918 // ----------------------------------------------------------------------------
919 void TCollection_AsciiString::Print(Standard_OStream& astream)const
920 {
921   if(mystring) astream << mystring;
922 }
923
924
925 // ----------------------------------------------------------------------------
926 Standard_OStream& operator << (Standard_OStream& astream,
927                                const TCollection_AsciiString& astring)
928 {
929   astring.Print(astream);
930   return astream;
931 }
932
933 // ----------------------------------------------------------------------------
934 // RemoveAll
935 // ----------------------------------------------------------------------------
936 void TCollection_AsciiString::RemoveAll(const Standard_Character what,
937                                         const Standard_Boolean CaseSensitive)
938 {   
939   if (mylength == 0) return;
940   int c = 0;
941   if (CaseSensitive) {
942     for (int i=0; i < mylength; i++)
943       if (mystring[i] != what) mystring[c++] = mystring[i];
944   }
945   else {
946     Standard_Character upperwhat = ::UpperCase(what);
947     for (int i=0; i < mylength; i++) { 
948       if (::UpperCase(mystring[i]) != upperwhat) mystring[c++] = mystring[i];
949     }
950   }
951   mylength = c;
952   mystring[mylength] = '\0';
953 }
954
955 // ----------------------------------------------------------------------------
956 // RemoveAll
957 // ----------------------------------------------------------------------------
958 void TCollection_AsciiString::RemoveAll(const Standard_Character what)
959 {
960   if (mylength == 0) return;
961   int c = 0;
962   for (int i=0; i < mylength; i++)
963     if (mystring[i] != what) mystring[c++] = mystring[i];
964   mylength = c;
965   mystring[mylength] = '\0';
966 }
967
968 // ----------------------------------------------------------------------------
969 // Remove
970 // ----------------------------------------------------------------------------
971 void TCollection_AsciiString::Remove (const Standard_Integer where,
972                                       const Standard_Integer ahowmany)
973 {
974  if (where+ahowmany <= mylength+1) {
975    int i,j;
976    for(i = where+ahowmany-1, j = where-1; i < mylength; i++, j++)
977      mystring[j] = mystring[i];
978    mylength -= ahowmany;
979    mystring[mylength] = '\0';
980  }
981  else {
982   Standard_OutOfRange::Raise("TCollection_AsciiString::Remove: "
983                              "Too many characters to erase or invalid "
984                              "starting value.");
985  }
986 }
987
988 //------------------------------------------------------------------------
989 //  RightAdjust
990 //------------------------------------------------------------------------
991 void TCollection_AsciiString::RightAdjust ()
992 {
993   Standard_Integer i ;
994   for ( i = mylength-1 ; i >= 0 ; i--)
995     if(!IsSpace(mystring[i]))
996       break;
997   if( i < mylength-1 )
998     Remove(i+2,mylength-(i+2)+1);
999 }
1000
1001 //------------------------------------------------------------------------
1002 //  RightJustify
1003 //------------------------------------------------------------------------
1004 void TCollection_AsciiString::RightJustify(const Standard_Integer Width,
1005                                            const Standard_Character Filler)
1006 {
1007   Standard_Integer i ;
1008   Standard_Integer k ;
1009   if (Width > mylength) {
1010     mystring = Reallocate (mystring, Width + 1);
1011
1012     for ( i = mylength-1, k = Width-1 ; i >= 0 ; i--, k--) 
1013       mystring[k] = mystring[i];
1014     for(; k >= 0 ; k--) mystring[k] = Filler;
1015     mylength = Width;
1016     mystring[mylength] = '\0';
1017   }
1018   else if (Width < 0) {
1019     Standard_NegativeValue::Raise();
1020   }
1021 }
1022
1023 // ----------------------------------------------------------------------------
1024 // Search
1025 // ----------------------------------------------------------------------------
1026 Standard_Integer TCollection_AsciiString::Search
1027                                         (const Standard_CString what)const
1028 {
1029   Standard_Integer size = Standard_Integer( what ? strlen( what ) : 0 );
1030   if (size) {
1031     int k,j;
1032     int i = 0;
1033     while ( i < mylength-size+1 ) {
1034       k = i++;
1035       j = 0;
1036       while (j < size && mystring[k++] == what[j++])
1037         if (j == size) return i;
1038     }
1039   }
1040   return -1;
1041 }
1042
1043
1044 // ----------------------------------------------------------------------------
1045 // Search
1046 // ----------------------------------------------------------------------------
1047 Standard_Integer TCollection_AsciiString::Search
1048                                 (const TCollection_AsciiString& what) const
1049 {
1050   Standard_Integer size = what.mylength;
1051   Standard_CString swhat = what.mystring;  
1052   if (size) {
1053     int k,j;
1054     int i = 0;
1055     while ( i < mylength-size+1 ) {
1056       k = i++;
1057       j = 0;
1058       while (j < size && mystring[k++] == swhat[j++])
1059         if (j == size) return i;
1060     }
1061   }
1062   return -1;
1063 }
1064
1065
1066 // ----------------------------------------------------------------------------
1067 // SearchFromEnd
1068 // ----------------------------------------------------------------------------
1069 Standard_Integer TCollection_AsciiString::SearchFromEnd
1070                                         (const Standard_CString what)const
1071 {
1072   Standard_Integer size = Standard_Integer( what ? strlen( what ) : 0 );
1073   if (size) {
1074     int k,j;
1075     int i = mylength-1;
1076     while ( i >= size-1 ) {
1077       k = i--;
1078       j = size-1;
1079       while (j >= 0 && mystring[k--] == what[j--])
1080         if (j == -1) return i-size+3;
1081     }
1082   }
1083   return -1;
1084 }
1085
1086
1087 // ----------------------------------------------------------------------------
1088 // SearchFromEnd
1089 // ----------------------------------------------------------------------------
1090 Standard_Integer TCollection_AsciiString::SearchFromEnd
1091                                 (const TCollection_AsciiString& what)const
1092 {
1093   int size = what.mylength;
1094   if (size) {
1095     Standard_CString swhat = what.mystring;  
1096     int k,j;
1097     int i = mylength-1;
1098     while ( i >= size-1 ) {
1099       k = i--;
1100       j = size-1;
1101       while (j >= 0 && mystring[k--] == swhat[j--])
1102         if (j == -1) return i-size+3;
1103     }
1104   }
1105   return -1;
1106 }
1107
1108 // ----------------------------------------------------------------------------
1109 // SetValue
1110 // ----------------------------------------------------------------------------
1111 void TCollection_AsciiString::SetValue(const Standard_Integer where,
1112                                        const Standard_Character what)
1113 {
1114   if (where > 0 && where <= mylength) {
1115     mystring[where-1] = what;
1116   }
1117   else {
1118     Standard_OutOfRange::Raise("TCollection_AsciiString::SetValue : "
1119                                "parameter where");
1120   }
1121 }
1122
1123 // ----------------------------------------------------------------------------
1124 // SetValue
1125 // ----------------------------------------------------------------------------
1126 void TCollection_AsciiString::SetValue(const Standard_Integer where,
1127                                        const Standard_CString what)
1128 {
1129  if (where > 0 && where <= mylength+1) {
1130    Standard_Integer size = Standard_Integer( what ? strlen( what ) : 0 );
1131    size += (where - 1);  
1132    if (size >= mylength) {
1133      mystring = Reallocate (mystring, size + 1);
1134      mylength = size;
1135    } 
1136    for (int i = where-1; i < size; i++)
1137      mystring[i] = what[i-(where-1)];
1138    mystring[mylength] = '\0';
1139  }
1140  else {
1141    Standard_OutOfRange::Raise("TCollection_AsciiString::SetValue : "
1142                               "parameter where");
1143  }
1144 }
1145
1146 // ----------------------------------------------------------------------------
1147 // SetValue
1148 // ----------------------------------------------------------------------------
1149 void TCollection_AsciiString::SetValue(const Standard_Integer where,
1150                                        const TCollection_AsciiString& what)
1151 {
1152  if (where > 0 && where <= mylength+1) {
1153    Standard_Integer size = what.mylength;
1154    Standard_CString swhat = what.mystring;  
1155    size += (where - 1);  
1156    if (size >= mylength) {
1157      mystring = Reallocate (mystring, size + 1);
1158      mylength = size;
1159    } 
1160    for (int i = where-1; i < size; i++)
1161      mystring[i] = swhat[i-(where-1)];
1162    mystring[mylength] = '\0';
1163  }
1164  else {
1165    Standard_OutOfRange::Raise("TCollection_AsciiString::SetValue : "
1166                               "parameter where");
1167  }
1168 }
1169
1170 // ----------------------------------------------------------------------------
1171 // Split
1172 // Private
1173 // ----------------------------------------------------------------------------
1174 void TCollection_AsciiString::Split(const Standard_Integer where,
1175                                     TCollection_AsciiString& res)
1176 {
1177   if (where >= 0 && where <= mylength) {
1178     res = &mystring[where] ;
1179     Trunc(where);
1180     return ;
1181   }
1182   Standard_OutOfRange::Raise("TCollection_AsciiString::Split index");
1183   return ;
1184 }
1185
1186 // ----------------------------------------------------------------------------
1187 // Split
1188 // ----------------------------------------------------------------------------
1189 TCollection_AsciiString TCollection_AsciiString::Split
1190                                                 (const Standard_Integer where)
1191 {
1192   if (where >= 0 && where <= mylength) {
1193     TCollection_AsciiString res( &mystring[where] , mylength - where );
1194     Trunc(where);
1195     return res;
1196   }
1197   Standard_OutOfRange::Raise("TCollection_AsciiString::Split index");
1198   TCollection_AsciiString res;
1199   return res;
1200 }
1201
1202 // ----------------------------------------------------------------------------
1203 // SubString
1204 // Private
1205 // ----------------------------------------------------------------------------
1206 void TCollection_AsciiString::SubString(const Standard_Integer FromIndex,
1207                                         const Standard_Integer ToIndex,
1208                                         TCollection_AsciiString& res) const
1209 {
1210
1211   if (ToIndex > mylength || FromIndex <= 0 || FromIndex > ToIndex )
1212     Standard_OutOfRange::Raise();
1213   Standard_Integer newlength = ToIndex-FromIndex+1;
1214   res.mystring =Reallocate (res.mystring, newlength + 1);
1215   strncpy( res.mystring, mystring + FromIndex - 1, newlength );
1216   res.mystring[newlength] = '\0';
1217   res.mylength = newlength;
1218   return ;
1219 }
1220
1221 // ----------------------------------------------------------------------------
1222 // Token
1223 // Private
1224 // ----------------------------------------------------------------------------
1225 void TCollection_AsciiString::Token(const Standard_CString separators,
1226                                     const Standard_Integer whichone,
1227                                     TCollection_AsciiString& res)const
1228 {
1229   res = Token( separators , whichone ) ;
1230 }
1231
1232 // ----------------------------------------------------------------------------
1233 // Token
1234 // ----------------------------------------------------------------------------
1235 TCollection_AsciiString TCollection_AsciiString::Token
1236                                         (const Standard_CString separators,
1237                                          const Standard_Integer whichone) const
1238 {
1239   if (!separators)
1240     Standard_NullObject::Raise("TCollection_AsciiString::Token : "
1241                                "parameter 'separators'");
1242
1243   Standard_Integer theOne ;
1244   Standard_Integer StringIndex = 0 ;
1245   Standard_Integer SeparatorIndex ;
1246   Standard_Integer BeginIndex=0 ;
1247   Standard_Integer EndIndex=0 ;
1248
1249 //  cout << "'" << mystring <<  "'" << endl ;
1250   for ( theOne = 0 ; theOne < whichone ; theOne++ ) {
1251      BeginIndex = 0 ;
1252      EndIndex = 0 ;
1253 //     cout << "theOne " << theOne << endl ;
1254      if ( StringIndex == mylength )
1255        break ;
1256      for (; StringIndex < mylength && EndIndex == 0 ; StringIndex++ ) {
1257         SeparatorIndex = 0 ;
1258 //        cout << "StringIndex " << StringIndex << endl ;
1259         while ( separators [ SeparatorIndex ] ) {
1260              if ( mystring [ StringIndex ] == separators [ SeparatorIndex ] ) {
1261                break ;
1262              }
1263              SeparatorIndex += 1 ;
1264            }
1265         if ( separators [ SeparatorIndex ] != '\0' ) { // We have a Separator
1266           if ( BeginIndex && EndIndex == 0 ) {
1267             EndIndex = StringIndex ;
1268 //            cout << "EndIndex " << EndIndex << " '" << SubString( BeginIndex , EndIndex ).ToCString() << "'" << endl ;
1269             break ;
1270           }
1271         }
1272         else if ( BeginIndex == 0 ) {               // We have not a Separator
1273           BeginIndex = StringIndex + 1 ;
1274 //          cout << "BeginIndex " << BeginIndex << endl ;
1275         }
1276      }
1277 //     cout << "BeginIndex " << BeginIndex << " EndIndex " << EndIndex << endl ;
1278   }
1279   if ( BeginIndex == 0 )
1280     return TCollection_AsciiString("",0) ;
1281   if ( EndIndex == 0 )
1282     EndIndex = mylength ;
1283 //    cout << "'" << SubString( BeginIndex , EndIndex ).ToCString() << "'" << endl ;
1284   return TCollection_AsciiString( &mystring [ BeginIndex - 1 ] ,
1285                                   EndIndex - BeginIndex + 1 ) ;
1286 }
1287
1288 // ----------------------------------------------------------------------------
1289 // Trunc
1290 // ----------------------------------------------------------------------------
1291 void TCollection_AsciiString::Trunc(const Standard_Integer ahowmany)
1292 {
1293   if (ahowmany < 0 || ahowmany > mylength)
1294     Standard_OutOfRange::Raise("TCollection_AsciiString::Trunc : "
1295                                "parameter 'ahowmany'");
1296   mylength = ahowmany;
1297   mystring[mylength] = '\0';
1298 }
1299
1300 // ----------------------------------------------------------------------------
1301 // UpperCase
1302 // ----------------------------------------------------------------------------
1303 void TCollection_AsciiString::UpperCase()
1304 {
1305   for (int i=0; i < mylength; i++)
1306     mystring[i] = ::UpperCase(mystring[i]);
1307 }
1308
1309 //------------------------------------------------------------------------
1310 //  UsefullLength
1311 //------------------------------------------------------------------------
1312 Standard_Integer TCollection_AsciiString::UsefullLength () const
1313 {
1314   Standard_Integer i ;
1315   for ( i = mylength -1 ; i >= 0 ; i--) 
1316     if (IsGraphic(mystring[i])) break;
1317   return i+1;
1318 }
1319
1320 // ----------------------------------------------------------------------------
1321 // Value
1322 // ----------------------------------------------------------------------------
1323 Standard_Character TCollection_AsciiString::Value
1324                                         (const Standard_Integer where)const
1325 {
1326  if (where > 0 && where <= mylength) {
1327    return mystring[where-1];
1328  }
1329  Standard_OutOfRange::Raise("TCollection_AsciiString::Value : parameter where");
1330  return '\0';
1331 }