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 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 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 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 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 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 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 136 Simstr::~Simstr() 137 { 138 delete [] sz; 139 } 140 141 char & 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 & 153 Simstr::null_() 154 { 155 static Simstr aNull_; 156 return aNull_; 157 } 158 159 160 Simstr 161 Simstr::operator+(const Simstr & S) const 162 { 163 Simstr ret = sz; 164 ret.push_back(S); 165 return ret; 166 } 167 168 Simstr & 169 Simstr::operator+=(const Simstr & S) 170 { 171 push_back(S); 172 return *this; 173 } 174 175 Simstr & 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 187 Simstr::operator==(const Simstr & S) const 188 { return !strcmp(sz,S.sz) ? true : false; } 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) < 0) ? 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 211 212 213 // ************** LIST - Funktionen ***************** 214 215 216 // Einzelzugriff 217 218 char 219 Simstr::get(int n) const { return (n >= len || n < 0) ? 0 : sz[n]; } 220 221 char 222 Simstr::get_front() const { return sz[0]; } 223 224 char 225 Simstr::get_back() const { return len ? sz[len-1] : 0; } 226 227 Simstr 228 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 241 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 253 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 266 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 276 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 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 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 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 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 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 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 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 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 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 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 442 Simstr::rem_back_from(int removeStartPos) 443 { 444 if (removeStartPos != NO_POS) 445 pop_back(len-removeStartPos); 446 } 447 448 void 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 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 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 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 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 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 571 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 582 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 597 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 608 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 618 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 635 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 645 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 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 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 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 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 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 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 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 740 operator+(char c, const Simstr & S) 741 { 742 Simstr ret = S; 743 ret.push_front(c); 744 return ret; 745 } 746 747 Simstr 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 758 operator==(const Simstr & S, const char * str) 759 { 760 return strcmp(S,str) == 0; 761 } 762 763 bool 764 operator!=(const Simstr & S, const char * str) 765 { 766 return strcmp(S,str) != 0; 767 } 768 769 bool 770 operator<(const Simstr & S, const char * str) 771 { 772 return strcmp(S,str) < 0; 773 } 774 775 bool 776 operator>(const Simstr & S, const char * str) 777 { 778 return strcmp(S,str) > 0; 779 } 780 781 bool 782 operator<=(const Simstr & S, const char * str) 783 { 784 return strcmp(S,str) <= 0; 785 } 786 787 bool 788 operator>=(const Simstr & S, const char * str) 789 { 790 return strcmp(S,str) >= 0; 791 } 792 793 bool 794 operator==(const char * str, const Simstr & S) 795 { 796 return strcmp(str,S) == 0; 797 } 798 799 bool 800 operator!=(const char * str, const Simstr & S) 801 { 802 return strcmp(str,S) != 0; 803 } 804 805 bool 806 operator<(const char * str, const Simstr & S) 807 { 808 return strcmp(str,S) < 0; 809 } 810 811 bool 812 operator>(const char * str, const Simstr & S) 813 { 814 return strcmp(str,S) > 0; 815 } 816 817 bool 818 operator<=(const char * str, const Simstr & S) 819 { 820 return strcmp(str,S) <= 0; 821 } 822 823 bool 824 operator>=(const char * str, const Simstr & S) 825 { 826 return strcmp(str,S) >= 0; 827 } 828 829 830