1 /* 2 ****************************************************************************** 3 * 4 * Copyright (C) 1998-2009, International Business Machines 5 * Corporation and others. All Rights Reserved. 6 * 7 ****************************************************************************** 8 * 9 * File ustring.h 10 * 11 * Modification History: 12 * 13 * Date Name Description 14 * 12/07/98 bertrand Creation. 15 ****************************************************************************** 16 */ 17 18 #include "unicode/utypes.h" 19 #include "unicode/putil.h" 20 #include "unicode/ustring.h" 21 #include "cstring.h" 22 #include "cwchar.h" 23 #include "cmemory.h" 24 #include "ustr_imp.h" 25 26 /* ANSI string.h - style functions ------------------------------------------ */ 27 28 /* U+ffff is the highest BMP code point, the highest one that fits into a 16-bit UChar */ 29 #define U_BMP_MAX 0xffff 30 31 /* Forward binary string search functions ----------------------------------- */ 32 33 /* 34 * Test if a substring match inside a string is at code point boundaries. 35 * All pointers refer to the same buffer. 36 * The limit pointer may be NULL, all others must be real pointers. 37 */ 38 static U_INLINE UBool 39 isMatchAtCPBoundary(const UChar *start, const UChar *match, const UChar *matchLimit, const UChar *limit) { 40 if(U16_IS_TRAIL(*match) && start!=match && U16_IS_LEAD(*(match-1))) { 41 /* the leading edge of the match is in the middle of a surrogate pair */ 42 return FALSE; 43 } 44 if(U16_IS_LEAD(*(matchLimit-1)) && match!=limit && U16_IS_TRAIL(*matchLimit)) { 45 /* the trailing edge of the match is in the middle of a surrogate pair */ 46 return FALSE; 47 } 48 return TRUE; 49 } 50 51 U_CAPI UChar * U_EXPORT2 52 u_strFindFirst(const UChar *s, int32_t length, 53 const UChar *sub, int32_t subLength) { 54 const UChar *start, *p, *q, *subLimit; 55 UChar c, cs, cq; 56 57 if(sub==NULL || subLength<-1) { 58 return (UChar *)s; 59 } 60 if(s==NULL || length<-1) { 61 return NULL; 62 } 63 64 start=s; 65 66 if(length<0 && subLength<0) { 67 /* both strings are NUL-terminated */ 68 if((cs=*sub++)==0) { 69 return (UChar *)s; 70 } 71 if(*sub==0 && !U16_IS_SURROGATE(cs)) { 72 /* the substring consists of a single, non-surrogate BMP code point */ 73 return u_strchr(s, cs); 74 } 75 76 while((c=*s++)!=0) { 77 if(c==cs) { 78 /* found first substring UChar, compare rest */ 79 p=s; 80 q=sub; 81 for(;;) { 82 if((cq=*q)==0) { 83 if(isMatchAtCPBoundary(start, s-1, p, NULL)) { 84 return (UChar *)(s-1); /* well-formed match */ 85 } else { 86 break; /* no match because surrogate pair is split */ 87 } 88 } 89 if((c=*p)==0) { 90 return NULL; /* no match, and none possible after s */ 91 } 92 if(c!=cq) { 93 break; /* no match */ 94 } 95 ++p; 96 ++q; 97 } 98 } 99 } 100 101 /* not found */ 102 return NULL; 103 } 104 105 if(subLength<0) { 106 subLength=u_strlen(sub); 107 } 108 if(subLength==0) { 109 return (UChar *)s; 110 } 111 112 /* get sub[0] to search for it fast */ 113 cs=*sub++; 114 --subLength; 115 subLimit=sub+subLength; 116 117 if(subLength==0 && !U16_IS_SURROGATE(cs)) { 118 /* the substring consists of a single, non-surrogate BMP code point */ 119 return length<0 ? u_strchr(s, cs) : u_memchr(s, cs, length); 120 } 121 122 if(length<0) { 123 /* s is NUL-terminated */ 124 while((c=*s++)!=0) { 125 if(c==cs) { 126 /* found first substring UChar, compare rest */ 127 p=s; 128 q=sub; 129 for(;;) { 130 if(q==subLimit) { 131 if(isMatchAtCPBoundary(start, s-1, p, NULL)) { 132 return (UChar *)(s-1); /* well-formed match */ 133 } else { 134 break; /* no match because surrogate pair is split */ 135 } 136 } 137 if((c=*p)==0) { 138 return NULL; /* no match, and none possible after s */ 139 } 140 if(c!=*q) { 141 break; /* no match */ 142 } 143 ++p; 144 ++q; 145 } 146 } 147 } 148 } else { 149 const UChar *limit, *preLimit; 150 151 /* subLength was decremented above */ 152 if(length<=subLength) { 153 return NULL; /* s is shorter than sub */ 154 } 155 156 limit=s+length; 157 158 /* the substring must start before preLimit */ 159 preLimit=limit-subLength; 160 161 while(s!=preLimit) { 162 c=*s++; 163 if(c==cs) { 164 /* found first substring UChar, compare rest */ 165 p=s; 166 q=sub; 167 for(;;) { 168 if(q==subLimit) { 169 if(isMatchAtCPBoundary(start, s-1, p, limit)) { 170 return (UChar *)(s-1); /* well-formed match */ 171 } else { 172 break; /* no match because surrogate pair is split */ 173 } 174 } 175 if(*p!=*q) { 176 break; /* no match */ 177 } 178 ++p; 179 ++q; 180 } 181 } 182 } 183 } 184 185 /* not found */ 186 return NULL; 187 } 188 189 U_CAPI UChar * U_EXPORT2 190 u_strstr(const UChar *s, const UChar *substring) { 191 return u_strFindFirst(s, -1, substring, -1); 192 } 193 194 U_CAPI UChar * U_EXPORT2 195 u_strchr(const UChar *s, UChar c) { 196 if(U16_IS_SURROGATE(c)) { 197 /* make sure to not find half of a surrogate pair */ 198 return u_strFindFirst(s, -1, &c, 1); 199 } else { 200 UChar cs; 201 202 /* trivial search for a BMP code point */ 203 for(;;) { 204 if((cs=*s)==c) { 205 return (UChar *)s; 206 } 207 if(cs==0) { 208 return NULL; 209 } 210 ++s; 211 } 212 } 213 } 214 215 U_CAPI UChar * U_EXPORT2 216 u_strchr32(const UChar *s, UChar32 c) { 217 if((uint32_t)c<=U_BMP_MAX) { 218 /* find BMP code point */ 219 return u_strchr(s, (UChar)c); 220 } else if((uint32_t)c<=UCHAR_MAX_VALUE) { 221 /* find supplementary code point as surrogate pair */ 222 UChar cs, lead=U16_LEAD(c), trail=U16_TRAIL(c); 223 224 while((cs=*s++)!=0) { 225 if(cs==lead && *s==trail) { 226 return (UChar *)(s-1); 227 } 228 } 229 return NULL; 230 } else { 231 /* not a Unicode code point, not findable */ 232 return NULL; 233 } 234 } 235 236 U_CAPI UChar * U_EXPORT2 237 u_memchr(const UChar *s, UChar c, int32_t count) { 238 if(count<=0) { 239 return NULL; /* no string */ 240 } else if(U16_IS_SURROGATE(c)) { 241 /* make sure to not find half of a surrogate pair */ 242 return u_strFindFirst(s, count, &c, 1); 243 } else { 244 /* trivial search for a BMP code point */ 245 const UChar *limit=s+count; 246 do { 247 if(*s==c) { 248 return (UChar *)s; 249 } 250 } while(++s!=limit); 251 return NULL; 252 } 253 } 254 255 U_CAPI UChar * U_EXPORT2 256 u_memchr32(const UChar *s, UChar32 c, int32_t count) { 257 if((uint32_t)c<=U_BMP_MAX) { 258 /* find BMP code point */ 259 return u_memchr(s, (UChar)c, count); 260 } else if(count<2) { 261 /* too short for a surrogate pair */ 262 return NULL; 263 } else if((uint32_t)c<=UCHAR_MAX_VALUE) { 264 /* find supplementary code point as surrogate pair */ 265 const UChar *limit=s+count-1; /* -1 so that we do not need a separate check for the trail unit */ 266 UChar lead=U16_LEAD(c), trail=U16_TRAIL(c); 267 268 do { 269 if(*s==lead && *(s+1)==trail) { 270 return (UChar *)s; 271 } 272 } while(++s!=limit); 273 return NULL; 274 } else { 275 /* not a Unicode code point, not findable */ 276 return NULL; 277 } 278 } 279 280 /* Backward binary string search functions ---------------------------------- */ 281 282 U_CAPI UChar * U_EXPORT2 283 u_strFindLast(const UChar *s, int32_t length, 284 const UChar *sub, int32_t subLength) { 285 const UChar *start, *limit, *p, *q, *subLimit; 286 UChar c, cs; 287 288 if(sub==NULL || subLength<-1) { 289 return (UChar *)s; 290 } 291 if(s==NULL || length<-1) { 292 return NULL; 293 } 294 295 /* 296 * This implementation is more lazy than the one for u_strFindFirst(): 297 * There is no special search code for NUL-terminated strings. 298 * It does not seem to be worth it for searching substrings to 299 * search forward and find all matches like in u_strrchr() and similar. 300 * Therefore, we simply get both string lengths and search backward. 301 * 302 * markus 2002oct23 303 */ 304 305 if(subLength<0) { 306 subLength=u_strlen(sub); 307 } 308 if(subLength==0) { 309 return (UChar *)s; 310 } 311 312 /* get sub[subLength-1] to search for it fast */ 313 subLimit=sub+subLength; 314 cs=*(--subLimit); 315 --subLength; 316 317 if(subLength==0 && !U16_IS_SURROGATE(cs)) { 318 /* the substring consists of a single, non-surrogate BMP code point */ 319 return length<0 ? u_strrchr(s, cs) : u_memrchr(s, cs, length); 320 } 321 322 if(length<0) { 323 length=u_strlen(s); 324 } 325 326 /* subLength was decremented above */ 327 if(length<=subLength) { 328 return NULL; /* s is shorter than sub */ 329 } 330 331 start=s; 332 limit=s+length; 333 334 /* the substring must start no later than s+subLength */ 335 s+=subLength; 336 337 while(s!=limit) { 338 c=*(--limit); 339 if(c==cs) { 340 /* found last substring UChar, compare rest */ 341 p=limit; 342 q=subLimit; 343 for(;;) { 344 if(q==sub) { 345 if(isMatchAtCPBoundary(start, p, limit+1, start+length)) { 346 return (UChar *)p; /* well-formed match */ 347 } else { 348 break; /* no match because surrogate pair is split */ 349 } 350 } 351 if(*(--p)!=*(--q)) { 352 break; /* no match */ 353 } 354 } 355 } 356 } 357 358 /* not found */ 359 return NULL; 360 } 361 362 U_CAPI UChar * U_EXPORT2 363 u_strrstr(const UChar *s, const UChar *substring) { 364 return u_strFindLast(s, -1, substring, -1); 365 } 366 367 U_CAPI UChar * U_EXPORT2 368 u_strrchr(const UChar *s, UChar c) { 369 if(U16_IS_SURROGATE(c)) { 370 /* make sure to not find half of a surrogate pair */ 371 return u_strFindLast(s, -1, &c, 1); 372 } else { 373 const UChar *result=NULL; 374 UChar cs; 375 376 /* trivial search for a BMP code point */ 377 for(;;) { 378 if((cs=*s)==c) { 379 result=s; 380 } 381 if(cs==0) { 382 return (UChar *)result; 383 } 384 ++s; 385 } 386 } 387 } 388 389 U_CAPI UChar * U_EXPORT2 390 u_strrchr32(const UChar *s, UChar32 c) { 391 if((uint32_t)c<=U_BMP_MAX) { 392 /* find BMP code point */ 393 return u_strrchr(s, (UChar)c); 394 } else if((uint32_t)c<=UCHAR_MAX_VALUE) { 395 /* find supplementary code point as surrogate pair */ 396 const UChar *result=NULL; 397 UChar cs, lead=U16_LEAD(c), trail=U16_TRAIL(c); 398 399 while((cs=*s++)!=0) { 400 if(cs==lead && *s==trail) { 401 result=s-1; 402 } 403 } 404 return (UChar *)result; 405 } else { 406 /* not a Unicode code point, not findable */ 407 return NULL; 408 } 409 } 410 411 U_CAPI UChar * U_EXPORT2 412 u_memrchr(const UChar *s, UChar c, int32_t count) { 413 if(count<=0) { 414 return NULL; /* no string */ 415 } else if(U16_IS_SURROGATE(c)) { 416 /* make sure to not find half of a surrogate pair */ 417 return u_strFindLast(s, count, &c, 1); 418 } else { 419 /* trivial search for a BMP code point */ 420 const UChar *limit=s+count; 421 do { 422 if(*(--limit)==c) { 423 return (UChar *)limit; 424 } 425 } while(s!=limit); 426 return NULL; 427 } 428 } 429 430 U_CAPI UChar * U_EXPORT2 431 u_memrchr32(const UChar *s, UChar32 c, int32_t count) { 432 if((uint32_t)c<=U_BMP_MAX) { 433 /* find BMP code point */ 434 return u_memrchr(s, (UChar)c, count); 435 } else if(count<2) { 436 /* too short for a surrogate pair */ 437 return NULL; 438 } else if((uint32_t)c<=UCHAR_MAX_VALUE) { 439 /* find supplementary code point as surrogate pair */ 440 const UChar *limit=s+count-1; 441 UChar lead=U16_LEAD(c), trail=U16_TRAIL(c); 442 443 do { 444 if(*limit==trail && *(limit-1)==lead) { 445 return (UChar *)(limit-1); 446 } 447 } while(s!=--limit); 448 return NULL; 449 } else { 450 /* not a Unicode code point, not findable */ 451 return NULL; 452 } 453 } 454 455 /* Tokenization functions --------------------------------------------------- */ 456 457 /* 458 * Match each code point in a string against each code point in the matchSet. 459 * Return the index of the first string code point that 460 * is (polarity==TRUE) or is not (FALSE) contained in the matchSet. 461 * Return -(string length)-1 if there is no such code point. 462 */ 463 static int32_t 464 _matchFromSet(const UChar *string, const UChar *matchSet, UBool polarity) { 465 int32_t matchLen, matchBMPLen, strItr, matchItr; 466 UChar32 stringCh, matchCh; 467 UChar c, c2; 468 469 /* first part of matchSet contains only BMP code points */ 470 matchBMPLen = 0; 471 while((c = matchSet[matchBMPLen]) != 0 && U16_IS_SINGLE(c)) { 472 ++matchBMPLen; 473 } 474 475 /* second part of matchSet contains BMP and supplementary code points */ 476 matchLen = matchBMPLen; 477 while(matchSet[matchLen] != 0) { 478 ++matchLen; 479 } 480 481 for(strItr = 0; (c = string[strItr]) != 0;) { 482 ++strItr; 483 if(U16_IS_SINGLE(c)) { 484 if(polarity) { 485 for(matchItr = 0; matchItr < matchLen; ++matchItr) { 486 if(c == matchSet[matchItr]) { 487 return strItr - 1; /* one matches */ 488 } 489 } 490 } else { 491 for(matchItr = 0; matchItr < matchLen; ++matchItr) { 492 if(c == matchSet[matchItr]) { 493 goto endloop; 494 } 495 } 496 return strItr - 1; /* none matches */ 497 } 498 } else { 499 /* 500 * No need to check for string length before U16_IS_TRAIL 501 * because c2 could at worst be the terminating NUL. 502 */ 503 if(U16_IS_SURROGATE_LEAD(c) && U16_IS_TRAIL(c2 = string[strItr])) { 504 ++strItr; 505 stringCh = U16_GET_SUPPLEMENTARY(c, c2); 506 } else { 507 stringCh = c; /* unpaired trail surrogate */ 508 } 509 510 if(polarity) { 511 for(matchItr = matchBMPLen; matchItr < matchLen;) { 512 U16_NEXT(matchSet, matchItr, matchLen, matchCh); 513 if(stringCh == matchCh) { 514 return strItr - U16_LENGTH(stringCh); /* one matches */ 515 } 516 } 517 } else { 518 for(matchItr = matchBMPLen; matchItr < matchLen;) { 519 U16_NEXT(matchSet, matchItr, matchLen, matchCh); 520 if(stringCh == matchCh) { 521 goto endloop; 522 } 523 } 524 return strItr - U16_LENGTH(stringCh); /* none matches */ 525 } 526 } 527 endloop: 528 /* wish C had continue with labels like Java... */; 529 } 530 531 /* Didn't find it. */ 532 return -strItr-1; 533 } 534 535 /* Search for a codepoint in a string that matches one of the matchSet codepoints. */ 536 U_CAPI UChar * U_EXPORT2 537 u_strpbrk(const UChar *string, const UChar *matchSet) 538 { 539 int32_t idx = _matchFromSet(string, matchSet, TRUE); 540 if(idx >= 0) { 541 return (UChar *)string + idx; 542 } else { 543 return NULL; 544 } 545 } 546 547 /* Search for a codepoint in a string that matches one of the matchSet codepoints. */ 548 U_CAPI int32_t U_EXPORT2 549 u_strcspn(const UChar *string, const UChar *matchSet) 550 { 551 int32_t idx = _matchFromSet(string, matchSet, TRUE); 552 if(idx >= 0) { 553 return idx; 554 } else { 555 return -idx - 1; /* == u_strlen(string) */ 556 } 557 } 558 559 /* Search for a codepoint in a string that does not match one of the matchSet codepoints. */ 560 U_CAPI int32_t U_EXPORT2 561 u_strspn(const UChar *string, const UChar *matchSet) 562 { 563 int32_t idx = _matchFromSet(string, matchSet, FALSE); 564 if(idx >= 0) { 565 return idx; 566 } else { 567 return -idx - 1; /* == u_strlen(string) */ 568 } 569 } 570 571 /* ----- Text manipulation functions --- */ 572 573 U_CAPI UChar* U_EXPORT2 574 u_strtok_r(UChar *src, 575 const UChar *delim, 576 UChar **saveState) 577 { 578 UChar *tokSource; 579 UChar *nextToken; 580 uint32_t nonDelimIdx; 581 582 /* If saveState is NULL, the user messed up. */ 583 if (src != NULL) { 584 tokSource = src; 585 *saveState = src; /* Set to "src" in case there are no delimiters */ 586 } 587 else if (*saveState) { 588 tokSource = *saveState; 589 } 590 else { 591 /* src == NULL && *saveState == NULL */ 592 /* This shouldn't happen. We already finished tokenizing. */ 593 return NULL; 594 } 595 596 /* Skip initial delimiters */ 597 nonDelimIdx = u_strspn(tokSource, delim); 598 tokSource = &tokSource[nonDelimIdx]; 599 600 if (*tokSource) { 601 nextToken = u_strpbrk(tokSource, delim); 602 if (nextToken != NULL) { 603 /* Create a token */ 604 *(nextToken++) = 0; 605 *saveState = nextToken; 606 return tokSource; 607 } 608 else if (*saveState) { 609 /* Return the last token */ 610 *saveState = NULL; 611 return tokSource; 612 } 613 } 614 else { 615 /* No tokens were found. Only delimiters were left. */ 616 *saveState = NULL; 617 } 618 return NULL; 619 } 620 621 /* Miscellaneous functions -------------------------------------------------- */ 622 623 U_CAPI UChar* U_EXPORT2 624 u_strcat(UChar *dst, 625 const UChar *src) 626 { 627 UChar *anchor = dst; /* save a pointer to start of dst */ 628 629 while(*dst != 0) { /* To end of first string */ 630 ++dst; 631 } 632 while((*(dst++) = *(src++)) != 0) { /* copy string 2 over */ 633 } 634 635 return anchor; 636 } 637 638 U_CAPI UChar* U_EXPORT2 639 u_strncat(UChar *dst, 640 const UChar *src, 641 int32_t n ) 642 { 643 if(n > 0) { 644 UChar *anchor = dst; /* save a pointer to start of dst */ 645 646 while(*dst != 0) { /* To end of first string */ 647 ++dst; 648 } 649 while((*dst = *src) != 0) { /* copy string 2 over */ 650 ++dst; 651 if(--n == 0) { 652 *dst = 0; 653 break; 654 } 655 ++src; 656 } 657 658 return anchor; 659 } else { 660 return dst; 661 } 662 } 663 664 /* ----- Text property functions --- */ 665 666 U_CAPI int32_t U_EXPORT2 667 u_strcmp(const UChar *s1, 668 const UChar *s2) 669 { 670 UChar c1, c2; 671 672 for(;;) { 673 c1=*s1++; 674 c2=*s2++; 675 if (c1 != c2 || c1 == 0) { 676 break; 677 } 678 } 679 return (int32_t)c1 - (int32_t)c2; 680 } 681 682 U_CFUNC int32_t U_EXPORT2 683 uprv_strCompare(const UChar *s1, int32_t length1, 684 const UChar *s2, int32_t length2, 685 UBool strncmpStyle, UBool codePointOrder) { 686 const UChar *start1, *start2, *limit1, *limit2; 687 UChar c1, c2; 688 689 /* setup for fix-up */ 690 start1=s1; 691 start2=s2; 692 693 /* compare identical prefixes - they do not need to be fixed up */ 694 if(length1<0 && length2<0) { 695 /* strcmp style, both NUL-terminated */ 696 if(s1==s2) { 697 return 0; 698 } 699 700 for(;;) { 701 c1=*s1; 702 c2=*s2; 703 if(c1!=c2) { 704 break; 705 } 706 if(c1==0) { 707 return 0; 708 } 709 ++s1; 710 ++s2; 711 } 712 713 /* setup for fix-up */ 714 limit1=limit2=NULL; 715 } else if(strncmpStyle) { 716 /* special handling for strncmp, assume length1==length2>=0 but also check for NUL */ 717 if(s1==s2) { 718 return 0; 719 } 720 721 limit1=start1+length1; 722 723 for(;;) { 724 /* both lengths are same, check only one limit */ 725 if(s1==limit1) { 726 return 0; 727 } 728 729 c1=*s1; 730 c2=*s2; 731 if(c1!=c2) { 732 break; 733 } 734 if(c1==0) { 735 return 0; 736 } 737 ++s1; 738 ++s2; 739 } 740 741 /* setup for fix-up */ 742 limit2=start2+length1; /* use length1 here, too, to enforce assumption */ 743 } else { 744 /* memcmp/UnicodeString style, both length-specified */ 745 int32_t lengthResult; 746 747 if(length1<0) { 748 length1=u_strlen(s1); 749 } 750 if(length2<0) { 751 length2=u_strlen(s2); 752 } 753 754 /* limit1=start1+min(lenght1, length2) */ 755 if(length1<length2) { 756 lengthResult=-1; 757 limit1=start1+length1; 758 } else if(length1==length2) { 759 lengthResult=0; 760 limit1=start1+length1; 761 } else /* length1>length2 */ { 762 lengthResult=1; 763 limit1=start1+length2; 764 } 765 766 if(s1==s2) { 767 return lengthResult; 768 } 769 770 for(;;) { 771 /* check pseudo-limit */ 772 if(s1==limit1) { 773 return lengthResult; 774 } 775 776 c1=*s1; 777 c2=*s2; 778 if(c1!=c2) { 779 break; 780 } 781 ++s1; 782 ++s2; 783 } 784 785 /* setup for fix-up */ 786 limit1=start1+length1; 787 limit2=start2+length2; 788 } 789 790 /* if both values are in or above the surrogate range, fix them up */ 791 if(c1>=0xd800 && c2>=0xd800 && codePointOrder) { 792 /* subtract 0x2800 from BMP code points to make them smaller than supplementary ones */ 793 if( 794 (c1<=0xdbff && (s1+1)!=limit1 && UTF_IS_TRAIL(*(s1+1))) || 795 (UTF_IS_TRAIL(c1) && start1!=s1 && UTF_IS_LEAD(*(s1-1))) 796 ) { 797 /* part of a surrogate pair, leave >=d800 */ 798 } else { 799 /* BMP code point - may be surrogate code point - make <d800 */ 800 c1-=0x2800; 801 } 802 803 if( 804 (c2<=0xdbff && (s2+1)!=limit2 && UTF_IS_TRAIL(*(s2+1))) || 805 (UTF_IS_TRAIL(c2) && start2!=s2 && UTF_IS_LEAD(*(s2-1))) 806 ) { 807 /* part of a surrogate pair, leave >=d800 */ 808 } else { 809 /* BMP code point - may be surrogate code point - make <d800 */ 810 c2-=0x2800; 811 } 812 } 813 814 /* now c1 and c2 are in the requested (code unit or code point) order */ 815 return (int32_t)c1-(int32_t)c2; 816 } 817 818 /* 819 * Compare two strings as presented by UCharIterators. 820 * Use code unit or code point order. 821 * When the function returns, it is undefined where the iterators 822 * have stopped. 823 */ 824 U_CAPI int32_t U_EXPORT2 825 u_strCompareIter(UCharIterator *iter1, UCharIterator *iter2, UBool codePointOrder) { 826 UChar32 c1, c2; 827 828 /* argument checking */ 829 if(iter1==NULL || iter2==NULL) { 830 return 0; /* bad arguments */ 831 } 832 if(iter1==iter2) { 833 return 0; /* identical iterators */ 834 } 835 836 /* reset iterators to start? */ 837 iter1->move(iter1, 0, UITER_START); 838 iter2->move(iter2, 0, UITER_START); 839 840 /* compare identical prefixes - they do not need to be fixed up */ 841 for(;;) { 842 c1=iter1->next(iter1); 843 c2=iter2->next(iter2); 844 if(c1!=c2) { 845 break; 846 } 847 if(c1==-1) { 848 return 0; 849 } 850 } 851 852 /* if both values are in or above the surrogate range, fix them up */ 853 if(c1>=0xd800 && c2>=0xd800 && codePointOrder) { 854 /* subtract 0x2800 from BMP code points to make them smaller than supplementary ones */ 855 if( 856 (c1<=0xdbff && UTF_IS_TRAIL(iter1->current(iter1))) || 857 (UTF_IS_TRAIL(c1) && (iter1->previous(iter1), UTF_IS_LEAD(iter1->previous(iter1)))) 858 ) { 859 /* part of a surrogate pair, leave >=d800 */ 860 } else { 861 /* BMP code point - may be surrogate code point - make <d800 */ 862 c1-=0x2800; 863 } 864 865 if( 866 (c2<=0xdbff && UTF_IS_TRAIL(iter2->current(iter2))) || 867 (UTF_IS_TRAIL(c2) && (iter2->previous(iter2), UTF_IS_LEAD(iter2->previous(iter2)))) 868 ) { 869 /* part of a surrogate pair, leave >=d800 */ 870 } else { 871 /* BMP code point - may be surrogate code point - make <d800 */ 872 c2-=0x2800; 873 } 874 } 875 876 /* now c1 and c2 are in the requested (code unit or code point) order */ 877 return (int32_t)c1-(int32_t)c2; 878 } 879 880 #if 0 881 /* 882 * u_strCompareIter() does not leave the iterators _on_ the different units. 883 * This is possible but would cost a few extra indirect function calls to back 884 * up if the last unit (c1 or c2 respectively) was >=0. 885 * 886 * Consistently leaving them _behind_ the different units is not an option 887 * because the current "unit" is the end of the string if that is reached, 888 * and in such a case the iterator does not move. 889 * For example, when comparing "ab" with "abc", both iterators rest _on_ the end 890 * of their strings. Calling previous() on each does not move them to where 891 * the comparison fails. 892 * 893 * So the simplest semantics is to not define where the iterators end up. 894 * 895 * The following fragment is part of what would need to be done for backing up. 896 */ 897 void fragment { 898 /* iff a surrogate is part of a surrogate pair, leave >=d800 */ 899 if(c1<=0xdbff) { 900 if(!UTF_IS_TRAIL(iter1->current(iter1))) { 901 /* lead surrogate code point - make <d800 */ 902 c1-=0x2800; 903 } 904 } else if(c1<=0xdfff) { 905 int32_t idx=iter1->getIndex(iter1, UITER_CURRENT); 906 iter1->previous(iter1); /* ==c1 */ 907 if(!UTF_IS_LEAD(iter1->previous(iter1))) { 908 /* trail surrogate code point - make <d800 */ 909 c1-=0x2800; 910 } 911 /* go back to behind where the difference is */ 912 iter1->move(iter1, idx, UITER_ZERO); 913 } else /* 0xe000<=c1<=0xffff */ { 914 /* BMP code point - make <d800 */ 915 c1-=0x2800; 916 } 917 } 918 #endif 919 920 U_CAPI int32_t U_EXPORT2 921 u_strCompare(const UChar *s1, int32_t length1, 922 const UChar *s2, int32_t length2, 923 UBool codePointOrder) { 924 /* argument checking */ 925 if(s1==NULL || length1<-1 || s2==NULL || length2<-1) { 926 return 0; 927 } 928 return uprv_strCompare(s1, length1, s2, length2, FALSE, codePointOrder); 929 } 930 931 /* String compare in code point order - u_strcmp() compares in code unit order. */ 932 U_CAPI int32_t U_EXPORT2 933 u_strcmpCodePointOrder(const UChar *s1, const UChar *s2) { 934 return uprv_strCompare(s1, -1, s2, -1, FALSE, TRUE); 935 } 936 937 U_CAPI int32_t U_EXPORT2 938 u_strncmp(const UChar *s1, 939 const UChar *s2, 940 int32_t n) 941 { 942 if(n > 0) { 943 int32_t rc; 944 for(;;) { 945 rc = (int32_t)*s1 - (int32_t)*s2; 946 if(rc != 0 || *s1 == 0 || --n == 0) { 947 return rc; 948 } 949 ++s1; 950 ++s2; 951 } 952 } else { 953 return 0; 954 } 955 } 956 957 U_CAPI int32_t U_EXPORT2 958 u_strncmpCodePointOrder(const UChar *s1, const UChar *s2, int32_t n) { 959 return uprv_strCompare(s1, n, s2, n, TRUE, TRUE); 960 } 961 962 U_CAPI UChar* U_EXPORT2 963 u_strcpy(UChar *dst, 964 const UChar *src) 965 { 966 UChar *anchor = dst; /* save a pointer to start of dst */ 967 968 while((*(dst++) = *(src++)) != 0) { /* copy string 2 over */ 969 } 970 971 return anchor; 972 } 973 974 U_CAPI UChar* U_EXPORT2 975 u_strncpy(UChar *dst, 976 const UChar *src, 977 int32_t n) 978 { 979 UChar *anchor = dst; /* save a pointer to start of dst */ 980 981 /* copy string 2 over */ 982 while(n > 0 && (*(dst++) = *(src++)) != 0) { 983 --n; 984 } 985 986 return anchor; 987 } 988 989 U_CAPI int32_t U_EXPORT2 990 u_strlen(const UChar *s) 991 { 992 #if U_SIZEOF_WCHAR_T == U_SIZEOF_UCHAR 993 return (int32_t)uprv_wcslen(s); 994 #else 995 const UChar *t = s; 996 while(*t != 0) { 997 ++t; 998 } 999 return t - s; 1000 #endif 1001 } 1002 1003 U_CAPI int32_t U_EXPORT2 1004 u_countChar32(const UChar *s, int32_t length) { 1005 int32_t count; 1006 1007 if(s==NULL || length<-1) { 1008 return 0; 1009 } 1010 1011 count=0; 1012 if(length>=0) { 1013 while(length>0) { 1014 ++count; 1015 if(UTF_IS_LEAD(*s) && length>=2 && UTF_IS_TRAIL(*(s+1))) { 1016 s+=2; 1017 length-=2; 1018 } else { 1019 ++s; 1020 --length; 1021 } 1022 } 1023 } else /* length==-1 */ { 1024 UChar c; 1025 1026 for(;;) { 1027 if((c=*s++)==0) { 1028 break; 1029 } 1030 ++count; 1031 1032 /* 1033 * sufficient to look ahead one because of UTF-16; 1034 * safe to look ahead one because at worst that would be the terminating NUL 1035 */ 1036 if(UTF_IS_LEAD(c) && UTF_IS_TRAIL(*s)) { 1037 ++s; 1038 } 1039 } 1040 } 1041 return count; 1042 } 1043 1044 U_CAPI UBool U_EXPORT2 1045 u_strHasMoreChar32Than(const UChar *s, int32_t length, int32_t number) { 1046 1047 if(number<0) { 1048 return TRUE; 1049 } 1050 if(s==NULL || length<-1) { 1051 return FALSE; 1052 } 1053 1054 if(length==-1) { 1055 /* s is NUL-terminated */ 1056 UChar c; 1057 1058 /* count code points until they exceed */ 1059 for(;;) { 1060 if((c=*s++)==0) { 1061 return FALSE; 1062 } 1063 if(number==0) { 1064 return TRUE; 1065 } 1066 if(U16_IS_LEAD(c) && U16_IS_TRAIL(*s)) { 1067 ++s; 1068 } 1069 --number; 1070 } 1071 } else { 1072 /* length>=0 known */ 1073 const UChar *limit; 1074 int32_t maxSupplementary; 1075 1076 /* s contains at least (length+1)/2 code points: <=2 UChars per cp */ 1077 if(((length+1)/2)>number) { 1078 return TRUE; 1079 } 1080 1081 /* check if s does not even contain enough UChars */ 1082 maxSupplementary=length-number; 1083 if(maxSupplementary<=0) { 1084 return FALSE; 1085 } 1086 /* there are maxSupplementary=length-number more UChars than asked-for code points */ 1087 1088 /* 1089 * count code points until they exceed and also check that there are 1090 * no more than maxSupplementary supplementary code points (UChar pairs) 1091 */ 1092 limit=s+length; 1093 for(;;) { 1094 if(s==limit) { 1095 return FALSE; 1096 } 1097 if(number==0) { 1098 return TRUE; 1099 } 1100 if(U16_IS_LEAD(*s++) && s!=limit && U16_IS_TRAIL(*s)) { 1101 ++s; 1102 if(--maxSupplementary<=0) { 1103 /* too many pairs - too few code points */ 1104 return FALSE; 1105 } 1106 } 1107 --number; 1108 } 1109 } 1110 } 1111 1112 U_CAPI UChar * U_EXPORT2 1113 u_memcpy(UChar *dest, const UChar *src, int32_t count) { 1114 return (UChar *)uprv_memcpy(dest, src, count*U_SIZEOF_UCHAR); 1115 } 1116 1117 U_CAPI UChar * U_EXPORT2 1118 u_memmove(UChar *dest, const UChar *src, int32_t count) { 1119 return (UChar *)uprv_memmove(dest, src, count*U_SIZEOF_UCHAR); 1120 } 1121 1122 U_CAPI UChar * U_EXPORT2 1123 u_memset(UChar *dest, UChar c, int32_t count) { 1124 if(count > 0) { 1125 UChar *ptr = dest; 1126 UChar *limit = dest + count; 1127 1128 while (ptr < limit) { 1129 *(ptr++) = c; 1130 } 1131 } 1132 return dest; 1133 } 1134 1135 U_CAPI int32_t U_EXPORT2 1136 u_memcmp(const UChar *buf1, const UChar *buf2, int32_t count) { 1137 if(count > 0) { 1138 const UChar *limit = buf1 + count; 1139 int32_t result; 1140 1141 while (buf1 < limit) { 1142 result = (int32_t)(uint16_t)*buf1 - (int32_t)(uint16_t)*buf2; 1143 if (result != 0) { 1144 return result; 1145 } 1146 buf1++; 1147 buf2++; 1148 } 1149 } 1150 return 0; 1151 } 1152 1153 U_CAPI int32_t U_EXPORT2 1154 u_memcmpCodePointOrder(const UChar *s1, const UChar *s2, int32_t count) { 1155 return uprv_strCompare(s1, count, s2, count, FALSE, TRUE); 1156 } 1157 1158 /* u_unescape & support fns ------------------------------------------------- */ 1159 1160 /* This map must be in ASCENDING ORDER OF THE ESCAPE CODE */ 1161 static const UChar UNESCAPE_MAP[] = { 1162 /*" 0x22, 0x22 */ 1163 /*' 0x27, 0x27 */ 1164 /*? 0x3F, 0x3F */ 1165 /*\ 0x5C, 0x5C */ 1166 /*a*/ 0x61, 0x07, 1167 /*b*/ 0x62, 0x08, 1168 /*e*/ 0x65, 0x1b, 1169 /*f*/ 0x66, 0x0c, 1170 /*n*/ 0x6E, 0x0a, 1171 /*r*/ 0x72, 0x0d, 1172 /*t*/ 0x74, 0x09, 1173 /*v*/ 0x76, 0x0b 1174 }; 1175 enum { UNESCAPE_MAP_LENGTH = sizeof(UNESCAPE_MAP) / sizeof(UNESCAPE_MAP[0]) }; 1176 1177 /* Convert one octal digit to a numeric value 0..7, or -1 on failure */ 1178 static int8_t _digit8(UChar c) { 1179 if (c >= 0x0030 && c <= 0x0037) { 1180 return (int8_t)(c - 0x0030); 1181 } 1182 return -1; 1183 } 1184 1185 /* Convert one hex digit to a numeric value 0..F, or -1 on failure */ 1186 static int8_t _digit16(UChar c) { 1187 if (c >= 0x0030 && c <= 0x0039) { 1188 return (int8_t)(c - 0x0030); 1189 } 1190 if (c >= 0x0041 && c <= 0x0046) { 1191 return (int8_t)(c - (0x0041 - 10)); 1192 } 1193 if (c >= 0x0061 && c <= 0x0066) { 1194 return (int8_t)(c - (0x0061 - 10)); 1195 } 1196 return -1; 1197 } 1198 1199 /* Parse a single escape sequence. Although this method deals in 1200 * UChars, it does not use C++ or UnicodeString. This allows it to 1201 * be used from C contexts. */ 1202 U_CAPI UChar32 U_EXPORT2 1203 u_unescapeAt(UNESCAPE_CHAR_AT charAt, 1204 int32_t *offset, 1205 int32_t length, 1206 void *context) { 1207 1208 int32_t start = *offset; 1209 UChar c; 1210 UChar32 result = 0; 1211 int8_t n = 0; 1212 int8_t minDig = 0; 1213 int8_t maxDig = 0; 1214 int8_t bitsPerDigit = 4; 1215 int8_t dig; 1216 int32_t i; 1217 UBool braces = FALSE; 1218 1219 /* Check that offset is in range */ 1220 if (*offset < 0 || *offset >= length) { 1221 goto err; 1222 } 1223 1224 /* Fetch first UChar after '\\' */ 1225 c = charAt((*offset)++, context); 1226 1227 /* Convert hexadecimal and octal escapes */ 1228 switch (c) { 1229 case 0x0075 /*'u'*/: 1230 minDig = maxDig = 4; 1231 break; 1232 case 0x0055 /*'U'*/: 1233 minDig = maxDig = 8; 1234 break; 1235 case 0x0078 /*'x'*/: 1236 minDig = 1; 1237 if (*offset < length && charAt(*offset, context) == 0x7B /*{*/) { 1238 ++(*offset); 1239 braces = TRUE; 1240 maxDig = 8; 1241 } else { 1242 maxDig = 2; 1243 } 1244 break; 1245 default: 1246 dig = _digit8(c); 1247 if (dig >= 0) { 1248 minDig = 1; 1249 maxDig = 3; 1250 n = 1; /* Already have first octal digit */ 1251 bitsPerDigit = 3; 1252 result = dig; 1253 } 1254 break; 1255 } 1256 if (minDig != 0) { 1257 while (*offset < length && n < maxDig) { 1258 c = charAt(*offset, context); 1259 dig = (int8_t)((bitsPerDigit == 3) ? _digit8(c) : _digit16(c)); 1260 if (dig < 0) { 1261 break; 1262 } 1263 result = (result << bitsPerDigit) | dig; 1264 ++(*offset); 1265 ++n; 1266 } 1267 if (n < minDig) { 1268 goto err; 1269 } 1270 if (braces) { 1271 if (c != 0x7D /*}*/) { 1272 goto err; 1273 } 1274 ++(*offset); 1275 } 1276 if (result < 0 || result >= 0x110000) { 1277 goto err; 1278 } 1279 /* If an escape sequence specifies a lead surrogate, see if 1280 * there is a trail surrogate after it, either as an escape or 1281 * as a literal. If so, join them up into a supplementary. 1282 */ 1283 if (*offset < length && U16_IS_LEAD(result)) { 1284 int32_t ahead = *offset + 1; 1285 c = charAt(*offset, context); 1286 if (c == 0x5C /*'\\'*/ && ahead < length) { 1287 c = (UChar) u_unescapeAt(charAt, &ahead, length, context); 1288 } 1289 if (U16_IS_TRAIL(c)) { 1290 *offset = ahead; 1291 result = U16_GET_SUPPLEMENTARY(result, c); 1292 } 1293 } 1294 return result; 1295 } 1296 1297 /* Convert C-style escapes in table */ 1298 for (i=0; i<UNESCAPE_MAP_LENGTH; i+=2) { 1299 if (c == UNESCAPE_MAP[i]) { 1300 return UNESCAPE_MAP[i+1]; 1301 } else if (c < UNESCAPE_MAP[i]) { 1302 break; 1303 } 1304 } 1305 1306 /* Map \cX to control-X: X & 0x1F */ 1307 if (c == 0x0063 /*'c'*/ && *offset < length) { 1308 c = charAt((*offset)++, context); 1309 if (UTF_IS_FIRST_SURROGATE(c) && *offset < length) { 1310 UChar c2 = charAt(*offset, context); 1311 if (UTF_IS_SECOND_SURROGATE(c2)) { 1312 ++(*offset); 1313 c = (UChar) UTF16_GET_PAIR_VALUE(c, c2); /* [sic] */ 1314 } 1315 } 1316 return 0x1F & c; 1317 } 1318 1319 /* If no special forms are recognized, then consider 1320 * the backslash to generically escape the next character. 1321 * Deal with surrogate pairs. */ 1322 if (UTF_IS_FIRST_SURROGATE(c) && *offset < length) { 1323 UChar c2 = charAt(*offset, context); 1324 if (UTF_IS_SECOND_SURROGATE(c2)) { 1325 ++(*offset); 1326 return UTF16_GET_PAIR_VALUE(c, c2); 1327 } 1328 } 1329 return c; 1330 1331 err: 1332 /* Invalid escape sequence */ 1333 *offset = start; /* Reset to initial value */ 1334 return (UChar32)0xFFFFFFFF; 1335 } 1336 1337 /* u_unescapeAt() callback to return a UChar from a char* */ 1338 static UChar U_CALLCONV 1339 _charPtr_charAt(int32_t offset, void *context) { 1340 UChar c16; 1341 /* It would be more efficient to access the invariant tables 1342 * directly but there is no API for that. */ 1343 u_charsToUChars(((char*) context) + offset, &c16, 1); 1344 return c16; 1345 } 1346 1347 /* Append an escape-free segment of the text; used by u_unescape() */ 1348 static void _appendUChars(UChar *dest, int32_t destCapacity, 1349 const char *src, int32_t srcLen) { 1350 if (destCapacity < 0) { 1351 destCapacity = 0; 1352 } 1353 if (srcLen > destCapacity) { 1354 srcLen = destCapacity; 1355 } 1356 u_charsToUChars(src, dest, srcLen); 1357 } 1358 1359 /* Do an invariant conversion of char* -> UChar*, with escape parsing */ 1360 U_CAPI int32_t U_EXPORT2 1361 u_unescape(const char *src, UChar *dest, int32_t destCapacity) { 1362 const char *segment = src; 1363 int32_t i = 0; 1364 char c; 1365 1366 while ((c=*src) != 0) { 1367 /* '\\' intentionally written as compiler-specific 1368 * character constant to correspond to compiler-specific 1369 * char* constants. */ 1370 if (c == '\\') { 1371 int32_t lenParsed = 0; 1372 UChar32 c32; 1373 if (src != segment) { 1374 if (dest != NULL) { 1375 _appendUChars(dest + i, destCapacity - i, 1376 segment, src - segment); 1377 } 1378 i += src - segment; 1379 } 1380 ++src; /* advance past '\\' */ 1381 c32 = u_unescapeAt(_charPtr_charAt, &lenParsed, uprv_strlen(src), (void*)src); 1382 if (lenParsed == 0) { 1383 goto err; 1384 } 1385 src += lenParsed; /* advance past escape seq. */ 1386 if (dest != NULL && UTF_CHAR_LENGTH(c32) <= (destCapacity - i)) { 1387 UTF_APPEND_CHAR_UNSAFE(dest, i, c32); 1388 } else { 1389 i += UTF_CHAR_LENGTH(c32); 1390 } 1391 segment = src; 1392 } else { 1393 ++src; 1394 } 1395 } 1396 if (src != segment) { 1397 if (dest != NULL) { 1398 _appendUChars(dest + i, destCapacity - i, 1399 segment, src - segment); 1400 } 1401 i += src - segment; 1402 } 1403 if (dest != NULL && i < destCapacity) { 1404 dest[i] = 0; 1405 } 1406 return i; 1407 1408 err: 1409 if (dest != NULL && destCapacity > 0) { 1410 *dest = 0; 1411 } 1412 return 0; 1413 } 1414 1415 /* C UGrowBuffer implementation --------------------------------------------- */ 1416 1417 U_CAPI UBool /* U_CALLCONV U_EXPORT2 */ 1418 u_growBufferFromStatic(void *context, 1419 UChar **pBuffer, int32_t *pCapacity, int32_t reqCapacity, 1420 int32_t length) { 1421 UChar *newBuffer=(UChar *)uprv_malloc(reqCapacity*U_SIZEOF_UCHAR); 1422 if(newBuffer!=NULL) { 1423 if(length>0) { 1424 uprv_memcpy(newBuffer, *pBuffer, length*U_SIZEOF_UCHAR); 1425 } 1426 *pCapacity=reqCapacity; 1427 } else { 1428 *pCapacity=0; 1429 } 1430 1431 /* release the old pBuffer if it was not statically allocated */ 1432 if(*pBuffer!=(UChar *)context) { 1433 uprv_free(*pBuffer); 1434 } 1435 1436 *pBuffer=newBuffer; 1437 return (UBool)(newBuffer!=NULL); 1438 } 1439 1440 /* NUL-termination of strings ----------------------------------------------- */ 1441 1442 /** 1443 * NUL-terminate a string no matter what its type. 1444 * Set warning and error codes accordingly. 1445 */ 1446 #define __TERMINATE_STRING(dest, destCapacity, length, pErrorCode) \ 1447 if(pErrorCode!=NULL && U_SUCCESS(*pErrorCode)) { \ 1448 /* not a public function, so no complete argument checking */ \ 1449 \ 1450 if(length<0) { \ 1451 /* assume that the caller handles this */ \ 1452 } else if(length<destCapacity) { \ 1453 /* NUL-terminate the string, the NUL fits */ \ 1454 dest[length]=0; \ 1455 /* unset the not-terminated warning but leave all others */ \ 1456 if(*pErrorCode==U_STRING_NOT_TERMINATED_WARNING) { \ 1457 *pErrorCode=U_ZERO_ERROR; \ 1458 } \ 1459 } else if(length==destCapacity) { \ 1460 /* unable to NUL-terminate, but the string itself fit - set a warning code */ \ 1461 *pErrorCode=U_STRING_NOT_TERMINATED_WARNING; \ 1462 } else /* length>destCapacity */ { \ 1463 /* even the string itself did not fit - set an error code */ \ 1464 *pErrorCode=U_BUFFER_OVERFLOW_ERROR; \ 1465 } \ 1466 } 1467 1468 U_CAPI int32_t U_EXPORT2 1469 u_terminateUChars(UChar *dest, int32_t destCapacity, int32_t length, UErrorCode *pErrorCode) { 1470 __TERMINATE_STRING(dest, destCapacity, length, pErrorCode); 1471 return length; 1472 } 1473 1474 U_CAPI int32_t U_EXPORT2 1475 u_terminateChars(char *dest, int32_t destCapacity, int32_t length, UErrorCode *pErrorCode) { 1476 __TERMINATE_STRING(dest, destCapacity, length, pErrorCode); 1477 return length; 1478 } 1479 1480 U_CAPI int32_t U_EXPORT2 1481 u_terminateUChar32s(UChar32 *dest, int32_t destCapacity, int32_t length, UErrorCode *pErrorCode) { 1482 __TERMINATE_STRING(dest, destCapacity, length, pErrorCode); 1483 return length; 1484 } 1485 1486 U_CAPI int32_t U_EXPORT2 1487 u_terminateWChars(wchar_t *dest, int32_t destCapacity, int32_t length, UErrorCode *pErrorCode) { 1488 __TERMINATE_STRING(dest, destCapacity, length, pErrorCode); 1489 return length; 1490 } 1491