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