1 7 package com.ibm.icu.text; 8 import com.ibm.icu.impl.NormalizerImpl; 9 import com.ibm.icu.impl.UCharacterProperty; 10 import com.ibm.icu.lang.UCharacter; 11 import com.ibm.icu.util.VersionInfo; 12 13 import java.text.CharacterIterator ; 14 import com.ibm.icu.impl.Utility; 15 16 117 118 public final class Normalizer implements Cloneable { 119 120 private char[] buffer = new char[100]; 124 private int bufferStart = 0; 125 private int bufferPos = 0; 126 private int bufferLimit = 0; 127 128 private static final int COMPAT_BIT = 1; 130 private static final int DECOMP_BIT = 2; 131 private static final int COMPOSE_BIT = 4; 132 133 private UCharacterIterator text; 135 private Mode mode = NFC; 136 private int options = 0; 137 private int currentIndex; 138 private int nextIndex; 139 140 146 public static final int UNICODE_3_2=0x20; 147 148 153 public static final int DONE = UCharacterIterator.DONE; 154 155 159 public static class Mode { 160 private int modeValue; 161 private Mode(int value) { 162 modeValue = value; 163 } 164 165 169 protected int normalize(char[] src, int srcStart, int srcLimit, 170 char[] dest,int destStart,int destLimit, 171 UnicodeSet nx) { 172 int srcLen = (srcLimit - srcStart); 173 int destLen = (destLimit - destStart); 174 if( srcLen > destLen ) { 175 return srcLen; 176 } 177 System.arraycopy(src,srcStart,dest,destStart,srcLen); 178 return srcLen; 179 } 180 181 185 protected int normalize(char[] src, int srcStart, int srcLimit, 186 char[] dest,int destStart,int destLimit, 187 int options) { 188 return normalize( src, srcStart, srcLimit, 189 dest,destStart,destLimit, 190 NormalizerImpl.getNX(options) 191 ); 192 } 193 194 198 protected String normalize(String src, int options) { 199 return src; 200 } 201 202 206 protected int getMinC() { 207 return -1; 208 } 209 210 214 protected int getMask() { 215 return -1; 216 } 217 218 222 protected IsPrevBoundary getPrevBoundary() { 223 return null; 224 } 225 226 230 protected IsNextBoundary getNextBoundary() { 231 return null; 232 } 233 234 238 protected QuickCheckResult quickCheck(char[] src,int start, int limit, 239 boolean allowMaybe,UnicodeSet nx) { 240 if(allowMaybe) { 241 return MAYBE; 242 } 243 return NO; 244 } 245 246 250 protected boolean isNFSkippable(int c) { 251 return true; 252 } 253 } 254 255 259 public static final Mode NONE = new Mode(1); 260 261 265 public static final Mode NFD = new NFDMode(2); 266 267 private static final class NFDMode extends Mode { 268 private NFDMode(int value) { 269 super(value); 270 } 271 272 protected int normalize(char[] src, int srcStart, int srcLimit, 273 char[] dest,int destStart,int destLimit, 274 UnicodeSet nx) { 275 int[] trailCC = new int[1]; 276 return NormalizerImpl.decompose(src, srcStart,srcLimit, 277 dest, destStart,destLimit, 278 false, trailCC,nx); 279 } 280 281 protected String normalize( String src, int options) { 282 return decompose(src,false); 283 } 284 285 protected int getMinC() { 286 return NormalizerImpl.MIN_WITH_LEAD_CC; 287 } 288 289 protected IsPrevBoundary getPrevBoundary() { 290 return new IsPrevNFDSafe(); 291 } 292 293 protected IsNextBoundary getNextBoundary() { 294 return new IsNextNFDSafe(); 295 } 296 297 protected int getMask() { 298 return (NormalizerImpl.CC_MASK|NormalizerImpl.QC_NFD); 299 } 300 301 protected QuickCheckResult quickCheck(char[] src,int start, 302 int limit,boolean allowMaybe, 303 UnicodeSet nx) { 304 return NormalizerImpl.quickCheck( 305 src, start,limit, 306 NormalizerImpl.getFromIndexesArr( 307 NormalizerImpl.INDEX_MIN_NFD_NO_MAYBE 308 ), 309 NormalizerImpl.QC_NFD, 310 0, 311 allowMaybe, 312 nx 313 ); 314 } 315 316 protected boolean isNFSkippable(int c) { 317 return NormalizerImpl.isNFSkippable(c,this, 318 (NormalizerImpl.CC_MASK|NormalizerImpl.QC_NFD) 319 ); 320 } 321 } 322 323 327 public static final Mode NFKD = new NFKDMode(3); 328 329 private static final class NFKDMode extends Mode { 330 private NFKDMode(int value) { 331 super(value); 332 } 333 334 protected int normalize(char[] src, int srcStart, int srcLimit, 335 char[] dest,int destStart,int destLimit, 336 UnicodeSet nx) { 337 int[] trailCC = new int[1]; 338 return NormalizerImpl.decompose(src, srcStart,srcLimit, 339 dest, destStart,destLimit, 340 true, trailCC, nx); 341 } 342 343 protected String normalize( String src, int options) { 344 return decompose(src,true); 345 } 346 347 protected int getMinC() { 348 return NormalizerImpl.MIN_WITH_LEAD_CC; 349 } 350 351 protected IsPrevBoundary getPrevBoundary() { 352 return new IsPrevNFDSafe(); 353 } 354 355 protected IsNextBoundary getNextBoundary() { 356 return new IsNextNFDSafe(); 357 } 358 359 protected int getMask() { 360 return (NormalizerImpl.CC_MASK|NormalizerImpl.QC_NFKD); 361 } 362 363 protected QuickCheckResult quickCheck(char[] src,int start, 364 int limit,boolean allowMaybe, 365 UnicodeSet nx) { 366 return NormalizerImpl.quickCheck( 367 src,start,limit, 368 NormalizerImpl.getFromIndexesArr( 369 NormalizerImpl.INDEX_MIN_NFKD_NO_MAYBE 370 ), 371 NormalizerImpl.QC_NFKD, 372 NormalizerImpl.OPTIONS_COMPAT, 373 allowMaybe, 374 nx 375 ); 376 } 377 378 protected boolean isNFSkippable(int c) { 379 return NormalizerImpl.isNFSkippable(c, this, 380 (NormalizerImpl.CC_MASK|NormalizerImpl.QC_NFKD) 381 ); 382 } 383 } 384 385 389 public static final Mode NFC = new NFCMode(4); 390 391 private static final class NFCMode extends Mode{ 392 private NFCMode(int value) { 393 super(value); 394 } 395 protected int normalize(char[] src, int srcStart, int srcLimit, 396 char[] dest,int destStart,int destLimit, 397 UnicodeSet nx) { 398 return NormalizerImpl.compose( src, srcStart, srcLimit, 399 dest,destStart,destLimit, 400 0, nx); 401 } 402 403 protected String normalize( String src, int options) { 404 return compose(src, false, options); 405 } 406 407 protected int getMinC() { 408 return NormalizerImpl.getFromIndexesArr( 409 NormalizerImpl.INDEX_MIN_NFC_NO_MAYBE 410 ); 411 } 412 protected IsPrevBoundary getPrevBoundary() { 413 return new IsPrevTrueStarter(); 414 } 415 protected IsNextBoundary getNextBoundary() { 416 return new IsNextTrueStarter(); 417 } 418 protected int getMask() { 419 return (NormalizerImpl.CC_MASK|NormalizerImpl.QC_NFC); 420 } 421 protected QuickCheckResult quickCheck(char[] src,int start, 422 int limit,boolean allowMaybe, 423 UnicodeSet nx) { 424 return NormalizerImpl.quickCheck( 425 src,start,limit, 426 NormalizerImpl.getFromIndexesArr( 427 NormalizerImpl.INDEX_MIN_NFC_NO_MAYBE 428 ), 429 NormalizerImpl.QC_NFC, 430 0, 431 allowMaybe, 432 nx 433 ); 434 } 435 protected boolean isNFSkippable(int c) { 436 return NormalizerImpl.isNFSkippable(c,this, 437 ( NormalizerImpl.CC_MASK|NormalizerImpl.COMBINES_ANY| 438 (NormalizerImpl.QC_NFC & NormalizerImpl.QC_ANY_NO) 439 ) 440 ); 441 } 442 }; 443 444 448 public static final Mode DEFAULT = NFC; 449 450 454 public static final Mode NFKC =new NFKCMode(5); 455 456 private static final class NFKCMode extends Mode{ 457 private NFKCMode(int value) { 458 super(value); 459 } 460 protected int normalize(char[] src, int srcStart, int srcLimit, 461 char[] dest,int destStart,int destLimit, 462 UnicodeSet nx) { 463 return NormalizerImpl.compose(src, srcStart,srcLimit, 464 dest, destStart,destLimit, 465 NormalizerImpl.OPTIONS_COMPAT, nx); 466 } 467 468 protected String normalize( String src, int options) { 469 return compose(src, true, options); 470 } 471 protected int getMinC() { 472 return NormalizerImpl.getFromIndexesArr( 473 NormalizerImpl.INDEX_MIN_NFKC_NO_MAYBE 474 ); 475 } 476 protected IsPrevBoundary getPrevBoundary() { 477 return new IsPrevTrueStarter(); 478 } 479 protected IsNextBoundary getNextBoundary() { 480 return new IsNextTrueStarter(); 481 } 482 protected int getMask() { 483 return (NormalizerImpl.CC_MASK|NormalizerImpl.QC_NFKC); 484 } 485 protected QuickCheckResult quickCheck(char[] src,int start, 486 int limit,boolean allowMaybe, 487 UnicodeSet nx) { 488 return NormalizerImpl.quickCheck( 489 src,start,limit, 490 NormalizerImpl.getFromIndexesArr( 491 NormalizerImpl.INDEX_MIN_NFKC_NO_MAYBE 492 ), 493 NormalizerImpl.QC_NFKC, 494 NormalizerImpl.OPTIONS_COMPAT, 495 allowMaybe, 496 nx 497 ); 498 } 499 protected boolean isNFSkippable(int c) { 500 return NormalizerImpl.isNFSkippable(c, this, 501 ( NormalizerImpl.CC_MASK|NormalizerImpl.COMBINES_ANY| 502 (NormalizerImpl.QC_NFKC & NormalizerImpl.QC_ANY_NO) 503 ) 504 ); 505 } 506 }; 507 508 512 public static final Mode FCD = new FCDMode(6); 513 514 private static final class FCDMode extends Mode{ 515 private FCDMode(int value) { 516 super(value); 517 } 518 protected int normalize(char[] src, int srcStart, int srcLimit, 519 char[] dest,int destStart,int destLimit, 520 UnicodeSet nx) { 521 return NormalizerImpl.makeFCD(src, srcStart,srcLimit, 522 dest, destStart,destLimit, nx); 523 } 524 protected String normalize( String src, int options) { 525 return makeFCD(src, options); 526 } 527 protected int getMinC() { 528 return NormalizerImpl.MIN_WITH_LEAD_CC; 529 } 530 protected IsPrevBoundary getPrevBoundary() { 531 return new IsPrevNFDSafe(); 532 } 533 protected IsNextBoundary getNextBoundary() { 534 return new IsNextNFDSafe(); 535 } 536 protected int getMask() { 537 return NormalizerImpl.CC_MASK|NormalizerImpl.QC_NFD; 538 } 539 protected QuickCheckResult quickCheck(char[] src,int start, 540 int limit,boolean allowMaybe, 541 UnicodeSet nx) { 542 return NormalizerImpl.checkFCD(src,start,limit,nx) ? YES : NO; 543 } 544 protected boolean isNFSkippable(int c) { 545 546 return (NormalizerImpl.getFCD16(c)>1); 547 } 548 }; 549 550 551 565 public static final Mode NO_OP = NONE; 566 567 583 public static final Mode COMPOSE = NFC; 584 585 601 public static final Mode COMPOSE_COMPAT = NFKC; 602 603 619 public static final Mode DECOMP = NFD; 620 621 637 public static final Mode DECOMP_COMPAT = NFKD; 638 639 657 public static final int IGNORE_HANGUL = 0x0001; 658 659 664 public static final class QuickCheckResult{ 665 private int resultValue; 666 private QuickCheckResult(int value) { 667 resultValue=value; 668 } 669 } 670 674 public static final QuickCheckResult NO = new QuickCheckResult(0); 675 676 680 public static final QuickCheckResult YES = new QuickCheckResult(1); 681 682 687 public static final QuickCheckResult MAYBE = new QuickCheckResult(2); 688 689 694 public static final int FOLD_CASE_DEFAULT = UCharacter.FOLD_CASE_DEFAULT; 695 696 701 public static final int INPUT_IS_FCD = 0x20000; 702 703 708 public static final int COMPARE_IGNORE_CASE = 0x10000; 709 710 715 public static final int COMPARE_CODE_POINT_ORDER = 0x8000; 716 717 722 public static final int FOLD_CASE_EXCLUDE_SPECIAL_I = UCharacter.FOLD_CASE_EXCLUDE_SPECIAL_I; 723 724 739 public static final int COMPARE_NORM_OPTIONS_SHIFT = 20; 740 741 745 763 public Normalizer(String str, Mode mode, int opt) { 764 this.text = UCharacterIterator.getInstance(str); 765 this.mode = mode; 766 this.options=opt; 767 } 768 769 784 public Normalizer(CharacterIterator iter, Mode mode, int opt) { 785 this.text = UCharacterIterator.getInstance( 786 (CharacterIterator )iter.clone() 787 ); 788 this.mode = mode; 789 this.options = opt; 790 } 791 792 803 public Normalizer(UCharacterIterator iter, Mode mode, int options) { 804 try { 805 this.text = (UCharacterIterator)iter.clone(); 806 this.mode = mode; 807 this.options = options; 808 } catch (CloneNotSupportedException e) { 809 throw new IllegalStateException (e.toString()); 810 } 811 } 812 813 823 public Object clone() { 824 try { 825 Normalizer copy = (Normalizer) super.clone(); 826 copy.text = (UCharacterIterator) text.clone(); 827 if (buffer != null) { 829 copy.buffer = new char[buffer.length]; 830 System.arraycopy(buffer,0,copy.buffer,0,buffer.length); 831 } 832 return copy; 833 } 834 catch (CloneNotSupportedException e) { 835 throw new IllegalStateException (e.toString()); 836 } 837 } 838 839 843 853 public static String compose(String str, boolean compat) { 854 return compose(str,compat,0); 855 } 856 857 868 public static String compose(String str, boolean compat, int options) { 869 870 char[] dest = new char[str.length()*MAX_BUF_SIZE_COMPOSE]; 871 int destSize=0; 872 char[] src = str.toCharArray(); 873 UnicodeSet nx = NormalizerImpl.getNX(options); 874 875 876 options&=~(NormalizerImpl.OPTIONS_SETS_MASK|NormalizerImpl.OPTIONS_COMPAT|NormalizerImpl.OPTIONS_COMPOSE_CONTIGUOUS); 877 878 if(compat) { 879 options|=NormalizerImpl.OPTIONS_COMPAT; 880 } 881 882 for(;;) { 883 destSize=NormalizerImpl.compose(src,0,src.length, 884 dest,0,dest.length,options, 885 nx); 886 if(destSize<=dest.length) { 887 return new String (dest,0,destSize); 888 } else { 889 dest = new char[destSize]; 890 } 891 } 892 } 893 894 909 public static int compose(char[] source,char[] target, boolean compat, int options) { 910 UnicodeSet nx = NormalizerImpl.getNX(options); 911 912 913 options&=~(NormalizerImpl.OPTIONS_SETS_MASK|NormalizerImpl.OPTIONS_COMPAT|NormalizerImpl.OPTIONS_COMPOSE_CONTIGUOUS); 914 915 if(compat) { 916 options|=NormalizerImpl.OPTIONS_COMPAT; 917 } 918 919 int length = NormalizerImpl.compose(source,0,source.length, 920 target,0,target.length, 921 options,nx); 922 if(length<=target.length) { 923 return length; 924 } else { 925 throw new IndexOutOfBoundsException (Integer.toString(length)); 926 } 927 } 928 929 948 public static int compose(char[] src,int srcStart, int srcLimit, 949 char[] dest,int destStart, int destLimit, 950 boolean compat, int options) { 951 UnicodeSet nx = NormalizerImpl.getNX(options); 952 953 954 options&=~(NormalizerImpl.OPTIONS_SETS_MASK|NormalizerImpl.OPTIONS_COMPAT|NormalizerImpl.OPTIONS_COMPOSE_CONTIGUOUS); 955 956 if(compat) { 957 options|=NormalizerImpl.OPTIONS_COMPAT; 958 } 959 960 int length = NormalizerImpl.compose(src,srcStart,srcLimit, 961 dest,destStart,destLimit, 962 options, nx); 963 if(length<=(destLimit-destStart)) { 964 return length; 965 } else { 966 throw new IndexOutOfBoundsException (Integer.toString(length)); 967 } 968 } 969 970 private static final int MAX_BUF_SIZE_COMPOSE = 2; 971 private static final int MAX_BUF_SIZE_DECOMPOSE = 3; 972 973 983 public static String decompose(String str, boolean compat) { 984 return decompose(str,compat,0); 985 } 986 987 998 public static String decompose(String str, boolean compat, int options) { 999 1000 char[] dest = new char[str.length()*MAX_BUF_SIZE_DECOMPOSE]; 1001 int[] trailCC = new int[1]; 1002 int destSize=0; 1003 UnicodeSet nx = NormalizerImpl.getNX(options); 1004 for(;;) { 1005 destSize=NormalizerImpl.decompose(str.toCharArray(),0,str.length(), 1006 dest,0,dest.length, 1007 compat,trailCC, nx); 1008 if(destSize<=dest.length) { 1009 return new String (dest,0,destSize); 1010 } else { 1011 dest = new char[destSize]; 1012 } 1013 } 1014 1015 } 1016 1017 1032 public static int decompose(char[] source,char[] target, boolean compat, int options) { 1033 int[] trailCC = new int[1]; 1034 UnicodeSet nx = NormalizerImpl.getNX(options); 1035 int length = NormalizerImpl.decompose(source,0,source.length, 1036 target,0,target.length, 1037 compat,trailCC,nx); 1038 if(length<=target.length) { 1039 return length; 1040 } else { 1041 throw new IndexOutOfBoundsException (Integer.toString(length)); 1042 } 1043 } 1044 1045 1064 public static int decompose(char[] src,int srcStart, int srcLimit, 1065 char[] dest,int destStart, int destLimit, 1066 boolean compat, int options) { 1067 int[] trailCC = new int[1]; 1068 UnicodeSet nx = NormalizerImpl.getNX(options); 1069 int length = NormalizerImpl.decompose(src,srcStart,srcLimit, 1070 dest,destStart,destLimit, 1071 compat,trailCC,nx); 1072 if(length<=(destLimit-destStart)) { 1073 return length; 1074 } else { 1075 throw new IndexOutOfBoundsException (Integer.toString(length)); 1076 } 1077 } 1078 1079 private static String makeFCD(String src,int options) { 1080 int srcLen = src.length(); 1081 char[] dest = new char[MAX_BUF_SIZE_DECOMPOSE*srcLen]; 1082 int length = 0; 1083 UnicodeSet nx = NormalizerImpl.getNX(options); 1084 for(;;) { 1085 length = NormalizerImpl.makeFCD(src.toCharArray(),0,srcLen, 1086 dest,0,dest.length,nx); 1087 if(length <= dest.length) { 1088 return new String (dest,0,length); 1089 } else { 1090 dest = new char[length]; 1091 } 1092 } 1093 } 1094 1095 1110 public static String normalize(String str, Mode mode, int options) { 1111 return mode.normalize(str,options); 1112 } 1113 1114 1126 public static String normalize(String src,Mode mode) { 1127 return normalize(src, mode, 0); 1128 } 1129 1145 public static int normalize(char[] source,char[] target, Mode mode, int options) { 1146 int length = normalize(source,0,source.length,target,0,target.length,mode, options); 1147 if(length<=target.length) { 1148 return length; 1149 } else { 1150 throw new IndexOutOfBoundsException (Integer.toString(length)); 1151 } 1152 } 1153 1154 1174 public static int normalize(char[] src,int srcStart, int srcLimit, 1175 char[] dest,int destStart, int destLimit, 1176 Mode mode, int options) { 1177 int length = mode.normalize(src,srcStart,srcLimit,dest,destStart,destLimit, options); 1178 1179 if(length<=(destLimit-destStart)) { 1180 return length; 1181 } else { 1182 throw new IndexOutOfBoundsException (Integer.toString(length)); 1183 } 1184 } 1185 1186 1196 public static String normalize(int char32, Mode mode, int options) { 1199 return normalize(UTF16.valueOf(char32), mode, options); 1200 } 1201 1202 1210 public static String normalize(int char32, Mode mode) { 1213 return normalize(UTF16.valueOf(char32), mode, 0); 1214 } 1215 1216 1226 public static QuickCheckResult quickCheck( String source, Mode mode) { 1227 return mode.quickCheck(source.toCharArray(),0,source.length(),true,null); 1228 } 1229 1230 1242 public static QuickCheckResult quickCheck( String source, Mode mode, int options) { 1243 return mode.quickCheck(source.toCharArray(),0,source.length(),true,NormalizerImpl.getNX(options)); 1244 } 1245 1246 1259 public static QuickCheckResult quickCheck(char[] source, Mode mode, int options) { 1260 return mode.quickCheck(source,0,source.length,true, NormalizerImpl.getNX(options)); 1261 } 1262 1263 1286 1287 public static QuickCheckResult quickCheck(char[] source,int start, 1288 int limit, Mode mode,int options) { 1289 return mode.quickCheck(source,start,limit,true,NormalizerImpl.getNX(options)); 1290 } 1291 1292 1296 1316 public static boolean isNormalized(char[] src,int start, 1317 int limit, Mode mode, 1318 int options) { 1319 return (mode.quickCheck(src,start,limit,false,NormalizerImpl.getNX(options))==YES); 1320 } 1321 1322 1332 public static boolean isNormalized(String str, Mode mode, int options) { 1333 return (mode.quickCheck(str.toCharArray(),0,str.length(),false,NormalizerImpl.getNX(options))==YES); 1334 } 1335 1336 1347 public static boolean isNormalized(int char32, Mode mode,int options) { 1350 return isNormalized(UTF16.valueOf(char32), mode, options); 1351 } 1352 1353 1406 public static int compare(char[] s1, int s1Start, int s1Limit, 1407 char[] s2, int s2Start, int s2Limit, 1408 int options) { 1409 return internalCompare(s1, s1Start, s1Limit, 1410 s2, s2Start, s2Limit, 1411 options); 1412 } 1413 1414 1447 public static int compare(String s1, String s2, int options) { 1448 1449 return compare(s1.toCharArray(),0,s1.length(), 1450 s2.toCharArray(),0,s2.length(), 1451 options); 1452 } 1453 1454 1487 public static int compare(char[] s1, char[] s2, int options) { 1488 return compare(s1,0,s1.length,s2,0,s2.length,options); 1489 } 1490 1491 1499 public static int compare(int char32a, int char32b,int options) { 1502 return compare(UTF16.valueOf(char32a), UTF16.valueOf(char32b), options); 1503 } 1504 1505 1513 public static int compare(int char32a, String str2, int options) { 1516 return compare(UTF16.valueOf(char32a), str2, options); 1517 } 1518 1519 1562 1563 1564 public static int concatenate(char[] left, int leftStart, int leftLimit, 1565 char[] right, int rightStart, int rightLimit, 1566 char[] dest, int destStart, int destLimit, 1567 Normalizer.Mode mode, int options) { 1568 1569 1570 UCharacterIterator iter; 1571 1572 int leftBoundary, rightBoundary, destLength; 1573 1574 if(dest == null) { 1575 throw new IllegalArgumentException (); 1576 } 1577 1578 1579 if (right == dest && rightStart < destLimit && destStart < rightLimit) { 1580 throw new IllegalArgumentException ("overlapping right and dst ranges"); 1581 } 1582 1583 1584 1585 1596 1597 1601 1602 iter = UCharacterIterator.getInstance(left, leftStart, leftLimit); 1603 1604 iter.setIndex(iter.getLength()); 1605 char[] buffer=new char[100]; 1606 int bufferLength; 1607 bufferLength=previous(iter, buffer,0,buffer.length,mode,false,null,options); 1608 1609 leftBoundary=iter.getIndex(); 1610 1611 if(bufferLength>buffer.length) { 1612 char[] newBuf = new char[buffer.length*2]; 1613 buffer = newBuf; 1614 newBuf = null; 1616 System.arraycopy(left,leftBoundary,buffer,0,bufferLength); 1617 } 1618 1619 1623 1624 iter = UCharacterIterator.getInstance(right, rightStart, rightLimit); 1625 1626 rightBoundary=next(iter,buffer,bufferLength, buffer.length-bufferLength, 1627 mode, false,null, options); 1628 1629 if(bufferLength>buffer.length) { 1630 char[] newBuf = new char[buffer.length*2]; 1631 buffer = newBuf; 1632 newBuf = null; 1634 System.arraycopy(right,rightBoundary,buffer, 1635 bufferLength,rightBoundary); 1636 } 1637 1638 bufferLength+=rightBoundary; 1639 1640 1641 if(left!=dest && leftBoundary>0 && (destLimit)>0) { 1642 System.arraycopy(left,0,dest,0, Math.min(leftBoundary,destLimit)); 1643 } 1644 destLength=leftBoundary; 1645 1646 1647 if(destLimit>destLength) { 1648 destLength+=Normalizer.normalize(buffer,0,bufferLength,dest, 1649 destLength,destLimit,mode,options); 1650 1651 } else { 1652 destLength+=Normalizer.normalize(buffer, 0, bufferLength,null,0,0,mode,options); 1653 } 1654 1655 1656 rightStart+=rightBoundary; 1657 int rightLength=(rightLimit-rightStart); 1658 if(rightLength>0 && destLimit>destLength) { 1659 System.arraycopy(right,rightStart,dest,destLength, 1660 Math.min(rightLength,destLength) 1661 ); 1662 } 1663 destLength+=rightLength; 1664 1665 if(destLength<=(destLimit-destStart)) { 1666 return destLength; 1667 } else { 1668 throw new IndexOutOfBoundsException (Integer.toString(destLength)); 1669 } 1670 } 1671 1672 1699 public static String concatenate(char[] left, char[] right,Mode mode, int options) { 1700 char[] result = new char[(left.length+right.length)* MAX_BUF_SIZE_DECOMPOSE]; 1701 for(;;) { 1702 1703 int length = concatenate(left, 0, left.length, 1704 right, 0, right.length, 1705 result,0, result.length, 1706 mode, options); 1707 if(length<=result.length) { 1708 return new String (result,0,length); 1709 } else { 1710 result = new char[length]; 1711 } 1712 } 1713 } 1714 1715 1742 public static String concatenate(String left, String right,Mode mode, int options) { 1743 char[] result = new char[(left.length()+right.length())* MAX_BUF_SIZE_DECOMPOSE]; 1744 for(;;) { 1745 1746 int length = concatenate(left.toCharArray(), 0, left.length(), 1747 right.toCharArray(),0, right.length(), 1748 result, 0, result.length, 1749 mode, options); 1750 if(length<=result.length) { 1751 return new String (result,0,length); 1752 } else { 1753 result = new char[length]; 1754 } 1755 } 1756 } 1757 1758 1765 public static int getFC_NFKC_Closure(int c,char[] dest) { 1766 return NormalizerImpl.getFC_NFKC_Closure(c,dest); 1767 } 1768 1775 public static String getFC_NFKC_Closure(int c) { 1776 char[] dest = new char[10]; 1777 for(;;) { 1778 int length = getFC_NFKC_Closure(c,dest); 1779 if(length<=dest.length) { 1780 return new String (dest,0,length); 1781 } else { 1782 dest = new char[length]; 1783 } 1784 } 1785 } 1786 1790 1795 public int current() { 1796 if(bufferPos<bufferLimit || nextNormalize()) { 1797 return getCodePointAt(bufferPos); 1798 } else { 1799 return DONE; 1800 } 1801 } 1802 1803 1810 public int next() { 1811 if(bufferPos<bufferLimit || nextNormalize()) { 1812 int c=getCodePointAt(bufferPos); 1813 bufferPos+=(c>0xFFFF) ? 2 : 1; 1814 return c; 1815 } else { 1816 return DONE; 1817 } 1818 } 1819 1820 1821 1828 public int previous() { 1829 if(bufferPos>0 || previousNormalize()) { 1830 int c=getCodePointAt(bufferPos-1); 1831 bufferPos-=(c>0xFFFF) ? 2 : 1; 1832 return c; 1833 } else { 1834 return DONE; 1835 } 1836 } 1837 1838 1843 public void reset() { 1844 text.setIndex(0); 1845 currentIndex=nextIndex=0; 1846 clearBuffer(); 1847 } 1848 1849 1858 public void setIndexOnly(int index) { 1859 text.setIndex(index); 1860 currentIndex=nextIndex=index; clearBuffer(); 1862 } 1863 1864 1886 public int setIndex(int index) { 1888 setIndexOnly(index); 1889 return current(); 1890 } 1891 1900 public int getBeginIndex() { 1901 return 0; 1902 } 1903 1904 1912 public int getEndIndex() { 1913 return endIndex(); 1914 } 1915 1921 public int first() { 1922 reset(); 1923 return next(); 1924 } 1925 1926 1933 public int last() { 1934 text.setToLimit(); 1935 currentIndex=nextIndex=text.getIndex(); 1936 clearBuffer(); 1937 return previous(); 1938 } 1939 1940 1955 public int getIndex() { 1956 if(bufferPos<bufferLimit) { 1957 return currentIndex; 1958 } else { 1959 return nextIndex; 1960 } 1961 } 1962 1963 1970 public int startIndex() { 1971 return 0; 1972 } 1973 1974 1981 public int endIndex() { 1982 return text.getLength(); 1983 } 1984 1985 2014 public void setMode(Mode newMode) { 2015 mode = newMode; 2016 } 2017 2023 public Mode getMode() { 2024 return mode; 2025 } 2026 2044 public void setOption(int option,boolean value) { 2045 if (value) { 2046 options |= option; 2047 } else { 2048 options &= (~option); 2049 } 2050 } 2051 2052 2058 public int getOption(int option) { 2059 if((options & option)!=0) { 2060 return 1 ; 2061 } else { 2062 return 0; 2063 } 2064 } 2065 2066 2075 public int getText(char[] fillIn) { 2076 return text.getText(fillIn); 2077 } 2078 2079 2084 public int getLength() { 2085 return text.getLength(); 2086 } 2087 2088 2093 public String getText() { 2094 return text.getText(); 2095 } 2096 2097 2103 public void setText(StringBuffer newText) { 2104 2105 UCharacterIterator newIter = UCharacterIterator.getInstance(newText); 2106 if (newIter == null) { 2107 throw new IllegalStateException ("Could not create a new UCharacterIterator"); 2108 } 2109 text = newIter; 2110 reset(); 2111 } 2112 2113 2119 public void setText(char[] newText) { 2120 2121 UCharacterIterator newIter = UCharacterIterator.getInstance(newText); 2122 if (newIter == null) { 2123 throw new IllegalStateException ("Could not create a new UCharacterIterator"); 2124 } 2125 text = newIter; 2126 reset(); 2127 } 2128 2129 2135 public void setText(String newText) { 2136 2137 UCharacterIterator newIter = UCharacterIterator.getInstance(newText); 2138 if (newIter == null) { 2139 throw new IllegalStateException ("Could not create a new UCharacterIterator"); 2140 } 2141 text = newIter; 2142 reset(); 2143 } 2144 2145 2151 public void setText(CharacterIterator newText) { 2152 2153 UCharacterIterator newIter = UCharacterIterator.getInstance(newText); 2154 if (newIter == null) { 2155 throw new IllegalStateException ("Could not create a new UCharacterIterator"); 2156 } 2157 text = newIter; 2158 reset(); 2159 } 2160 2161 2167 public void setText(UCharacterIterator newText) { 2168 try{ 2169 UCharacterIterator newIter = (UCharacterIterator)newText.clone(); 2170 if (newIter == null) { 2171 throw new IllegalStateException ("Could not create a new UCharacterIterator"); 2172 } 2173 text = newIter; 2174 reset(); 2175 }catch(CloneNotSupportedException e) { 2176 throw new IllegalStateException ("Could not clone the UCharacterIterator"); 2177 } 2178 } 2179 2180 2184 2185 2186 2187 2193 2194 private static long getPrevNorm32(UCharacterIterator src, 2195 int minC, 2196 int mask, 2197 char[] chars) { 2198 long norm32; 2199 int ch=0; 2200 2201 if((ch=src.previous()) == UCharacterIterator.DONE) { 2202 return 0; 2203 } 2204 chars[0]=(char)ch; 2205 chars[1]=0; 2206 2207 2209 if(chars[0]<minC) { 2210 return 0; 2211 } else if(!UTF16.isSurrogate(chars[0])) { 2212 return NormalizerImpl.getNorm32(chars[0]); 2213 } else if(UTF16.isLeadSurrogate(chars[0]) || (src.getIndex()==0)) { 2214 2215 chars[1]=(char)src.current(); 2216 return 0; 2217 } else if(UTF16.isLeadSurrogate(chars[1]=(char)src.previous())) { 2218 norm32=NormalizerImpl.getNorm32(chars[1]); 2219 if((norm32&mask)==0) { 2220 2222 return 0; 2223 } else { 2224 2225 return NormalizerImpl.getNorm32FromSurrogatePair(norm32,chars[0]); 2226 } 2227 } else { 2228 2229 src.moveIndex( 1); 2230 return 0; 2231 } 2232 } 2233 2234 private interface IsPrevBoundary{ 2235 public boolean isPrevBoundary(UCharacterIterator src, 2236 int minC, 2237 int mask, 2238 char[] chars); 2239 } 2240 private static final class IsPrevNFDSafe implements IsPrevBoundary{ 2241 2247 public boolean isPrevBoundary(UCharacterIterator src, 2248 int minC, 2249 int ccOrQCMask, 2250 char[] chars) { 2251 2252 return NormalizerImpl.isNFDSafe(getPrevNorm32(src, minC, 2253 ccOrQCMask, chars), 2254 ccOrQCMask, 2255 ccOrQCMask& NormalizerImpl.QC_MASK); 2256 } 2257 } 2258 2259 private static final class IsPrevTrueStarter implements IsPrevBoundary{ 2260 2266 public boolean isPrevBoundary(UCharacterIterator src, 2267 int minC, 2268 int ccOrQCMask, 2269 char[] chars) { 2270 long norm32; 2271 int decompQCMask; 2272 2273 decompQCMask=(ccOrQCMask<<2)&0xf; 2274 norm32=getPrevNorm32(src, minC, ccOrQCMask|decompQCMask, chars); 2275 return NormalizerImpl.isTrueStarter(norm32,ccOrQCMask,decompQCMask); 2276 } 2277 } 2278 2279 private static int findPreviousIterationBoundary(UCharacterIterator src, 2280 IsPrevBoundary obj, 2281 int minC, 2282 int mask, 2283 char[] buffer, 2284 int[] startIndex) { 2285 char[] chars=new char[2]; 2286 boolean isBoundary; 2287 2288 2289 startIndex[0] = buffer.length; 2290 chars[0]=0; 2291 while(src.getIndex()>0 && chars[0]!=UCharacterIterator.DONE) { 2292 isBoundary=obj.isPrevBoundary(src, minC, mask, chars); 2293 2294 2295 2296 if(startIndex[0] < (chars[1]==0 ? 1 : 2)) { 2297 2298 char[] newBuf = new char[buffer.length*2]; 2300 2301 System.arraycopy(buffer,startIndex[0],newBuf, 2302 newBuf.length-(buffer.length-startIndex[0]), 2303 buffer.length-startIndex[0]); 2304 startIndex[0]+=newBuf.length-buffer.length; 2306 2307 buffer=newBuf; 2308 newBuf=null; 2309 2310 } 2311 2312 buffer[--startIndex[0]]=chars[0]; 2313 if(chars[1]!=0) { 2314 buffer[--startIndex[0]]=chars[1]; 2315 } 2316 2317 2318 if(isBoundary) { 2319 break; 2320 } 2321 } 2322 2323 2324 return buffer.length-startIndex[0]; 2325 } 2326 2327 private static int previous(UCharacterIterator src, 2328 char[] dest, int destStart, int destLimit, 2329 Mode mode, 2330 boolean doNormalize, 2331 boolean[] pNeededToNormalize, 2332 int options) { 2333 2334 IsPrevBoundary isPreviousBoundary; 2335 int destLength, bufferLength; 2336 int mask; 2337 2338 int c,c2; 2339 2340 char minC; 2341 int destCapacity = destLimit-destStart; 2342 destLength=0; 2343 2344 2345 if(pNeededToNormalize!=null) { 2346 pNeededToNormalize[0]=false; 2347 } 2348 minC = (char)mode.getMinC(); 2349 mask = mode.getMask(); 2350 isPreviousBoundary = mode.getPrevBoundary(); 2351 2352 if(isPreviousBoundary==null) { 2353 destLength=0; 2354 if((c=src.previous())>=0) { 2355 destLength=1; 2356 if(UTF16.isTrailSurrogate((char)c)) { 2357 c2= src.previous(); 2358 if(c2!= UCharacterIterator.DONE) { 2359 if(UTF16.isLeadSurrogate((char)c2)) { 2360 if(destCapacity>=2) { 2361 dest[1]=(char)c; destLength=2; 2363 } 2364 c=c2; 2366 } else { 2367 src.moveIndex(1); 2368 } 2369 } 2370 } 2371 2372 if(destCapacity>0) { 2373 dest[0]=(char)c; 2374 } 2375 } 2376 return destLength; 2377 } 2378 2379 char[] buffer = new char[100]; 2380 int[] startIndex= new int[1]; 2381 bufferLength=findPreviousIterationBoundary(src, 2382 isPreviousBoundary, 2383 minC, mask,buffer, 2384 startIndex); 2385 if(bufferLength>0) { 2386 if(doNormalize) { 2387 destLength=Normalizer.normalize(buffer,startIndex[0], 2388 startIndex[0]+bufferLength, 2389 dest, destStart,destLimit, 2390 mode, options); 2391 2392 if(pNeededToNormalize!=null) { 2393 pNeededToNormalize[0]=(boolean)(destLength!=bufferLength || 2394 Utility.arrayRegionMatches( 2395 buffer,0,dest, 2396 destStart,destLimit 2397 )); 2398 } 2399 } else { 2400 2401 if(destCapacity>0) { 2402 System.arraycopy(buffer,startIndex[0],dest,0, 2403 (bufferLength<destCapacity) ? 2404 bufferLength : destCapacity 2405 ); 2406 } 2407 } 2408 } 2409 2410 2411 return destLength; 2412 } 2413 2414 2415 2416 2417 2421 private interface IsNextBoundary{ 2422 boolean isNextBoundary(UCharacterIterator src, 2423 int minC, 2424 int mask, 2425 int[] chars); 2426 } 2427 2433 private static long getNextNorm32(UCharacterIterator src, 2434 int minC, 2435 int mask, 2436 int[] chars) { 2437 long norm32; 2438 2439 2440 chars[0]=src.next(); 2441 chars[1]=0; 2442 2443 if(chars[0]<minC) { 2444 return 0; 2445 } 2446 2447 norm32=NormalizerImpl.getNorm32((char)chars[0]); 2448 if(UTF16.isLeadSurrogate((char)chars[0])) { 2449 if(src.current()!=UCharacterIterator.DONE && 2450 UTF16.isTrailSurrogate((char)(chars[1]=src.current()))) { 2451 src.moveIndex(1); 2452 if((norm32&mask)==0) { 2453 2454 return 0; 2455 } else { 2456 2457 return NormalizerImpl.getNorm32FromSurrogatePair(norm32,(char)chars[1]); 2458 } 2459 } else { 2460 2461 return 0; 2462 } 2463 } 2464 return norm32; 2465 } 2466 2467 2468 2473 private static final class IsNextNFDSafe implements IsNextBoundary{ 2474 public boolean isNextBoundary(UCharacterIterator src, 2475 int minC, 2476 int ccOrQCMask, 2477 int[] chars) { 2478 return NormalizerImpl.isNFDSafe(getNextNorm32(src,minC,ccOrQCMask,chars), 2479 ccOrQCMask, ccOrQCMask&NormalizerImpl.QC_MASK); 2480 } 2481 } 2482 2483 2489 private static final class IsNextTrueStarter implements IsNextBoundary{ 2490 public boolean isNextBoundary(UCharacterIterator src, 2491 int minC, 2492 int ccOrQCMask, 2493 int[] chars) { 2494 long norm32; 2495 int decompQCMask; 2496 2497 decompQCMask=(ccOrQCMask<<2)&0xf; 2498 norm32=getNextNorm32(src, minC, ccOrQCMask|decompQCMask, chars); 2499 return NormalizerImpl.isTrueStarter(norm32, ccOrQCMask, decompQCMask); 2500 } 2501 } 2502 2503 private static int findNextIterationBoundary(UCharacterIterator src, 2504 IsNextBoundary obj, 2505 int minC, 2506 int mask, 2507 char[] buffer) { 2508 int[] chars = new int[2]; 2509 int bufferIndex =0; 2510 2511 if(src.current()==UCharacterIterator.DONE) { 2512 return 0; 2513 } 2514 2515 chars[0]=src.next(); 2516 buffer[0]=(char)chars[0]; 2517 bufferIndex=1; 2518 2519 if(UTF16.isLeadSurrogate((char)chars[0])&& 2520 src.current()!=UCharacterIterator.DONE) { 2521 if(UTF16.isTrailSurrogate((char)(chars[1]=src.next()))) { 2522 buffer[bufferIndex++]=(char)chars[1]; 2523 } else { 2524 src.moveIndex(-1); 2525 } 2526 } 2527 2528 2529 2531 while( src.current()!=UCharacterIterator.DONE) { 2532 if(obj.isNextBoundary(src, minC, mask, chars)) { 2533 2534 src.moveIndex(chars[1]==0 ? -1 : -2); 2535 break; 2536 } else { 2537 if(bufferIndex+(chars[1]==0 ? 1 : 2)<=buffer.length) { 2538 buffer[bufferIndex++]=(char)chars[0]; 2539 if(chars[1]!=0) { 2540 buffer[bufferIndex++]=(char)chars[1]; 2541 } 2542 } else { 2543 char[] newBuf = new char[buffer.length *2]; 2544 System.arraycopy(buffer,0,newBuf,0,bufferIndex); 2545 buffer = newBuf; 2546 buffer[bufferIndex++]=(char)chars[0]; 2547 if(chars[1]!=0) { 2548 buffer[bufferIndex++]=(char)chars[1]; 2549 } 2550 } 2551 } 2552 } 2553 2554 2555 return bufferIndex; 2556 } 2557 2558 private static int next(UCharacterIterator src, 2559 char[] dest, int destStart, int destLimit, 2560 Normalizer.Mode mode, 2561 boolean doNormalize, 2562 boolean[] pNeededToNormalize, 2563 int options) { 2564 2565 IsNextBoundary isNextBoundary; 2566 int mask; 2567 int bufferLength; 2568 int c,c2; 2569 char minC; 2570 int destCapacity = destLimit - destStart; 2571 int destLength = 0; 2572 2573 if(pNeededToNormalize!=null) { 2574 pNeededToNormalize[0]=false; 2575 } 2576 2577 minC = (char)mode.getMinC(); 2578 mask = mode.getMask(); 2579 isNextBoundary = mode.getNextBoundary(); 2580 2581 if(isNextBoundary==null) { 2582 destLength=0; 2583 c=src.next(); 2584 if(c!=UCharacterIterator.DONE) { 2585 destLength=1; 2586 if(UTF16.isLeadSurrogate((char)c)) { 2587 c2= src.next(); 2588 if(c2!= UCharacterIterator.DONE) { 2589 if(UTF16.isTrailSurrogate((char)c2)) { 2590 if(destCapacity>=2) { 2591 dest[1]=(char)c2; destLength=2; 2593 } 2594 } else { 2596 src.moveIndex(-1); 2597 } 2598 } 2599 } 2600 2601 if(destCapacity>0) { 2602 dest[0]=(char)c; 2603 } 2604 } 2605 return destLength; 2606 } 2607 2608 char[] buffer=new char[100]; 2609 int[] startIndex = new int[1]; 2610 2611 bufferLength=findNextIterationBoundary(src,isNextBoundary, minC, mask, 2612 buffer); 2613 if(bufferLength>0) { 2614 if(doNormalize) { 2615 destLength=mode.normalize(buffer,startIndex[0],bufferLength, 2616 dest,destStart,destLimit, options); 2617 2618 if(pNeededToNormalize!=null) { 2619 pNeededToNormalize[0]=(boolean)(destLength!=bufferLength || 2620 Utility.arrayRegionMatches(buffer,startIndex[0], 2621 dest,destStart, 2622 destLength)); 2623 } 2624 } else { 2625 2626 if(destCapacity>0) { 2627 System.arraycopy(buffer,0,dest,destStart, 2628 Math.min(bufferLength,destCapacity) 2629 ); 2630 } 2631 2632 2633 } 2634 } 2635 return destLength; 2636 } 2637 2638 private void clearBuffer() { 2639 bufferLimit=bufferStart=bufferPos=0; 2640 } 2641 2642 private boolean nextNormalize() { 2643 2644 clearBuffer(); 2645 currentIndex=nextIndex; 2646 text.setIndex(nextIndex); 2647 2648 bufferLimit=next(text,buffer,bufferStart,buffer.length,mode,true,null,options); 2649 2650 nextIndex=text.getIndex(); 2651 return (bufferLimit>0); 2652 } 2653 2654 private boolean previousNormalize() { 2655 2656 clearBuffer(); 2657 nextIndex=currentIndex; 2658 text.setIndex(currentIndex); 2659 bufferLimit=previous(text,buffer,bufferStart,buffer.length,mode,true,null,options); 2660 2661 currentIndex=text.getIndex(); 2662 bufferPos = bufferLimit; 2663 return bufferLimit>0; 2664 } 2665 2666 private int getCodePointAt(int index) { 2667 if( UTF16.isSurrogate(buffer[index])) { 2668 if(UTF16.isLeadSurrogate(buffer[index])) { 2669 if((index+1)<bufferLimit && 2670 UTF16.isTrailSurrogate(buffer[index+1])) { 2671 return UCharacterProperty.getRawSupplementary( 2672 buffer[index], 2673 buffer[index+1] 2674 ); 2675 } 2676 }else if(UTF16.isTrailSurrogate(buffer[index])) { 2677 if(index>0 && UTF16.isLeadSurrogate(buffer[index-1])) { 2678 return UCharacterProperty.getRawSupplementary( 2679 buffer[index-1], 2680 buffer[index] 2681 ); 2682 } 2683 } 2684 } 2685 return buffer[index]; 2686 2687 } 2688 2689 2694 public static boolean isNFSkippable(int c, Mode mode) { 2695 return mode.isNFSkippable(c); 2696 } 2697 2698 2699 private static int internalCompare(char[] s1, int s1Start,int s1Limit, 2700 char[] s2, int s2Start,int s2Limit, 2701 int options) { 2702 2703 char[] fcd1 = new char[300]; 2704 char[] fcd2 = new char[300]; 2705 2706 Normalizer.Mode mode; 2707 int result; 2708 2709 if( s1==null || s1Start<0 || s1Limit<0 || 2710 s2==null || s2Start<0 || s2Limit<0 || 2711 s1Limit<s1Start || s2Limit<s2Start 2712 ) { 2713 2714 throw new IllegalArgumentException (); 2715 } 2716 2717 UnicodeSet nx=NormalizerImpl.getNX((int)(options>>Normalizer.COMPARE_NORM_OPTIONS_SHIFT)); 2718 options|= NormalizerImpl.COMPARE_EQUIV; 2719 result=0; 2720 2721 2742 if((options& Normalizer.FOLD_CASE_EXCLUDE_SPECIAL_I) >0 ) { 2743 mode=Normalizer.NFD; 2744 options&=~ Normalizer.INPUT_IS_FCD; 2745 } else { 2746 mode=Normalizer.FCD; 2747 } 2748 if((options& Normalizer.INPUT_IS_FCD)==0) { 2749 char[] dest; 2750 int fcdLen1, fcdLen2; 2751 boolean isFCD1, isFCD2; 2752 2753 isFCD1= Normalizer.YES==mode.quickCheck(s1, s1Start, s1Limit, true, nx); 2755 isFCD2= Normalizer.YES==mode.quickCheck(s2, s2Start, s2Limit, true, nx); 2756 2764 2765 if(!isFCD1) { 2766 fcdLen1=mode.normalize(s1, 0, s1.length, 2767 fcd1, 0, fcd1.length, 2768 nx); 2769 2770 if(fcdLen1>fcd1.length) { 2771 dest=new char[fcdLen1]; 2772 fcdLen1=mode.normalize( s1, 0, s1.length, 2773 dest, 0, dest.length, 2774 nx); 2775 s1=dest; 2776 } else { 2777 s1=fcd1; 2778 } 2779 s1Limit=fcdLen1; 2780 s1Start=0; 2781 } 2782 2783 if(!isFCD2) { 2784 fcdLen2=mode.normalize(s2,s2Start,s2Limit, 2785 fcd2,0,fcd2.length, 2786 nx); 2787 2788 if(fcdLen2>fcd2.length) { 2789 dest=new char[fcdLen2]; 2790 fcdLen2=mode.normalize( s2,s2Start,s2Limit, 2791 dest,0,dest.length, 2792 nx); 2793 s2=dest; 2794 } else { 2795 s2=fcd2; 2796 } 2797 s2Limit=fcdLen2; 2798 s2Start=0; 2799 } 2800 2801 } 2802 2803 result=NormalizerImpl.cmpEquivFold(s1, s1Start, s1Limit, 2804 s2, s2Start, s2Limit, options); 2805 return result; 2806 } 2807 2808 2814 static VersionInfo getUnicodeVersion() { 2815 return NormalizerImpl.getUnicodeVersion(); 2816 } 2817} 2818
| Popular Tags
|