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