1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 /* 3 ******************************************************************************* 4 * Copyright (C) 2009-2014, International Business Machines 5 * Corporation and others. All Rights Reserved. 6 ******************************************************************************* 7 */ 8 9 package android.icu.impl; 10 11 import java.io.IOException; 12 import java.nio.ByteBuffer; 13 14 import android.icu.text.Normalizer; 15 import android.icu.text.Normalizer2; 16 import android.icu.util.ICUUncheckedIOException; 17 18 /** 19 * @hide Only a subset of ICU is exposed in Android 20 */ 21 public final class Norm2AllModes { 22 // Public API dispatch via Normalizer2 subclasses -------------------------- *** 23 24 // Normalizer2 implementation for the old UNORM_NONE. 25 public static final class NoopNormalizer2 extends Normalizer2 { 26 @Override 27 public StringBuilder normalize(CharSequence src, StringBuilder dest) { 28 if(dest!=src) { 29 dest.setLength(0); 30 return dest.append(src); 31 } else { 32 throw new IllegalArgumentException(); 33 } 34 } 35 @Override 36 public Appendable normalize(CharSequence src, Appendable dest) { 37 if(dest!=src) { 38 try { 39 return dest.append(src); 40 } catch(IOException e) { 41 throw new ICUUncheckedIOException(e); // Avoid declaring "throws IOException". 42 } 43 } else { 44 throw new IllegalArgumentException(); 45 } 46 } 47 @Override 48 public StringBuilder normalizeSecondAndAppend(StringBuilder first, CharSequence second) { 49 if(first!=second) { 50 return first.append(second); 51 } else { 52 throw new IllegalArgumentException(); 53 } 54 } 55 @Override 56 public StringBuilder append(StringBuilder first, CharSequence second) { 57 if(first!=second) { 58 return first.append(second); 59 } else { 60 throw new IllegalArgumentException(); 61 } 62 } 63 @Override 64 public String getDecomposition(int c) { 65 return null; 66 } 67 // No need to override the default getRawDecomposition(). 68 @Override 69 public boolean isNormalized(CharSequence s) { return true; } 70 @Override 71 public Normalizer.QuickCheckResult quickCheck(CharSequence s) { return Normalizer.YES; } 72 @Override 73 public int spanQuickCheckYes(CharSequence s) { return s.length(); } 74 @Override 75 public boolean hasBoundaryBefore(int c) { return true; } 76 @Override 77 public boolean hasBoundaryAfter(int c) { return true; } 78 @Override 79 public boolean isInert(int c) { return true; } 80 } 81 82 // Intermediate class: 83 // Has Normalizer2Impl and does boilerplate argument checking and setup. 84 public static abstract class Normalizer2WithImpl extends Normalizer2 { 85 public Normalizer2WithImpl(Normalizer2Impl ni) { 86 impl=ni; 87 } 88 89 // normalize 90 @Override 91 public StringBuilder normalize(CharSequence src, StringBuilder dest) { 92 if(dest==src) { 93 throw new IllegalArgumentException(); 94 } 95 dest.setLength(0); 96 normalize(src, new Normalizer2Impl.ReorderingBuffer(impl, dest, src.length())); 97 return dest; 98 } 99 @Override 100 public Appendable normalize(CharSequence src, Appendable dest) { 101 if(dest==src) { 102 throw new IllegalArgumentException(); 103 } 104 Normalizer2Impl.ReorderingBuffer buffer= 105 new Normalizer2Impl.ReorderingBuffer(impl, dest, src.length()); 106 normalize(src, buffer); 107 buffer.flush(); 108 return dest; 109 } 110 protected abstract void normalize(CharSequence src, Normalizer2Impl.ReorderingBuffer buffer); 111 112 // normalize and append 113 @Override 114 public StringBuilder normalizeSecondAndAppend(StringBuilder first, CharSequence second) { 115 return normalizeSecondAndAppend(first, second, true); 116 } 117 @Override 118 public StringBuilder append(StringBuilder first, CharSequence second) { 119 return normalizeSecondAndAppend(first, second, false); 120 } 121 public StringBuilder normalizeSecondAndAppend( 122 StringBuilder first, CharSequence second, boolean doNormalize) { 123 if(first==second) { 124 throw new IllegalArgumentException(); 125 } 126 normalizeAndAppend( 127 second, doNormalize, 128 new Normalizer2Impl.ReorderingBuffer(impl, first, first.length()+second.length())); 129 return first; 130 } 131 protected abstract void normalizeAndAppend( 132 CharSequence src, boolean doNormalize, Normalizer2Impl.ReorderingBuffer buffer); 133 134 @Override 135 public String getDecomposition(int c) { 136 return impl.getDecomposition(c); 137 } 138 @Override 139 public String getRawDecomposition(int c) { 140 return impl.getRawDecomposition(c); 141 } 142 @Override 143 public int composePair(int a, int b) { 144 return impl.composePair(a, b); 145 } 146 147 @Override 148 public int getCombiningClass(int c) { 149 return impl.getCC(impl.getNorm16(c)); 150 } 151 152 // quick checks 153 @Override 154 public boolean isNormalized(CharSequence s) { 155 return s.length()==spanQuickCheckYes(s); 156 } 157 @Override 158 public Normalizer.QuickCheckResult quickCheck(CharSequence s) { 159 return isNormalized(s) ? Normalizer.YES : Normalizer.NO; 160 } 161 162 public abstract int getQuickCheck(int c); 163 164 public final Normalizer2Impl impl; 165 } 166 167 public static final class DecomposeNormalizer2 extends Normalizer2WithImpl { 168 public DecomposeNormalizer2(Normalizer2Impl ni) { 169 super(ni); 170 } 171 172 @Override 173 protected void normalize(CharSequence src, Normalizer2Impl.ReorderingBuffer buffer) { 174 impl.decompose(src, 0, src.length(), buffer); 175 } 176 @Override 177 protected void normalizeAndAppend( 178 CharSequence src, boolean doNormalize, Normalizer2Impl.ReorderingBuffer buffer) { 179 impl.decomposeAndAppend(src, doNormalize, buffer); 180 } 181 @Override 182 public int spanQuickCheckYes(CharSequence s) { 183 return impl.decompose(s, 0, s.length(), null); 184 } 185 @Override 186 public int getQuickCheck(int c) { 187 return impl.isDecompYes(impl.getNorm16(c)) ? 1 : 0; 188 } 189 @Override 190 public boolean hasBoundaryBefore(int c) { return impl.hasDecompBoundary(c, true); } 191 @Override 192 public boolean hasBoundaryAfter(int c) { return impl.hasDecompBoundary(c, false); } 193 @Override 194 public boolean isInert(int c) { return impl.isDecompInert(c); } 195 } 196 197 public static final class ComposeNormalizer2 extends Normalizer2WithImpl { 198 public ComposeNormalizer2(Normalizer2Impl ni, boolean fcc) { 199 super(ni); 200 onlyContiguous=fcc; 201 } 202 203 @Override 204 protected void normalize(CharSequence src, Normalizer2Impl.ReorderingBuffer buffer) { 205 impl.compose(src, 0, src.length(), onlyContiguous, true, buffer); 206 } 207 @Override 208 protected void normalizeAndAppend( 209 CharSequence src, boolean doNormalize, Normalizer2Impl.ReorderingBuffer buffer) { 210 impl.composeAndAppend(src, doNormalize, onlyContiguous, buffer); 211 } 212 213 @Override 214 public boolean isNormalized(CharSequence s) { 215 // 5: small destCapacity for substring normalization 216 return impl.compose(s, 0, s.length(), 217 onlyContiguous, false, 218 new Normalizer2Impl.ReorderingBuffer(impl, new StringBuilder(), 5)); 219 } 220 @Override 221 public Normalizer.QuickCheckResult quickCheck(CharSequence s) { 222 int spanLengthAndMaybe=impl.composeQuickCheck(s, 0, s.length(), onlyContiguous, false); 223 if((spanLengthAndMaybe&1)!=0) { 224 return Normalizer.MAYBE; 225 } else if((spanLengthAndMaybe>>>1)==s.length()) { 226 return Normalizer.YES; 227 } else { 228 return Normalizer.NO; 229 } 230 } 231 @Override 232 public int spanQuickCheckYes(CharSequence s) { 233 return impl.composeQuickCheck(s, 0, s.length(), onlyContiguous, true)>>>1; 234 } 235 @Override 236 public int getQuickCheck(int c) { 237 return impl.getCompQuickCheck(impl.getNorm16(c)); 238 } 239 @Override 240 public boolean hasBoundaryBefore(int c) { return impl.hasCompBoundaryBefore(c); } 241 @Override 242 public boolean hasBoundaryAfter(int c) { 243 return impl.hasCompBoundaryAfter(c, onlyContiguous, false); 244 } 245 @Override 246 public boolean isInert(int c) { 247 return impl.hasCompBoundaryAfter(c, onlyContiguous, true); 248 } 249 250 private final boolean onlyContiguous; 251 } 252 253 public static final class FCDNormalizer2 extends Normalizer2WithImpl { 254 public FCDNormalizer2(Normalizer2Impl ni) { 255 super(ni); 256 } 257 258 @Override 259 protected void normalize(CharSequence src, Normalizer2Impl.ReorderingBuffer buffer) { 260 impl.makeFCD(src, 0, src.length(), buffer); 261 } 262 @Override 263 protected void normalizeAndAppend( 264 CharSequence src, boolean doNormalize, Normalizer2Impl.ReorderingBuffer buffer) { 265 impl.makeFCDAndAppend(src, doNormalize, buffer); 266 } 267 @Override 268 public int spanQuickCheckYes(CharSequence s) { 269 return impl.makeFCD(s, 0, s.length(), null); 270 } 271 @Override 272 public int getQuickCheck(int c) { 273 return impl.isDecompYes(impl.getNorm16(c)) ? 1 : 0; 274 } 275 @Override 276 public boolean hasBoundaryBefore(int c) { return impl.hasFCDBoundaryBefore(c); } 277 @Override 278 public boolean hasBoundaryAfter(int c) { return impl.hasFCDBoundaryAfter(c); } 279 @Override 280 public boolean isInert(int c) { return impl.isFCDInert(c); } 281 } 282 283 // instance cache ---------------------------------------------------------- *** 284 285 private Norm2AllModes(Normalizer2Impl ni) { 286 impl=ni; 287 comp=new ComposeNormalizer2(ni, false); 288 decomp=new DecomposeNormalizer2(ni); 289 fcd=new FCDNormalizer2(ni); 290 fcc=new ComposeNormalizer2(ni, true); 291 } 292 293 public final Normalizer2Impl impl; 294 public final ComposeNormalizer2 comp; 295 public final DecomposeNormalizer2 decomp; 296 public final FCDNormalizer2 fcd; 297 public final ComposeNormalizer2 fcc; 298 299 private static Norm2AllModes getInstanceFromSingleton(Norm2AllModesSingleton singleton) { 300 if(singleton.exception!=null) { 301 throw singleton.exception; 302 } 303 return singleton.allModes; 304 } 305 public static Norm2AllModes getNFCInstance() { 306 return getInstanceFromSingleton(NFCSingleton.INSTANCE); 307 } 308 public static Norm2AllModes getNFKCInstance() { 309 return getInstanceFromSingleton(NFKCSingleton.INSTANCE); 310 } 311 public static Norm2AllModes getNFKC_CFInstance() { 312 return getInstanceFromSingleton(NFKC_CFSingleton.INSTANCE); 313 } 314 // For use in properties APIs. 315 public static Normalizer2WithImpl getN2WithImpl(int index) { 316 switch(index) { 317 case 0: return getNFCInstance().decomp; // NFD 318 case 1: return getNFKCInstance().decomp; // NFKD 319 case 2: return getNFCInstance().comp; // NFC 320 case 3: return getNFKCInstance().comp; // NFKC 321 default: return null; 322 } 323 } 324 public static Norm2AllModes getInstance(ByteBuffer bytes, String name) { 325 if(bytes==null) { 326 Norm2AllModesSingleton singleton; 327 if(name.equals("nfc")) { 328 singleton=NFCSingleton.INSTANCE; 329 } else if(name.equals("nfkc")) { 330 singleton=NFKCSingleton.INSTANCE; 331 } else if(name.equals("nfkc_cf")) { 332 singleton=NFKC_CFSingleton.INSTANCE; 333 } else { 334 singleton=null; 335 } 336 if(singleton!=null) { 337 if(singleton.exception!=null) { 338 throw singleton.exception; 339 } 340 return singleton.allModes; 341 } 342 } 343 return cache.getInstance(name, bytes); 344 } 345 private static CacheBase<String, Norm2AllModes, ByteBuffer> cache = 346 new SoftCache<String, Norm2AllModes, ByteBuffer>() { 347 protected Norm2AllModes createInstance(String key, ByteBuffer bytes) { 348 Normalizer2Impl impl; 349 if(bytes==null) { 350 impl=new Normalizer2Impl().load(key+".nrm"); 351 } else { 352 impl=new Normalizer2Impl().load(bytes); 353 } 354 return new Norm2AllModes(impl); 355 } 356 }; 357 358 public static final NoopNormalizer2 NOOP_NORMALIZER2=new NoopNormalizer2(); 359 /** 360 * Gets the FCD normalizer, with the FCD data initialized. 361 * @return FCD normalizer 362 */ 363 public static Normalizer2 getFCDNormalizer2() { 364 return getNFCInstance().fcd; 365 } 366 367 private static final class Norm2AllModesSingleton { 368 private Norm2AllModesSingleton(String name) { 369 try { 370 Normalizer2Impl impl=new Normalizer2Impl().load(name+".nrm"); 371 allModes=new Norm2AllModes(impl); 372 } catch(RuntimeException e) { 373 exception=e; 374 } 375 } 376 377 private Norm2AllModes allModes; 378 private RuntimeException exception; 379 } 380 private static final class NFCSingleton { 381 private static final Norm2AllModesSingleton INSTANCE=new Norm2AllModesSingleton("nfc"); 382 } 383 private static final class NFKCSingleton { 384 private static final Norm2AllModesSingleton INSTANCE=new Norm2AllModesSingleton("nfkc"); 385 } 386 private static final class NFKC_CFSingleton { 387 private static final Norm2AllModesSingleton INSTANCE=new Norm2AllModesSingleton("nfkc_cf"); 388 } 389 } 390