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
|
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
|
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
|