source: trunk/src/cppbase/bs_string.cpp@ 422

Last change on this file since 422 was 421, checked in by pr, 11 years ago

Add find_first_of(char...)

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Author Date Id Revision
File size: 27.4 KB
Line 
1
2/*
3 *@@sourcefile bs_string.cpp:
4 * BSString implementation.
5 *
6 *@@header "cppbase\bs_string.h"
7 */
8
9/*
10 * This file Copyright (C) 1999-2015 Ulrich M”ller.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, in version 2 as it comes in the COPYING
14 * file of this distribution.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20
21#define OS2EMX_PLAIN_CHAR
22 // this is needed for "os2emx.h"; if this is defined,
23 // emx will define PSZ as _signed_ char, otherwise
24 // as unsigned char
25
26#define INCL_DOSSEMAPHORES
27#include <os2.h>
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <stdarg.h>
33
34#include "setup.h"
35
36#include "helpers\stringh.h"
37#include "helpers\xstring.h"
38
39// base includes
40#include "cppbase\bs_base.h"
41#include "cppbase\bs_string.h"
42#include "cppbase\bs_errors.h"
43
44#pragma hdrstop
45
46// #define dprintf printf
47
48DEFINE_CLASS(BSString, BSStringBase);
49
50/* ******************************************************************
51 *
52 * BSString implementation
53 *
54 ********************************************************************/
55
56/*
57 *@@ BSString:
58 * copy constructor to copy from
59 * another BSString. As opposed to the
60 * first version, you can specify a substring
61 * here.
62 *
63 * Characters are copied from s starting
64 * at ulPos. Copying is stopped at the end
65 * of s or if n characters have been copied.
66 */
67
68BSString::BSString(const BSString &s, // in: source string
69 size_type ulPos, // in: first pos to copy
70 size_type n) // in: maximum no. of chars to copy, defaults to npos
71 : BSStringBase(tBSString)
72{
73 STRINGLOCK;
74 // Init(); is called by parent already V0.9.20 (2002-07-03) [umoeller]
75 CopyFrom(s, ulPos, n);
76}
77
78/*
79 *@@ BSString:
80 * copy constructor to copy from a C string.
81 */
82
83BSString::BSString(const char *psz) // in: string to copy
84 : BSStringBase(tBSString)
85{
86 STRINGLOCK;
87 // Init(); is called by parent already V0.9.20 (2002-07-03) [umoeller]
88 CopyFrom(psz);
89}
90
91/*
92 *@@ BSString:
93 * copy constructor to extract a new
94 * BSString from a codepaged C string.
95 *
96 * Characters are copied starting at p1.
97 * Copying is stopped at p2, which is not
98 * included.
99 *
100 * Note: as far as I know, something like this
101 * is NOT defined with the C++ string class.
102 */
103
104BSString::BSString(const char *p1, const char *p2)
105 : BSStringBase(tBSString)
106{
107 STRINGLOCK;
108 // Init(); is called by parent already V0.9.20 (2002-07-03) [umoeller]
109 CopyFrom(p1, p2);
110}
111
112/*
113 *@@ BSString:
114 * copy constructor to convert from a
115 * UTF-8 BSUString, using the
116 * specified BSUniCodec for conversion.
117 *
118 *@@added V0.9.20 (2002-07-03) [umoeller]
119 */
120
121BSString::BSString(BSUniCodec *pCodec,
122 const BSUString &ustr)
123 : BSStringBase(tBSString)
124{
125 STRINGLOCK;
126
127 if (!pCodec)
128 throw BSExcptBase("pCodec is NULL.");
129
130 size_type st;
131 if (st = ustr.length())
132 {
133 pCodec->Uni2Codepage(*this,
134 ustr.GetBuffer(),
135 st);
136 }
137}
138
139/*
140 *@@ operator[]:
141 * returns the ul'th character of the
142 * string or 0 if ul is too large.
143 */
144
145char BSString::operator[](const size_type ul) // in: character offset
146 const
147{
148 STRINGLOCK;
149 if ( (_pBuf)
150 && (_pBuf->_str.psz)
151 && (ul < _pBuf->_str.ulLength)
152 )
153 return (_pBuf->_str.psz[ul]);
154
155 return ('\0');
156}
157
158/*
159 *@@ assign:
160 * assigns a codepaged BSString to this.
161 *
162 * This is also used internally for
163 * BSString::operator=.
164 *
165 * Returns *this.
166 *
167 *@@added V0.9.7 (2001-01-07) [umoeller]
168 */
169
170BSString& BSString::assign(const BSString &s)
171{
172 STRINGLOCK;
173 // avoid self assignment
174 if (_pBuf != s._pBuf)
175 {
176 FreeBuf();
177 CopyFrom(s);
178 }
179
180 return (*this);
181}
182
183/*
184 *@@ assign:
185 * assigns a part of the given codepaged
186 * BSString to this.
187 *
188 * Characters are copied from s starting
189 * at ulPos. Copying is stopped at the end
190 * of s or if n characters have been copied.
191 *
192 * Returns *this.
193 *
194 *@@added V0.9.7 (2001-01-07) [umoeller]
195 */
196
197BSString& BSString::assign(const BSString &s,
198 size_type ulPos, // in: start copy, defaults to 0
199 size_type n) // in: copy count, defaults to npos
200{
201 STRINGLOCK;
202 FreeBuf();
203 CopyFrom(s, ulPos, n);
204
205 return (*this);
206}
207
208/*
209 *@@ assign:
210 * assigns a codepaged C string to this.
211 *
212 * Returns *this.
213 *
214 *@@added V0.9.18 (2002-03-08) [umoeller]
215 */
216
217BSString& BSString::assign(const char *psz)
218{
219 STRINGLOCK;
220 FreeBuf();
221 CopyFrom(psz);
222
223 return (*this);
224}
225
226/*
227 *@@ assign:
228 * copies from a C string.
229 *
230 * Characters are copied starting at p1.
231 * Copying is stopped at p2, which is not
232 * included.
233 *
234 * Returns *this.
235 *
236 *@@added V0.9.18 (2002-03-08) [umoeller]
237 */
238
239BSString& BSString::assign(const char *p1, const char *p2)
240{
241 STRINGLOCK;
242 FreeBuf();
243 CopyFrom(p1, p2);
244
245 return (*this);
246}
247
248/*
249 *@@ assign:
250 * assigns the given single character to this.
251 *
252 * Returns *this.
253 *
254 *@@added V0.9.18 (2002-03-08) [umoeller]
255 */
256
257BSString& BSString::assign(char c) // in: character to copy
258{
259 STRINGLOCK;
260 FreeBuf();
261 CopyFrom(c);
262
263 return (*this);
264}
265
266/*
267 *@@ assignUtf8:
268 * assigns the given UTF-8 BSUString to this,
269 * using the specified BSUniCodec for conversion.
270 *
271 * Returns *this.
272 *
273 *@@added V0.9.18 (2002-03-08) [umoeller]
274 */
275
276BSString& BSString::assignUtf8(BSUniCodec *pCodec,
277 const BSUString &ustr)
278{
279 STRINGLOCK;
280 FreeBuf();
281
282 if (!pCodec)
283 throw BSExcptBase("pCodec is NULL.");
284
285 size_type st;
286 if (st = ustr.length())
287 {
288 pCodec->Uni2Codepage(*this,
289 ustr.GetBuffer(),
290 st);
291 }
292
293 return (*this);
294}
295
296/*
297 *@@ append:
298 * appends the given codepaged BSString to this.
299 *
300 * Returns *this.
301 *
302 *@@changed V0.9.7 (2001-01-15) [umoeller]: ClearShiftTable was missing
303 */
304
305BSString& BSString::append(const BSString &s) // in: string to append
306{
307 STRINGLOCK;
308 size_type ulSourceLen;
309 if (ulSourceLen = s.size())
310 {
311 // assert that we have a modifiable
312 // copy with enough space
313 reserve(ulSourceLen + size() + 1);
314 xstrcats(&_pBuf->_str, &s._pBuf->_str);
315 }
316
317 return (*this);
318}
319
320/*
321 *@@ append:
322 * appends the given codepaged C string to this.
323 *
324 * Returns *this.
325 */
326
327BSString& BSString::append(const char *psz) // in: string to append
328{
329 STRINGLOCK;
330 size_type ulSourceLen;
331 if ( (psz)
332 && (ulSourceLen = strlen(psz))
333 )
334 {
335 // assert that we have a modifiable
336 // copy with enough space
337 reserve(ulSourceLen + size() + 1);
338 xstrcat(&_pBuf->_str, psz, ulSourceLen);
339 }
340
341 return (*this);
342}
343
344/*
345 *@@ append:
346 * appends the given single character to this.
347 *
348 * Returns *this.
349 *
350 *@@changed V0.9.7 (2001-01-15) [umoeller]: now using xstrcatc
351 */
352
353BSString& BSString::append(char c) // in: character to append
354{
355 STRINGLOCK;
356 if (c)
357 {
358 // assert that we have a modifiable
359 // copy with enough space
360 reserve(1 + size() + 1);
361 xstrcatc(&_pBuf->_str, c);
362 }
363
364 return (*this);
365}
366
367/*
368 *@@ appendCP:
369 * assigns the given UTF-8 BSUString to this,
370 * using the specified BSUniCodec for conversion
371 * before appending.
372 *
373 * Returns *this.
374 *
375 *@@added V0.9.18 (2002-03-08) [umoeller]
376 */
377
378BSString& BSString::appendUtf8(BSUniCodec *pCodec,
379 const BSUString &s)
380{
381 STRINGLOCK;
382 if (!pCodec)
383 throw BSExcptBase("pCodec is NULL.");
384
385 size_type st;
386 if (st = s.length())
387 {
388 BSString strTemp;
389 pCodec->Uni2Codepage(strTemp,
390 s.GetBuffer(),
391 st);
392 append(strTemp);
393 }
394
395 return (*this);
396}
397
398/*
399 *@@ compare:
400 * returns 0 if the two strings are the
401 * same, -1 if "this" is smaller, 1 if
402 * "s" is smaller.
403 *
404 * As opposed to the standard compare,
405 * this only compares the first "n"
406 * characters of the member string,
407 * counting from ulPos.
408 *
409 * If ulPos is specified, the returned offset
410 * is from the beginning of the string, not
411 * from the offset.
412 */
413
414int BSString::compare(size_type ulPos,
415 size_type n,
416 const BSString &s)
417 const
418{
419 STRINGLOCK;
420 const BSString strTemp(*this, ulPos, n);
421 return (strTemp.compare(s));
422}
423
424/*
425 *@@ find:
426 * first version of find.
427 *
428 * Finds the first position of a substring in the string.
429 *
430 * The search is started at iPos, which defaults to 0.
431 * Returns BSString::npos if not found.
432 *
433 *@@changed V0.9.18 (2002-03-08) [umoeller]: now using strhmemfind
434 */
435
436size_type BSString::find(const BSString &strFind, // in: string to find
437 size_type ulPos) // in: offset to start at (defaults to 0)
438 const
439{
440 STRINGLOCK;
441 if ( (ulPos < size())
442 && (strFind.size())
443 )
444 {
445 // if this is the first time strFind is used as
446 // a "find" string, allocate a shift table...
447 if (strFind._pBuf->_pShiftTable == NULL)
448 {
449 strFind._pBuf->_pShiftTable = (size_t*)malloc(sizeof(size_t) * 256);
450 strFind._pBuf->_fRepeat = FALSE;
451 }
452
453 char *p;
454 if (p = (char*)strhmemfind(_pBuf->_str.psz + ulPos, // in: haystack
455 _pBuf->_str.ulLength - ulPos,
456 strFind._pBuf->_str.psz,
457 strFind._pBuf->_str.ulLength,
458 strFind._pBuf->_pShiftTable,
459 &strFind._pBuf->_fRepeat))
460 return (p - _pBuf->_str.psz);
461
462 /* char *p;
463 if (p = strstr(_pBuf->_str.psz + ulPos,
464 strFind._pBuf->_str.psz))
465 // found: calculate offset
466 return (p - _pBuf->_str.psz); */
467 }
468
469 return (npos);
470}
471
472/*
473 *@@ find:
474 * second version of find.
475 *
476 * Finds the first position of a substring in the string.
477 *
478 * The search is started at iPos, which defaults to 0.
479 * Returns BSString::npos if not found.
480 */
481
482size_type BSString::find(const char *pszFind, // in: string to find
483 size_type ulPos) // in: offset to start at (defaults to 0)
484 const
485{
486 STRINGLOCK;
487 if ( (ulPos < size())
488 && (pszFind)
489 && (*pszFind)
490 )
491 {
492 char *p;
493 if (p = strstr(_pBuf->_str.psz + ulPos,
494 pszFind))
495 // found: calculate offset
496 return (p - _pBuf->_str.psz);
497 }
498
499 return (npos);
500}
501
502/*
503 *@@ find:
504 * third version of find.
505 *
506 * Finds the first position of a character in the string.
507 * The search is started at iPos, which defaults to 0.
508 *
509 * Returns BSString::npos if not found.
510 */
511
512size_type BSString::find(char c, // in: character to find
513 size_type ulPos) // in: offset to start at (defaults to 0)
514 const
515{
516 STRINGLOCK;
517 if ( (ulPos < size())
518 && (c)
519 )
520 {
521 char *p;
522 if (p = strchr(_pBuf->_str.psz + ulPos, c))
523 // found: calculate offset
524 return (p - _pBuf->_str.psz);
525 }
526
527 return (npos);
528}
529
530/*
531 *@@ rfind:
532 * finds the last position of a character in the string.
533 *
534 * Returns BSString::npos if not found.
535 *
536 *@@changed V0.9.18 (2002-03-08) [umoeller]: rewritten using strrchr
537 */
538
539size_type BSString::rfind(char c, // in: character to find
540 size_type ulPos) // in: position to search from (from the right);
541 // defaults to npos (means end of string)
542 const
543{
544 STRINGLOCK;
545 size_type Size;
546
547 if ( (Size = size())
548 && (c)
549 )
550 {
551 const char *p;
552 if ( (ulPos == npos)
553 || (ulPos > Size)
554 )
555 p = _pBuf->_str.psz;
556 else
557 p = _pBuf->_str.psz + ulPos;
558
559 if (p = strrchr(p, c))
560 // found: calculate offset
561 return (p - _pBuf->_str.psz);
562
563 /* char *p;
564
565 if ( (ulPos == npos)
566 || (ulPos > Size)
567 )
568 p = _str.psz + Size - 1;
569 else
570 p = _str.psz + ulPos;
571
572 // search backwards
573 for (;
574 p >= _str.psz;
575 p--)
576 if (*p == c)
577 return (p - _str.psz);
578 */
579 }
580
581 return (npos);
582}
583
584/*
585 *@@ find_first_of:
586 * finds the first character in the member
587 * string which is the same as "c".
588 *
589 * The search is started at ulPos, which
590 * defaults to 0.
591 *
592 * Returns BSString::npos if not found.
593 *
594 *@@added V1.0.21 (2015-01-29) [pr]
595 */
596
597size_type BSString::find_first_of(char c, // in: character to find
598 size_type ulPos) // in: start of search (defaults to 0)
599 const
600{
601 STRINGLOCK;
602 size_type Size = size();
603
604 if ( (ulPos < Size)
605 && (c)
606 )
607 {
608 char *p;
609 size_type ul;
610 for (p = _pBuf->_str.psz + ulPos, ul = ulPos;
611 ul < Size;
612 ++p, ++ul)
613 {
614 if (*p != c)
615 return (ul);
616 }
617 }
618
619 // not found:
620 return (npos);
621}
622
623/*
624 *@@ find_first_of:
625 * finds the first character in the member
626 * string which is one of the chars in achChars.
627 *
628 * The search is started at ulPos, which
629 * defaults to 0.
630 *
631 * Returns BSString::npos if not found.
632 *
633 *@@added V0.9.7 (2001-01-07) [umoeller]
634 */
635
636size_type BSString::find_first_of(const char *achChars, // in: chars array to look for
637 size_type ulPos) // in: start of search (defaults to 0)
638 const
639{
640 STRINGLOCK;
641 size_type Size = size();
642
643 if ( (ulPos < Size)
644 && (achChars)
645 && (*achChars)
646 )
647 {
648 char *p;
649 size_type ul;
650 for (p = _pBuf->_str.psz + ulPos, ul = ulPos;
651 ul < Size;
652 ++p, ++ul)
653 {
654 if (strchr(achChars, *p))
655 // *p is in achChars:
656 return (ul);
657 }
658 }
659
660 // not found:
661 return (npos);
662}
663
664/*
665 *@@ find_first_not_of:
666 * finds the first character in the member
667 * string which is different from "c".
668 *
669 * The search is started at ulPos, which
670 * defaults to 0.
671 *
672 * Returns BSString::npos if not found.
673 */
674
675size_type BSString::find_first_not_of(char c, // in: character to ignore
676 size_type ulPos) // in: start of search (defaults to 0)
677 const
678{
679 STRINGLOCK;
680 size_type Size = size();
681
682 if ( (ulPos < Size)
683 && (c)
684 )
685 {
686 char *p;
687 size_type ul;
688 for (p = _pBuf->_str.psz + ulPos, ul = ulPos;
689 ul < Size;
690 ++p, ++ul)
691 {
692 if (*p != c)
693 return (ul);
694 }
695 }
696
697 // not found:
698 return (npos);
699}
700
701/*
702 *@@ find_first_not_of:
703 * finds the first character in the member
704 * string which is NOT one of the chars in achChars.
705 *
706 * The search is started at ulPos, which
707 * defaults to 0.
708 *
709 * Returns BSString::npos if not found.
710 *
711 *@@added V0.9.7 (2001-01-07) [umoeller]
712 */
713
714size_type BSString::find_first_not_of(const char *achChars, // in: characters to ignore
715 size_type ulPos) // in: start of search (defaults to 0)
716 const
717{
718 STRINGLOCK;
719 size_type Size = size();
720
721 if ( (ulPos < Size)
722 && (achChars)
723 && (*achChars)
724 )
725 {
726 char *p;
727 size_type ul;
728 for (p = _pBuf->_str.psz + ulPos, ul = ulPos;
729 ul < Size;
730 ++p, ++ul)
731 {
732 if (!strchr(achChars, *p))
733 // *p is NOT in achChars:
734 return (ul);
735 }
736 }
737
738 // not found:
739 return (npos);
740}
741
742/*
743 *@@ replace:
744 * replaces "nThis" characters, starting at
745 * position ulPosThis, in the member string
746 * with "strReplace".
747 *
748 * Returns *this.
749 *
750 *@@added V0.9.7 (2001-01-15) [umoeller]
751 */
752
753BSString& BSString::replace(size_type ulPosThis, // in: ofs of first char to replace
754 size_type nThis, // in: char count to replace
755 const BSString &strReplace) // in: string to replace with
756{
757 STRINGLOCK;
758 if (size())
759 {
760 reserve(0);
761
762 if (nThis == npos)
763 // I'm not sure if the C++ string allows setting nThis to npos...
764 // but we'll just support it, it won't hurt
765 nThis = _pBuf->_str.ulLength - ulPosThis;
766
767 xstrrpl(&_pBuf->_str,
768 ulPosThis,
769 nThis,
770 strReplace._pBuf->_str.psz,
771 strReplace._pBuf->_str.ulLength);
772 }
773
774 return (*this);
775}
776
777/*
778 *@@ substr:
779 * creates a new string containing parts of
780 * the member string.
781 *
782 * Copying is started at offset ulPos, from
783 * which n characters are copied. If
784 * (n == BSString::npos), all remaining characters
785 * are copied.
786 *
787 * This always returns a string, but it may be
788 * empty if invalid parameters are specified.
789 */
790
791BSString BSString::substr(size_type ulPos, // in: start pos, defaults to 0
792 size_type n) // in: no. of characters to copy,
793 // defaults to npos (== up to rest of string)
794 const
795{
796 STRINGLOCK;
797 return BSString(*this, ulPos, n);
798}
799
800/*
801 *@@ _find_word:
802 * searches for strWord in the string, whose offset
803 * is returned if found (or BSString::npos if not).
804 *
805 * As opposed to BSString::find, this finds strWord
806 * only if it is a "word". A search string is
807 * considered a word if the character _before_
808 * it is in pcszBeginChars and the char _after_
809 * it is in pcszEndChars.
810 *
811 * Example:
812 + BSString str("This is an example.");
813 + str._find_word(, "is");
814 *
815 * returns the offset of "is", but not the "is" in "This".
816 *
817 * Note: as far as I know, something like this
818 * is NOT defined with the C++ string class.
819 */
820
821size_type BSString::_find_word(BSString &strFind,
822 size_type ulPos, // defaults to 0
823 const char *pcszBeginChars, // = "\x0d\x0a ()/\\-,.",
824 const char *pcszEndChars) // = "\x0d\x0a ()/\\-,.:;")
825 const
826{
827 STRINGLOCK;
828 if ( (ulPos < size())
829 && (strFind.size())
830 )
831 {
832 // if this is the first time strFind is used as
833 // a "find" string, allocate a shift table...
834 if (strFind._pBuf->_pShiftTable == NULL)
835 {
836 strFind._pBuf->_pShiftTable = (size_t*)malloc(sizeof(size_t) * 256);
837 strFind._pBuf->_fRepeat = FALSE;
838 }
839
840 char *p;
841 if (p = xstrFindWord(&_pBuf->_str,
842 ulPos,
843 &strFind._pBuf->_str,
844 strFind._pBuf->_pShiftTable,
845 (PBOOL)&strFind._pBuf->_fRepeat,
846 pcszBeginChars,
847 pcszEndChars))
848 // found: calculate offset
849 return (p - _pBuf->_str.psz);
850 }
851
852 return (npos);
853}
854
855/*
856 *@@ _find_word:
857 * second version of _find_word, which takes
858 * a const PSZ as input.
859 *
860 * Note: as far as I know, something like this
861 * is NOT defined with the C++ string class.
862 */
863
864size_type BSString::_find_word(const char *pszFind,
865 size_type ulPos, // defaults to 0
866 const char *pcszBeginChars, // = "\x0d\x0a ()/\\-,.",
867 const char *pcszEndChars) // = "\x0d\x0a ()/\\-,.:;")
868 const
869{
870 STRINGLOCK;
871 if ( (ulPos < size())
872 && (pszFind)
873 && (*pszFind)
874 )
875 {
876 char *p;
877 if (p = strhFindWord(_pBuf->_str.psz + ulPos,
878 pszFind,
879 pcszBeginChars,
880 pcszEndChars))
881 // found: calculate offset
882 return (p - _pBuf->_str.psz);
883 }
884
885 return (npos);
886}
887
888/*
889 *@@ _extract_word:
890 * extracts a word from the member string,
891 * which is written into strTarget.
892 *
893 * Returns 1 (TRUE) if the specified word still
894 * existed or 0 otherwise.
895 *
896 * Note: as far as I know, something like this
897 * is NOT defined with the C++ string class.
898 *
899 *@@added V0.9.7 (2001-01-07) [umoeller]
900 */
901
902int BSString::_extract_word(unsigned long ulIndex, // in: word index
903 BSString &strTarget, // out: word
904 size_type ulPos, // defaults to 0
905 const char *pcszBeginChars, // = "\x0d\x0a ()/\\-,.",
906 const char *pcszEndChars) // = "\x0d\x0a ()/\\-,.:;")
907 const
908{
909 STRINGLOCK;
910 int rc = 0;
911
912 unsigned long ul = 0;
913 for (ul = 0;
914 ul <= ulIndex;
915 ++ul)
916 {
917 ULONG ulStart = find_first_not_of(pcszBeginChars, ulPos);
918 if (ulStart == npos)
919 break;
920 else
921 {
922 ULONG ulEnd = find_first_of(pcszEndChars, ulStart + 1);
923 if (ulEnd == npos)
924 {
925 if (ul == ulIndex)
926 {
927 // copy till the end
928 strTarget.assign(*this,
929 ulStart);
930 rc = 1;
931 break;
932 }
933 else
934 // not there yet: get outta here
935 break;
936 }
937 else
938 if (ul == ulIndex)
939 {
940 // that's the word we want:
941 strTarget.assign(*this,
942 ulStart,
943 (ulEnd - ulStart));
944 rc = 1;
945 break;
946 }
947 else
948 // we need more words:
949 ulPos = ulEnd;
950 // and search on
951 }
952 }
953
954 return (rc);
955}
956
957/*
958 *@@ _format:
959 * this removes all EOL's and double spaces.
960 * Also removes leading and trailing spaces.
961 *
962 * Note: as far as I know, something like this
963 * is NOT defined with the C++ string class.
964 */
965
966VOID BSString::_format()
967{
968 STRINGLOCK;
969 reserve(0);
970
971 if (_pBuf && _pBuf->_str.psz)
972 {
973 PSZ p;
974 // replace \n, \r with spaces (length is constant)
975 for (p = _pBuf->_str.psz;
976 p < _pBuf->_str.psz + _pBuf->_str.ulLength;
977 ++p)
978 {
979 if (*p == 0x0a)
980 *p = ' ';
981 else if (*p == 0x0d)
982 *p = ' ';
983 }
984
985 // remove double spaces
986 for (p = _pBuf->_str.psz;
987 p < _pBuf->_str.psz + _pBuf->_str.ulLength;
988 ++p)
989 {
990 if ((*p == ' ') && (*(p+1) == ' '))
991 {
992 PSZ p2 = p;
993 while (*p2)
994 {
995 *p2 = *(p2+1);
996 ++p2;
997 }
998 --(_pBuf->_str.ulLength);
999 --p;
1000 }
1001 }
1002
1003 // remove leading spaces
1004 for (p = _pBuf->_str.psz;
1005 p < _pBuf->_str.psz + _pBuf->_str.ulLength;
1006 ++p)
1007 {
1008 if (*p == ' ')
1009 {
1010 PSZ p2 = p;
1011 while (*p2)
1012 {
1013 *p2 = *(p2+1);
1014 ++p2;
1015 }
1016 _pBuf->_str.ulLength--;
1017 }
1018 else
1019 break;
1020 }
1021
1022 // remove trailing spaces
1023 for (p = _pBuf->_str.psz + _pBuf->_str.ulLength - 1;
1024 p > _pBuf->_str.psz;
1025 p--)
1026 {
1027 if (*p == ' ')
1028 {
1029 *p = 0;
1030 _pBuf->_str.ulLength--;
1031 }
1032 else
1033 break;
1034 }
1035 }
1036}
1037
1038int operator==(const BSString &s1, const BSString &s2)
1039{
1040 return (s1.compare(s2) == 0);
1041}
1042
1043int operator==(const char *psz1, const BSString &s2)
1044{
1045 return (s2.compare(psz1) == 0);
1046}
1047
1048int operator==(const BSString &s1, const char *psz2)
1049{
1050 return (s1.compare(psz2) == 0);
1051}
1052
1053int operator!=(const BSString &s1, const BSString &s2)
1054{
1055 return (s1.compare(s2) != 0);
1056}
1057
1058int operator!=(const char *psz1, const BSString &s2)
1059{
1060 return (s2.compare(psz1) != 0);
1061}
1062
1063int operator!=(const BSString &s1, const char *psz2)
1064{
1065 return (s1.compare(psz2) != 0);
1066}
1067
1068int operator<(const BSString &s1, const BSString &s2)
1069{
1070 return (s1.compare(s2) < 0);
1071}
1072
1073BSString operator+(const BSString &s1, const BSString &s2)
1074{
1075 BSString str(s1);
1076 str.append(s2);
1077 return (str);
1078}
1079
1080BSString operator+(const char *psz1, const BSString &s2)
1081{
1082 BSString str(psz1);
1083 str.append(s2);
1084 return (str);
1085}
1086
1087BSString operator+(const BSString &s1, const char *psz2)
1088{
1089 BSString str(s1);
1090 str.append(psz2);
1091 return (str);
1092}
1093
1094
1095// test case
1096
1097/* int main()
1098{
1099 BSString str1("This is a test string."),
1100 str2(str1, 0);
1101
1102 printf("Original was: %s\n", str1.c_str());
1103 printf("Second is: %s\n", str2.c_str());
1104
1105 str2 = str1 + " Now we appended something.";
1106 printf("Third is: %s\n", str2.c_str());
1107
1108 BSString strFind = "e";
1109 BSString strRepl = "DJASDKL™ASDPO(u";
1110 ULONG ulPos = 0;
1111 while (str2._find_replace(strFind, strRepl, &ulPos)
1112 != string::npos)
1113 ;
1114
1115 printf("After repl: %s\n", str2.c_str());
1116
1117 return (0);
1118}
1119*/
Note: See TracBrowser for help on using the repository browser.