Home | History | Annotate | Download | only in impl
      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