xref: /AOO41X/main/soltools/support/simstr.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org 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 Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_soltools.hxx"
30 
31 
32 #include <simstr.hxx>
33 
34 #include <string.h>  // strlen(), memcpy(), memset()
35 #include <ctype.h>   // tolower()
36 #include <limits.h>  // INT_MAX
37 
38 const char NULCH = '\0';
39 const int  NO_POS = -1;
40 
41 
42 Simstr::Simstr(const char * s_)
43 {
44    if (s_ == 0)
45       {
46          len = 0;
47          sz = new char[1];
48          *sz = 0;
49       }
50    else
51       {
52          len = strlen(s_);
53          sz = new char[len+1];
54          memcpy(sz,s_,len+1);
55       }
56 }
57 
58 Simstr::Simstr(const char * anybytes, int  nrOfBytes)
59 {
60     if (anybytes == 0)
61     {
62 	    len = 0;
63 		sz = new char[1];
64 		*sz = 0;
65         return;
66     }
67 
68     int slen = static_cast<int>( strlen(anybytes) );
69 
70     len =  slen < nrOfBytes
71                   ? slen
72                   : nrOfBytes;
73     sz = new char[len+1];
74     memcpy( sz, anybytes, len );
75     *( sz + len ) = 0;
76 }
77 
78 Simstr::Simstr(char c, int anzahl)
79 {
80    if (anzahl < 1)
81       {
82          len = 0;
83          sz = new char[1];
84          *sz = 0;
85       }
86    else
87       {
88          len = anzahl;
89          sz = new char[len+1];
90          memset(sz,c,anzahl);
91          sz[len] = 0;
92       }
93 }
94 
95 Simstr::Simstr( const char *   anybytes,
96 				int            firstBytesPos,
97 				int            nrOfBytes)
98 {
99    unsigned slen = strlen(anybytes);
100    if (anybytes == 0 || slen <= unsigned(firstBytesPos))
101 	  {
102 		 len = 0;
103 		 sz = new char[1];
104 		 *sz = 0;
105 	  }
106    else
107 	  {
108          int maxLen = slen - unsigned(firstBytesPos);
109          len =  maxLen < nrOfBytes
110                   ? maxLen
111                   : nrOfBytes;
112          sz = new char[len+1];
113          memcpy(sz,anybytes+firstBytesPos,len);
114          *(sz+len) = 0;
115       }
116 }
117 
118 
119 Simstr::Simstr(const Simstr & S)
120 {
121    len = S.len;
122    sz = new char[len+1];
123    memcpy(sz,S.sz,len+1);
124 }
125 
126 Simstr & Simstr::operator=(const Simstr & S)
127 {
128    if (sz == S.sz)
129       return *this;
130 
131    delete [] sz;
132 
133    len = S.len;
134    sz = new char[len+1];
135    memcpy(sz,S.sz,len+1);
136 
137    return *this;
138 }
139 
140 Simstr::~Simstr()
141 {
142    delete [] sz;
143 }
144 
145 char &
146 Simstr::ch(int  n)
147 {
148    static char nullCh = NULCH;
149    nullCh = NULCH;
150    if (n >= long(len) || n < 0)
151       return nullCh;
152    else
153       return sz[unsigned(n)];
154 }
155 
156 const Simstr &
157 Simstr::null_()
158 {
159     static Simstr aNull_;
160     return aNull_;
161 }
162 
163 
164 Simstr
165 Simstr::operator+(const Simstr & S) const
166 {
167    Simstr ret = sz;
168    ret.push_back(S);
169    return ret;
170 }
171 
172 Simstr &
173 Simstr::operator+=(const Simstr & S)
174 {
175    push_back(S);
176    return *this;
177 }
178 
179 Simstr &
180 Simstr::operator+=(const char * s_)
181 {
182     Simstr a(s_);
183     push_back(a);
184     return *this;
185 }
186 
187 
188 // REL
189 
190 bool
191 Simstr::operator==(const Simstr & S) const
192 { return !strcmp(sz,S.sz) ? true : false; }
193 
194 bool
195 Simstr::operator!=(const Simstr & S) const
196 { return strcmp(sz,S.sz) ? true : false; }
197 
198 bool
199 Simstr::operator<(const Simstr & S) const
200 { return (strcmp(sz,S.sz) < 0) ? true : false; }
201 
202 bool
203 Simstr::operator>(const Simstr & S) const
204 { return (strcmp(sz,S.sz) > 0) ? true : false; }
205 
206 bool
207 Simstr::operator<=(const Simstr & S) const
208 { return (strcmp(sz,S.sz) <= 0) ? true : false; }
209 
210 bool
211 Simstr::operator>=(const Simstr & S) const
212 { return (strcmp(sz,S.sz) >= 0) ? true : false; }
213 
214 
215 
216 
217 // **************          LIST - Funktionen        *****************
218 
219 
220 // Einzelzugriff
221 
222 char
223 Simstr::get(int  n) const     { return (n >= len || n < 0) ? 0 : sz[n]; }
224 
225 char
226 Simstr::get_front() const        { return sz[0]; }
227 
228 char
229 Simstr::get_back() const        { return  len ? sz[len-1] : 0; }
230 
231 Simstr
232 Simstr::get(int  startPos, int  anzahl) const
233 {
234    if (startPos >= len || startPos < 0 || anzahl < 1)
235       return "";
236 
237    int anz = len - startPos < anzahl ? len - startPos : anzahl;
238 
239    Simstr ret(' ',anz);
240    memcpy(ret.sz, sz+startPos, anz);
241    return ret;
242 }
243 
244 Simstr
245 Simstr::get_front(int  anzahl) const
246 {
247    int anz = len < anzahl ? len : anzahl;
248    if (anz < 1)
249       return "";
250 
251    Simstr ret(' ',anz);
252    memcpy(ret.sz, sz, anz);
253    return ret;
254 }
255 
256 Simstr
257 Simstr::get_back(int  anzahl) const
258 {
259    int anz = len < anzahl ? len : anzahl;
260    if (anz < 1)
261       return "";
262    int start = len-anz;
263 
264    Simstr ret(' ',anz);
265    memcpy(ret.sz, sz+start, anz);
266    return ret;
267 }
268 
269 Simstr
270 Simstr::get_first_token(char c) const
271 {
272    int posc = pos_first(c);
273    if (posc != NO_POS)
274       return get_front(posc);
275    else
276       return sz;
277 }
278 
279 Simstr
280 Simstr::get_last_token(char c) const
281 {
282    int posc = pos_last(c);
283    if (posc != NO_POS)
284       return get_back(len-posc-1);
285    else
286       return sz;
287 }
288 
289 
290 
291 // Insert
292 
293 void
294 Simstr::insert(int  pos, char c)
295 {
296    if (pos < 0 || pos > len)
297       return;
298 
299    char * result = new char[len+2];
300 
301    memcpy(result,sz,pos);
302    result[pos] = c;
303    memcpy(result+pos+1,sz+pos,len-pos+1);
304 
305    delete [] sz;
306    sz = result;
307    len++;
308 }
309 
310 void
311 Simstr::push_front(char c)
312 {
313    char * result = new char[len+2];
314 
315    result[0] = c;
316    memcpy(result+1,sz,len+1);
317 
318    delete [] sz;
319    sz = result;
320    len++;
321 }
322 
323 void
324 Simstr::push_back(char c)
325 {
326    char * result = new char[len+2];
327 
328    memcpy(result,sz,len);
329    result[len] = c;
330    result[len+1] = 0;
331 
332    delete [] sz;
333    sz = result;
334    len++;
335 }
336 
337 void
338 Simstr::insert(int  pos, const Simstr & S)
339 {
340    if (pos < 0 || pos > len)
341       return;
342 
343    char * result = new char[len+1+S.len];
344 
345    memcpy(result,sz,pos);
346    memcpy(result+pos,S.sz,S.len);
347    memcpy(result+pos+S.len,sz+pos,len-pos+1);
348 
349    delete [] sz;
350    sz = result;
351    len += S.len;
352 }
353 
354 void
355 Simstr::push_front(const Simstr & S)
356 {
357    char * result = new char[len+1+S.len];
358 
359    memcpy(result,S.sz,S.len);
360    memcpy(result+S.len,sz,len+1);
361 
362    delete [] sz;
363    sz = result;
364    len += S.len;
365 }
366 
367 void
368 Simstr::push_back(const Simstr & S)
369 {
370    char * result = new char[len+1+S.len];
371 
372    memcpy(result,sz,len);
373    memcpy(result+len,S.sz,S.len+1);
374 
375    delete [] sz;
376    sz = result;
377    len += S.len;
378 }
379 
380 
381 // Remove
382 
383 void
384 Simstr::remove(int  pos, int  anzahl)
385 {
386    if (pos >= len || pos < 0 || anzahl < 1)
387       return;
388 
389 	int anz = len - pos < anzahl ? len - pos : anzahl;
390 
391 	char * result = new char[len-anz+1];
392 
393 	memcpy(result,sz,pos);
394    memcpy(result+pos,sz+pos+anz,len-pos-anz+1);
395 
396    delete [] sz;
397    sz = result;
398    len -= anz;
399 }
400 
401 void
402 Simstr::remove_trailing_blanks()
403 {
404 	int newlen = len-1;
405 	for ( ; newlen > 1 && sz[newlen] <= 32; --newlen ) {}
406 
407 	if (newlen < len-1)
408     	remove ( newlen+1, len-newlen);
409 }
410 
411 void
412 Simstr::pop_front(int  anzahl)
413 {
414    if (anzahl < 1)
415       return;
416    int anz = len < anzahl ? len : anzahl;
417 
418    char * result = new char[len-anz+1];
419 
420    memcpy(result,sz+anz,len-anz+1);
421 
422    delete [] sz;
423    sz = result;
424    len -= anz;
425 }
426 
427 void
428 Simstr::pop_back(int  anzahl)
429 {
430    if (anzahl < 1)
431       return;
432 
433    int anz = len < anzahl ? len : anzahl;
434 
435    char * result = new char[len-anz+1];
436 
437    memcpy(result,sz,len-anz);
438    result[len-anz] = 0;
439 
440    delete [] sz;
441    sz = result;
442    len -= anz;
443 }
444 
445 void
446 Simstr::rem_back_from(int  removeStartPos)
447 {
448    if (removeStartPos != NO_POS)
449       pop_back(len-removeStartPos);
450 }
451 
452 void
453 Simstr::remove_all(char c)
454 {
455    if (!len)
456       return;
457    char * result = new char[len];
458    int i,j=0;
459    for (i = 0; i < len; i++)
460        if (sz[i] != c)
461           result[j++] = sz[i];
462 
463    delete [] sz;
464    sz = new char[j+1];
465    memcpy(sz,result,j);
466    sz[j] = 0;
467    len = j;
468    delete [] result;
469 }
470 
471 void
472 Simstr::remove_all(const Simstr & S)
473 {
474    int  pos;
475    while ( (pos=pos_first(S)) != NO_POS )
476       remove(pos,S.len);
477 }
478 
479 void
480 Simstr::strip(char c)
481 {
482 	int start = 0;
483    if (c == ' ')
484    {  // Sonderbehandlung: SPC entfernt auch TABs:
485    	while ( start < len
486                  ?  sz[start] == ' '
487                     || sz[start] == '\t'
488                  :  false )
489 	   	start++;
490    }
491    else
492    {
493    	while (start < len && sz[start] == c)
494 	   	start++;
495    }
496 
497 	int ende = len-1;
498    if (c == ' ')
499    {  // Sonderbehandlung: SPC entfernt auch TABs:
500    	while ( ende >= start
501                  ?  sz[ende] == ' '
502                     || sz[ende] == '\t'
503                  :  false  )
504 	   	ende--;
505    }
506    else
507    {
508    	while (ende >= start && sz[ende] == c)
509 	   	ende--;
510    }
511 	*this = get(start,ende-start+1);
512 }
513 
514 void
515 Simstr::empty()
516 {
517    if (len > 0)
518    {
519       delete [] sz;
520       sz = new char[1];
521       *sz = 0;
522       len = 0;
523    }
524 }
525 
526 Simstr
527 Simstr::take_first_token(char c)
528 {
529    Simstr ret;
530    int pos = pos_first(c);
531    if (pos != NO_POS)
532       {
533          ret = get_front(pos);
534          pop_front(pos+1);
535       }
536    else
537       {
538          ret = sz;
539          delete [] sz;
540          sz = new char[1];
541          *sz = NULCH;
542          len = 0;
543       }
544 
545    return ret;
546 }
547 
548 Simstr
549 Simstr::take_last_token(char c)
550 {
551    Simstr ret;
552    int pos = pos_last(c);
553    if (pos != NO_POS)
554       {
555          ret = get_back(len-pos-1);
556          pop_back(len-pos);
557       }
558    else
559       {
560          ret = sz;
561          delete [] sz;
562          sz = new char[1];
563          *sz = NULCH;
564          len = 0;
565       }
566 
567    return ret;
568 }
569 
570 
571 
572 // Find
573 
574 int
575 Simstr::pos_first(char c) const
576 {
577    int i = 0;
578    for (i = 0; i < len ? sz[i] != c : false; i++) ;
579    if (i >= len)
580       return NO_POS;
581    else
582       return i;
583 }
584 
585 int
586 Simstr::pos_first_after( char           c,
587                          int            startSearchPos) const
588 {
589    int i = 0;
590    if (startSearchPos >= i)
591       i = startSearchPos+1;
592    for (; i < len ? sz[i] != c : false; i++) ;
593    if (i >= len)
594       return NO_POS;
595    else
596       return i;
597 }
598 
599 
600 int
601 Simstr::pos_last(char c) const
602 {
603    int i = 0;
604    for (i = len-1; i >= 0 ? sz[i] != c : false; i--) ;
605    if (i < 0)
606       return NO_POS;
607    else
608       return i;
609 }
610 
611 int
612 Simstr::pos_first(const Simstr & S) const
613 {
614    char * ptr = strstr(sz,S.sz);
615    if (ptr)
616       return int(ptr-sz);
617    else
618       return NO_POS;
619 }
620 
621 int
622 Simstr::pos_last(const Simstr & S) const
623 {
624    Simstr vgl;
625    int i;
626    for (i = len-S.len; i >= 0 ; i--)
627       {
628          vgl = get(i,S.len);
629          if (vgl == S)
630             break;
631       }
632    if (i >= 0)
633       return i;
634    else
635       return NO_POS;
636 }
637 
638 int
639 Simstr::count(char c) const
640 {
641    int ret = 0;
642    for (int i =0; i < len; i++)
643 	  if (sz[i] == c)
644 		 ret++;
645    return ret;
646 }
647 
648 bool
649 Simstr::is_no_text() const
650 {
651    if (!len)
652 	  return true;
653 
654    int i;
655    for (i = 0; sz[i] <= 32 && i < len; i++) ;
656    if (i < len)
657 		return false;
658 	return true;
659 }
660 
661 // Change
662 
663 void
664 Simstr::replace(int  pos, char c)
665 {
666 	if (pos < 0 || pos >= len)
667       return;
668    else
669       sz[unsigned(pos)] = c;
670 }
671 
672 void
673 Simstr::replace(int  startPos, int  anzahl, const Simstr & S)
674 {
675    if (startPos >= len || startPos < 0 || anzahl < 1)
676       return;
677 
678    int anz = len - startPos < anzahl ? len - startPos : anzahl;
679 
680    char * result = new char[len-anz+S.len+1];
681 
682    memcpy(result,sz,startPos);
683    memcpy(result+startPos, S.sz, S.len);
684    memcpy(result+startPos+S.len, sz+startPos+anz, len-startPos-anz+1);
685 
686    delete [] sz;
687    sz = result;
688    len = len-anz+S.len;
689 }
690 
691 void
692 Simstr::replace_all(char oldCh, char newCh)
693 {
694    for (int i=0; i < len; i++)
695       if (sz[i] == oldCh)
696          sz[i] = newCh;
697 }
698 
699 void
700 Simstr::replace_all(const Simstr & oldS, const Simstr & newS)
701 {
702    Simstr vgl;
703    int i = 0;
704 	while (i <= len-oldS.len)
705 		{
706          vgl = get(i,oldS.len);
707          if (strcmp(vgl.sz,oldS.sz) == 0)
708             {
709                replace(i,oldS.len,newS);
710                i += newS.len;
711             }
712          else
713             i++;
714       }
715 }
716 
717 void
718 Simstr::to_lower()
719 {
720 	for (int i = 0; i < len; i++)
721    	sz[i] = (char) tolower(sz[i]);
722 }
723 
724 
725 
726 //   Simstr addition
727 Simstr
728 operator+(const char * str, const Simstr & S)
729 {
730    Simstr ret = S;
731    ret.push_front(str);
732    return ret;
733 }
734 
735 Simstr
736 operator+(const Simstr & S, const char * str)
737 {
738    Simstr ret = S;
739    ret.push_back(str);
740    return ret;
741 }
742 
743 Simstr
744 operator+(char c, const Simstr & S)
745 {
746    Simstr ret = S;
747    ret.push_front(c);
748    return ret;
749 }
750 
751 Simstr
752 operator+(const Simstr & S, char c)
753 {
754    Simstr ret = S;
755    ret.push_back(c);
756    return ret;
757 }
758 
759 
760 // Simstr-Vergleiche mit char *
761 bool
762 operator==(const Simstr & S, const char * str)
763 {
764    return strcmp(S,str) == 0;
765 }
766 
767 bool
768 operator!=(const Simstr & S, const char * str)
769 {
770    return strcmp(S,str) != 0;
771 }
772 
773 bool
774 operator<(const Simstr & S, const char * str)
775 {
776    return strcmp(S,str) < 0;
777 }
778 
779 bool
780 operator>(const Simstr & S, const char * str)
781 {
782    return strcmp(S,str) > 0;
783 }
784 
785 bool
786 operator<=(const Simstr & S, const char * str)
787 {
788    return strcmp(S,str) <= 0;
789 }
790 
791 bool
792 operator>=(const Simstr & S, const char * str)
793 {
794    return strcmp(S,str) >= 0;
795 }
796 
797 bool
798 operator==(const char * str, const Simstr & S)
799 {
800    return strcmp(str,S) == 0;
801 }
802 
803 bool
804 operator!=(const char * str, const Simstr & S)
805 {
806    return strcmp(str,S) != 0;
807 }
808 
809 bool
810 operator<(const char * str, const Simstr & S)
811 {
812    return strcmp(str,S) < 0;
813 }
814 
815 bool
816 operator>(const char * str, const Simstr & S)
817 {
818    return strcmp(str,S) > 0;
819 }
820 
821 bool
822 operator<=(const char * str, const Simstr & S)
823 {
824    return strcmp(str,S) <= 0;
825 }
826 
827 bool
828 operator>=(const char * str, const Simstr & S)
829 {
830    return strcmp(str,S) >= 0;
831 }
832 
833 
834