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

  1 mike  1.27 //%/////////////////////////////////////////////////////////////////////////////
  2            //
  3            // Copyright (c) 2000, 2001 The Open group, BMC Software, Tivoli Systems, IBM
  4            //
  5            // Permission is hereby granted, free of charge, to any person obtaining a copy
  6            // of this software and associated documentation files (the "Software"), to 
  7            // deal in the Software without restriction, including without limitation the 
  8            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
  9            // sell copies of the Software, and to permit persons to whom the Software is
 10            // furnished to do so, subject to the following conditions:
 11            // 
 12            // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN 
 13            // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 14            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 15            // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 16            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
 17            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
 18            // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 19            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 20            //
 21            //==============================================================================
 22 mike  1.27 //
 23            // Author: Mike Brasher (mbrasher@bmc.com)
 24            //
 25            // Modified By:
 26            //
 27            //%/////////////////////////////////////////////////////////////////////////////
 28            
 29            
 30            #include <cctype>
 31            #include "String.h"
 32            #include "Exception.h"
 33            #include "String.h"
 34            #include <iostream>
 35            
 36 mike  1.28 PEGASUS_USING_STD;
 37            
 38 mike  1.27 PEGASUS_NAMESPACE_BEGIN
 39            
 40            #define PEGASUS_ARRAY_T String
 41            #include <Pegasus/Common/ArrayImpl.h>
 42            #undef PEGASUS_ARRAY_T
 43            
 44            const String String::EMPTY;
 45            
 46            static inline void _SkipWhitespace(const Char16*& p)
 47            {
 48                while (*p && isspace(*p))
 49                    p++;
 50            }
 51            
 52            inline Uint32 StrLen(const char* str)
 53            {
 54                if (!str)
 55            	throw NullPointer();
 56            
 57                return strlen(str);
 58            }
 59 mike  1.27 
 60            inline Uint32 StrLen(const Char16* str)
 61            {
 62                if (!str)
 63            	throw NullPointer();
 64            
 65                Uint32 n = 0;
 66            
 67                while (*str++)
 68            	n++;
 69            
 70                return n;
 71            }
 72            
 73            String::String()
 74            {
 75                _rep.append('\0');
 76            }
 77            
 78            String::String(const String& x) : _rep(x._rep)
 79            {
 80 mike  1.27 
 81            }
 82            
 83            String::String(const String& x, Uint32 n)
 84            {
 85                _rep.append('\0');
 86                append(x.getData(), n);
 87            }
 88            
 89            String::String(const Char16* x) : _rep(x, StrLen(x) + 1)
 90            {
 91            
 92            }
 93            
 94            String::String(const Char16* x, Uint32 n)
 95            {
 96                assign(x, n);
 97            }
 98            
 99            String::String(const char* str)
