17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*
27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*******************************************************************************
37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*   Copyright (C) 2011-2014, International Business Machines
47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*   Corporation and others.  All Rights Reserved.
57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*******************************************************************************
67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*   created on: 2011jan05
77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*   created by: Markus W. Scherer
87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*   ported from ICU4C bytestriebuilder.h/.cpp
97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*/
107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.util;
127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.nio.ByteBuffer;
147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/**
167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Builder class for BytesTrie.
177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>This class is not intended for public subclassing.
197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 4.8
217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @author Markus W. Scherer
227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic final class BytesTrieBuilder extends StringTrieBuilder {
247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs an empty builder.
267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 4.8
277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public BytesTrieBuilder() {}
297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Used in add() to wrap the bytes into a CharSequence for StringTrieBuilder.addImpl().
317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final class BytesAsCharSequence implements CharSequence {
327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public BytesAsCharSequence(byte[] sequence, int length) {
337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            s=sequence;
347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            len=length;
357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public char charAt(int i) { return (char)(s[i]&0xff); }
377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public int length() { return len; }
387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public CharSequence subSequence(int start, int end) { return null; }
397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private byte[] s;
417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private int len;
427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Adds a (byte sequence, value) pair.
467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The byte sequence must be unique.
477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Bytes 0..length-1 will be copied; the builder does not keep
487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * a reference to the input array.
497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param sequence The array that contains the byte sequence, starting at index 0.
507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param length The length of the byte sequence.
517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param value The value associated with this byte sequence.
527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return this
537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 4.8
547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public BytesTrieBuilder add(byte[] sequence, int length, int value) {
567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        addImpl(new BytesAsCharSequence(sequence, length), value);
577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this;
587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Builds a BytesTrie for the add()ed data.
627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Once built, no further data can be add()ed until clear() is called.
637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>A BytesTrie cannot be empty. At least one (byte sequence, value) pair
657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * must have been add()ed.
667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>Multiple calls to build() or buildByteBuffer() return tries or buffers
687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * which share the builder's byte array, without rebuilding.
697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <em>The byte array must not be modified via the buildByteBuffer() result object.</em>
707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * After clear() has been called, a new array will be used.
717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param buildOption Build option, see StringTrieBuilder.Option.
727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A new BytesTrie for the add()ed data.
737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 4.8
747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public BytesTrie build(StringTrieBuilder.Option buildOption) {
767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        buildBytes(buildOption);
777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return new BytesTrie(bytes, bytes.length-bytesLength);
787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Builds a BytesTrie for the add()ed data and byte-serializes it.
827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Once built, no further data can be add()ed until clear() is called.
837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>A BytesTrie cannot be empty. At least one (byte sequence, value) pair
857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * must have been add()ed.
867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>Multiple calls to build() or buildByteBuffer() return tries or buffers
887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * which share the builder's byte array, without rebuilding.
897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <em>Do not modify the bytes in the buffer!</em>
907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * After clear() has been called, a new array will be used.
917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>The serialized BytesTrie is accessible via the buffer's
937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * array()/arrayOffset()+position() or remaining()/get(byte[]) etc.
947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param buildOption Build option, see StringTrieBuilder.Option.
957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return A ByteBuffer with the byte-serialized BytesTrie for the add()ed data.
967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *         The buffer is not read-only and array() can be called.
977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 4.8
987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public ByteBuffer buildByteBuffer(StringTrieBuilder.Option buildOption) {
1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        buildBytes(buildOption);
1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return ByteBuffer.wrap(bytes, bytes.length-bytesLength, bytesLength);
1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private void buildBytes(StringTrieBuilder.Option buildOption) {
1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Create and byte-serialize the trie for the elements.
1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(bytes==null) {
1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            bytes=new byte[1024];
1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        buildImpl(buildOption);
1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Removes all (byte sequence, value) pairs.
1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * New data can then be add()ed and a new trie can be built.
1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return this
1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 4.8
1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public BytesTrieBuilder clear() {
1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        clearImpl();
1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        bytes=null;
1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        bytesLength=0;
1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return this;
1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Override
1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected boolean matchNodesCanHaveValues() /*const*/ { return false; }
1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Override
1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int getMaxBranchLinearSubNodeLength() /*const*/ { return BytesTrie.kMaxBranchLinearSubNodeLength; }
1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Override
1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int getMinLinearMatch() /*const*/ { return BytesTrie.kMinLinearMatch; }
1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Override
1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int getMaxLinearMatchLength() /*const*/ { return BytesTrie.kMaxLinearMatchLength; }
1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private void ensureCapacity(int length) {
1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(length>bytes.length) {
1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int newCapacity=bytes.length;
1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            do {
1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                newCapacity*=2;
1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } while(newCapacity<=length);
1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            byte[] newBytes=new byte[newCapacity];
1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            System.arraycopy(bytes, bytes.length-bytesLength,
1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                             newBytes, newBytes.length-bytesLength, bytesLength);
1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            bytes=newBytes;
1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Override
1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int write(int b) {
1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int newLength=bytesLength+1;
1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ensureCapacity(newLength);
1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        bytesLength=newLength;
1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        bytes[bytes.length-bytesLength]=(byte)b;
1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return bytesLength;
1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Override
1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int write(int offset, int length) {
1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int newLength=bytesLength+length;
1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ensureCapacity(newLength);
1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        bytesLength=newLength;
1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int bytesOffset=bytes.length-bytesLength;
1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        while(length>0) {
1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            bytes[bytesOffset++]=(byte)strings.charAt(offset++);
1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            --length;
2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return bytesLength;
2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private int write(byte[] b, int length) {
2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int newLength=bytesLength+length;
2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ensureCapacity(newLength);
2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        bytesLength=newLength;
2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        System.arraycopy(b, 0, bytes, bytes.length-bytesLength, length);
2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return bytesLength;
2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // For writeValueAndFinal() and writeDeltaTo().
2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private final byte[] intBytes=new byte[5];
2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Override
2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int writeValueAndFinal(int i, boolean isFinal) {
2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(0<=i && i<=BytesTrie.kMaxOneByteValue) {
2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return write(((BytesTrie.kMinOneByteValueLead+i)<<1)|(isFinal?1:0));
2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int length=1;
2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(i<0 || i>0xffffff) {
2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            intBytes[0]=(byte)BytesTrie.kFiveByteValueLead;
2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            intBytes[1]=(byte)(i>>24);
2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            intBytes[2]=(byte)(i>>16);
2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            intBytes[3]=(byte)(i>>8);
2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            intBytes[4]=(byte)i;
2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            length=5;
2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // } else if(i<=BytesTrie.kMaxOneByteValue) {
2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //     intBytes[0]=(byte)(BytesTrie.kMinOneByteValueLead+i);
2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {
2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(i<=BytesTrie.kMaxTwoByteValue) {
2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                intBytes[0]=(byte)(BytesTrie.kMinTwoByteValueLead+(i>>8));
2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(i<=BytesTrie.kMaxThreeByteValue) {
2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    intBytes[0]=(byte)(BytesTrie.kMinThreeByteValueLead+(i>>16));
2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    intBytes[0]=(byte)BytesTrie.kFourByteValueLead;
2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    intBytes[1]=(byte)(i>>16);
2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    length=2;
2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                intBytes[length++]=(byte)(i>>8);
2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            intBytes[length++]=(byte)i;
2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        intBytes[0]=(byte)((intBytes[0]<<1)|(isFinal?1:0));
2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return write(intBytes, length);
2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Override
2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int writeValueAndType(boolean hasValue, int value, int node) {
2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int offset=write(node);
2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(hasValue) {
2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            offset=writeValueAndFinal(value, false);
2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return offset;
2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Override
2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int writeDeltaTo(int jumpTarget) {
2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i=bytesLength-jumpTarget;
2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        assert(i>=0);
2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(i<=BytesTrie.kMaxOneByteDelta) {
2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return write(i);
2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int length;
2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(i<=BytesTrie.kMaxTwoByteDelta) {
2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            intBytes[0]=(byte)(BytesTrie.kMinTwoByteDeltaLead+(i>>8));
2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            length=1;
2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {
2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(i<=BytesTrie.kMaxThreeByteDelta) {
2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                intBytes[0]=(byte)(BytesTrie.kMinThreeByteDeltaLead+(i>>16));
2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                length=2;
2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(i<=0xffffff) {
2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    intBytes[0]=(byte)BytesTrie.kFourByteDeltaLead;
2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    length=3;
2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    intBytes[0]=(byte)BytesTrie.kFiveByteDeltaLead;
2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    intBytes[1]=(byte)(i>>24);
2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    length=4;
2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                intBytes[1]=(byte)(i>>16);
2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            intBytes[1]=(byte)(i>>8);
3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        intBytes[length++]=(byte)i;
3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return write(intBytes, length);
3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Byte serialization of the trie.
3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Grows from the back: bytesLength measures from the end of the buffer!
3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private byte[] bytes;
3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private int bytesLength;
3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}
310