Home | History | Annotate | Download | only in util
      1 /* GENERATED SOURCE. DO NOT MODIFY. */
      2 //  2016 and later: Unicode, Inc. and others.
      3 // License & terms of use: http://www.unicode.org/copyright.html#License
      4 /*
      5 *******************************************************************************
      6 *   Copyright (C) 2011-2014, International Business Machines
      7 *   Corporation and others.  All Rights Reserved.
      8 *******************************************************************************
      9 *   created on: 2011jan05
     10 *   created by: Markus W. Scherer
     11 *   ported from ICU4C bytestriebuilder.h/.cpp
     12 */
     13 
     14 package android.icu.util;
     15 
     16 import java.nio.ByteBuffer;
     17 
     18 /**
     19  * Builder class for BytesTrie.
     20  *
     21  * <p>This class is not intended for public subclassing.
     22  *
     23  * @author Markus W. Scherer
     24  * @hide Only a subset of ICU is exposed in Android
     25  */
     26 public final class BytesTrieBuilder extends StringTrieBuilder {
     27     /**
     28      * Constructs an empty builder.
     29      */
     30     public BytesTrieBuilder() {}
     31 
     32     // Used in add() to wrap the bytes into a CharSequence for StringTrieBuilder.addImpl().
     33     private static final class BytesAsCharSequence implements CharSequence {
     34         public BytesAsCharSequence(byte[] sequence, int length) {
     35             s=sequence;
     36             len=length;
     37         }
     38         public char charAt(int i) { return (char)(s[i]&0xff); }
     39         public int length() { return len; }
     40         public CharSequence subSequence(int start, int end) { return null; }
     41 
     42         private byte[] s;
     43         private int len;
     44     }
     45 
     46     /**
     47      * Adds a (byte sequence, value) pair.
     48      * The byte sequence must be unique.
     49      * Bytes 0..length-1 will be copied; the builder does not keep
     50      * a reference to the input array.
     51      * @param sequence The array that contains the byte sequence, starting at index 0.
     52      * @param length The length of the byte sequence.
     53      * @param value The value associated with this byte sequence.
     54      * @return this
     55      */
     56     public BytesTrieBuilder add(byte[] sequence, int length, int value) {
     57         addImpl(new BytesAsCharSequence(sequence, length), value);
     58         return this;
     59     }
     60 
     61     /**
     62      * Builds a BytesTrie for the add()ed data.
     63      * Once built, no further data can be add()ed until clear() is called.
     64      *
     65      * <p>A BytesTrie cannot be empty. At least one (byte sequence, value) pair
     66      * must have been add()ed.
     67      *
     68      * <p>Multiple calls to build() or buildByteBuffer() return tries or buffers
     69      * which share the builder's byte array, without rebuilding.
     70      * <em>The byte array must not be modified via the buildByteBuffer() result object.</em>
     71      * After clear() has been called, a new array will be used.
     72      * @param buildOption Build option, see StringTrieBuilder.Option.
     73      * @return A new BytesTrie for the add()ed data.
     74      */
     75     public BytesTrie build(StringTrieBuilder.Option buildOption) {
     76         buildBytes(buildOption);
     77         return new BytesTrie(bytes, bytes.length-bytesLength);
     78     }
     79 
     80     /**
     81      * Builds a BytesTrie for the add()ed data and byte-serializes it.
     82      * Once built, no further data can be add()ed until clear() is called.
     83      *
     84      * <p>A BytesTrie cannot be empty. At least one (byte sequence, value) pair
     85      * must have been add()ed.
     86      *
     87      * <p>Multiple calls to build() or buildByteBuffer() return tries or buffers
     88      * which share the builder's byte array, without rebuilding.
     89      * <em>Do not modify the bytes in the buffer!</em>
     90      * After clear() has been called, a new array will be used.
     91      *
     92      * <p>The serialized BytesTrie is accessible via the buffer's
     93      * array()/arrayOffset()+position() or remaining()/get(byte[]) etc.
     94      * @param buildOption Build option, see StringTrieBuilder.Option.
     95      * @return A ByteBuffer with the byte-serialized BytesTrie for the add()ed data.
     96      *         The buffer is not read-only and array() can be called.
     97      */
     98     public ByteBuffer buildByteBuffer(StringTrieBuilder.Option buildOption) {
     99         buildBytes(buildOption);
    100         return ByteBuffer.wrap(bytes, bytes.length-bytesLength, bytesLength);
    101     }
    102 
    103     private void buildBytes(StringTrieBuilder.Option buildOption) {
    104         // Create and byte-serialize the trie for the elements.
    105         if(bytes==null) {
    106             bytes=new byte[1024];
    107         }
    108         buildImpl(buildOption);
    109     }
    110 
    111     /**
    112      * Removes all (byte sequence, value) pairs.
    113      * New data can then be add()ed and a new trie can be built.
    114      * @return this
    115      */
    116     public BytesTrieBuilder clear() {
    117         clearImpl();
    118         bytes=null;
    119         bytesLength=0;
    120         return this;
    121     }
    122 
    123     /**
    124      * {@inheritDoc}
    125      * @deprecated This API is ICU internal only.
    126      * @hide draft / provisional / internal are hidden on Android
    127      */
    128     @Deprecated
    129     @Override
    130     protected boolean matchNodesCanHaveValues() /*const*/ { return false; }
    131 
    132     /**
    133      * {@inheritDoc}
    134      * @deprecated This API is ICU internal only.
    135      * @hide draft / provisional / internal are hidden on Android
    136      */
    137     @Deprecated
    138     @Override
    139     protected int getMaxBranchLinearSubNodeLength() /*const*/ { return BytesTrie.kMaxBranchLinearSubNodeLength; }
    140     /**
    141      * {@inheritDoc}
    142      * @deprecated This API is ICU internal only.
    143      * @hide draft / provisional / internal are hidden on Android
    144      */
    145     @Deprecated
    146     @Override
    147     protected int getMinLinearMatch() /*const*/ { return BytesTrie.kMinLinearMatch; }
    148     /**
    149      * {@inheritDoc}
    150      * @deprecated This API is ICU internal only.
    151      * @hide draft / provisional / internal are hidden on Android
    152      */
    153     @Deprecated
    154     @Override
    155     protected int getMaxLinearMatchLength() /*const*/ { return BytesTrie.kMaxLinearMatchLength; }
    156 
    157     private void ensureCapacity(int length) {
    158         if(length>bytes.length) {
    159             int newCapacity=bytes.length;
    160             do {
    161                 newCapacity*=2;
    162             } while(newCapacity<=length);
    163             byte[] newBytes=new byte[newCapacity];
    164             System.arraycopy(bytes, bytes.length-bytesLength,
    165                              newBytes, newBytes.length-bytesLength, bytesLength);
    166             bytes=newBytes;
    167         }
    168     }
    169     /**
    170      * {@inheritDoc}
    171      * @deprecated This API is ICU internal only.
    172      * @hide draft / provisional / internal are hidden on Android
    173      */
    174     @Deprecated
    175     @Override
    176     protected int write(int b) {
    177         int newLength=bytesLength+1;
    178         ensureCapacity(newLength);
    179         bytesLength=newLength;
    180         bytes[bytes.length-bytesLength]=(byte)b;
    181         return bytesLength;
    182     }
    183     /**
    184      * {@inheritDoc}
    185      * @deprecated This API is ICU internal only.
    186      * @hide draft / provisional / internal are hidden on Android
    187      */
    188     @Deprecated
    189     @Override
    190     protected int write(int offset, int length) {
    191         int newLength=bytesLength+length;
    192         ensureCapacity(newLength);
    193         bytesLength=newLength;
    194         int bytesOffset=bytes.length-bytesLength;
    195         while(length>0) {
    196             bytes[bytesOffset++]=(byte)strings.charAt(offset++);
    197             --length;
    198         }
    199         return bytesLength;
    200     }
    201     private int write(byte[] b, int length) {
    202         int newLength=bytesLength+length;
    203         ensureCapacity(newLength);
    204         bytesLength=newLength;
    205         System.arraycopy(b, 0, bytes, bytes.length-bytesLength, length);
    206         return bytesLength;
    207     }
    208 
    209     // For writeValueAndFinal() and writeDeltaTo().
    210     private final byte[] intBytes=new byte[5];
    211 
    212     /**
    213      * {@inheritDoc}
    214      * @deprecated This API is ICU internal only.
    215      * @hide draft / provisional / internal are hidden on Android
    216      */
    217     @Deprecated
    218     @Override
    219     protected int writeValueAndFinal(int i, boolean isFinal) {
    220         if(0<=i && i<=BytesTrie.kMaxOneByteValue) {
    221             return write(((BytesTrie.kMinOneByteValueLead+i)<<1)|(isFinal?1:0));
    222         }
    223         int length=1;
    224         if(i<0 || i>0xffffff) {
    225             intBytes[0]=(byte)BytesTrie.kFiveByteValueLead;
    226             intBytes[1]=(byte)(i>>24);
    227             intBytes[2]=(byte)(i>>16);
    228             intBytes[3]=(byte)(i>>8);
    229             intBytes[4]=(byte)i;
    230             length=5;
    231         // } else if(i<=BytesTrie.kMaxOneByteValue) {
    232         //     intBytes[0]=(byte)(BytesTrie.kMinOneByteValueLead+i);
    233         } else {
    234             if(i<=BytesTrie.kMaxTwoByteValue) {
    235                 intBytes[0]=(byte)(BytesTrie.kMinTwoByteValueLead+(i>>8));
    236             } else {
    237                 if(i<=BytesTrie.kMaxThreeByteValue) {
    238                     intBytes[0]=(byte)(BytesTrie.kMinThreeByteValueLead+(i>>16));
    239                 } else {
    240                     intBytes[0]=(byte)BytesTrie.kFourByteValueLead;
    241                     intBytes[1]=(byte)(i>>16);
    242                     length=2;
    243                 }
    244                 intBytes[length++]=(byte)(i>>8);
    245             }
    246             intBytes[length++]=(byte)i;
    247         }
    248         intBytes[0]=(byte)((intBytes[0]<<1)|(isFinal?1:0));
    249         return write(intBytes, length);
    250     }
    251     /**
    252      * {@inheritDoc}
    253      * @deprecated This API is ICU internal only.
    254      * @hide draft / provisional / internal are hidden on Android
    255      */
    256     @Deprecated
    257     @Override
    258     protected int writeValueAndType(boolean hasValue, int value, int node) {
    259         int offset=write(node);
    260         if(hasValue) {
    261             offset=writeValueAndFinal(value, false);
    262         }
    263         return offset;
    264     }
    265     /**
    266      * {@inheritDoc}
    267      * @deprecated This API is ICU internal only.
    268      * @hide draft / provisional / internal are hidden on Android
    269      */
    270     @Deprecated
    271     @Override
    272     protected int writeDeltaTo(int jumpTarget) {
    273         int i=bytesLength-jumpTarget;
    274         assert(i>=0);
    275         if(i<=BytesTrie.kMaxOneByteDelta) {
    276             return write(i);
    277         }
    278         int length;
    279         if(i<=BytesTrie.kMaxTwoByteDelta) {
    280             intBytes[0]=(byte)(BytesTrie.kMinTwoByteDeltaLead+(i>>8));
    281             length=1;
    282         } else {
    283             if(i<=BytesTrie.kMaxThreeByteDelta) {
    284                 intBytes[0]=(byte)(BytesTrie.kMinThreeByteDeltaLead+(i>>16));
    285                 length=2;
    286             } else {
    287                 if(i<=0xffffff) {
    288                     intBytes[0]=(byte)BytesTrie.kFourByteDeltaLead;
    289                     length=3;
    290                 } else {
    291                     intBytes[0]=(byte)BytesTrie.kFiveByteDeltaLead;
    292                     intBytes[1]=(byte)(i>>24);
    293                     length=4;
    294                 }
    295                 intBytes[1]=(byte)(i>>16);
    296             }
    297             intBytes[1]=(byte)(i>>8);
    298         }
    299         intBytes[length++]=(byte)i;
    300         return write(intBytes, length);
    301     }
    302 
    303     // Byte serialization of the trie.
    304     // Grows from the back: bytesLength measures from the end of the buffer!
    305     private byte[] bytes;
    306     private int bytesLength;
    307 }
    308