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