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 // no include "precompiled_tools.hxx" because this is included in other cxx files. 29 30 // ======================================================================= 31 32 static sal_Int32 ImplStringCompare( const STRCODE* pStr1, const STRCODE* pStr2 ) 33 { 34 sal_Int32 nRet; 35 while ( ((nRet = ((sal_Int32)((STRCODEU)*pStr1))-((sal_Int32)((STRCODEU)*pStr2))) == 0) && 36 *pStr2 ) 37 { 38 ++pStr1, 39 ++pStr2; 40 } 41 42 return nRet; 43 } 44 45 // ----------------------------------------------------------------------- 46 47 static sal_Int32 ImplStringCompare( const STRCODE* pStr1, const STRCODE* pStr2, 48 xub_StrLen nCount ) 49 { 50 sal_Int32 nRet = 0; 51 while ( nCount && 52 ((nRet = ((sal_Int32)((STRCODEU)*pStr1))-((sal_Int32)((STRCODEU)*pStr2))) == 0) && 53 *pStr2 ) 54 { 55 ++pStr1, 56 ++pStr2, 57 --nCount; 58 } 59 60 return nRet; 61 } 62 63 // ----------------------------------------------------------------------- 64 65 static sal_Int32 ImplStringCompareWithoutZero( const STRCODE* pStr1, const STRCODE* pStr2, 66 sal_Int32 nCount ) 67 { 68 sal_Int32 nRet = 0; 69 while ( nCount && 70 ((nRet = ((sal_Int32)((STRCODEU)*pStr1))-((sal_Int32)((STRCODEU)*pStr2))) == 0) ) 71 { 72 ++pStr1, 73 ++pStr2, 74 --nCount; 75 } 76 77 return nRet; 78 } 79 80 // ----------------------------------------------------------------------- 81 82 static sal_Int32 ImplStringICompare( const STRCODE* pStr1, const STRCODE* pStr2 ) 83 { 84 sal_Int32 nRet; 85 STRCODE c1; 86 STRCODE c2; 87 do 88 { 89 // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln 90 c1 = *pStr1; 91 c2 = *pStr2; 92 if ( (c1 >= 65) && (c1 <= 90) ) 93 c1 += 32; 94 if ( (c2 >= 65) && (c2 <= 90) ) 95 c2 += 32; 96 nRet = ((sal_Int32)((STRCODEU)c1))-((sal_Int32)((STRCODEU)c2)); 97 if ( nRet != 0 ) 98 break; 99 100 ++pStr1, 101 ++pStr2; 102 } 103 while ( c2 ); 104 105 return nRet; 106 } 107 108 // ----------------------------------------------------------------------- 109 110 static sal_Int32 ImplStringICompare( const STRCODE* pStr1, const STRCODE* pStr2, 111 xub_StrLen nCount ) 112 { 113 sal_Int32 nRet = 0; 114 STRCODE c1; 115 STRCODE c2; 116 do 117 { 118 if ( !nCount ) 119 break; 120 121 // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln 122 c1 = *pStr1; 123 c2 = *pStr2; 124 if ( (c1 >= 65) && (c1 <= 90) ) 125 c1 += 32; 126 if ( (c2 >= 65) && (c2 <= 90) ) 127 c2 += 32; 128 nRet = ((sal_Int32)((STRCODEU)c1))-((sal_Int32)((STRCODEU)c2)); 129 if ( nRet != 0 ) 130 break; 131 132 ++pStr1, 133 ++pStr2, 134 --nCount; 135 } 136 while ( c2 ); 137 138 return nRet; 139 } 140 141 // ----------------------------------------------------------------------- 142 143 static sal_Int32 ImplStringICompareWithoutZero( const STRCODE* pStr1, const STRCODE* pStr2, 144 sal_Int32 nCount ) 145 { 146 sal_Int32 nRet = 0; 147 STRCODE c1; 148 STRCODE c2; 149 do 150 { 151 if ( !nCount ) 152 break; 153 154 // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln 155 c1 = *pStr1; 156 c2 = *pStr2; 157 if ( (c1 >= 65) && (c1 <= 90) ) 158 c1 += 32; 159 if ( (c2 >= 65) && (c2 <= 90) ) 160 c2 += 32; 161 nRet = ((sal_Int32)((STRCODEU)c1))-((sal_Int32)((STRCODEU)c2)); 162 163 ++pStr1, 164 ++pStr2, 165 --nCount; 166 } 167 while ( nRet == 0 ); 168 169 return nRet; 170 } 171 172 // ======================================================================= 173 174 #ifdef DBG_UTIL 175 const char* DBGCHECKSTRING( const void* pString ) 176 { 177 STRING* p = (STRING*)pString; 178 179 if ( p->GetBuffer()[p->Len()] != 0 ) 180 return "String damaged: aStr[nLen] != 0"; 181 182 return NULL; 183 } 184 #endif 185 186 // ======================================================================= 187 188 static STRINGDATA* ImplAllocData( sal_Int32 nLen ) 189 { 190 // Dann kopiere die Daten 191 STRINGDATA* pData = (STRINGDATA*)rtl_allocateMemory( sizeof(STRINGDATA)+(nLen*sizeof( STRCODE )) ); 192 pData->mnRefCount = 1; 193 pData->mnLen = nLen; 194 pData->maStr[nLen] = 0; 195 return pData; 196 } 197 198 // ----------------------------------------------------------------------- 199 200 static STRINGDATA* _ImplCopyData( STRINGDATA* pData ) 201 { 202 unsigned int nSize = sizeof(STRINGDATA)+(pData->mnLen*sizeof( STRCODE )); 203 STRINGDATA* pNewData = (STRINGDATA*)rtl_allocateMemory( nSize ); 204 memcpy( pNewData, pData, nSize ); 205 pNewData->mnRefCount = 1; 206 STRING_RELEASE((STRING_TYPE *)pData); 207 return pNewData; 208 } 209 210 // ----------------------------------------------------------------------- 211 212 inline void STRING::ImplCopyData() 213 { 214 DBG_ASSERT( (mpData->mnRefCount != 0), "String::ImplCopyData() - RefCount == 0" ); 215 216 // ist es ein referenzierter String, dann die Daten abkoppeln 217 if ( mpData->mnRefCount != 1 ) 218 mpData = _ImplCopyData( mpData ); 219 } 220 221 // ----------------------------------------------------------------------- 222 223 inline STRCODE* STRING::ImplCopyStringData( STRCODE* pStr ) 224 { 225 // Ist der Referenzzaehler groesser 0 226 if ( mpData->mnRefCount != 1 ) { 227 DBG_ASSERT( (pStr >= mpData->maStr) && 228 ((pStr-mpData->maStr) < mpData->mnLen), 229 "ImplCopyStringData - pStr from other String-Instanz" ); 230 unsigned int nIndex = (unsigned int)(pStr-mpData->maStr); 231 mpData = _ImplCopyData( mpData ); 232 pStr = mpData->maStr + nIndex; 233 } 234 return pStr; 235 } 236 237 // ----------------------------------------------------------------------- 238 239 inline sal_Int32 ImplGetCopyLen( sal_Int32 nStrLen, sal_Int32 nCopyLen ) 240 { 241 OSL_ASSERT(nStrLen <= STRING_MAXLEN && nCopyLen <= STRING_MAXLEN); 242 if ( nCopyLen > STRING_MAXLEN-nStrLen ) 243 nCopyLen = STRING_MAXLEN-nStrLen; 244 return nCopyLen; 245 } 246 247 // ======================================================================= 248 249 STRING::STRING() 250 : mpData(NULL) 251 { 252 DBG_CTOR( STRING, DBGCHECKSTRING ); 253 254 STRING_NEW((STRING_TYPE **)&mpData); 255 } 256 257 // ----------------------------------------------------------------------- 258 259 STRING::STRING( const STRING& rStr ) 260 { 261 DBG_CTOR( STRING, DBGCHECKSTRING ); 262 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 263 264 // Pointer auf die Daten des uebergebenen Strings setzen und 265 // Referenzzaehler erhoehen 266 STRING_ACQUIRE((STRING_TYPE *)rStr.mpData); 267 mpData = rStr.mpData; 268 } 269 270 // ----------------------------------------------------------------------- 271 272 STRING::STRING( const STRING& rStr, xub_StrLen nPos, xub_StrLen nLen ) 273 : mpData( NULL ) 274 { 275 DBG_CTOR( STRING, DBGCHECKSTRING ); 276 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 277 278 // Stringlaenge ermitteln 279 if ( nPos > rStr.mpData->mnLen ) 280 nLen = 0; 281 else 282 { 283 // Laenge korrigieren, wenn noetig 284 sal_Int32 nMaxLen = rStr.mpData->mnLen-nPos; 285 if ( nLen > nMaxLen ) 286 nLen = static_cast< xub_StrLen >(nMaxLen); 287 } 288 289 // Ist es kein leerer String 290 if ( nLen ) 291 { 292 // Reicht ein einfaches erhoehen des Referenzcounters 293 if ( (nPos == 0) && (nLen == rStr.mpData->mnLen) ) 294 { 295 STRING_ACQUIRE((STRING_TYPE *)rStr.mpData); 296 mpData = rStr.mpData; 297 } 298 else 299 { 300 // Verwaltungsdaten anlegen und String kopieren 301 mpData = ImplAllocData( nLen ); 302 memcpy( mpData->maStr, rStr.mpData->maStr+nPos, nLen*sizeof( STRCODE ) ); 303 } 304 } 305 else 306 { 307 STRING_NEW((STRING_TYPE **)&mpData); 308 } 309 } 310 311 // ----------------------------------------------------------------------- 312 313 STRING::STRING( const STRCODE* pCharStr ) 314 : mpData(NULL) 315 { 316 DBG_CTOR( STRING, DBGCHECKSTRING ); 317 318 // Stringlaenge ermitteln 319 // Bei diesem Ctor darf NULL uebergeben werden 320 xub_StrLen nLen; 321 if ( pCharStr ) 322 nLen = ImplStringLen( pCharStr ); 323 else 324 nLen = 0; 325 326 // Ist es kein leerer String 327 if ( nLen ) 328 { 329 // Verwaltungsdaten anlegen und String kopieren 330 mpData = ImplAllocData( nLen ); 331 memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) ); 332 } 333 else 334 { 335 STRING_NEW((STRING_TYPE **)&mpData); 336 } 337 } 338 339 // ----------------------------------------------------------------------- 340 341 STRING::STRING( const STRCODE* pCharStr, xub_StrLen nLen ) 342 : mpData(NULL) 343 { 344 DBG_CTOR( STRING, DBGCHECKSTRING ); 345 DBG_ASSERT( pCharStr, "String::String() - pCharStr is NULL" ); 346 347 if ( nLen == STRING_LEN ) 348 nLen = ImplStringLen( pCharStr ); 349 350 #ifdef DBG_UTIL 351 if ( DbgIsAssert() ) 352 { 353 for ( xub_StrLen i = 0; i < nLen; i++ ) 354 { 355 if ( !pCharStr[i] ) 356 { 357 DBG_ERROR( "String::String() : nLen is wrong" ); 358 } 359 } 360 } 361 #endif 362 363 // Ist es kein leerer String 364 if ( nLen ) 365 { 366 // Verwaltungsdaten anlegen und String kopieren 367 mpData = ImplAllocData( nLen ); 368 memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) ); 369 } 370 else 371 { 372 STRING_NEW((STRING_TYPE **)&mpData); 373 } 374 } 375 376 // ----------------------------------------------------------------------- 377 378 STRING::STRING( STRCODE c ) 379 { 380 DBG_CTOR( STRING, DBGCHECKSTRING ); 381 DBG_ASSERT( c, "String::String() - c is 0" ); 382 383 // Verwaltungsdaten anlegen und initialisieren 384 mpData = ImplAllocData( 1 ); 385 mpData->maStr[0] = c; 386 } 387 388 // ----------------------------------------------------------------------- 389 390 STRING::~STRING() 391 { 392 DBG_DTOR( STRING, DBGCHECKSTRING ); 393 394 // Daten loeschen 395 STRING_RELEASE((STRING_TYPE *)mpData); 396 } 397 398 // ----------------------------------------------------------------------- 399 400 STRING& STRING::Assign( const STRING& rStr ) 401 { 402 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 403 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 404 405 STRING_ACQUIRE((STRING_TYPE *)rStr.mpData); 406 STRING_RELEASE((STRING_TYPE *)mpData); 407 mpData = rStr.mpData; 408 return *this; 409 } 410 411 // ----------------------------------------------------------------------- 412 413 STRING& STRING::Assign( const STRCODE* pCharStr ) 414 { 415 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 416 DBG_ASSERT( pCharStr, "String::Assign() - pCharStr is NULL" ); 417 418 // Stringlaenge ermitteln 419 xub_StrLen nLen = ImplStringLen( pCharStr ); 420 421 if ( !nLen ) 422 { 423 STRING_NEW((STRING_TYPE **)&mpData); 424 } 425 else 426 { 427 // Wenn String genauso lang ist, wie der String, dann direkt kopieren 428 if ( (nLen == mpData->mnLen) && (mpData->mnRefCount == 1) ) 429 memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) ); 430 else 431 { 432 // Alte Daten loeschen 433 STRING_RELEASE((STRING_TYPE *)mpData); 434 435 // Daten initialisieren und String kopieren 436 mpData = ImplAllocData( nLen ); 437 memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) ); 438 } 439 } 440 441 return *this; 442 } 443 444 // ----------------------------------------------------------------------- 445 446 STRING& STRING::Assign( const STRCODE* pCharStr, xub_StrLen nLen ) 447 { 448 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 449 DBG_ASSERT( pCharStr, "String::Assign() - pCharStr is NULL" ); 450 451 if ( nLen == STRING_LEN ) 452 nLen = ImplStringLen( pCharStr ); 453 454 #ifdef DBG_UTIL 455 if ( DbgIsAssert() ) 456 { 457 for ( xub_StrLen i = 0; i < nLen; i++ ) 458 { 459 if ( !pCharStr[i] ) 460 { 461 DBG_ERROR( "String::Assign() : nLen is wrong" ); 462 } 463 } 464 } 465 #endif 466 467 if ( !nLen ) 468 { 469 STRING_NEW((STRING_TYPE **)&mpData); 470 } 471 else 472 { 473 // Wenn String genauso lang ist, wie der String, dann direkt kopieren 474 if ( (nLen == mpData->mnLen) && (mpData->mnRefCount == 1) ) 475 memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) ); 476 else 477 { 478 // Alte Daten loeschen 479 STRING_RELEASE((STRING_TYPE *)mpData); 480 481 // Daten initialisieren und String kopieren 482 mpData = ImplAllocData( nLen ); 483 memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) ); 484 } 485 } 486 487 return *this; 488 } 489 490 // ----------------------------------------------------------------------- 491 492 STRING& STRING::Assign( STRCODE c ) 493 { 494 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 495 DBG_ASSERT( c, "String::Assign() - c is 0" ); 496 497 // Verwaltungsdaten anlegen und initialisieren 498 STRING_RELEASE((STRING_TYPE *)mpData); 499 mpData = ImplAllocData( 1 ); 500 mpData->maStr[0] = c; 501 return *this; 502 } 503 504 // ----------------------------------------------------------------------- 505 506 STRING& STRING::Append( const STRING& rStr ) 507 { 508 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 509 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 510 511 // Wenn String leer, dann reicht eine Zuweisung 512 sal_Int32 nLen = mpData->mnLen; 513 if ( !nLen ) 514 { 515 STRING_ACQUIRE((STRING_TYPE *)rStr.mpData); 516 STRING_RELEASE((STRING_TYPE *)mpData); 517 mpData = rStr.mpData; 518 } 519 else 520 { 521 // Ueberlauf abfangen 522 sal_Int32 nCopyLen = ImplGetCopyLen( nLen, rStr.mpData->mnLen ); 523 524 // Ist der uebergebene String kein Leerstring 525 if ( nCopyLen ) 526 { 527 // Neue Datenstruktur und neuen String erzeugen 528 STRINGDATA* pNewData = ImplAllocData( nLen+nCopyLen ); 529 530 // String kopieren 531 memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) ); 532 memcpy( pNewData->maStr+nLen, rStr.mpData->maStr, nCopyLen*sizeof( STRCODE ) ); 533 534 // Alte Daten loeschen und Neue zuweisen 535 STRING_RELEASE((STRING_TYPE *)mpData); 536 mpData = pNewData; 537 } 538 } 539 540 return *this; 541 } 542 543 // ----------------------------------------------------------------------- 544 545 STRING& STRING::Append( const STRCODE* pCharStr ) 546 { 547 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 548 DBG_ASSERT( pCharStr, "String::Append() - pCharStr is NULL" ); 549 550 // Stringlaenge ermitteln 551 sal_Int32 nLen = mpData->mnLen; 552 sal_Int32 nCopyLen = ImplStringLen( pCharStr ); 553 554 // Ueberlauf abfangen 555 nCopyLen = ImplGetCopyLen( nLen, nCopyLen ); 556 557 // Ist es kein leerer String 558 if ( nCopyLen ) 559 { 560 // Neue Datenstruktur und neuen String erzeugen 561 STRINGDATA* pNewData = ImplAllocData( nLen+nCopyLen ); 562 563 // String kopieren 564 memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) ); 565 memcpy( pNewData->maStr+nLen, pCharStr, nCopyLen*sizeof( STRCODE ) ); 566 567 // Alte Daten loeschen und Neue zuweisen 568 STRING_RELEASE((STRING_TYPE *)mpData); 569 mpData = pNewData; 570 } 571 572 return *this; 573 } 574 575 // ----------------------------------------------------------------------- 576 577 STRING& STRING::Append( const STRCODE* pCharStr, xub_StrLen nCharLen ) 578 { 579 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 580 DBG_ASSERT( pCharStr, "String::Append() - pCharStr is NULL" ); 581 582 if ( nCharLen == STRING_LEN ) 583 nCharLen = ImplStringLen( pCharStr ); 584 585 #ifdef DBG_UTIL 586 if ( DbgIsAssert() ) 587 { 588 for ( xub_StrLen i = 0; i < nCharLen; i++ ) 589 { 590 if ( !pCharStr[i] ) 591 { 592 DBG_ERROR( "String::Append() : nLen is wrong" ); 593 } 594 } 595 } 596 #endif 597 598 // Ueberlauf abfangen 599 sal_Int32 nLen = mpData->mnLen; 600 sal_Int32 nCopyLen = ImplGetCopyLen( nLen, nCharLen ); 601 602 // Ist es kein leerer String 603 if ( nCopyLen ) 604 { 605 // Neue Datenstruktur und neuen String erzeugen 606 STRINGDATA* pNewData = ImplAllocData( nLen+nCopyLen ); 607 608 // String kopieren 609 memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) ); 610 memcpy( pNewData->maStr+nLen, pCharStr, nCopyLen*sizeof( STRCODE ) ); 611 612 // Alte Daten loeschen und Neue zuweisen 613 STRING_RELEASE((STRING_TYPE *)mpData); 614 mpData = pNewData; 615 } 616 617 return *this; 618 } 619 620 // ----------------------------------------------------------------------- 621 622 STRING& STRING::Append( STRCODE c ) 623 { 624 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 625 626 // kein 0-Character und maximale Stringlaenge nicht ueberschreiten 627 sal_Int32 nLen = mpData->mnLen; 628 if ( c && (nLen < STRING_MAXLEN) ) 629 { 630 // Neue Datenstruktur und neuen String erzeugen 631 STRINGDATA* pNewData = ImplAllocData( nLen+1 ); 632 633 // String kopieren 634 memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) ); 635 pNewData->maStr[nLen] = c; 636 637 // Alte Daten loeschen und Neue zuweisen 638 STRING_RELEASE((STRING_TYPE *)mpData); 639 mpData = pNewData; 640 } 641 642 return *this; 643 } 644 645 // ----------------------------------------------------------------------- 646 647 void STRING::SetChar( xub_StrLen nIndex, STRCODE c ) 648 { 649 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 650 DBG_ASSERT( nIndex < mpData->mnLen, "String::SetChar() - nIndex > String.Len()" ); 651 652 // Daten kopieren, wenn noetig und Character zuweisen 653 ImplCopyData(); 654 mpData->maStr[nIndex] = c; 655 } 656 657 // ----------------------------------------------------------------------- 658 659 STRING& STRING::Insert( const STRING& rStr, xub_StrLen nIndex ) 660 { 661 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 662 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 663 664 // Ueberlauf abfangen 665 sal_Int32 nCopyLen = ImplGetCopyLen( mpData->mnLen, rStr.mpData->mnLen ); 666 667 // Ist der einzufuegende String ein Leerstring 668 if ( !nCopyLen ) 669 return *this; 670 671 // Index groesser als Laenge 672 if ( nIndex > mpData->mnLen ) 673 nIndex = static_cast< xub_StrLen >(mpData->mnLen); 674 675 // Neue Laenge ermitteln und neuen String anlegen 676 STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+nCopyLen ); 677 678 // String kopieren 679 memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) ); 680 memcpy( pNewData->maStr+nIndex, rStr.mpData->maStr, nCopyLen*sizeof( STRCODE ) ); 681 memcpy( pNewData->maStr+nIndex+nCopyLen, mpData->maStr+nIndex, 682 (mpData->mnLen-nIndex)*sizeof( STRCODE ) ); 683 684 // Alte Daten loeschen und Neue zuweisen 685 STRING_RELEASE((STRING_TYPE *)mpData); 686 mpData = pNewData; 687 688 return *this; 689 } 690 691 // ----------------------------------------------------------------------- 692 693 STRING& STRING::Insert( const STRING& rStr, xub_StrLen nPos, xub_StrLen nLen, 694 xub_StrLen nIndex ) 695 { 696 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 697 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 698 699 // Stringlaenge ermitteln 700 if ( nPos > rStr.mpData->mnLen ) 701 nLen = 0; 702 else 703 { 704 // Laenge korrigieren, wenn noetig 705 sal_Int32 nMaxLen = rStr.mpData->mnLen-nPos; 706 if ( nLen > nMaxLen ) 707 nLen = static_cast< xub_StrLen >(nMaxLen); 708 } 709 710 // Ueberlauf abfangen 711 sal_Int32 nCopyLen = ImplGetCopyLen( mpData->mnLen, nLen ); 712 713 // Ist der einzufuegende String ein Leerstring 714 if ( !nCopyLen ) 715 return *this; 716 717 // Index groesser als Laenge 718 if ( nIndex > mpData->mnLen ) 719 nIndex = static_cast< xub_StrLen >(mpData->mnLen); 720 721 // Neue Laenge ermitteln und neuen String anlegen 722 STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+nCopyLen ); 723 724 // String kopieren 725 memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) ); 726 memcpy( pNewData->maStr+nIndex, rStr.mpData->maStr+nPos, nCopyLen*sizeof( STRCODE ) ); 727 memcpy( pNewData->maStr+nIndex+nCopyLen, mpData->maStr+nIndex, 728 (mpData->mnLen-nIndex)*sizeof( STRCODE ) ); 729 730 // Alte Daten loeschen und Neue zuweisen 731 STRING_RELEASE((STRING_TYPE *)mpData); 732 mpData = pNewData; 733 734 return *this; 735 } 736 737 // ----------------------------------------------------------------------- 738 739 STRING& STRING::Insert( const STRCODE* pCharStr, xub_StrLen nIndex ) 740 { 741 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 742 DBG_ASSERT( pCharStr, "String::Insert() - pCharStr is NULL" ); 743 744 // Stringlaenge ermitteln 745 sal_Int32 nCopyLen = ImplStringLen( pCharStr ); 746 747 // Ueberlauf abfangen 748 nCopyLen = ImplGetCopyLen( mpData->mnLen, nCopyLen ); 749 750 // Ist der einzufuegende String ein Leerstring 751 if ( !nCopyLen ) 752 return *this; 753 754 // Index groesser als Laenge 755 if ( nIndex > mpData->mnLen ) 756 nIndex = static_cast< xub_StrLen >(mpData->mnLen); 757 758 // Neue Laenge ermitteln und neuen String anlegen 759 STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+nCopyLen ); 760 761 // String kopieren 762 memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) ); 763 memcpy( pNewData->maStr+nIndex, pCharStr, nCopyLen*sizeof( STRCODE ) ); 764 memcpy( pNewData->maStr+nIndex+nCopyLen, mpData->maStr+nIndex, 765 (mpData->mnLen-nIndex)*sizeof( STRCODE ) ); 766 767 // Alte Daten loeschen und Neue zuweisen 768 STRING_RELEASE((STRING_TYPE *)mpData); 769 mpData = pNewData; 770 771 return *this; 772 } 773 774 // ----------------------------------------------------------------------- 775 776 STRING& STRING::Insert( STRCODE c, xub_StrLen nIndex ) 777 { 778 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 779 780 // Ist es kein 0-Character 781 if ( !c || (mpData->mnLen == STRING_MAXLEN) ) 782 return *this; 783 784 // Index groesser als Laenge 785 if ( nIndex > mpData->mnLen ) 786 nIndex = static_cast< xub_StrLen >(mpData->mnLen); 787 788 // Neue Laenge ermitteln und neuen String anlegen 789 STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+1 ); 790 791 // String kopieren 792 memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) ); 793 pNewData->maStr[nIndex] = c; 794 memcpy( pNewData->maStr+nIndex+1, mpData->maStr+nIndex, 795 (mpData->mnLen-nIndex)*sizeof( STRCODE ) ); 796 797 // Alte Daten loeschen und Neue zuweisen 798 STRING_RELEASE((STRING_TYPE *)mpData); 799 mpData = pNewData; 800 801 return *this; 802 } 803 804 // ----------------------------------------------------------------------- 805 806 STRING& STRING::Replace( xub_StrLen nIndex, xub_StrLen nCount, const STRING& rStr ) 807 { 808 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 809 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 810 811 // Wenn Index groessergleich Laenge ist, dann ist es ein Append 812 if ( nIndex >= mpData->mnLen ) 813 { 814 Append( rStr ); 815 return *this; 816 } 817 818 // Ist es eine Zuweisung 819 if ( (nIndex == 0) && (nCount >= mpData->mnLen) ) 820 { 821 Assign( rStr ); 822 return *this; 823 } 824 825 // Reicht ein Erase 826 sal_Int32 nStrLen = rStr.mpData->mnLen; 827 if ( !nStrLen ) 828 return Erase( nIndex, nCount ); 829 830 // nCount darf nicht ueber das Stringende hinnausgehen 831 if ( nCount > mpData->mnLen - nIndex ) 832 nCount = static_cast< xub_StrLen >(mpData->mnLen-nIndex); 833 834 // Reicht ein Insert 835 if ( !nCount ) 836 return Insert( rStr, nIndex ); 837 838 // Reicht eine zeichenweise Zuweisung 839 if ( nCount == nStrLen ) 840 { 841 ImplCopyData(); 842 memcpy( mpData->maStr+nIndex, rStr.mpData->maStr, nCount*sizeof( STRCODE ) ); 843 return *this; 844 } 845 846 // Ueberlauf abfangen 847 nStrLen = ImplGetCopyLen( mpData->mnLen-nCount, nStrLen ); 848 849 // Neue Daten anlegen 850 STRINGDATA* pNewData = ImplAllocData( mpData->mnLen-nCount+nStrLen ); 851 852 // String kopieren 853 memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) ); 854 memcpy( pNewData->maStr+nIndex, rStr.mpData->maStr, nStrLen*sizeof( STRCODE ) ); 855 memcpy( pNewData->maStr+nIndex+nStrLen, mpData->maStr+nIndex+nCount, 856 (mpData->mnLen-nIndex-nCount+1)*sizeof( STRCODE ) ); 857 858 // Alte Daten loeschen und Neue zuweisen 859 STRING_RELEASE((STRING_TYPE *)mpData); 860 mpData = pNewData; 861 862 return *this; 863 } 864 865 // ----------------------------------------------------------------------- 866 867 STRING& STRING::Erase( xub_StrLen nIndex, xub_StrLen nCount ) 868 { 869 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 870 871 // Ist der Index ausserhalb des Strings oder ist nCount == 0 872 if ( (nIndex >= mpData->mnLen) || !nCount ) 873 return *this; 874 875 // nCount darf nicht ueber das Stringende hinnausgehen 876 if ( nCount > mpData->mnLen - nIndex ) 877 nCount = static_cast< xub_StrLen >(mpData->mnLen-nIndex); 878 879 // Ist das Ergebnis kein Leerstring 880 if ( mpData->mnLen - nCount ) 881 { 882 // Neue Daten anlegen 883 STRINGDATA* pNewData = ImplAllocData( mpData->mnLen-nCount ); 884 885 // String kopieren 886 memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) ); 887 memcpy( pNewData->maStr+nIndex, mpData->maStr+nIndex+nCount, 888 (mpData->mnLen-nIndex-nCount+1)*sizeof( STRCODE ) ); 889 890 // Alte Daten loeschen und Neue zuweisen 891 STRING_RELEASE((STRING_TYPE *)mpData); 892 mpData = pNewData; 893 } 894 else 895 { 896 STRING_NEW((STRING_TYPE **)&mpData); 897 } 898 899 return *this; 900 } 901 902 // ----------------------------------------------------------------------- 903 904 STRING& STRING::Fill( xub_StrLen nCount, STRCODE cFillChar ) 905 { 906 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 907 908 if ( !nCount ) 909 return *this; 910 911 // Ist nCount groesser wie der jetzige String, dann verlaengern 912 if ( nCount > mpData->mnLen ) 913 { 914 // dann neuen String mit der neuen Laenge anlegen 915 STRINGDATA* pNewData = ImplAllocData( nCount ); 916 STRING_RELEASE((STRING_TYPE *)mpData); 917 mpData = pNewData; 918 } 919 else 920 ImplCopyData(); 921 922 STRCODE* pStr = mpData->maStr; 923 do 924 { 925 *pStr = cFillChar; 926 ++pStr, 927 --nCount; 928 } 929 while ( nCount ); 930 931 return *this; 932 } 933 934 // ----------------------------------------------------------------------- 935 936 STRING& STRING::Expand( xub_StrLen nCount, STRCODE cExpandChar ) 937 { 938 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 939 940 // Muss der String erweitert werden 941 sal_Int32 nLen = mpData->mnLen; 942 if ( nCount <= nLen ) 943 return *this; 944 945 // Neuen String anlegen 946 STRINGDATA* pNewData = ImplAllocData( nCount ); 947 948 // Alten String kopieren 949 memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) ); 950 951 // und initialisieren 952 STRCODE* pStr = pNewData->maStr; 953 pStr += nLen; 954 for (sal_Int32 i = nCount - nLen; i > 0; --i) { 955 *pStr++ = cExpandChar; 956 } 957 958 // Alte Daten loeschen und Neue zuweisen 959 STRING_RELEASE((STRING_TYPE *)mpData); 960 mpData = pNewData; 961 962 return *this; 963 } 964 965 // ----------------------------------------------------------------------- 966 967 STRING& STRING::EraseLeadingChars( STRCODE c ) 968 { 969 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 970 971 if ( mpData->maStr[0] != c ) 972 return *this; 973 974 xub_StrLen nStart = 0; 975 while ( mpData->maStr[nStart] == c ) 976 ++nStart; 977 978 return Erase( 0, nStart ); 979 } 980 981 // ----------------------------------------------------------------------- 982 983 STRING& STRING::EraseTrailingChars( STRCODE c ) 984 { 985 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 986 987 sal_Int32 nEnd = mpData->mnLen; 988 while ( nEnd && (mpData->maStr[nEnd-1] == c) ) 989 nEnd--; 990 991 if ( nEnd != mpData->mnLen ) 992 Erase( static_cast< xub_StrLen >(nEnd) ); 993 994 return *this; 995 } 996 997 // ----------------------------------------------------------------------- 998 999 STRING& STRING::EraseLeadingAndTrailingChars( STRCODE c ) 1000 { 1001 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1002 1003 xub_StrLen nStart = 0; 1004 while ( mpData->maStr[nStart] == c ) 1005 ++nStart; 1006 if ( nStart ) 1007 Erase( 0, nStart ); 1008 1009 sal_Int32 nEnd = mpData->mnLen; 1010 while ( nEnd && (mpData->maStr[nEnd-1] == c) ) 1011 nEnd--; 1012 if ( nEnd != mpData->mnLen ) 1013 Erase( static_cast< xub_StrLen >(nEnd) ); 1014 1015 return *this; 1016 } 1017 1018 // ----------------------------------------------------------------------- 1019 1020 STRING& STRING::EraseAllChars( STRCODE c ) 1021 { 1022 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1023 1024 sal_Int32 nCount = 0; 1025 for (sal_Int32 i = 0; i < mpData->mnLen; ++i) { 1026 if ( mpData->maStr[i] == c ) 1027 ++nCount; 1028 } 1029 1030 if ( nCount ) 1031 { 1032 if ( nCount == mpData->mnLen ) 1033 { 1034 STRING_NEW((STRING_TYPE **)&mpData); 1035 } 1036 else 1037 { 1038 // Neuen String anlegen 1039 STRINGDATA* pNewData = ImplAllocData( mpData->mnLen-nCount ); 1040 1041 // Alten String kopieren und initialisieren 1042 nCount = 0; 1043 for( xub_StrLen j = 0; j < mpData->mnLen; ++j ) 1044 { 1045 if ( mpData->maStr[j] != c ) 1046 { 1047 pNewData->maStr[nCount] = mpData->maStr[j]; 1048 ++nCount; 1049 } 1050 } 1051 1052 // Alte Daten loeschen und Neue zuweisen 1053 STRING_RELEASE((STRING_TYPE *)mpData); 1054 mpData = pNewData; 1055 } 1056 } 1057 1058 return *this; 1059 } 1060 1061 // ----------------------------------------------------------------------- 1062 1063 STRING& STRING::Reverse() 1064 { 1065 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1066 1067 if ( !mpData->mnLen ) 1068 return *this; 1069 1070 // Daten kopieren, wenn noetig 1071 ImplCopyData(); 1072 1073 // Reverse 1074 sal_Int32 nCount = mpData->mnLen / 2; 1075 for ( sal_Int32 i = 0; i < nCount; ++i ) 1076 { 1077 STRCODE cTemp = mpData->maStr[i]; 1078 mpData->maStr[i] = mpData->maStr[mpData->mnLen-i-1]; 1079 mpData->maStr[mpData->mnLen-i-1] = cTemp; 1080 } 1081 1082 return *this; 1083 } 1084 1085 // ----------------------------------------------------------------------- 1086 1087 STRING& STRING::ToLowerAscii() 1088 { 1089 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1090 1091 sal_Int32 nIndex = 0; 1092 sal_Int32 nLen = mpData->mnLen; 1093 STRCODE* pStr = mpData->maStr; 1094 while ( nIndex < nLen ) 1095 { 1096 // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln 1097 if ( (*pStr >= 65) && (*pStr <= 90) ) 1098 { 1099 // Daten kopieren, wenn noetig 1100 pStr = ImplCopyStringData( pStr ); 1101 *pStr += 32; 1102 } 1103 1104 ++pStr, 1105 ++nIndex; 1106 } 1107 1108 return *this; 1109 } 1110 1111 // ----------------------------------------------------------------------- 1112 1113 STRING& STRING::ToUpperAscii() 1114 { 1115 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1116 1117 sal_Int32 nIndex = 0; 1118 sal_Int32 nLen = mpData->mnLen; 1119 STRCODE* pStr = mpData->maStr; 1120 while ( nIndex < nLen ) 1121 { 1122 // Ist das Zeichen zwischen 'a' und 'z' dann umwandeln 1123 if ( (*pStr >= 97) && (*pStr <= 122) ) 1124 { 1125 // Daten kopieren, wenn noetig 1126 pStr = ImplCopyStringData( pStr ); 1127 *pStr -= 32; 1128 } 1129 1130 ++pStr, 1131 ++nIndex; 1132 } 1133 1134 return *this; 1135 } 1136 1137 // ----------------------------------------------------------------------- 1138 1139 STRING& STRING::ConvertLineEnd( LineEnd eLineEnd ) 1140 { 1141 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1142 1143 // Zeilenumbrueche ermitteln und neue Laenge berechnen 1144 sal_Bool bConvert = sal_False; // Muss konvertiert werden 1145 const STRCODE* pStr = mpData->maStr; // damit es schneller geht 1146 xub_StrLen nLineEndLen = (eLineEnd == LINEEND_CRLF) ? 2 : 1; 1147 xub_StrLen nLen = 0; // Ziel-Laenge 1148 xub_StrLen i = 0; // Source-Zaehler 1149 1150 while ( i < mpData->mnLen ) 1151 { 1152 // Bei \r oder \n gibt es neuen Zeilenumbruch 1153 if ( (pStr[i] == _CR) || (pStr[i] == _LF) ) 1154 { 1155 nLen = nLen + nLineEndLen; 1156 1157 // Wenn schon gesetzt, dann brauchen wir keine aufwendige Abfrage 1158 if ( !bConvert ) 1159 { 1160 // Muessen wir Konvertieren 1161 if ( ((eLineEnd != LINEEND_LF) && (pStr[i] == _LF)) || 1162 ((eLineEnd == LINEEND_CRLF) && (pStr[i+1] != _LF)) || 1163 ((eLineEnd == LINEEND_LF) && 1164 ((pStr[i] == _CR) || (pStr[i+1] == _CR))) || 1165 ((eLineEnd == LINEEND_CR) && 1166 ((pStr[i] == _LF) || (pStr[i+1] == _LF))) ) 1167 bConvert = sal_True; 1168 } 1169 1170 // \r\n oder \n\r, dann Zeichen ueberspringen 1171 if ( ((pStr[i+1] == _CR) || (pStr[i+1] == _LF)) && 1172 (pStr[i] != pStr[i+1]) ) 1173 ++i; 1174 } 1175 else 1176 ++nLen; 1177 ++i; 1178 1179 // Wenn String zu lang, dann konvertieren wir nicht 1180 if ( nLen >= STRING_MAXLEN ) 1181 return *this; 1182 } 1183 1184 // Zeilenumbrueche konvertieren 1185 if ( bConvert ) 1186 { 1187 // Neuen String anlegen 1188 STRINGDATA* pNewData = ImplAllocData( nLen ); 1189 xub_StrLen j = 0; 1190 i = 0; 1191 while ( i < mpData->mnLen ) 1192 { 1193 // Bei \r oder \n gibt es neuen Zeilenumbruch 1194 if ( (pStr[i] == _CR) || (pStr[i] == _LF) ) 1195 { 1196 if ( eLineEnd == LINEEND_CRLF ) 1197 { 1198 pNewData->maStr[j] = _CR; 1199 pNewData->maStr[j+1] = _LF; 1200 j += 2; 1201 } 1202 else 1203 { 1204 if ( eLineEnd == LINEEND_CR ) 1205 pNewData->maStr[j] = _CR; 1206 else 1207 pNewData->maStr[j] = _LF; 1208 ++j; 1209 } 1210 1211 if ( ((pStr[i+1] == _CR) || (pStr[i+1] == _LF)) && 1212 (pStr[i] != pStr[i+1]) ) 1213 ++i; 1214 } 1215 else 1216 { 1217 pNewData->maStr[j] = mpData->maStr[i]; 1218 ++j; 1219 } 1220 1221 ++i; 1222 } 1223 1224 // Alte Daten loeschen und Neue zuweisen 1225 STRING_RELEASE((STRING_TYPE *)mpData); 1226 mpData = pNewData; 1227 } 1228 1229 return *this; 1230 } 1231 1232 // ----------------------------------------------------------------------- 1233 1234 StringCompare STRING::CompareTo( const STRING& rStr, xub_StrLen nLen ) const 1235 { 1236 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1237 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 1238 1239 // Auf Gleichheit der Pointer testen 1240 if ( mpData == rStr.mpData ) 1241 return COMPARE_EQUAL; 1242 1243 // Maximale Laenge ermitteln 1244 if ( mpData->mnLen < nLen ) 1245 nLen = static_cast< xub_StrLen >(mpData->mnLen+1); 1246 if ( rStr.mpData->mnLen < nLen ) 1247 nLen = static_cast< xub_StrLen >(rStr.mpData->mnLen+1); 1248 1249 // String vergleichen 1250 sal_Int32 nCompare = ImplStringCompareWithoutZero( mpData->maStr, rStr.mpData->maStr, nLen ); 1251 1252 // Rueckgabewert anpassen 1253 if ( nCompare == 0 ) 1254 return COMPARE_EQUAL; 1255 else if ( nCompare < 0 ) 1256 return COMPARE_LESS; 1257 else 1258 return COMPARE_GREATER; 1259 } 1260 1261 // ----------------------------------------------------------------------- 1262 1263 StringCompare STRING::CompareTo( const STRCODE* pCharStr, xub_StrLen nLen ) const 1264 { 1265 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1266 1267 // String vergleichen 1268 sal_Int32 nCompare = ImplStringCompare( mpData->maStr, pCharStr, nLen ); 1269 1270 // Rueckgabewert anpassen 1271 if ( nCompare == 0 ) 1272 return COMPARE_EQUAL; 1273 else if ( nCompare < 0 ) 1274 return COMPARE_LESS; 1275 else 1276 return COMPARE_GREATER; 1277 } 1278 1279 // ----------------------------------------------------------------------- 1280 1281 StringCompare STRING::CompareIgnoreCaseToAscii( const STRING& rStr, 1282 xub_StrLen nLen ) const 1283 { 1284 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1285 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 1286 1287 // Auf Gleichheit der Pointer testen 1288 if ( mpData == rStr.mpData ) 1289 return COMPARE_EQUAL; 1290 1291 // Maximale Laenge ermitteln 1292 if ( mpData->mnLen < nLen ) 1293 nLen = static_cast< xub_StrLen >(mpData->mnLen+1); 1294 if ( rStr.mpData->mnLen < nLen ) 1295 nLen = static_cast< xub_StrLen >(rStr.mpData->mnLen+1); 1296 1297 // String vergleichen 1298 sal_Int32 nCompare = ImplStringICompareWithoutZero( mpData->maStr, rStr.mpData->maStr, nLen ); 1299 1300 // Rueckgabewert anpassen 1301 if ( nCompare == 0 ) 1302 return COMPARE_EQUAL; 1303 else if ( nCompare < 0 ) 1304 return COMPARE_LESS; 1305 else 1306 return COMPARE_GREATER; 1307 } 1308 1309 // ----------------------------------------------------------------------- 1310 1311 StringCompare STRING::CompareIgnoreCaseToAscii( const STRCODE* pCharStr, 1312 xub_StrLen nLen ) const 1313 { 1314 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1315 1316 // String vergleichen 1317 sal_Int32 nCompare = ImplStringICompare( mpData->maStr, pCharStr, nLen ); 1318 1319 // Rueckgabewert anpassen 1320 if ( nCompare == 0 ) 1321 return COMPARE_EQUAL; 1322 else if ( nCompare < 0 ) 1323 return COMPARE_LESS; 1324 else 1325 return COMPARE_GREATER; 1326 } 1327 1328 // ----------------------------------------------------------------------- 1329 1330 sal_Bool STRING::Equals( const STRING& rStr ) const 1331 { 1332 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1333 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 1334 1335 // Sind die Daten gleich 1336 if ( mpData == rStr.mpData ) 1337 return sal_True; 1338 1339 // Gleiche Laenge 1340 if ( mpData->mnLen != rStr.mpData->mnLen ) 1341 return sal_False; 1342 1343 // String vergleichen 1344 return (ImplStringCompareWithoutZero( mpData->maStr, rStr.mpData->maStr, mpData->mnLen ) == 0); 1345 } 1346 1347 // ----------------------------------------------------------------------- 1348 1349 sal_Bool STRING::Equals( const STRCODE* pCharStr ) const 1350 { 1351 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1352 1353 return (ImplStringCompare( mpData->maStr, pCharStr ) == 0); 1354 } 1355 1356 // ----------------------------------------------------------------------- 1357 1358 sal_Bool STRING::EqualsIgnoreCaseAscii( const STRING& rStr ) const 1359 { 1360 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1361 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 1362 1363 // Sind die Daten gleich 1364 if ( mpData == rStr.mpData ) 1365 return sal_True; 1366 1367 // Gleiche Laenge 1368 if ( mpData->mnLen != rStr.mpData->mnLen ) 1369 return sal_False; 1370 1371 // String vergleichen 1372 return (ImplStringICompareWithoutZero( mpData->maStr, rStr.mpData->maStr, mpData->mnLen ) == 0); 1373 } 1374 1375 // ----------------------------------------------------------------------- 1376 1377 sal_Bool STRING::EqualsIgnoreCaseAscii( const STRCODE* pCharStr ) const 1378 { 1379 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1380 1381 return (ImplStringICompare( mpData->maStr, pCharStr ) == 0); 1382 } 1383 1384 // ----------------------------------------------------------------------- 1385 1386 sal_Bool STRING::Equals( const STRING& rStr, xub_StrLen nIndex, xub_StrLen nLen ) const 1387 { 1388 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1389 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 1390 1391 // Are there enough codes for comparing? 1392 if ( nIndex > mpData->mnLen ) 1393 return (rStr.mpData->mnLen == 0); 1394 sal_Int32 nMaxLen = mpData->mnLen-nIndex; 1395 if ( nMaxLen < nLen ) 1396 { 1397 if ( rStr.mpData->mnLen != nMaxLen ) 1398 return sal_False; 1399 nLen = static_cast< xub_StrLen >(nMaxLen); 1400 } 1401 1402 // String vergleichen 1403 return (ImplStringCompareWithoutZero( mpData->maStr+nIndex, rStr.mpData->maStr, nLen ) == 0); 1404 } 1405 1406 // ----------------------------------------------------------------------- 1407 1408 sal_Bool STRING::Equals( const STRCODE* pCharStr, xub_StrLen nIndex, xub_StrLen nLen ) const 1409 { 1410 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1411 1412 // Are there enough codes for comparing? 1413 if ( nIndex > mpData->mnLen ) 1414 return (*pCharStr == 0); 1415 1416 return (ImplStringCompare( mpData->maStr+nIndex, pCharStr, nLen ) == 0); 1417 } 1418 1419 // ----------------------------------------------------------------------- 1420 1421 sal_Bool STRING::EqualsIgnoreCaseAscii( const STRING& rStr, xub_StrLen nIndex, xub_StrLen nLen ) const 1422 { 1423 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1424 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 1425 1426 // Are there enough codes for comparing? 1427 if ( nIndex > mpData->mnLen ) 1428 return (rStr.mpData->mnLen == 0); 1429 sal_Int32 nMaxLen = mpData->mnLen-nIndex; 1430 if ( nMaxLen < nLen ) 1431 { 1432 if ( rStr.mpData->mnLen != nMaxLen ) 1433 return sal_False; 1434 nLen = static_cast< xub_StrLen >(nMaxLen); 1435 } 1436 1437 // String vergleichen 1438 return (ImplStringICompareWithoutZero( mpData->maStr+nIndex, rStr.mpData->maStr, nLen ) == 0); 1439 } 1440 1441 // ----------------------------------------------------------------------- 1442 1443 sal_Bool STRING::EqualsIgnoreCaseAscii( const STRCODE* pCharStr, xub_StrLen nIndex, xub_StrLen nLen ) const 1444 { 1445 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1446 1447 // Are there enough codes for comparing? 1448 if ( nIndex > mpData->mnLen ) 1449 return (*pCharStr == 0); 1450 1451 return (ImplStringICompare( mpData->maStr+nIndex, pCharStr, nLen ) == 0); 1452 } 1453 1454 // ----------------------------------------------------------------------- 1455 1456 xub_StrLen STRING::Match( const STRING& rStr ) const 1457 { 1458 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1459 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 1460 1461 // Ist dieser String leer 1462 if ( !mpData->mnLen ) 1463 return STRING_MATCH; 1464 1465 // Suche bis Stringende nach dem ersten nicht uebereinstimmenden Zeichen 1466 const STRCODE* pStr1 = mpData->maStr; 1467 const STRCODE* pStr2 = rStr.mpData->maStr; 1468 xub_StrLen i = 0; 1469 while ( i < mpData->mnLen ) 1470 { 1471 // Stimmt das Zeichen nicht ueberein, dann abbrechen 1472 if ( *pStr1 != *pStr2 ) 1473 return i; 1474 ++pStr1, 1475 ++pStr2, 1476 ++i; 1477 } 1478 1479 return STRING_MATCH; 1480 } 1481 1482 // ----------------------------------------------------------------------- 1483 1484 xub_StrLen STRING::Match( const STRCODE* pCharStr ) const 1485 { 1486 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1487 1488 // Ist dieser String leer 1489 if ( !mpData->mnLen ) 1490 return STRING_MATCH; 1491 1492 // Suche bis Stringende nach dem ersten nicht uebereinstimmenden Zeichen 1493 const STRCODE* pStr = mpData->maStr; 1494 xub_StrLen i = 0; 1495 while ( i < mpData->mnLen ) 1496 { 1497 // Stimmt das Zeichen nicht ueberein, dann abbrechen 1498 if ( *pStr != *pCharStr ) 1499 return i; 1500 ++pStr, 1501 ++pCharStr, 1502 ++i; 1503 } 1504 1505 return STRING_MATCH; 1506 } 1507 1508 // ----------------------------------------------------------------------- 1509 1510 xub_StrLen STRING::Search( STRCODE c, xub_StrLen nIndex ) const 1511 { 1512 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1513 1514 sal_Int32 nLen = mpData->mnLen; 1515 const STRCODE* pStr = mpData->maStr; 1516 pStr += nIndex; 1517 while ( nIndex < nLen ) 1518 { 1519 if ( *pStr == c ) 1520 return nIndex; 1521 ++pStr, 1522 ++nIndex; 1523 } 1524 1525 return STRING_NOTFOUND; 1526 } 1527 1528 // ----------------------------------------------------------------------- 1529 1530 xub_StrLen STRING::Search( const STRING& rStr, xub_StrLen nIndex ) const 1531 { 1532 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1533 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 1534 1535 sal_Int32 nLen = mpData->mnLen; 1536 sal_Int32 nStrLen = rStr.mpData->mnLen; 1537 1538 // Falls die Laenge des uebergebenen Strings 0 ist oder der Index 1539 // hinter dem String liegt, dann wurde der String nicht gefunden 1540 if ( !nStrLen || (nIndex >= nLen) ) 1541 return STRING_NOTFOUND; 1542 1543 const STRCODE* pStr1 = mpData->maStr; 1544 pStr1 += nIndex; 1545 1546 if ( nStrLen == 1 ) 1547 { 1548 STRCODE cSearch = rStr.mpData->maStr[0]; 1549 while ( nIndex < nLen ) 1550 { 1551 if ( *pStr1 == cSearch ) 1552 return nIndex; 1553 ++pStr1, 1554 ++nIndex; 1555 } 1556 } 1557 else 1558 { 1559 const STRCODE* pStr2 = rStr.mpData->maStr; 1560 1561 // Nur innerhalb des Strings suchen 1562 while ( nLen - nIndex >= nStrLen ) 1563 { 1564 // Stimmt der String ueberein 1565 if ( ImplStringCompareWithoutZero( pStr1, pStr2, nStrLen ) == 0 ) 1566 return nIndex; 1567 ++pStr1, 1568 ++nIndex; 1569 } 1570 } 1571 1572 return STRING_NOTFOUND; 1573 } 1574 1575 // ----------------------------------------------------------------------- 1576 1577 xub_StrLen STRING::Search( const STRCODE* pCharStr, xub_StrLen nIndex ) const 1578 { 1579 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1580 1581 sal_Int32 nLen = mpData->mnLen; 1582 xub_StrLen nStrLen = ImplStringLen( pCharStr ); 1583 1584 // Falls die Laenge des uebergebenen Strings 0 ist oder der Index 1585 // hinter dem String liegt, dann wurde der String nicht gefunden 1586 if ( !nStrLen || (nIndex >= nLen) ) 1587 return STRING_NOTFOUND; 1588 1589 const STRCODE* pStr = mpData->maStr; 1590 pStr += nIndex; 1591 1592 if ( nStrLen == 1 ) 1593 { 1594 STRCODE cSearch = *pCharStr; 1595 while ( nIndex < nLen ) 1596 { 1597 if ( *pStr == cSearch ) 1598 return nIndex; 1599 ++pStr, 1600 ++nIndex; 1601 } 1602 } 1603 else 1604 { 1605 // Nur innerhalb des Strings suchen 1606 while ( nLen - nIndex >= nStrLen ) 1607 { 1608 // Stimmt der String ueberein 1609 if ( ImplStringCompareWithoutZero( pStr, pCharStr, nStrLen ) == 0 ) 1610 return nIndex; 1611 ++pStr, 1612 ++nIndex; 1613 } 1614 } 1615 1616 return STRING_NOTFOUND; 1617 } 1618 1619 // ----------------------------------------------------------------------- 1620 1621 xub_StrLen STRING::SearchBackward( STRCODE c, xub_StrLen nIndex ) const 1622 { 1623 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1624 1625 if ( nIndex > mpData->mnLen ) 1626 nIndex = (xub_StrLen)mpData->mnLen; 1627 1628 const STRCODE* pStr = mpData->maStr; 1629 pStr += nIndex; 1630 1631 while ( nIndex ) 1632 { 1633 nIndex--; 1634 pStr--; 1635 if ( *pStr == c ) 1636 return nIndex; 1637 } 1638 1639 return STRING_NOTFOUND; 1640 } 1641 1642 // ----------------------------------------------------------------------- 1643 1644 xub_StrLen STRING::SearchChar( const STRCODE* pChars, xub_StrLen nIndex ) const 1645 { 1646 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1647 1648 sal_Int32 nLen = mpData->mnLen; 1649 const STRCODE* pStr = mpData->maStr; 1650 pStr += nIndex; 1651 while ( nIndex < nLen ) 1652 { 1653 STRCODE c = *pStr; 1654 const STRCODE* pCompStr = pChars; 1655 while ( *pCompStr ) 1656 { 1657 if ( *pCompStr == c ) 1658 return nIndex; 1659 ++pCompStr; 1660 } 1661 ++pStr, 1662 ++nIndex; 1663 } 1664 1665 return STRING_NOTFOUND; 1666 } 1667 1668 // ----------------------------------------------------------------------- 1669 1670 xub_StrLen STRING::SearchCharBackward( const STRCODE* pChars, xub_StrLen nIndex ) const 1671 { 1672 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1673 1674 if ( nIndex > mpData->mnLen ) 1675 nIndex = (xub_StrLen)mpData->mnLen; 1676 1677 const STRCODE* pStr = mpData->maStr; 1678 pStr += nIndex; 1679 1680 while ( nIndex ) 1681 { 1682 nIndex--; 1683 pStr--; 1684 1685 STRCODE c =*pStr; 1686 const STRCODE* pCompStr = pChars; 1687 while ( *pCompStr ) 1688 { 1689 if ( *pCompStr == c ) 1690 return nIndex; 1691 ++pCompStr; 1692 } 1693 } 1694 1695 return STRING_NOTFOUND; 1696 } 1697 1698 // ----------------------------------------------------------------------- 1699 1700 xub_StrLen STRING::SearchAndReplace( STRCODE c, STRCODE cRep, xub_StrLen nIndex ) 1701 { 1702 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1703 1704 sal_Int32 nLen = mpData->mnLen; 1705 const STRCODE* pStr = mpData->maStr; 1706 pStr += nIndex; 1707 while ( nIndex < nLen ) 1708 { 1709 if ( *pStr == c ) 1710 { 1711 ImplCopyData(); 1712 mpData->maStr[nIndex] = cRep; 1713 return nIndex; 1714 } 1715 ++pStr, 1716 ++nIndex; 1717 } 1718 1719 return STRING_NOTFOUND; 1720 } 1721 1722 // ----------------------------------------------------------------------- 1723 1724 xub_StrLen STRING::SearchAndReplace( const STRING& rStr, const STRING& rRepStr, 1725 xub_StrLen nIndex ) 1726 { 1727 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1728 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 1729 DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING ); 1730 1731 xub_StrLen nSPos = Search( rStr, nIndex ); 1732 if ( nSPos != STRING_NOTFOUND ) 1733 Replace( nSPos, rStr.Len(), rRepStr ); 1734 1735 return nSPos; 1736 } 1737 1738 // ----------------------------------------------------------------------- 1739 1740 xub_StrLen STRING::SearchAndReplace( const STRCODE* pCharStr, const STRING& rRepStr, 1741 xub_StrLen nIndex ) 1742 { 1743 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1744 DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING ); 1745 1746 xub_StrLen nSPos = Search( pCharStr, nIndex ); 1747 if ( nSPos != STRING_NOTFOUND ) 1748 Replace( nSPos, ImplStringLen( pCharStr ), rRepStr ); 1749 1750 return nSPos; 1751 } 1752 1753 // ----------------------------------------------------------------------- 1754 1755 void STRING::SearchAndReplaceAll( STRCODE c, STRCODE cRep ) 1756 { 1757 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1758 1759 sal_Int32 nLen = mpData->mnLen; 1760 const STRCODE* pStr = mpData->maStr; 1761 sal_Int32 nIndex = 0; 1762 while ( nIndex < nLen ) 1763 { 1764 if ( *pStr == c ) 1765 { 1766 ImplCopyData(); 1767 mpData->maStr[nIndex] = cRep; 1768 } 1769 ++pStr, 1770 ++nIndex; 1771 } 1772 } 1773 1774 // ----------------------------------------------------------------------- 1775 1776 void STRING::SearchAndReplaceAll( const STRCODE* pCharStr, const STRING& rRepStr ) 1777 { 1778 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1779 DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING ); 1780 1781 xub_StrLen nCharLen = ImplStringLen( pCharStr ); 1782 xub_StrLen nSPos = Search( pCharStr, 0 ); 1783 while ( nSPos != STRING_NOTFOUND ) 1784 { 1785 Replace( nSPos, nCharLen, rRepStr ); 1786 nSPos = nSPos + rRepStr.Len(); 1787 nSPos = Search( pCharStr, nSPos ); 1788 } 1789 } 1790 1791 // ----------------------------------------------------------------------- 1792 1793 void STRING::SearchAndReplaceAll( const STRING& rStr, const STRING& rRepStr ) 1794 { 1795 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1796 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 1797 DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING ); 1798 1799 xub_StrLen nSPos = Search( rStr, 0 ); 1800 while ( nSPos != STRING_NOTFOUND ) 1801 { 1802 Replace( nSPos, rStr.Len(), rRepStr ); 1803 nSPos = nSPos + rRepStr.Len(); 1804 nSPos = Search( rStr, nSPos ); 1805 } 1806 } 1807 1808 // ----------------------------------------------------------------------- 1809 1810 xub_StrLen STRING::GetTokenCount( STRCODE cTok ) const 1811 { 1812 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1813 1814 // Leerer String: TokenCount per Definition 0 1815 if ( !mpData->mnLen ) 1816 return 0; 1817 1818 xub_StrLen nTokCount = 1; 1819 sal_Int32 nLen = mpData->mnLen; 1820 const STRCODE* pStr = mpData->maStr; 1821 sal_Int32 nIndex = 0; 1822 while ( nIndex < nLen ) 1823 { 1824 // Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount 1825 if ( *pStr == cTok ) 1826 ++nTokCount; 1827 ++pStr, 1828 ++nIndex; 1829 } 1830 1831 return nTokCount; 1832 } 1833 1834 // ----------------------------------------------------------------------- 1835 1836 void STRING::SetToken( xub_StrLen nToken, STRCODE cTok, const STRING& rStr, 1837 xub_StrLen nIndex ) 1838 { 1839 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1840 DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING ); 1841 1842 const STRCODE* pStr = mpData->maStr; 1843 xub_StrLen nLen = (xub_StrLen)mpData->mnLen; 1844 xub_StrLen nTok = 0; 1845 xub_StrLen nFirstChar = nIndex; 1846 xub_StrLen i = nFirstChar; 1847 1848 // Bestimme die Token-Position und Laenge 1849 pStr += i; 1850 while ( i < nLen ) 1851 { 1852 // Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount 1853 if ( *pStr == cTok ) 1854 { 1855 ++nTok; 1856 1857 if ( nTok == nToken ) 1858 nFirstChar = i+1; 1859 else 1860 { 1861 if ( nTok > nToken ) 1862 break; 1863 } 1864 } 1865 1866 ++pStr, 1867 ++i; 1868 } 1869 1870 if ( nTok >= nToken ) 1871 Replace( nFirstChar, i-nFirstChar, rStr ); 1872 } 1873 1874 // ----------------------------------------------------------------------- 1875 1876 STRING STRING::GetToken( xub_StrLen nToken, STRCODE cTok, xub_StrLen& rIndex ) const 1877 { 1878 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1879 1880 const STRCODE* pStr = mpData->maStr; 1881 xub_StrLen nLen = (xub_StrLen)mpData->mnLen; 1882 xub_StrLen nTok = 0; 1883 xub_StrLen nFirstChar = rIndex; 1884 xub_StrLen i = nFirstChar; 1885 1886 // Bestimme die Token-Position und Laenge 1887 pStr += i; 1888 while ( i < nLen ) 1889 { 1890 // Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount 1891 if ( *pStr == cTok ) 1892 { 1893 ++nTok; 1894 1895 if ( nTok == nToken ) 1896 nFirstChar = i+1; 1897 else 1898 { 1899 if ( nTok > nToken ) 1900 break; 1901 } 1902 } 1903 1904 ++pStr, 1905 ++i; 1906 } 1907 1908 if ( nTok >= nToken ) 1909 { 1910 if ( i < nLen ) 1911 rIndex = i+1; 1912 else 1913 rIndex = STRING_NOTFOUND; 1914 return Copy( nFirstChar, i-nFirstChar ); 1915 } 1916 else 1917 { 1918 rIndex = STRING_NOTFOUND; 1919 return STRING(); 1920 } 1921 } 1922 1923 // ----------------------------------------------------------------------- 1924 1925 xub_StrLen STRING::GetQuotedTokenCount( const STRING& rQuotedPairs, STRCODE cTok ) const 1926 { 1927 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1928 DBG_CHKOBJ( &rQuotedPairs, STRING, DBGCHECKSTRING ); 1929 DBG_ASSERT( !(rQuotedPairs.Len()%2), "String::GetQuotedTokenCount() - QuotedString%2 != 0" ); 1930 DBG_ASSERT( rQuotedPairs.Search(cTok) == STRING_NOTFOUND, "String::GetQuotedTokenCount() - cTok in QuotedString" ); 1931 1932 // Leerer String: TokenCount per Definition 0 1933 if ( !mpData->mnLen ) 1934 return 0; 1935 1936 xub_StrLen nTokCount = 1; 1937 sal_Int32 nLen = mpData->mnLen; 1938 xub_StrLen nQuotedLen = rQuotedPairs.Len(); 1939 STRCODE cQuotedEndChar = 0; 1940 const STRCODE* pQuotedStr = rQuotedPairs.mpData->maStr; 1941 const STRCODE* pStr = mpData->maStr; 1942 sal_Int32 nIndex = 0; 1943 while ( nIndex < nLen ) 1944 { 1945 STRCODE c = *pStr; 1946 if ( cQuotedEndChar ) 1947 { 1948 // Ende des Quotes erreicht ? 1949 if ( c == cQuotedEndChar ) 1950 cQuotedEndChar = 0; 1951 } 1952 else 1953 { 1954 // Ist das Zeichen ein Quote-Anfang-Zeichen ? 1955 xub_StrLen nQuoteIndex = 0; 1956 while ( nQuoteIndex < nQuotedLen ) 1957 { 1958 if ( pQuotedStr[nQuoteIndex] == c ) 1959 { 1960 cQuotedEndChar = pQuotedStr[nQuoteIndex+1]; 1961 break; 1962 } 1963 else 1964 nQuoteIndex += 2; 1965 } 1966 1967 // Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount 1968 if ( c == cTok ) 1969 ++nTokCount; 1970 } 1971 1972 ++pStr, 1973 ++nIndex; 1974 } 1975 1976 return nTokCount; 1977 } 1978 1979 // ----------------------------------------------------------------------- 1980 1981 STRING STRING::GetQuotedToken( xub_StrLen nToken, const STRING& rQuotedPairs, 1982 STRCODE cTok, xub_StrLen& rIndex ) const 1983 { 1984 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 1985 DBG_CHKOBJ( &rQuotedPairs, STRING, DBGCHECKSTRING ); 1986 DBG_ASSERT( !(rQuotedPairs.Len()%2), "String::GetQuotedToken() - QuotedString%2 != 0" ); 1987 DBG_ASSERT( rQuotedPairs.Search(cTok) == STRING_NOTFOUND, "String::GetQuotedToken() - cTok in QuotedString" ); 1988 1989 const STRCODE* pStr = mpData->maStr; 1990 const STRCODE* pQuotedStr = rQuotedPairs.mpData->maStr; 1991 STRCODE cQuotedEndChar = 0; 1992 xub_StrLen nQuotedLen = rQuotedPairs.Len(); 1993 xub_StrLen nLen = (xub_StrLen)mpData->mnLen; 1994 xub_StrLen nTok = 0; 1995 xub_StrLen nFirstChar = rIndex; 1996 xub_StrLen i = nFirstChar; 1997 1998 // Bestimme die Token-Position und Laenge 1999 pStr += i; 2000 while ( i < nLen ) 2001 { 2002 STRCODE c = *pStr; 2003 if ( cQuotedEndChar ) 2004 { 2005 // Ende des Quotes erreicht ? 2006 if ( c == cQuotedEndChar ) 2007 cQuotedEndChar = 0; 2008 } 2009 else 2010 { 2011 // Ist das Zeichen ein Quote-Anfang-Zeichen ? 2012 xub_StrLen nQuoteIndex = 0; 2013 while ( nQuoteIndex < nQuotedLen ) 2014 { 2015 if ( pQuotedStr[nQuoteIndex] == c ) 2016 { 2017 cQuotedEndChar = pQuotedStr[nQuoteIndex+1]; 2018 break; 2019 } 2020 else 2021 nQuoteIndex += 2; 2022 } 2023 2024 // Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount 2025 if ( c == cTok ) 2026 { 2027 ++nTok; 2028 2029 if ( nTok == nToken ) 2030 nFirstChar = i+1; 2031 else 2032 { 2033 if ( nTok > nToken ) 2034 break; 2035 } 2036 } 2037 } 2038 2039 ++pStr, 2040 ++i; 2041 } 2042 2043 if ( nTok >= nToken ) 2044 { 2045 if ( i < nLen ) 2046 rIndex = i+1; 2047 else 2048 rIndex = STRING_NOTFOUND; 2049 return Copy( nFirstChar, i-nFirstChar ); 2050 } 2051 else 2052 { 2053 rIndex = STRING_NOTFOUND; 2054 return STRING(); 2055 } 2056 } 2057 2058 // ----------------------------------------------------------------------- 2059 2060 STRCODE* STRING::GetBufferAccess() 2061 { 2062 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 2063 2064 // Daten kopieren, wenn noetig 2065 if ( mpData->mnLen ) 2066 ImplCopyData(); 2067 2068 // Pointer auf den String zurueckgeben 2069 return mpData->maStr; 2070 } 2071 2072 // ----------------------------------------------------------------------- 2073 2074 void STRING::ReleaseBufferAccess( xub_StrLen nLen ) 2075 { 2076 // Hier ohne Funktionstest, da String nicht konsistent 2077 DBG_CHKTHIS( STRING, NULL ); 2078 DBG_ASSERT( mpData->mnRefCount == 1, "String::ReleaseCharStr() called for String with RefCount" ); 2079 2080 if ( nLen > mpData->mnLen ) 2081 nLen = ImplStringLen( mpData->maStr ); 2082 OSL_ASSERT(nLen <= mpData->mnLen); 2083 if ( !nLen ) 2084 { 2085 STRING_NEW((STRING_TYPE **)&mpData); 2086 } 2087 // Bei mehr als 8 Zeichen unterschied, kuerzen wir den Buffer 2088 else if ( mpData->mnLen - nLen > 8 ) 2089 { 2090 STRINGDATA* pNewData = ImplAllocData( nLen ); 2091 memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) ); 2092 STRING_RELEASE((STRING_TYPE *)mpData); 2093 mpData = pNewData; 2094 } 2095 else 2096 mpData->mnLen = nLen; 2097 } 2098 2099 // ----------------------------------------------------------------------- 2100 2101 STRCODE* STRING::AllocBuffer( xub_StrLen nLen ) 2102 { 2103 DBG_CHKTHIS( STRING, DBGCHECKSTRING ); 2104 2105 STRING_RELEASE((STRING_TYPE *)mpData); 2106 if ( nLen ) 2107 mpData = ImplAllocData( nLen ); 2108 else 2109 { 2110 mpData = NULL; 2111 STRING_NEW((STRING_TYPE **)&mpData); 2112 } 2113 2114 return mpData->maStr; 2115 } 2116