(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.27 Uint32 String::find(const String& s) const
354            {
355                const Char16* pSubStr = s.getData();
356                const Char16* pStr = getData();
357                Uint32 subStrLen = s.size();
358                Uint32 strLen = size();
359            
360                // loop to find first char match
361                Uint32 loc = 0;
362                for( ; loc <= (strLen-subStrLen); loc++)
363                {
364            	if (*pStr++ == *pSubStr)  // match first char
365            	{
366            	    // point to substr 2nd char
367            	    const Char16* p = pSubStr + 1;
368            
369            	    // Test remaining chars for equal
370            	    Uint32 i = 1;
371            	    for (; i < subStrLen; i++)
372            		if (*pStr++ != *p++ )
373            		    {pStr--; break;} // break from loop
374 mike  1.27 	    if (i == subStrLen)
375            		return loc;
376            	}
377                }
378                return PEG_NOT_FOUND;
379            }
380            
381            // ATTN:KS 5 apr 2000 Need to add the Char16* version.
382            Uint32 String::find(const char* s) const
383            {
384                return find(String(s));
385            }
386            
387            Uint32 String::reverseFind(Char16 c) const
388            {
389                const Char16* first = getData();
390                const Char16* last = getData() + size();
391            
392                while (last != first)
393                {
394            	if (*--last == c)
395 mike  1.27 	    return last - first;
396                }
397            
398                return PEG_NOT_FOUND;
399            }
400            
401            void String::toLower()
402            {
403                for (Char16* p = &_rep[0]; *p; p++)
404                {
405            	if (*p <= 127)
406            	    *p = tolower(*p);
407                }
408            }
409            
410            void String::translate(Char16 fromChar, Char16 toChar)
411            {
412                for (Char16* p = &_rep[0]; *p; p++)
413                {
414            	if (*p == fromChar)
415            	    *p = toChar;
416 mike  1.27     }
417            }
418            
419            int String::compare(const Char16* s1, const Char16* s2)
420            {
421                while (*s1 && *s2)
422                {
423            	int r = *s1++ - *s2++;
424            
425            	if (r)
426            	    return r;
427                }
428            
429                if (*s2)
430            	return -1;
431                else if (*s1)
432            	return 1;
433            
434                return 0;
435            }
436            
437 mike  1.27 PEGASUS_STD(ostream)& operator<<(PEGASUS_STD(ostream)& os, const String& x)
438            {
439                for (Uint32 i = 0, n = x.size(); i < n; i++)
440            	os << x[i];
441            
442                return os;
443            }
444            
445            void String::toLower(char* str)
446            {
447                while (*str)
448            	tolower(*str++);
449            }
450            
451            String ToLower(const String& str)
452            {
453                String tmp(str);
454            
455                for (Uint32 i = 0, n = tmp.size(); i < n; i++)
456                {
457            	Char16 c = tmp[i];
458 mike  1.27 
459            	if (c <= 127)
460            	    tmp[i] = tolower(c);
461                }
462            
463                return tmp;
464            }
465            
466            int CompareNoCase(const char* s1, const char* s2)
467            {
468                while (*s1 && *s2)
469                {
470            	int r = tolower(*s1++) - tolower(*s2++);
471            
472            	if (r)
473            	    return r;
474                }
475            
476                if (*s2)
477            	return -1;
478                else if (*s1)
479 mike  1.27 	return 1;
480            
481                return 0;
482            }
483            
484            Boolean GetLine(PEGASUS_STD(istream)& is, String& line)
485            {
486                line.clear();
487            
488                Boolean gotChar = false;
489                char c;
490            
491                while (is.get(c))
492                {
493            	gotChar = true;
494            
495            	if (c == '\n')
496            	    break;
497            
498            	line.append(c);
499                }
500 mike  1.27 
501                return gotChar;
502            }
503            
504            String::~String()
505            {
506            }
507            
508            String& String::assign(const String& x)
509            {
510                _rep = x._rep;
511                return *this;
512            }
513            
514            String& String::append(const Char16& c)
515            {
516                _rep.insert(_rep.size() - 1, c);
517                return *this;
518            }
519            
520            void String::clear()
521 mike  1.27 {
522                _rep.clear();
523                _rep.append('\0');
524            }
525            
526 mike  1.28 void String::print() const
527            {
528                cout << *this << endl;
529            }
530            
531 mike  1.27 void String::reserve(Uint32 capacity)
532            {
533                _rep.reserve(capacity + 1);
534            }
535            
536            const Array<String>& EmptyStringArray()
537            {
538                static Array<String> tmp;
539                return tmp;
540            }
541 mike  1.28 
542 mike  1.27 
543            PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2