1 mike 1.27 //%/////////////////////////////////////////////////////////////////////////////
2 //
|
3 kumpf 1.41 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
|
5 mike 1.27 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 kumpf 1.41 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
10 mike 1.27 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
|
13 kumpf 1.41 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
14 mike 1.27 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
16 kumpf 1.41 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
19 mike 1.27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 //==============================================================================
23 //
24 // Author: Mike Brasher (mbrasher@bmc.com)
25 //
|
26 kumpf 1.39 // Modified By: Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
|
27 mike 1.27 //
28 //%/////////////////////////////////////////////////////////////////////////////
29
30
31 #include <cctype>
|
32 kumpf 1.64 #include <cstring>
|
33 mike 1.27 #include "String.h"
|
34 kumpf 1.43 #include "Array.h"
|
35 kumpf 1.48 #include "InternalException.h"
|
36 mike 1.27 #include <iostream>
|
37 kumpf 1.63 #include <fstream>
|
38 kumpf 1.61 #ifndef PEGASUS_REMOVE_DEPRECATED
|
39 kumpf 1.60 #include "System.h"
40 #endif
|
41 mike 1.27
|
42 mike 1.28 PEGASUS_USING_STD;
43
|
44 mike 1.27 PEGASUS_NAMESPACE_BEGIN
45
|
46 kumpf 1.39 ///////////////////////////////////////////////////////////////////////////////
47 //
|
48 kumpf 1.54 // CString
49 //
50 ///////////////////////////////////////////////////////////////////////////////
51
52 CString::CString()
53 : _rep(0)
54 {
55 }
56
57 CString::CString(const CString& cstr)
58 {
|
59 kumpf 1.59 _rep = (void*)new char[strlen((char*)cstr._rep)+1];
60 strcpy((char*)_rep, (char*)cstr._rep);
|
61 kumpf 1.54 }
62
63 CString::CString(char* cstr)
64 : _rep(cstr)
65 {
66 }
67
68 CString::~CString()
69 {
70 if (_rep)
|
71 kumpf 1.59 delete [] (char*)_rep;
|
72 kumpf 1.54 }
73
|
74 kumpf 1.56 CString& CString::operator=(const CString& cstr)
75 {
|
76 kumpf 1.59 _rep = (char*)new char[strlen((char*)cstr._rep)+1];
77 strcpy((char*)_rep, (char*)cstr._rep);
|
78 kumpf 1.56 return *this;
79 }
80
|
81 kumpf 1.54 CString::operator const char*() const
82 {
|
83 kumpf 1.59 return (char*)_rep;
|
84 kumpf 1.54 }
85
86 ///////////////////////////////////////////////////////////////////////////////
87 //
|
88 kumpf 1.39 // String
89 //
90 ///////////////////////////////////////////////////////////////////////////////
91
|
92 kumpf 1.37 const String String::EMPTY = String();
|
93 mike 1.27
|
94 kumpf 1.38 Uint32 _strnlen(const char* str, Uint32 n)
95 {
96 if (!str)
97 throw NullPointer();
98
99 for (Uint32 i=0; i<n; i++)
100 {
101 if (!*str)
102 {
103 return i;
104 }
105 }
106
107 return n;
108 }
109
110 Uint32 _strnlen(const Char16* str, Uint32 n)
111 {
112 if (!str)
113 throw NullPointer();
114
115 kumpf 1.38 for (Uint32 i=0; i<n; i++)
116 {
117 if (!*str)
118 {
119 return i;
120 }
121 }
122
123 return n;
124 }
125
|
126 kumpf 1.39 inline Uint32 _StrLen(const char* str)
|
127 mike 1.27 {
128 if (!str)
129 throw NullPointer();
130
131 return strlen(str);
132 }
133
|
134 kumpf 1.39 inline Uint32 _StrLen(const Char16* str)
|
135 mike 1.27 {
136 if (!str)
137 throw NullPointer();
138
139 Uint32 n = 0;
140
141 while (*str++)
142 n++;
143
144 return n;
145 }
146
|
147 kumpf 1.43 class StringRep
148 {
149 public:
150 StringRep()
151 {}
152 StringRep(const StringRep& r)
153 : c16a(r.c16a)
154 {}
155 StringRep(const Char16* str)
156 : c16a(str, _StrLen(str) + 1)
157 {}
158
159 Array<Char16> c16a;
160 };
161
|
162 mike 1.27 String::String()
163 {
|
164 kumpf 1.43 _rep = new StringRep;
165 _rep->c16a.append('\0');
|
166 mike 1.27 }
167
|
168 kumpf 1.39 String::String(const String& str)
|
169 mike 1.27 {
|
170 tony 1.66 if (str._rep != NULL)
171 {
|
172 kumpf 1.43 _rep = new StringRep(*str._rep);
|
173 tony 1.66 }
174 else
175 {
176 _rep = new StringRep();
177 }
|
178 kumpf 1.39 }
|
179 tony 1.66
|
180 mike 1.27
|
181 kumpf 1.39 String::String(const String& str, Uint32 n)
182 {
|
183 kumpf 1.43 _rep = new StringRep;
|
184 kumpf 1.55 assign(str.getChar16Data(), n);
|
185 kumpf 1.39 }
186
187 String::String(const Char16* str)
188 {
|
189 kumpf 1.43 _rep = new StringRep(str);
|
190 mike 1.27 }
191
|
192 kumpf 1.39 String::String(const Char16* str, Uint32 n)
193 {
|
194 kumpf 1.43 _rep = new StringRep;
|
195 kumpf 1.39 assign(str, n);
196 }
197
198 String::String(const char* str)
|
199 mike 1.27 {
|
200 kumpf 1.43 _rep = new StringRep;
|
201 kumpf 1.39 assign(str);
|
202 mike 1.27 }
203
|
204 kumpf 1.39 String::String(const char* str, Uint32 n)
|
205 mike 1.27 {
|
206 kumpf 1.43 _rep = new StringRep;
|
207 kumpf 1.39 assign(str, n);
208 }
|
209 mike 1.27
|
210 kumpf 1.39 String::~String()
211 {
|
212 kumpf 1.43 delete _rep;
|
213 mike 1.27 }
214
|
215 kumpf 1.39 String& String::operator=(const String& str)
|
216 mike 1.27 {
|
217 kumpf 1.39 return assign(str);
|
218 mike 1.27 }
219
|
220 kumpf 1.39 String& String::assign(const String& str)
|
221 mike 1.27 {
|
222 kumpf 1.43 _rep->c16a = str._rep->c16a;
|
223 kumpf 1.39 return *this;
|
224 mike 1.27 }
225
|
226 kumpf 1.39 String& String::assign(const Char16* str)
|
227 mike 1.27 {
|
228 kumpf 1.43 _rep->c16a.clear();
229 _rep->c16a.append(str, _StrLen(str) + 1);
|
230 mike 1.27 return *this;
231 }
232
233 String& String::assign(const Char16* str, Uint32 n)
234 {
|
235 kumpf 1.43 _rep->c16a.clear();
|
236 kumpf 1.38 Uint32 m = _strnlen(str, n);
|
237 kumpf 1.43 _rep->c16a.append(str, m);
238 _rep->c16a.append('\0');
|
239 mike 1.27 return *this;
240 }
241
|
242 kumpf 1.39 String& String::assign(const char* str)
|
243 mike 1.27 {
|
244 kumpf 1.43 _rep->c16a.clear();
|
245 kumpf 1.38
|
246 kumpf 1.39 Uint32 n = strlen(str) + 1;
|
247 kumpf 1.45 _rep->c16a.reserveCapacity(n);
|
248 mike 1.27
249 while (n--)
|
250 kumpf 1.43 _rep->c16a.append(*str++);
|
251 mike 1.27
252 return *this;
253 }
254
|
255 kumpf 1.39 String& String::assign(const char* str, Uint32 n)
|
256 mike 1.27 {
|
257 kumpf 1.43 _rep->c16a.clear();
|
258 mike 1.27
|
259 kumpf 1.39 Uint32 _n = _strnlen(str, n);
|
260 kumpf 1.45 _rep->c16a.reserveCapacity(_n + 1);
|
261 mike 1.27
|
262 kumpf 1.39 while (_n--)
|
263 kumpf 1.43 _rep->c16a.append(*str++);
|
264 mike 1.27
|
265 kumpf 1.43 _rep->c16a.append('\0');
|
266 mike 1.27
267 return *this;
268 }
269
|
270 kumpf 1.39 void String::clear()
271 {
|
272 kumpf 1.43 _rep->c16a.clear();
273 _rep->c16a.append('\0');
|
274 kumpf 1.39 }
275
|
276 kumpf 1.43 void String::reserveCapacity(Uint32 capacity)
|
277 kumpf 1.39 {
|
278 kumpf 1.45 _rep->c16a.reserveCapacity(capacity + 1);
|
279 kumpf 1.39 }
280
281 Uint32 String::size() const
282 {
|
283 kumpf 1.43 return _rep->c16a.size() - 1;
|
284 kumpf 1.39 }
285
|
286 kumpf 1.55 const Char16* String::getChar16Data() const
|
287 kumpf 1.39 {
|
288 kumpf 1.43 return _rep->c16a.getData();
|
289 kumpf 1.39 }
290
|
291 kumpf 1.54 CString String::getCString() const
|
292 mike 1.27 {
293 Uint32 n = size() + 1;
|
294 kumpf 1.54 char* str = new char[n];
|
295 mike 1.27 char* p = str;
|
296 kumpf 1.55 const Char16* q = getChar16Data();
|
297 mike 1.27
298 for (Uint32 i = 0; i < n; i++)
299 {
300 Uint16 c = *q++;
301 *p++ = char(c);
302
|
303 kumpf 1.54 //if (c & 0xff00)
304 // truncatedCharacters = true;
|
305 mike 1.27 }
306
|
307 kumpf 1.54 return CString(str);
|
308 kumpf 1.49 }
309
|
310 kumpf 1.53 Char16& String::operator[](Uint32 index)
|
311 mike 1.27 {
|
312 kumpf 1.53 if (index > size())
|
313 kumpf 1.49 throw IndexOutOfBoundsException();
|
314 mike 1.27
|
315 kumpf 1.53 return _rep->c16a[index];
|
316 mike 1.27 }
317
|
318 kumpf 1.53 const Char16 String::operator[](Uint32 index) const
|
319 mike 1.27 {
|
320 kumpf 1.53 if (index > size())
|
321 kumpf 1.49 throw IndexOutOfBoundsException();
|
322 mike 1.27
|
323 kumpf 1.53 return _rep->c16a[index];
|
324 mike 1.27 }
325
|
326 kumpf 1.39 String& String::append(const Char16& c)
327 {
|
328 kumpf 1.43 _rep->c16a.insert(_rep->c16a.size() - 1, c);
|
329 kumpf 1.39 return *this;
330 }
331
|
332 mike 1.27 String& String::append(const Char16* str, Uint32 n)
333 {
|
334 kumpf 1.38 Uint32 m = _strnlen(str, n);
|
335 kumpf 1.45 _rep->c16a.reserveCapacity(_rep->c16a.size() + m);
|
336 kumpf 1.43 _rep->c16a.remove(_rep->c16a.size() - 1);
337 _rep->c16a.append(str, m);
338 _rep->c16a.append('\0');
|
339 mike 1.27 return *this;
340 }
341
|
342 kumpf 1.39 String& String::append(const String& str)
|
343 mike 1.27 {
|
344 kumpf 1.55 return append(str.getChar16Data(), str.size());
|
345 mike 1.27 }
346
|
347 kumpf 1.53 void String::remove(Uint32 index, Uint32 size)
|
348 mike 1.27 {
|
349 kumpf 1.39 if (size == PEG_NOT_FOUND)
|
350 kumpf 1.53 size = this->size() - index;
|
351 mike 1.27
|
352 kumpf 1.53 if (index + size > this->size())
|
353 kumpf 1.49 throw IndexOutOfBoundsException();
|
354 mike 1.27
|
355 kumpf 1.39 if (size)
|
356 kumpf 1.53 _rep->c16a.remove(index, size);
|
357 mike 1.27 }
358
|
359 kumpf 1.53 String String::subString(Uint32 index, Uint32 length) const
|
360 mike 1.27 {
|
361 kumpf 1.53 if (index < size())
|
362 mike 1.27 {
|
363 kumpf 1.57 if ((length == PEG_NOT_FOUND) || (length > size() - index))
|
364 kumpf 1.53 length = size() - index;
|
365 mike 1.27
|
366 kumpf 1.55 return String(getChar16Data() + index, length);
|
367 mike 1.27 }
368 else
369 return String();
370 }
371
372 Uint32 String::find(Char16 c) const
373 {
|
374 kumpf 1.55 const Char16* first = getChar16Data();
|
375 mike 1.27
376 for (const Char16* p = first; *p; p++)
377 {
378 if (*p == c)
379 return p - first;
380 }
381
382 return PEG_NOT_FOUND;
383 }
384
|
385 kumpf 1.53 Uint32 String::find(Uint32 index, Char16 c) const
|
386 mike 1.30 {
|
387 kumpf 1.55 const Char16* data = getChar16Data();
|
388 mike 1.30
|
389 kumpf 1.53 for (Uint32 i = index, n = size(); i < n; i++)
|
390 mike 1.30 {
391 if (data[i] == c)
392 return i;
393 }
394
395 return PEG_NOT_FOUND;
396 }
397
|
398 mike 1.27 Uint32 String::find(const String& s) const
399 {
|
400 kumpf 1.55 const Char16* pSubStr = s.getChar16Data();
401 const Char16* pStr = getChar16Data();
|
402 mike 1.27 Uint32 subStrLen = s.size();
403 Uint32 strLen = size();
404
|
405 mike 1.30 if (subStrLen > strLen)
406 {
407 return PEG_NOT_FOUND;
408 }
409
|
410 mike 1.27 // loop to find first char match
411 Uint32 loc = 0;
412 for( ; loc <= (strLen-subStrLen); loc++)
413 {
414 if (*pStr++ == *pSubStr) // match first char
415 {
416 // point to substr 2nd char
417 const Char16* p = pSubStr + 1;
418
419 // Test remaining chars for equal
420 Uint32 i = 1;
421 for (; i < subStrLen; i++)
422 if (*pStr++ != *p++ )
423 {pStr--; break;} // break from loop
424 if (i == subStrLen)
425 return loc;
426 }
427 }
428 return PEG_NOT_FOUND;
429 }
430
431 mike 1.27 Uint32 String::reverseFind(Char16 c) const
432 {
|
433 kumpf 1.55 const Char16* first = getChar16Data();
434 const Char16* last = getChar16Data() + size();
|
435 mike 1.27
436 while (last != first)
437 {
438 if (*--last == c)
439 return last - first;
440 }
441
442 return PEG_NOT_FOUND;
443 }
444
|
445 kumpf 1.62 // ATTN-RK-P3-20020509: Define case-sensitivity for non-English characters
|
446 mike 1.27 void String::toLower()
447 {
|
448 kumpf 1.43 for (Char16* p = &_rep->c16a[0]; *p; p++)
|
449 mike 1.27 {
|
450 kumpf 1.46 if (*p <= PEGASUS_MAX_PRINTABLE_CHAR)
|
451 mike 1.27 *p = tolower(*p);
452 }
|
453 kumpf 1.39 }
454
|
455 kumpf 1.43 int String::compare(const String& s1, const String& s2, Uint32 n)
|
456 kumpf 1.39 {
|
457 kumpf 1.55 const Char16* s1c16 = s1.getChar16Data();
458 const Char16* s2c16 = s2.getChar16Data();
|
459 kumpf 1.39
460 while (n--)
|
461 mike 1.27 {
|
462 kumpf 1.43 int r = *s1c16++ - *s2c16++;
|
463 mike 1.27
464 if (r)
465 return r;
466 }
467
468 return 0;
469 }
470
|
471 kumpf 1.43 int String::compare(const String& s1, const String& s2)
|
472 mike 1.30 {
|
473 kumpf 1.55 const Char16* s1c16 = s1.getChar16Data();
474 const Char16* s2c16 = s2.getChar16Data();
|
475 kumpf 1.43
476 while (*s1c16 && *s2c16)
|
477 mike 1.30 {
|
478 kumpf 1.43 int r = *s1c16++ - *s2c16++;
|
479 mike 1.30
480 if (r)
481 return r;
482 }
483
|
484 kumpf 1.43 if (*s2c16)
|
485 mike 1.30 return -1;
|
486 kumpf 1.43 else if (*s1c16)
|
487 mike 1.30 return 1;
488
489 return 0;
490 }
491
|
492 kumpf 1.40 int String::compareNoCase(const String& s1, const String& s2)
493 {
|
494 kumpf 1.55 const Char16* _s1 = s1.getChar16Data();
495 const Char16* _s2 = s2.getChar16Data();
|
496 kumpf 1.40
497 while (*_s1 && *_s2)
498 {
499 int r;
500
|
501 kumpf 1.46 if (*_s1 <= PEGASUS_MAX_PRINTABLE_CHAR &&
502 *_s2 <= PEGASUS_MAX_PRINTABLE_CHAR)
|
503 kumpf 1.40 {
504 r = tolower(*_s1++) - tolower(*_s2++);
505 }
506 else
507 {
508 r = *_s1++ - *_s2++;
509 }
510
511 if (r)
512 return r;
513 }
514
515 if (*_s2)
516 return -1;
517 else if (*_s1)
518 return 1;
519
520 return 0;
521 }
522
|
523 kumpf 1.39 Boolean String::equal(const String& str1, const String& str2)
|
524 mike 1.27 {
|
525 kumpf 1.43 return String::compare(str1, str2) == 0;
|
526 mike 1.27 }
527
|
528 kumpf 1.39 Boolean String::equalNoCase(const String& str1, const String& str2)
|
529 mike 1.27 {
|
530 kumpf 1.39 if (str1.size() != str2.size())
531 return false;
532
|
533 kumpf 1.55 const Char16* p = str1.getChar16Data();
534 const Char16* q = str2.getChar16Data();
|
535 kumpf 1.39
536 Uint32 n = str1.size();
|
537 mike 1.27
|
538 kumpf 1.39 while (n--)
539 {
|
540 kumpf 1.46 if (*p <= PEGASUS_MAX_PRINTABLE_CHAR &&
541 *q <= PEGASUS_MAX_PRINTABLE_CHAR)
|
542 kumpf 1.39 {
543 if (tolower(*p++) != tolower(*q++))
544 return false;
545 }
546 else if (*p++ != *q++)
547 return false;
548 }
|
549 mike 1.28
|
550 kumpf 1.39 return true;
|
551 mike 1.27 }
552
|
553 kumpf 1.42
|
554 kumpf 1.65 #if 0
|
555 kumpf 1.42 // ATTN-RK-P3-20020603: This code is not completely correct
|
556 karl 1.36 // Wildcard String matching function that may be useful in the future
557 // The following code was provided by Bob Blair.
558
559 /* _StringMatch Match input MatchString against a GLOB style pattern
560 Note that MatchChar is the char type so that this source
561 in portable to different string types. This is an internal function
562
563 Results: The return value is 1 if string matches pattern, and
564 0 otherwise. The matching operation permits the following
565 special characters in the pattern: *?\[] (see the manual
566 entry for details on what these mean).
567
568 Side effects: None.
569 */
570
571 /* MatchChar defined as a separate entity because this function source used
572 elsewhere was an unsigned char *. Here we use Uint16 to maintain 16 bit
573 size.
574 */
575 typedef Uint16 MatchChar;
576
577 karl 1.36 inline Uint16 _ToLower(Uint16 ch)
578 {
|
579 kumpf 1.46 return ch <= PEGASUS_MAX_PRINTABLE_CHAR ? tolower(char(ch)) : ch;
|
580 karl 1.36 }
581
582 inline Boolean _Equal(MatchChar ch1, MatchChar ch2, int nocase)
583 {
584 if (nocase)
585 return _ToLower(ch1) == _ToLower(ch2);
586 else
587 return ch1 == ch2;
588 }
|
589 mike 1.28
|
590 kumpf 1.35
|
591 karl 1.36 static const MatchChar *
592 _matchrange(const MatchChar *range, MatchChar c, int nocase)
593 {
594 const MatchChar *p = range;
595 const MatchChar *rstart = range + 1;
596 const MatchChar *rend = 0;
597 MatchChar compchar;
598
|
599 kumpf 1.35 for (rend = rstart; *rend && *rend != ']'; rend++);
|
600 karl 1.36 if (*rend == ']') { // if there is an end to this pattern
|
601 kumpf 1.35 for (compchar = *rstart; rstart != rend; rstart++) {
|
602 karl 1.36 if (_Equal(*rstart, c, nocase))
|
603 kumpf 1.35 return ++rend;
604 if (*rstart == '-') {
605 rstart++;
606 if (c >= compchar && c <= *rstart)
607 return ++rend;
608 }
609 }
610 }
|
611 karl 1.36 return (const MatchChar *)0;
|
612 kumpf 1.35 }
613
614 static int
|
615 karl 1.36 _StringMatch(
616 const MatchChar *testString,
617 const MatchChar *pattern,
618 int nocase ) /* Ignore case if this is true */
619 {
620 const MatchChar *pat = pattern;
621 const MatchChar *str = testString;
|
622 kumpf 1.35 unsigned int done = 0;
623 unsigned int res = 0; // the result: 1 == match
624
625 while (!done) { // main loop walks through pattern and test string
626 //cerr << "Comparing <" << *pat << "> and <" << *str << ">" << endl;
627 if (!*pat) { //end of pattern
628 done = 1; // we're done
629 if (!*str) //end of test, too?
630 res = 1; // then we matched
631 } else { //Not end of pattern
632 if (!*str) { // but end of test
633 done = 1; // We're done
634 if (*pat == '*') // If pattern openends
635 res = 1; // then we matched
636 } else { //Not end of test
637 if (*pat == '*') { //Ambiguuity found
638 if (!*++pat) { //and it ends pattern
639 done = 1; // then we're done
640 res = 1; // and match
641 } else { //if it doesn't end
642 while (!done) { // until we're done
|
643 karl 1.36 if (_StringMatch(str, pat, nocase)) { // we recurse
|
644 kumpf 1.35 done = 1; //if it recurses true
645 res = 1; // we done and match
646 } else { //it recurses false
647 if (!*str) // see if test is done
648 done = 1; // yes: we done
649 else // not done:
650 str++; // keep testing
651 } // end test on recursive call
652 } // end looping on recursive calls
653 } // end logic when pattern is ambiguous
654 } else { //pattern not ambiguus
655 if (*pat == '?') { //pattern is 'any'
656 pat++, str++; // so move along
657 } else if (*pat == '[') { //see if it's a range
|
658 karl 1.36 pat = _matchrange(pat, *str, nocase); // and is a match
|
659 kumpf 1.35 if (!pat) { //It is not a match
660 done = 1; // we're done
|
661 kumpf 1.42 res = 0; // no match
|
662 kumpf 1.35 } else { //Range matches
663 str++, pat++; // keep going
664 }
665 } else { // only case left is individual characters
|
666 karl 1.36 if (!_Equal(*pat++, *str++, nocase)) // if they don't match
|
667 kumpf 1.35 done = 1; // bail.
668 }
669 } // end ("pattern is not ambiguous (*)" logic
670 } // end logic when pattern and string still have data
671 } // end logic when pattern still has data
672 } // end main loop
673 return res;
674 }
675
|
676 kumpf 1.39
|
677 kumpf 1.65 /** match matches a string against a GLOB style pattern.
678 Return trues if the String parameter matches the pattern. C-Shell style
679 glob matching is used.
680 @param str String to be matched against the pattern
681 @param pattern Pattern to use in the match
682 @return Boolean true if str matches pattern
683 The pattern definition is as follows:
684 <pre>
685 * Matches any number of any characters
686 ? Match exactly one character
687 [chars] Match any character in chars
688 [chara-charb] Match any character in the range between chara and charb
689 </pre>
690 The literal characters *, ?, [, ] can be included in a string by
691 escaping them with backslash "\". Ranges of characters can be concatenated.
692 <pre>
693 examples:
694 Boolean result = String::match("This is a test", "*is*");
695 Boolean works = String::match("abcdef123", "*[0-9]");
696 </pre>
697 */
|
698 karl 1.36 Boolean String::match(const String& str, const String& pattern)
699 {
700 return _StringMatch(
|
701 kumpf 1.55 (Uint16*)str.getChar16Data(), (Uint16*)pattern.getChar16Data(), 0) != 0;
|
702 karl 1.36 }
703
|
704 kumpf 1.65 /** matchNoCase Matches a String against a GLOB style pattern independent
705 of case.
706 Returns true if the str parameter matches the pattern. C-Shell style
707 glob matching is used. Ignore case in all comparisons. Case is
708 ignored in the match.
709 @parm str String containing the string to be matched\
710 @parm pattern GLOB style patterh to use in the match.
711 @return Boolean true if str matches patterh
712 @SeeAlso match
713 */
|
714 karl 1.36 Boolean String::matchNoCase(const String& str, const String& pattern)
715 {
716 return _StringMatch(
|
717 kumpf 1.55 (Uint16*)str.getChar16Data(), (Uint16*)pattern.getChar16Data(), 1) != 0;
|
718 kumpf 1.39 }
|
719 kumpf 1.65 #endif
|
720 kumpf 1.39
721
722 ///////////////////////////////////////////////////////////////////////////////
723 //
724 // String-related functions
725 //
726 ///////////////////////////////////////////////////////////////////////////////
727
728 Boolean operator==(const String& str1, const String& str2)
729 {
730 return String::equal(str1, str2);
731 }
732
733 Boolean operator==(const String& str1, const char* str2)
734 {
735 return String::equal(str1, str2);
736 }
737
738 Boolean operator==(const char* str1, const String& str2)
739 {
740 return String::equal(str1, str2);
741 kumpf 1.39 }
742
743 Boolean operator!=(const String& str1, const String& str2)
744 {
745 return !String::equal(str1, str2);
746 }
747
|
748 kumpf 1.47 PEGASUS_STD(ostream)& operator<<(PEGASUS_STD(ostream)& os, const String& str)
|
749 kumpf 1.39 {
|
750 kumpf 1.47 for (Uint32 i = 0, n = str.size(); i < n; i++)
|
751 kumpf 1.50 {
752 Uint16 code = str[i];
753
754 if (code > 0 && code <= PEGASUS_MAX_PRINTABLE_CHAR)
755 {
756 os << char(code);
757 }
758 else
759 {
760 // Print in hex format:
761 char buffer[8];
762 sprintf(buffer, "\\x%04X", code);
763 os << buffer;
764 }
765 }
|
766 kumpf 1.39
767 return os;
768 }
769
770 String operator+(const String& str1, const String& str2)
771 {
772 return String(str1).append(str2);
773 }
774
775 Boolean operator<(const String& str1, const String& str2)
776 {
|
777 kumpf 1.43 return String::compare(str1, str2) < 0;
|
778 kumpf 1.39 }
779
780 Boolean operator<=(const String& str1, const String& str2)
781 {
|
782 kumpf 1.43 return String::compare(str1, str2) <= 0;
|
783 kumpf 1.39 }
784
785 Boolean operator>(const String& str1, const String& str2)
786 {
|
787 kumpf 1.43 return String::compare(str1, str2) > 0;
|
788 kumpf 1.39 }
789
790 Boolean operator>=(const String& str1, const String& str2)
791 {
|
792 kumpf 1.43 return String::compare(str1, str2) >= 0;
|
793 kumpf 1.39 }
794
|
795 kumpf 1.61 #ifndef PEGASUS_REMOVE_DEPRECATED
|
796 kumpf 1.39 int CompareNoCase(const char* s1, const char* s2)
797 {
|
798 kumpf 1.60 return System::strcasecmp(s1, s2);
|
799 kumpf 1.39 }
|
800 kumpf 1.60 #endif
|
801 kumpf 1.39
|
802 mike 1.27 PEGASUS_NAMESPACE_END
|