100            {
101 mike  1.27     Uint32 n = ::strlen(str) + 1;
102                reserve(n);
103            
104                while (n--)
105            	_rep.append(*str++);
106            }
107            
108            String::String(const char* str, Uint32 n_)
109            {
110                Uint32 n = _min(strlen(str), n_);
111                reserve(n + 1);
112            
113                while (n--)
114            	_rep.append(*str++);
115            
116                _rep.append('\0');
117            }
118            
119            String& String::assign(const Char16* x)
120            {
121                _rep.clear();
122 mike  1.27     _rep.append(x, StrLen(x) + 1);
123                return *this;
124            }
125            
126            String& String::assign(const Char16* str, Uint32 n)
127            {
128                _rep.clear();
129                Uint32 m = _min(StrLen(str), n);
130                _rep.append(str, m);
131                _rep.append('\0');
132                return *this;
133            }
134            
135            String& String::assign(const char* x)
136            {
137                _rep.clear();
138                Uint32 n = strlen(x);
139                _rep.reserve(n + 1);
140            
141                while (n--)
142            	_rep.append(*x++);
143 mike  1.27 
144                _rep.append('\0');
145            
146                return *this;
147            }
148            
149            String& String::assign(const char* x, Uint32 n_)
150            {
151                _rep.clear();
152            
153                Uint32 n = _min(strlen(x), n_);
154                _rep.reserve(n + 1);
155            
156                while (n--)
157            	_rep.append(*x++);
158            
159                _rep.append('\0');
160            
161                return *this;
162            }
163            
164 mike  1.27 char* String::allocateCString(Uint32 extraBytes, Boolean noThrow) const
165            {
166                Uint32 n = size() + 1;
167                char* str = new char[n + extraBytes];
168                char* p = str;
169                const Char16* q = getData();
170            
171                for (Uint32 i = 0; i < n; i++)
172                {
173            	Uint16 c = *q++;
174            	*p++ = char(c);
175            
176            	if ((c & 0xff00) && !noThrow)
177            	    throw TruncatedCharacter();
178                }
179            
180                return str;
181            }
182            
183            void String::appendToCString(
184                char* str,
185 mike  1.27     Uint32 length,
186                Boolean noThrow) const
187            {
188                if (!str)
189            	throw NullPointer();
190            
191                Uint32 n = _min(size(), length);
192            
193                char* p = str + strlen(str);
194                const Char16* q = getData();
195            
196                for (Uint32 i = 0; i < n; i++)
197                {
198            	Uint16 c = *q++;
199            	*p++ = char(c);
200            
201            	if ((c & 0xff00) && !noThrow)
202            	    throw TruncatedCharacter();
203                }
204            
205                *p = '\0';
206 mike  1.27 }
207            
208            Char16& String::operator[](Uint32 i)
209            {
210                if (i > size())
211            	ThrowOutOfBounds();
212            
213                return _rep[i];
214            }
215            
216            const Char16 String::operator[](Uint32 i) const
217            {
218                if (i > size())
219            	ThrowOutOfBounds();
220            
221                return _rep[i];
222            }
223            
224            String& String::append(const Char16* str, Uint32 n)
225            {
226                Uint32 m = _min(StrLen(str), n);
227 mike  1.27     _rep.reserve(_rep.size() + m);
228                _rep.remove(_rep.size() - 1);
229                _rep.append(str, m);
230                _rep.append('\0');
231                return *this;
232            }
233            
234            void String::remove(Uint32 pos, Uint32 size)
235            {
236                if (size == PEG_NOT_FOUND)
237            	size = this->size() - pos;
238            
239                if (pos + size > this->size())
240            	ThrowOutOfBounds();
241            
242                if (size)
243            	_rep.remove(pos, size);
244            }
245            
246            int String::compare(const Char16* s1, const Char16* s2, Uint32 n)
247            {
248 mike  1.27     while (n--)
249                {
250            	int r = *s1++ - *s2++;
251            
252            	if (r)
253            	    return r;
254                }
255            
256                return 0;
257            }
258            
259            int String::compareNoCase(const char* s1, const char* s2, Uint32 n)
260            {
261                while (n--)
262                {
263            	int r = tolower(*s1++) - tolower(*s2++);
264            
265            	if (r)
266            	    return r;
267                }
268            
269 mike  1.27     return 0;
270            }
271            
272            Boolean String::equal(const String& x, const String& y)
273            {
274                if (x.size() != y.size())
275            	return false;
276            
277                return String::compare(x.getData(), y.getData(), x.size()) == 0;
278            }
279            
280            Boolean String::equal(const String& x, const Char16* y)
281            {
282                if (x.size() != StrLen(y))
283            	return false;
284            
285                return String::compare(x.getData(), y, x.size()) == 0;
286            }
287            
288            Boolean String::equal(const Char16* x, const String& y)
289            {
290 mike  1.27     return equal(y, x);
291            }
292            
293            Boolean String::equal(const String& x, const char* y)
294            {
295                return equal(x, String(y));
296            }
297            
298            Boolean String::equal(const char* x, const String& y)
299            {
300                return equal(String(x), y);
301            }
302            
303            Boolean String::equalNoCase(const String& x, const String& y)
304            {
305                if (x.size() != y.size())
306            	return false;
307            
308                const Char16* p = x.getData();
309                const Char16* q = y.getData();
310            
311 mike  1.27     Uint32 n = x.size();
312            
313                while (n--)
314                {
315            	if (*p <= 127 && *q <= 127)
316            	{
317            	    if (tolower(*p++) != tolower(*q++))
318            		return false;
319            	}
320            	else if (*p++ != *q++)
321            	    return false;
322                }
323            
324                return true;
325            }
326            
327            String String::subString(Uint32 pos, Uint32 length) const
328            {
329                if (pos < size())
330                {
331            	if (length == PEG_NOT_FOUND)
332 mike  1.27 	    length = size() - pos;
333            
334            	return String(getData() + pos, length);
335                }
336                else
337            	return String();
338            }
339            
340            Uint32 String::find(Char16 c) const
341            {
342                const Char16* first = getData();
343            
344                for (const Char16* p = first; *p; p++)
345                {
346            	if (*p == c)
347            	    return  p - first;
348                }
349            
350                return PEG_NOT_FOUND;
351            }
352            
353 mike  1.28.2.2 Uint32 String::find(Uint32 pos, Char16 c) const
354                {
355                    const Char16* data = getData();
356                
357                    for (Uint32 i = pos, n = size(); i < n; i++)
358                    {
359                	if (data[i] == c)
360                	    return i;
361                    }
362                
363                    return PEG_NOT_FOUND;
364                }
365                
366 mike  1.27     Uint32 String::find(const String& s) const
367                {
368                    const Char16* pSubStr = s.getData();
369                    const Char16* pStr = getData();
370                    Uint32 subStrLen = s.size();
371                    Uint32 strLen = size();
372                
373                    // loop to find first char match
374                    Uint32 loc = 0;
375                    for( ; loc <= (strLen-subStrLen); loc++)
376                    {
377                	if (*pStr++ == *pSubStr)  // match first char
378                	{
379                	    // point to substr 2nd char
380                	    const Char16* p = pSubStr + 1;
381                
382                	    // Test remaining chars for equal
383                	    Uint32 i = 1;
384                	    for (; i < subStrLen; i++)
385                		if (*pStr++ != *p++ )
386                		    {pStr--; break;} // break from loop
387 mike  1.27     	    if (i == subStrLen)
388                		return loc;
389                	}
390                    }
391                    return PEG_NOT_FOUND;
392                }
393                
394                // ATTN:KS 5 apr 2000 Need to add the Char16* version.
395                Uint32 String::find(const char* s) const
396                {
397                    return find(String(s));
398                }
399                
400                Uint32 String::reverseFind(Char16 c) const
401                {
402                    const Char16* first = getData();
403                    const Char16* last = getData() + size();
404                
405                    while (last != first)
406                    {
407                	if (*--last == c)
408 mike  1.27     	    return last - first;
409                    }
410                
411                    return PEG_NOT_FOUND;
412                }
413                
414                void String::toLower()
415                {
416                    for (Char16* p = &_rep[0]; *p; p++)
417                    {
418                	if (*p <= 127)
419                	    *p = tolower(*p);
420                    }
421                }
422                
423                void String::translate(Char16 fromChar, Char16 toChar)
424                {
425                    for (Char16* p = &_rep[0]; *p; p++)
426                    {
427                	if (*p == fromChar)
428                	    *p = toChar;
429 mike  1.27         }
430                }
431                
432                int String::compare(const Char16* s1, const Char16* s2)
433                {
434                    while (*s1 && *s2)
435                    {
436                	int r = *s1++ - *s2++;
437                
438                	if (r)
439                	    return r;
440                    }
441                
442                    if (*s2)
443                	return -1;
444                    else if (*s1)
445                	return 1;
446                
447                    return 0;
448                }
449                
450 mike  1.28.2.1 int String::compareNoCase(const char* s1, const char* s2)
451                {
452                    while (*s1 && *s2)
453                    {
454                	int r = tolower(*s1++) - tolower(*s2++);
455                
456                	if (r)
457                	    return r;
458                    }
459                
460                    if (*s2)
461                	return -1;
462                    else if (*s1)
463                	return 1;
464                
465                    return 0;
466                }
467                
468 mike  1.27     PEGASUS_STD(ostream)& operator<<(PEGASUS_STD(ostream)& os, const String& x)
469                {
470                    for (Uint32 i = 0, n = x.size(); i < n; i++)
471                	os << x[i];
472                
473                    return os;
474                }
475                
476                void String::toLower(char* str)
477                {
478                    while (*str)
479                	tolower(*str++);
480                }
481                
482                String ToLower(const String& str)
483                {
484                    String tmp(str);
485                
486                    for (Uint32 i = 0, n = tmp.size(); i < n; i++)
487                    {
488                	Char16 c = tmp[i];
489 mike  1.27     
490                	if (c <= 127)
491                	    tmp[i] = tolower(c);
492                    }
493                
494                    return tmp;
495                }
496                
497                int CompareNoCase(const char* s1, const char* s2)
498                {
499                    while (*s1 && *s2)
500                    {
501                	int r = tolower(*s1++) - tolower(*s2++);
502                
503                	if (r)
504                	    return r;
505                    }
506                
507                    if (*s2)
508                	return -1;
509                    else if (*s1)
510 mike  1.27     	return 1;
511                
512                    return 0;
513                }
514                
515                Boolean GetLine(PEGASUS_STD(istream)& is, String& line)
516                {
517                    line.clear();
518                
519                    Boolean gotChar = false;
520                    char c;
521                
522                    while (is.get(c))
523                    {
524                	gotChar = true;
525                
526                	if (c == '\n')
527                	    break;
528                
529                	line.append(c);
530                    }
531 mike  1.27     
532                    return gotChar;
533                }
534                
535                String::~String()
536                {
537                }
538                
539                String& String::assign(const String& x)
540                {
541                    _rep = x._rep;
542                    return *this;
543                }
544                
545                String& String::append(const Char16& c)
546                {
547                    _rep.insert(_rep.size() - 1, c);
548                    return *this;
549                }
550                
551                void String::clear()
552 mike  1.27     {
553                    _rep.clear();
554                    _rep.append('\0');
555                }
556                
557 mike  1.28     void String::print() const
558                {
559                    cout << *this << endl;
560                }
561                
562 mike  1.27     void String::reserve(Uint32 capacity)
563                {
564                    _rep.reserve(capacity + 1);
565                }
566                
567                const Array<String>& EmptyStringArray()
568                {
569                    static Array<String> tmp;
570                    return tmp;
571                }
572 mike  1.28     
573 mike  1.27     
574                PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2