(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            PEGASUS_NAMESPACE_BEGIN
 37            
 38            #define PEGASUS_ARRAY_T String
 39            #include <Pegasus/Common/ArrayImpl.h>
 40            #undef PEGASUS_ARRAY_T
 41            
 42            const String String::EMPTY;
 43 mike  1.27 
 44            static inline void _SkipWhitespace(const Char16*& p)
 45            {
 46                while (*p && isspace(*p))
 47                    p++;
 48            }
 49            
 50            inline Uint32 StrLen(const char* str)
 51            {
 52                if (!str)
 53            	throw NullPointer();
 54            
 55                return strlen(str);
 56            }
 57            
 58            inline Uint32 StrLen(const Char16* str)
 59            {
 60                if (!str)
 61            	throw NullPointer();
 62            
 63                Uint32 n = 0;
 64 mike  1.27 
 65                while (*str++)
 66            	n++;
 67            
 68                return n;
 69            }
 70            
 71            String::String()
 72            {
 73                _rep.append('\0');
 74            }
 75            
 76            String::String(const String& x) : _rep(x._rep)
 77            {
 78            
 79            }
 80            
 81            String::String(const String& x, Uint32 n)
 82            {
 83                _rep.append('\0');
 84                append(x.getData(), n);
 85 mike  1.27 }
 86            
 87            String::String(const Char16* x) : _rep(x, StrLen(x) + 1)
 88            {
 89            
 90            }
 91            
 92            String::String(const Char16* x, Uint32 n)
 93            {
 94                assign(x, n);
 95            }
 96            
 97            String::String(const char* str)
 98            {
 99                Uint32 n = ::strlen(str) + 1;
100                reserve(n);
101            
102                while (n--)
103            	_rep.append(*str++);
104            }
105            
106 mike  1.27 String::String(const char* str, Uint32 n_)
107            {
108                Uint32 n = _min(strlen(str), n_);
109                reserve(n + 1);
110            
111                while (n--)
112            	_rep.append(*str++);
113            
114                _rep.append('\0');
115            }
116            
117            String& String::assign(const Char16* x)
118            {
119                _rep.clear();
120                _rep.append(x, StrLen(x) + 1);
121                return *this;
122            }
123            
124            String& String::assign(const Char16* str, Uint32 n)
125            {
126                _rep.clear();
127 mike  1.27     Uint32 m = _min(StrLen(str), n);
128                _rep.append(str, m);
129                _rep.append('\0');
130                return *this;
131            }
132            
133            String& String::assign(const char* x)
134            {
135                _rep.clear();
136                Uint32 n = strlen(x);
137                _rep.reserve(n + 1);
138            
139                while (n--)
140            	_rep.append(*x++);
141            
142                _rep.append('\0');
143            
144                return *this;
145            }
146            
147            String& String::assign(const char* x, Uint32 n_)
148 mike  1.27 {
149                _rep.clear();
150            
151                Uint32 n = _min(strlen(x), n_);
152                _rep.reserve(n + 1);
153            
154                while (n--)
155            	_rep.append(*x++);
156            
157                _rep.append('\0');
158            
159                return *this;
160            }
161            
162            char* String::allocateCString(Uint32 extraBytes, Boolean noThrow) const
163            {
164                Uint32 n = size() + 1;
165                char* str = new char[n + extraBytes];
166                char* p = str;
167                const Char16* q = getData();
168            
169 mike  1.27     for (Uint32 i = 0; i < n; i++)
170                {
171            	Uint16 c = *q++;
172            	*p++ = char(c);
173            
174            	if ((c & 0xff00) && !noThrow)
175            	    throw TruncatedCharacter();
176                }
177            
178                return str;
179            }
180            
181            void String::appendToCString(
182                char* str,
183                Uint32 length,
184                Boolean noThrow) const
185            {
186                if (!str)
187            	throw NullPointer();
188            
189                Uint32 n = _min(size(), length);
190 mike  1.27 
191                char* p = str + strlen(str);
192                const Char16* q = getData();
193            
194                for (Uint32 i = 0; i < n; i++)
195                {
196            	Uint16 c = *q++;
197            	*p++ = char(c);
198            
199            	if ((c & 0xff00) && !noThrow)
200            	    throw TruncatedCharacter();
201                }
202            
203                *p = '\0';
204            }
205            
206            Char16& String::operator[](Uint32 i)
207            {
208                if (i > size())
209            	ThrowOutOfBounds();
210            
211 mike  1.27     return _rep[i];
212            }
213            
214            const Char16 String::operator[](Uint32 i) const
215            {
216                if (i > size())
217            	ThrowOutOfBounds();
218            
219                return _rep[i];
220            }
221            
222            String& String::append(const Char16* str, Uint32 n)
223            {
224                Uint32 m = _min(StrLen(str), n);
225                _rep.reserve(_rep.size() + m);
226                _rep.remove(_rep.size() - 1);
227                _rep.append(str, m);
228                _rep.append('\0');
229                return *this;
230            }
231            
232 mike  1.27 void String::remove(Uint32 pos, Uint32 size)
233            {
234                if (size == PEG_NOT_FOUND)
235            	size = this->size() - pos;
236            
237                if (pos + size > this->size())
238            	ThrowOutOfBounds();
239            
240                if (size)
241            	_rep.remove(pos, size);
242            }
243            
244            int String::compare(const Char16* s1, const Char16* s2, Uint32 n)
245            {
246                while (n--)
247                {
248            	int r = *s1++ - *s2++;
249            
250            	if (r)
251            	    return r;
252                }
253 mike  1.27 
254                return 0;
255            }
256            
257            int String::compareNoCase(const char* s1, const char* s2, Uint32 n)
258            {
259                while (n--)
260                {
261            	int r = tolower(*s1++) - tolower(*s2++);
262            
263            	if (r)
264            	    return r;
265                }
266            
267                return 0;
268            }
269            
270            Boolean String::equal(const String& x, const String& y)
271            {
272                if (x.size() != y.size())
273            	return false;
274 mike  1.27 
275                return String::compare(x.getData(), y.getData(), x.size()) == 0;
276            }
277            
278            Boolean String::equal(const String& x, const Char16* y)
279            {
280                if (x.size() != StrLen(y))
281            	return false;
282            
283                return String::compare(x.getData(), y, x.size()) == 0;
284            }
285            
286            Boolean String::equal(const Char16* x, const String& y)
287            {
288                return equal(y, x);
289            }
290            
291            Boolean String::equal(const String& x, const char* y)
292            {
293                return equal(x, String(y));
294            }
295 mike  1.27 
296            Boolean String::equal(const char* x, const String& y)
297            {
298                return equal(String(x), y);
299            }
300            
301            Boolean String::equalNoCase(const String& x, const String& y)
302            {
303                if (x.size() != y.size())
304            	return false;
305            
306                const Char16* p = x.getData();
307                const Char16* q = y.getData();
308            
309                Uint32 n = x.size();
310            
311                while (n--)
312                {
313            	if (*p <= 127 && *q <= 127)
314            	{
315            	    if (tolower(*p++) != tolower(*q++))
316 mike  1.27 		return false;
317            	}
318            	else if (*p++ != *q++)
319            	    return false;
320                }
321            
322                return true;
323            }
324            
325            String String::subString(Uint32 pos, Uint32 length) const
326            {
327                if (pos < size())
328                {
329            	if (length == PEG_NOT_FOUND)
330            	    length = size() - pos;
331            
332            	return String(getData() + pos, length);
333                }
334                else
335            	return String();
336            }
337 mike  1.27 
338            Uint32 String::find(Char16 c) const
339            {
340                const Char16* first = getData();
341            
342                for (const Char16* p = first; *p; p++)
343                {
344            	if (*p == c)
345            	    return  p - first;
346                }
347            
348                return PEG_NOT_FOUND;
349            }
350            
351            Uint32 String::find(const String& s) const
352            {
353                const Char16* pSubStr = s.getData();
354                const Char16* pStr = getData();
355                Uint32 subStrLen = s.size();
356                Uint32 strLen = size();
357            
358 mike  1.27     // loop to find first char match
359                Uint32 loc = 0;
360                for( ; loc <= (strLen-subStrLen); loc++)
361                {
362            	if (*pStr++ == *pSubStr)  // match first char
363            	{
364            	    // point to substr 2nd char
365            	    const Char16* p = pSubStr + 1;
366            
367            	    // Test remaining chars for equal
368            	    Uint32 i = 1;
369            	    for (; i < subStrLen; i++)
370            		if (*pStr++ != *p++ )
371            		    {pStr--; break;} // break from loop
372            	    if (i == subStrLen)
373            		return loc;
374            	}
375                }
376                return PEG_NOT_FOUND;
377            }
378            
379 mike  1.27 // ATTN:KS 5 apr 2000 Need to add the Char16* version.
380            Uint32 String::find(const char* s) const
381            {
382                return find(String(s));
383            }
384            
385            Uint32 String::reverseFind(Char16 c) const
386            {
387                const Char16* first = getData();
388                const Char16* last = getData() + size();
389            
390                while (last != first)
391                {
392            	if (*--last == c)
393            	    return last - first;
394                }
395            
396                return PEG_NOT_FOUND;
397            }
398            
399            void String::toLower()
400 mike  1.27 {
401                for (Char16* p = &_rep[0]; *p; p++)
402                {
403            	if (*p <= 127)
404            	    *p = tolower(*p);
405                }
406            }
407            
408            void String::translate(Char16 fromChar, Char16 toChar)
409            {
410                for (Char16* p = &_rep[0]; *p; p++)
411                {
412            	if (*p == fromChar)
413            	    *p = toChar;
414                }
415            }
416            
417            int String::compare(const Char16* s1, const Char16* s2)
418            {
419                while (*s1 && *s2)
420                {
421 mike  1.27 	int r = *s1++ - *s2++;
422            
423            	if (r)
424            	    return r;
425                }
426            
427                if (*s2)
428            	return -1;
429                else if (*s1)
430            	return 1;
431            
432                return 0;
433            }
434            
435            PEGASUS_STD(ostream)& operator<<(PEGASUS_STD(ostream)& os, const String& x)
436            {
437                for (Uint32 i = 0, n = x.size(); i < n; i++)
438            	os << x[i];
439            
440                return os;
441            }
442 mike  1.27 
443            void String::toLower(char* str)
444            {
445                while (*str)
446            	tolower(*str++);
447            }
448            
449            String ToLower(const String& str)
450            {
451                String tmp(str);
452            
453                for (Uint32 i = 0, n = tmp.size(); i < n; i++)
454                {
455            	Char16 c = tmp[i];
456            
457            	if (c <= 127)
458            	    tmp[i] = tolower(c);
459                }
460            
461                return tmp;
462            }
463 mike  1.27 
464            int CompareNoCase(const char* s1, const char* s2)
465            {
466                while (*s1 && *s2)
467                {
468            	int r = tolower(*s1++) - tolower(*s2++);
469            
470            	if (r)
471            	    return r;
472                }
473            
474                if (*s2)
475            	return -1;
476                else if (*s1)
477            	return 1;
478            
479                return 0;
480            }
481            
482            Boolean GetLine(PEGASUS_STD(istream)& is, String& line)
483            {
484 mike  1.27     line.clear();
485            
486                Boolean gotChar = false;
487                char c;
488            
489                while (is.get(c))
490                {
491            	gotChar = true;
492            
493            	if (c == '\n')
494            	    break;
495            
496            	line.append(c);
497                }
498            
499                return gotChar;
500            }
501            
502            String::~String()
503            {
504            }
505 mike  1.27 
506            String& String::assign(const String& x)
507            {
508                _rep = x._rep;
509                return *this;
510            }
511            
512            String& String::append(const Char16& c)
513            {
514                _rep.insert(_rep.size() - 1, c);
515                return *this;
516            }
517            
518            void String::clear()
519            {
520                _rep.clear();
521                _rep.append('\0');
522            }
523            
524            void String::reserve(Uint32 capacity)
525            {
526 mike  1.27     _rep.reserve(capacity + 1);
527            }
528            
529            const Array<String>& EmptyStringArray()
530            {
531                static Array<String> tmp;
532                return tmp;
533            }
534            
535            PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2