1 mike 1.12 //%/////////////////////////////////////////////////////////////////////////////
|
2 mike 1.1 //
3 // Copyright (c) 2000 The Open Group, BMC Software, Tivoli Systems, IBM
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a
6 // copy of this software and associated documentation files (the "Software"),
7 // to deal in the Software without restriction, including without limitation
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 // and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18 // DEALINGS IN THE SOFTWARE.
19 //
|
20 mike 1.12 //==============================================================================
|
21 mike 1.1 //
|
22 mike 1.12 // Author: Mike Brasher (mbrasher@bmc.com)
|
23 mike 1.1 //
|
24 mike 1.12 // Modified By:
|
25 mike 1.11 //
|
26 mike 1.12 //%/////////////////////////////////////////////////////////////////////////////
|
27 mike 1.1
|
28 karl 1.6
|
29 mike 1.2 #include <cctype>
|
30 mike 1.1 #include "String.h"
31 #include "Exception.h"
32 #include "String.h"
33
|
34 karl 1.6 // For debugging
|
35 karl 1.7 #include <iostream>
36 using namespace std;
|
37 karl 1.6
38
|
39 mike 1.1 PEGASUS_NAMESPACE_BEGIN
40
41 const String String::EMPTY;
42
|
43 mike 1.2 inline Uint32 StrLen(const char* str)
|
44 mike 1.1 {
|
45 mike 1.2 if (!str)
46 throw NullPointer();
47
48 return strlen(str);
|
49 mike 1.1 }
50
|
51 mike 1.2 inline Uint32 StrLen(const Char16* str)
|
52 mike 1.1 {
53 if (!str)
|
54 mike 1.2 throw NullPointer();
|
55 mike 1.1
56 Uint32 n = 0;
57
58 while (*str++)
59 n++;
60
61 return n;
62 }
63
|
64 karl 1.5 String::String()
|
65 mike 1.2 {
|
66 karl 1.5 _rep.append('\0');
|
67 mike 1.1 }
68
|
69 karl 1.5 String::String(const String& x) : _rep(x._rep)
|
70 mike 1.1 {
71
72 }
73
74 String::String(const String& x, Uint32 n)
75 {
76 _rep.append('\0');
77 append(x.getData(), n);
78 }
79
|
80 karl 1.5 String::String(const Char16* x) : _rep(x, StrLen(x) + 1)
81 {
|
82 mike 1.1
83 }
84
|
85 karl 1.5 String::String(const Char16* x, Uint32 n)
86 {
87 assign(x, n);
|
88 mike 1.1 }
89
90 String::String(const char* str)
91 {
92 Uint32 n = ::strlen(str) + 1;
93 reserve(n);
94
95 while (n--)
96 _rep.append(*str++);
97 }
98
|
99 karl 1.5 String::String(const char* str, Uint32 n_)
|
100 mike 1.1 {
101 Uint32 n = _min(strlen(str), n_);
102 reserve(n + 1);
103
104 while (n--)
105 _rep.append(*str++);
106
107 _rep.append('\0');
108 }
109
|
110 karl 1.5 String& String::assign(const Char16* x)
|
111 mike 1.1 {
112 _rep.clear();
113 _rep.append(x, StrLen(x) + 1);
|
114 karl 1.5 return *this;
|
115 mike 1.1 }
116
117 String& String::assign(const Char16* str, Uint32 n)
118 {
119 _rep.clear();
120 Uint32 m = _min(StrLen(str), n);
121 _rep.append(str, m);
122 _rep.append('\0');
123 return *this;
124 }
125
|
126 karl 1.5 String& String::assign(const char* x)
|
127 mike 1.1 {
128 _rep.clear();
129 Uint32 n = strlen(x);
130 _rep.reserve(n + 1);
131
132 while (n--)
133 _rep.append(*x++);
134
135 _rep.append('\0');
136
|
137 karl 1.5 return *this;
|
138 mike 1.1 }
139
140 String& String::assign(const char* x, Uint32 n_)
141 {
142 _rep.clear();
143
144 Uint32 n = _min(strlen(x), n_);
145 _rep.reserve(n + 1);
146
147 while (n--)
148 _rep.append(*x++);
149
150 _rep.append('\0');
151
|
152 karl 1.5 return *this;
|
153 mike 1.1 }
154
155 char* String::allocateCString(Uint32 extraBytes, Boolean noThrow) const
156 {
157 Uint32 n = getLength() + 1;
158 char* str = new char[n + extraBytes];
159 char* p = str;
160 const Char16* q = getData();
161
162 for (Uint32 i = 0; i < n; i++)
163 {
164 Uint16 c = *q++;
165 *p++ = char(c);
166
167 if ((c & 0xff00) && !noThrow)
168 throw TruncatedCharacter();
169 }
170
171 return str;
172 }
173
174 mike 1.1 void String::appendToCString(
|
175 karl 1.5 char* str,
176 Uint32 length,
|
177 mike 1.1 Boolean noThrow) const
178 {
179 if (!str)
180 throw NullPointer();
181
182 Uint32 n = _min(getLength(), length);
183
184 char* p = str + strlen(str);
185 const Char16* q = getData();
186
187 for (Uint32 i = 0; i < n; i++)
188 {
189 Uint16 c = *q++;
190 *p++ = char(c);
191
192 if ((c & 0xff00) && !noThrow)
193 throw TruncatedCharacter();
194 }
195
196 *p = '\0';
197 }
198 mike 1.1
|
199 karl 1.5 Char16& String::operator[](Uint32 i)
|
200 mike 1.1 {
201 if (i > getLength())
202 ThrowOutOfBounds();
203
|
204 karl 1.5 return _rep[i];
|
205 mike 1.1 }
206
207 const Char16 String::operator[](Uint32 i) const
208 {
209 if (i > getLength())
210 ThrowOutOfBounds();
211
|
212 karl 1.5 return _rep[i];
|
213 mike 1.1 }
214
215 String& String::append(const Char16* str, Uint32 n)
216 {
217 Uint32 m = _min(StrLen(str), n);
218 _rep.reserve(_rep.getSize() + m);
219 _rep.remove(_rep.getSize() - 1);
220 _rep.append(str, m);
221 _rep.append('\0');
222 return *this;
223 }
224
225 void String::remove(Uint32 pos, Uint32 size)
226 {
227 if (size == Uint32(-1))
228 size = getLength() - pos;
229
230 if (pos + size > getLength())
231 ThrowOutOfBounds();
232
233 if (size)
234 mike 1.1 _rep.remove(pos, size);
235 }
236
|
237 mike 1.4 int String::compare(const Char16* s1, const Char16* s2, Uint32 n)
238 {
239 while (n--)
240 {
241 int r = *s1++ - *s2++;
242
243 if (r)
244 return r;
245 }
246
247 return 0;
248 }
249
250 Boolean String::equal(const String& x, const String& y)
|
251 mike 1.1 {
252 if (x.getLength() != y.getLength())
253 return false;
254
255 return String::compare(x.getData(), y.getData(), x.getLength()) == 0;
256 }
257
|
258 mike 1.4 Boolean String::equal(const String& x, const Char16* y)
|
259 mike 1.1 {
260 if (x.getLength() != StrLen(y))
261 return false;
262
263 return String::compare(x.getData(), y, x.getLength()) == 0;
264 }
265
|
266 mike 1.4 Boolean String::equal(const Char16* x, const String& y)
|
267 mike 1.1 {
|
268 mike 1.4 return equal(y, x);
|
269 mike 1.1 }
270
|
271 mike 1.4 Boolean String::equal(const String& x, const char* y)
|
272 mike 1.1 {
|
273 mike 1.4 return equal(x, String(y));
274 }
|
275 mike 1.1
|
276 mike 1.4 Boolean String::equal(const char* x, const String& y)
277 {
278 return equal(String(x), y);
279 }
|
280 mike 1.1
281
282 String String::subString(Uint32 pos, Uint32 length) const
283 {
284 if (pos < getLength())
285 {
286 if (length == Uint32(-1))
287 length = getLength() - pos;
288
289 return String(getData() + pos, length);
290 }
291 else
292 return String();
293 }
294
295 Uint32 String::find(Char16 c) const
296 {
297 const Char16* first = getData();
298
299 for (const Char16* p = first; *p; p++)
300 {
301 mike 1.1 if (*p == c)
302 return p - first;
|
303 mike 1.3 }
304
305 return Uint32(-1);
|
306 karl 1.6 }
307
|
308 karl 1.7 Uint32 String::find(const String& s) const
|
309 karl 1.6 {
|
310 karl 1.7 const Char16* pSubStr = s.getData();
311 const Char16* pStr = getData();
312 Uint32 subStrLen = s.getLength();
313 Uint32 strLen = getLength();
314
315 // loop to find first char match
316 Uint32 loc = 0;
317 for( ; loc <= (strLen-subStrLen); loc++)
|
318 karl 1.6 {
|
319 karl 1.7 if (*pStr++ == *pSubStr) // match first char
320 {
321 // point to substr 2nd char
322 const Char16* p = pSubStr + 1;
323
324 // Test remaining chars for equal
325 Uint32 i = 1;
326 for (; i < subStrLen; i++)
327 if (*pStr++ != *p++ )
328 {pStr--; break;} // break from loop
329 if (i == subStrLen)
330 return loc;
331 }
332 }
|
333 mike 1.9 return Uint32(-1);
|
334 karl 1.6 }
|
335 mike 1.8
|
336 karl 1.6 // ATTN:KS 5 apr 2000 Need to add the Char16* version.
337 Uint32 String::find(const char* s) const
338 {
339 return find(String(s));
|
340 mike 1.3 }
341
342 Uint32 String::reverseFind(Char16 c) const
343 {
344 const Char16* first = getData();
345 const Char16* last = getData() + getLength();
346
347 while (last != first)
348 {
349 if (*--last == c)
350 return last - first;
|
351 mike 1.1 }
352
353 return Uint32(-1);
354 }
355
|
356 mike 1.13 void String::toLower()
357 {
358 for (Char16* p = &_rep[0]; *p; p++)
359 {
360 if (*p <= 127)
361 *p = tolower(*p);
362 }
363 }
364
|
365 mike 1.1 int String::compare(const Char16* s1, const Char16* s2)
366 {
367 while (*s1 && *s2)
368 {
369 int r = *s1++ - *s2++;
370
371 if (r)
372 return r;
373 }
374
375 if (*s2)
376 return -1;
377 else if (*s1)
378 return 1;
379
380 return 0;
381 }
382
383 std::ostream& operator<<(std::ostream& os, const String& x)
384 {
385 for (Uint32 i = 0, n = x.getLength(); i < n; i++)
386 mike 1.1 os << x[i];
387
388 return os;
|
389 mike 1.2 }
390
391 void String::toLower(char* str)
392 {
393 while (*str)
394 tolower(*str++);
395 }
396
397 String ToLower(const String& str)
398 {
399 String tmp(str);
400
401 for (Uint32 i = 0, n = tmp.getLength(); i < n; i++)
402 {
403 Char16 c = tmp[i];
404
405 if (c <= 127)
406 tmp[i] = tolower(c);
407 }
408
409 return tmp;
|
410 mike 1.10 }
411
412 int CompareIgnoreCase(const char* s1, const char* s2)
413 {
414 while (*s1 && *s2)
415 {
416 int r = tolower(*s1++) - tolower(*s2++);
417
418 if (r)
419 return r;
420 }
421
422 if (*s2)
423 return -1;
424 else if (*s1)
425 return 1;
426
427 return 0;
|
428 mike 1.11 }
429
430 Boolean GetLine(istream& is, String& line)
431 {
432 line.clear();
433
434 Boolean gotChar = false;
435 char c;
436
437 while (is.get(c))
438 {
439 gotChar = true;
440
441 if (c == '\n')
442 break;
443
444 line.append(c);
445 }
446
447 return gotChar;
|
448 mike 1.1 }
449
450 PEGASUS_NAMESPACE_END
|