(file) Return to String.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 mike  1.27 //%/////////////////////////////////////////////////////////////////////////////
  2            //
  3 kumpf 1.41 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4            // The Open Group, Tivoli Systems
  5 mike  1.27 //
  6            // Permission is hereby granted, free of charge, to any person obtaining a copy
  7 kumpf 1.41 // of this software and associated documentation files (the "Software"), to
  8            // deal in the Software without restriction, including without limitation the
  9            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 10 mike  1.27 // sell copies of the Software, and to permit persons to whom the Software is
 11            // furnished to do so, subject to the following conditions:
 12            // 
 13 kumpf 1.41 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 14 mike  1.27 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 15            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 16 kumpf 1.41 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 17            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 18            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 19 mike  1.27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 20            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 21            //
 22            //==============================================================================
 23            //
 24            // Author: Mike Brasher (mbrasher@bmc.com)
 25            //
 26 kumpf 1.39 // Modified By: Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
 27 mike  1.27 //
 28            //%/////////////////////////////////////////////////////////////////////////////
 29            
 30            
 31            #include <cctype>
 32            #include "String.h"
 33 kumpf 1.43 #include "Array.h"
 34 kumpf 1.48 #include "InternalException.h"
 35 mike  1.27 #include <iostream>
 36            
 37 mike  1.28 PEGASUS_USING_STD;
 38            
 39 mike  1.27 PEGASUS_NAMESPACE_BEGIN
 40            
 41 kumpf 1.39 ///////////////////////////////////////////////////////////////////////////////
 42            //
 43 kumpf 1.54 // CString
 44            //
 45            ///////////////////////////////////////////////////////////////////////////////
 46            
 47            CString::CString()
 48                : _rep(0)
 49            {
 50            }
 51            
 52            CString::CString(const CString& cstr)
 53            {
 54                _rep = new char[strlen(cstr._rep)+1];
 55                _rep = strcpy(_rep, cstr._rep);
 56            }
 57            
 58            CString::CString(char* cstr)
 59                : _rep(cstr)
 60            {
 61            }
 62            
 63            CString::~CString()
 64 kumpf 1.54 {
 65                if (_rep)
 66                    delete [] _rep;
 67            }
 68            
 69 kumpf 1.56 CString& CString::operator=(const CString& cstr)
 70            {
 71                _rep = new char[strlen(cstr._rep)+1];
 72                _rep = strcpy(_rep, cstr._rep);
 73                return *this;
 74            }
 75            
 76 kumpf 1.54 CString::operator const char*() const
 77            {
 78                return _rep;
 79            }
 80            
 81            ///////////////////////////////////////////////////////////////////////////////
 82            //
 83 kumpf 1.39 // String
 84            //
 85            ///////////////////////////////////////////////////////////////////////////////
 86            
 87 kumpf 1.37 const String String::EMPTY = String();
 88 mike  1.27 
 89 kumpf 1.38 Uint32 _strnlen(const char* str, Uint32 n)
 90            {
 91                if (!str)
 92            	throw NullPointer();
 93            
 94                for (Uint32 i=0; i<n; i++)
 95                {
 96                    if (!*str)
 97                    {
 98                        return i;
 99                    }
100                }
101            
102                return n;
103            }
104            
105            Uint32 _strnlen(const Char16* str, Uint32 n)
106            {
107                if (!str)
108            	throw NullPointer();
109            
110 kumpf 1.38     for (Uint32 i=0; i<n; i++)
111                {
112                    if (!*str)
113                    {
114                        return i;
115                    }
116                }
117            
118                return n;
119            }
120            
121 kumpf 1.39 inline Uint32 _StrLen(const char* str)
122 mike  1.27 {
123                if (!str)
124            	throw NullPointer();
125            
126                return strlen(str);
127            }
128            
129 kumpf 1.39 inline Uint32 _StrLen(const Char16* str)
130 mike  1.27 {
131                if (!str)
132            	throw NullPointer();
133            
134                Uint32 n = 0;
135            
136                while (*str++)
137            	n++;
138            
139                return n;
140            }
141            
142 kumpf 1.43 class StringRep
143            {
144            public:
145                StringRep()
146                {}
147                StringRep(const StringRep& r)
148                    : c16a(r.c16a)
149                {}
150                StringRep(const Char16* str)
151                    : c16a(str, _StrLen(str) + 1)
152                {}
153            
154                Array<Char16> c16a;
155            };
156            
157 mike  1.27 String::String()
158            {
159 kumpf 1.43     _rep = new StringRep;
160                _rep->c16a.append('\0');
161 mike  1.27 }
162            
163 kumpf 1.39 String::String(const String& str)
164 mike  1.27 {
165 kumpf 1.43     _rep = new StringRep(*str._rep);
166 kumpf 1.39 }
167 mike  1.27 
168 kumpf 1.39 String::String(const String& str, Uint32 n)
169            {
170 kumpf 1.43     _rep = new StringRep;
171 kumpf 1.55     assign(str.getChar16Data(), n);
172 kumpf 1.39 }
173            
174            String::String(const Char16* str)
175            {
176 kumpf 1.43     _rep = new StringRep(str);
177 mike  1.27 }
178            
179 kumpf 1.39 String::String(const Char16* str, Uint32 n)
180            {
181 kumpf 1.43     _rep = new StringRep;
182 kumpf 1.39     assign(str, n);
183            }
184            
185            String::String(const char* str)
186 mike  1.27 {
187 kumpf 1.43     _rep = new StringRep;
188 kumpf 1.39     assign(str);
189 mike  1.27 }
190            
191 kumpf 1.39 String::String(const char* str, Uint32 n)
192 mike  1.27 {
193 kumpf 1.43     _rep = new StringRep;
194 kumpf 1.39     assign(str, n);
195            }
196 mike  1.27 
197 kumpf 1.39 String::~String()
198            {
199 kumpf 1.43     delete _rep;
200 mike  1.27 }
201            
202 kumpf 1.39 String& String::operator=(const String& str)
203 mike  1.27 {
204 kumpf 1.39     return assign(str);
205 mike  1.27 }
206            
207 kumpf 1.39 String& String::assign(const String& str)
208 mike  1.27 {
209 kumpf 1.43     _rep->c16a = str._rep->c16a;
210 kumpf 1.39     return *this;
211 mike  1.27 }
212            
213 kumpf 1.39 String& String::assign(const Char16* str)
214 mike  1.27 {
215 kumpf 1.43     _rep->c16a.clear();
216                _rep->c16a.append(str, _StrLen(str) + 1);
217 mike  1.27     return *this;
218            }
219            
220            String& String::assign(const Char16* str, Uint32 n)
221            {
222 kumpf 1.43     _rep->c16a.clear();
223 kumpf 1.38     Uint32 m = _strnlen(str, n);
224 kumpf 1.43     _rep->c16a.append(str, m);
225                _rep->c16a.append('\0');
226 mike  1.27     return *this;
227            }
228            
229 kumpf 1.39 String& String::assign(const char* str)
230 mike  1.27 {
231 kumpf 1.43     _rep->c16a.clear();
232 kumpf 1.38 
233 kumpf 1.39     Uint32 n = strlen(str) + 1;
234 kumpf 1.45     _rep->c16a.reserveCapacity(n);
235 mike  1.27 
236                while (n--)
237 kumpf 1.43 	_rep->c16a.append(*str++);
238 mike  1.27 
239                return *this;
240            }
241            
242 kumpf 1.39 String& String::assign(const char* str, Uint32 n)
243 mike  1.27 {
244 kumpf 1.43     _rep->c16a.clear();
245 mike  1.27 
246 kumpf 1.39     Uint32 _n = _strnlen(str, n);
247 kumpf 1.45     _rep->c16a.reserveCapacity(_n + 1);
248 mike  1.27 
249 kumpf 1.39     while (_n--)
250 kumpf 1.43 	_rep->c16a.append(*str++);
251 mike  1.27 
252 kumpf 1.43     _rep->c16a.append('\0');
253 mike  1.27 
254                return *this;
255            }
256            
257 kumpf 1.39 void String::clear()
258            {
259 kumpf 1.43     _rep->c16a.clear();
260                _rep->c16a.append('\0');
261 kumpf 1.39 }
262            
263 kumpf 1.43 void String::reserveCapacity(Uint32 capacity)
264 kumpf 1.39 {
265 kumpf 1.45     _rep->c16a.reserveCapacity(capacity + 1);
266 kumpf 1.39 }
267            
268            Uint32 String::size() const
269            {
270 kumpf 1.43     return _rep->c16a.size() - 1;
271 kumpf 1.39 }
272            
273 kumpf 1.55 const Char16* String::getChar16Data() const
274 kumpf 1.39 {
275 kumpf 1.43     return _rep->c16a.getData();
276 kumpf 1.39 }
277            
278 kumpf 1.54 CString String::getCString() const
279 mike  1.27 {
280                Uint32 n = size() + 1;
281 kumpf 1.54     char* str = new char[n];
282 mike  1.27     char* p = str;
283 kumpf 1.55     const Char16* q = getChar16Data();
284 mike  1.27 
285                for (Uint32 i = 0; i < n; i++)
286                {
287            	Uint16 c = *q++;
288            	*p++ = char(c);
289            
290 kumpf 1.54 	//if (c & 0xff00)
291            	//    truncatedCharacters = true;
292 mike  1.27     }
293            
294 kumpf 1.54     return CString(str);
295 kumpf 1.49 }
296            
297 kumpf 1.53 Char16& String::operator[](Uint32 index)
298 mike  1.27 {
299 kumpf 1.53     if (index > size())
300 kumpf 1.49 	throw IndexOutOfBoundsException();
301 mike  1.27 
302 kumpf 1.53     return _rep->c16a[index];
303 mike  1.27 }
304            
305 kumpf 1.53 const Char16 String::operator[](Uint32 index) const
306 mike  1.27 {
307 kumpf 1.53     if (index > size())
308 kumpf 1.49 	throw IndexOutOfBoundsException();
309 mike  1.27 
310 kumpf 1.53     return _rep->c16a[index];
311 mike  1.27 }
312            
313 kumpf 1.39 String& String::append(const Char16& c)
314            {
315 kumpf 1.43     _rep->c16a.insert(_rep->c16a.size() - 1, c);
316 kumpf 1.39     return *this;
317            }
318            
319 mike  1.27 String& String::append(const Char16* str, Uint32 n)
320            {
321 kumpf 1.38     Uint32 m = _strnlen(str, n);
322 kumpf 1.45     _rep->c16a.reserveCapacity(_rep->c16a.size() + m);
323 kumpf 1.43     _rep->c16a.remove(_rep->c16a.size() - 1);
324                _rep->c16a.append(str, m);
325                _rep->c16a.append('\0');
326 mike  1.27     return *this;
327            }
328            
329 kumpf 1.39 String& String::append(const String& str)
330 mike  1.27 {
331 kumpf 1.55     return append(str.getChar16Data(), str.size());
332 mike  1.27 }
333            
334 kumpf 1.53 void String::remove(Uint32 index, Uint32 size)
335 mike  1.27 {
336 kumpf 1.39     if (size == PEG_NOT_FOUND)
337 kumpf 1.53 	size = this->size() - index;
338 mike  1.27 
339 kumpf 1.53     if (index + size > this->size())
340 kumpf 1.49 	throw IndexOutOfBoundsException();
341 mike  1.27 
342 kumpf 1.39     if (size)
343 kumpf 1.53 	_rep->c16a.remove(index, size);
344 mike  1.27 }
345            
346 kumpf 1.53 String String::subString(Uint32 index, Uint32 length) const
347 mike  1.27 {
348 kumpf 1.53     if (index < size())
349 mike  1.27     {
350 kumpf 1.57 	if ((length == PEG_NOT_FOUND) || (length > size() - index))
351 kumpf 1.53 	    length = size() - index;
352 mike  1.27 
353 kumpf 1.55 	return String(getChar16Data() + index, length);
354 mike  1.27     }
355                else
356            	return String();
357            }
358            
359            Uint32 String::find(Char16 c) const
360            {
361 kumpf 1.55     const Char16* first = getChar16Data();
362 mike  1.27 
363                for (const Char16* p = first; *p; p++)
364                {
365            	if (*p == c)
366            	    return  p - first;
367                }
368            
369                return PEG_NOT_FOUND;
370            }
371            
372 kumpf 1.53 Uint32 String::find(Uint32 index, Char16 c) const
373 mike  1.30 {
374 kumpf 1.55     const Char16* data = getChar16Data();
375 mike  1.30 
376 kumpf 1.53     for (Uint32 i = index, n = size(); i < n; i++)
377 mike  1.30     {
378            	if (data[i] == c)
379            	    return i;
380                }
381            
382                return PEG_NOT_FOUND;
383            }
384            
385 mike  1.27 Uint32 String::find(const String& s) const
386            {
387 kumpf 1.55     const Char16* pSubStr = s.getChar16Data();
388                const Char16* pStr = getChar16Data();
389 mike  1.27     Uint32 subStrLen = s.size();
390                Uint32 strLen = size();
391            
392 mike  1.30     if (subStrLen > strLen)
393                {
394                    return PEG_NOT_FOUND;
395                }
396            
397 mike  1.27     // loop to find first char match
398                Uint32 loc = 0;
399                for( ; loc <= (strLen-subStrLen); loc++)
400                {
401            	if (*pStr++ == *pSubStr)  // match first char
402            	{
403            	    // point to substr 2nd char
404            	    const Char16* p = pSubStr + 1;
405            
406            	    // Test remaining chars for equal
407            	    Uint32 i = 1;
408            	    for (; i < subStrLen; i++)
409            		if (*pStr++ != *p++ )
410            		    {pStr--; break;} // break from loop
411            	    if (i == subStrLen)
412            		return loc;
413            	}
414                }
415                return PEG_NOT_FOUND;
416            }
417            
418 mike  1.27 Uint32 String::reverseFind(Char16 c) const
419            {
420 kumpf 1.55     const Char16* first = getChar16Data();
421                const Char16* last = getChar16Data() + size();
422 mike  1.27 
423                while (last != first)
424                {
425            	if (*--last == c)
426            	    return last - first;
427                }
428            
429                return PEG_NOT_FOUND;
430            }
431            
432            void String::toLower()
433            {
434 kumpf 1.43     for (Char16* p = &_rep->c16a[0]; *p; p++)
435 mike  1.27     {
436 kumpf 1.46 	if (*p <= PEGASUS_MAX_PRINTABLE_CHAR)
437 mike  1.27 	    *p = tolower(*p);
438                }
439 kumpf 1.39 }
440            
441 kumpf 1.43 int String::compare(const String& s1, const String& s2, Uint32 n)
442 kumpf 1.39 {
443 kumpf 1.55     const Char16* s1c16 = s1.getChar16Data();
444                const Char16* s2c16 = s2.getChar16Data();
445 kumpf 1.39 
446                while (n--)
447 mike  1.27     {
448 kumpf 1.43 	int r = *s1c16++ - *s2c16++;
449 mike  1.27 
450            	if (r)
451            	    return r;
452                }
453            
454                return 0;
455            }
456            
457 kumpf 1.43 int String::compare(const String& s1, const String& s2)
458 mike  1.30 {
459 kumpf 1.55     const Char16* s1c16 = s1.getChar16Data();
460                const Char16* s2c16 = s2.getChar16Data();
461 kumpf 1.43 
462                while (*s1c16 && *s2c16)
463 mike  1.30     {
464 kumpf 1.43 	int r = *s1c16++ - *s2c16++;
465 mike  1.30 
466            	if (r)
467            	    return r;
468                }
469            
470 kumpf 1.43     if (*s2c16)
471 mike  1.30 	return -1;
472 kumpf 1.43     else if (*s1c16)
473 mike  1.30 	return 1;
474            
475                return 0;
476            }
477            
478 kumpf 1.40 int String::compareNoCase(const String& s1, const String& s2)
479            {
480 kumpf 1.55     const Char16* _s1 = s1.getChar16Data();
481                const Char16* _s2 = s2.getChar16Data();
482 kumpf 1.40 
483                while (*_s1 && *_s2)
484                {
485                    int r;
486            
487 kumpf 1.46         if (*_s1 <= PEGASUS_MAX_PRINTABLE_CHAR &&
488                        *_s2 <= PEGASUS_MAX_PRINTABLE_CHAR)
489 kumpf 1.40         {
490                        r = tolower(*_s1++) - tolower(*_s2++);
491                    }
492                    else
493                    {
494                        r = *_s1++ - *_s2++;
495                    }
496            
497            	if (r)
498            	    return r;
499                }
500            
501                if (*_s2)
502            	return -1;
503                else if (*_s1)
504            	return 1;
505            
506                return 0;
507            }
508            
509 kumpf 1.39 Boolean String::equal(const String& str1, const String& str2)
510 mike  1.27 {
511 kumpf 1.43     return String::compare(str1, str2) == 0;
512 mike  1.27 }
513            
514 kumpf 1.39 Boolean String::equalNoCase(const String& str1, const String& str2)
515 mike  1.27 {
516 kumpf 1.39     if (str1.size() != str2.size())
517            	return false;
518            
519 kumpf 1.55     const Char16* p = str1.getChar16Data();
520                const Char16* q = str2.getChar16Data();
521 kumpf 1.39 
522                Uint32 n = str1.size();
523 mike  1.27 
524 kumpf 1.39     while (n--)
525                {
526 kumpf 1.46 	if (*p <= PEGASUS_MAX_PRINTABLE_CHAR &&
527                        *q <= PEGASUS_MAX_PRINTABLE_CHAR)
528 kumpf 1.39 	{
529            	    if (tolower(*p++) != tolower(*q++))
530            		return false;
531            	}
532            	else if (*p++ != *q++)
533            	    return false;
534                }
535 mike  1.28 
536 kumpf 1.39     return true;
537 mike  1.27 }
538            
539 kumpf 1.42 
540            // ATTN-RK-P3-20020603: This code is not completely correct
541 karl  1.36  // Wildcard String matching function that may be useful in the future
542            // The following code was provided by Bob Blair.
543            
544            /* _StringMatch Match input MatchString against a GLOB style pattern
545                   Note that MatchChar is the char type so that this source
546                   in portable to different string types. This is an internal function
547             
548              Results: The return value is 1 if string matches pattern, and
549             	0 otherwise.  The matching operation permits the following
550             	special characters in the pattern: *?\[] (see the manual
551             	entry for details on what these mean).
552             
553              Side effects: None.
554             */
555            
556            /* MatchChar defined as a separate entity because this function source used
557                elsewhere was an unsigned char *. Here we use Uint16 to  maintain 16 bit 
558                size.
559            */
560            typedef Uint16 MatchChar;
561            
562 karl  1.36 inline Uint16 _ToLower(Uint16 ch)
563            {
564 kumpf 1.46     return ch <= PEGASUS_MAX_PRINTABLE_CHAR ? tolower(char(ch)) : ch;
565 karl  1.36 }
566            
567            inline Boolean _Equal(MatchChar ch1, MatchChar ch2, int nocase)
568            {
569                if (nocase)
570            	return _ToLower(ch1) == _ToLower(ch2);
571                else
572            	return ch1 == ch2;
573            }
574 mike  1.28 
575 kumpf 1.35 
576 karl  1.36 static const MatchChar *
577            _matchrange(const MatchChar *range, MatchChar c, int nocase)
578            {
579              const MatchChar *p = range;
580              const MatchChar *rstart = range + 1;
581              const MatchChar *rend = 0;
582              MatchChar compchar;
583            
584 kumpf 1.35   for (rend = rstart; *rend && *rend != ']'; rend++);
585 karl  1.36   if (*rend == ']') {  // if there is an end to this pattern
586 kumpf 1.35     for (compchar = *rstart; rstart != rend; rstart++) {
587 karl  1.36       if (_Equal(*rstart, c, nocase))
588 kumpf 1.35         return ++rend;
589                  if (*rstart == '-') {
590                    rstart++;
591                    if (c >= compchar && c <= *rstart)
592                      return ++rend;
593                  }
594                }
595              }
596 karl  1.36   return (const MatchChar *)0;
597 kumpf 1.35 }
598            
599            static int
600 karl  1.36 _StringMatch( 
601                const MatchChar *testString, 
602                const MatchChar *pattern,
603                int nocase ) 		/* Ignore case if this is true */
604            {
605              const MatchChar *pat = pattern;
606              const MatchChar *str = testString;
607 kumpf 1.35   unsigned int done = 0;
608              unsigned int res = 0;  // the result: 1 == match
609            
610              while (!done) { // main loop walks through pattern and test string
611                //cerr << "Comparing <" << *pat << "> and <" << *str << ">" << endl;
612                if (!*pat) {                                         //end of pattern
613                  done = 1;                                          // we're done
614                  if (!*str)                                         //end of test, too?
615                    res = 1;                                         // then we matched
616                } else {                                             //Not end of pattern
617                  if (!*str) {                                       // but end of test
618                    done = 1;                                        // We're done
619                    if (*pat == '*')                                 // If pattern openends
620                      res = 1;                                       //  then we matched
621                  } else {                                           //Not end of test
622                    if (*pat == '*') {                               //Ambiguuity found
623                      if (!*++pat) {                                 //and it ends pattern
624                        done = 1;                                    //  then we're done
625                        res = 1;                                     //  and match
626                      } else {                                       //if it doesn't end
627                        while (!done) {                              //  until we're done
628 karl  1.36               if (_StringMatch(str, pat, nocase)) {      //  we recurse
629 kumpf 1.35                 done = 1;                                //if it recurses true
630                            res = 1;                                 //  we done and match
631                          } else {                                   //it recurses false
632                            if (!*str)                               // see if test is done
633                              done = 1;                              //  yes: we done
634                            else                                     // not done:
635                              str++;                                 //   keep testing
636                          } // end test on recursive call
637                        } // end looping on recursive calls
638                      } // end logic when pattern is ambiguous
639                    } else {                                         //pattern not ambiguus
640                      if (*pat == '?') {                             //pattern is 'any'
641                        pat++, str++;                                //  so move along
642                      } else if (*pat == '[') {                      //see if it's a range
643 karl  1.36             pat = _matchrange(pat, *str, nocase);         // and is a match
644 kumpf 1.35             if (!pat) {                                  //It is not a match
645                          done = 1;                                  //  we're done
646 kumpf 1.42               res = 0;                                   //  no match
647 kumpf 1.35             } else {                                     //Range matches
648                          str++, pat++;                              //  keep going
649                        }
650                      } else {               // only case left is individual characters
651 karl  1.36             if (!_Equal(*pat++, *str++, nocase))         // if they don't match
652 kumpf 1.35               done = 1;                                  //   bail.
653                      }
654                    }  // end ("pattern is not ambiguous (*)" logic
655                  } // end logic when pattern and string still have data
656                } // end logic when pattern still has data
657              } // end main loop
658              return res;
659            }
660            
661 kumpf 1.39 
662 karl  1.36 Boolean String::match(const String& str, const String& pattern)
663            {
664                return _StringMatch(
665 kumpf 1.55 	(Uint16*)str.getChar16Data(), (Uint16*)pattern.getChar16Data(), 0) != 0;
666 karl  1.36 }
667            
668            Boolean String::matchNoCase(const String& str, const String& pattern)
669            {
670                return _StringMatch(
671 kumpf 1.55 	(Uint16*)str.getChar16Data(), (Uint16*)pattern.getChar16Data(), 1) != 0;
672 kumpf 1.39 }
673            
674            
675            ///////////////////////////////////////////////////////////////////////////////
676            //
677            // String-related functions
678            //
679            ///////////////////////////////////////////////////////////////////////////////
680            
681            Boolean operator==(const String& str1, const String& str2)
682            {
683                return String::equal(str1, str2);
684            }
685            
686            Boolean operator==(const String& str1, const char* str2)
687            {
688                return String::equal(str1, str2);
689            }
690            
691            Boolean operator==(const char* str1, const String& str2)
692            {
693 kumpf 1.39     return String::equal(str1, str2);
694            }
695            
696            Boolean operator!=(const String& str1, const String& str2)
697            {
698                return !String::equal(str1, str2);
699            }
700            
701 kumpf 1.47 PEGASUS_STD(ostream)& operator<<(PEGASUS_STD(ostream)& os, const String& str)
702 kumpf 1.39 {
703 kumpf 1.47     for (Uint32 i = 0, n = str.size(); i < n; i++)
704 kumpf 1.50     {
705                    Uint16 code = str[i];
706            
707                    if (code > 0 && code <= PEGASUS_MAX_PRINTABLE_CHAR)
708                    {
709                        os << char(code);
710                    }
711                    else
712                    {
713                        // Print in hex format:
714                        char buffer[8];
715                        sprintf(buffer, "\\x%04X", code);
716                        os << buffer;
717                    }
718                }
719 kumpf 1.39 
720                return os;
721            }
722            
723            String operator+(const String& str1, const String& str2)
724            {
725                return String(str1).append(str2);
726            }
727            
728            Boolean operator<(const String& str1, const String& str2)
729            {
730 kumpf 1.43     return String::compare(str1, str2) < 0;
731 kumpf 1.39 }
732            
733            Boolean operator<=(const String& str1, const String& str2)
734            {
735 kumpf 1.43     return String::compare(str1, str2) <= 0;
736 kumpf 1.39 }
737            
738            Boolean operator>(const String& str1, const String& str2)
739            {
740 kumpf 1.43     return String::compare(str1, str2) > 0;
741 kumpf 1.39 }
742            
743            Boolean operator>=(const String& str1, const String& str2)
744            {
745 kumpf 1.43     return String::compare(str1, str2) >= 0;
746 kumpf 1.39 }
747            
748            int CompareNoCase(const char* s1, const char* s2)
749            {
750                while (*s1 && *s2)
751                {
752            	int r = tolower(*s1++) - tolower(*s2++);
753            
754            	if (r)
755            	    return r;
756                }
757            
758                if (*s2)
759            	return -1;
760                else if (*s1)
761            	return 1;
762            
763                return 0;
764            }
765            
766 mike  1.27 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2