/*
 *******************************************************************************
 * Copyright (C) 2004-2015, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */
package com.ibm.icu.impl;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.IntBuffer;

import com.ibm.icu.util.ICUException;
import com.ibm.icu.util.ICUUncheckedIOException;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;
import com.ibm.icu.util.VersionInfo;

/**
 * This class reads the *.res resource bundle format.
 *
 * For the file format documentation see ICU4C's source/common/uresdata.h file.
 */
public final class ICUResourceBundleReader {
    /**
     * File format version that this class understands.
     * "ResB"
     */
    private static final int DATA_FORMAT = 0x52657342;
    private static final class IsAcceptable implements ICUBinary.Authenticate {
        // @Override when we switch to Java 6
        public boolean isDataVersionAcceptable(byte formatVersion[]) {
            return
                    (formatVersion[0] == 1 && (formatVersion[1] & 0xff) >= 1) ||
                    (2 <= formatVersion[0] && formatVersion[0] <= 3);
        }
    }
    private static final IsAcceptable IS_ACCEPTABLE = new IsAcceptable();

    /* indexes[] value names; indexes are generally 32-bit (Resource) indexes */
    /**
     * [0] contains the length of indexes[]
     * which is at most URES_INDEX_TOP of the latest format version
     *
     * formatVersion==1: all bits contain the length of indexes[]
     *   but the length is much less than 0xff;
     * formatVersion>1:
     *   only bits  7..0 contain the length of indexes[],
     *        bits 31..8 are reserved and set to 0
     * formatVersion>=3:
     *        bits 31..8 poolStringIndexLimit bits 23..0
     */
    private static final int URES_INDEX_LENGTH           = 0;
    /**
     * [1] contains the top of the key strings,
     *     same as the bottom of resources or UTF-16 strings, rounded up
     */
    private static final int URES_INDEX_KEYS_TOP         = 1;
    /** [2] contains the top of all resources */
    //ivate static final int URES_INDEX_RESOURCES_TOP    = 2;
    /**
     * [3] contains the top of the bundle,
     *     in case it were ever different from [2]
     */
    private static final int URES_INDEX_BUNDLE_TOP       = 3;
    /** [4] max. length of any table */
    private static final int URES_INDEX_MAX_TABLE_LENGTH = 4;
    /**
     * [5] attributes bit set, see URES_ATT_* (new in formatVersion 1.2)
     *
     * formatVersion>=3:
     *   bits 31..16 poolStringIndex16Limit
     *   bits 15..12 poolStringIndexLimit bits 27..24
     */
    private static final int URES_INDEX_ATTRIBUTES       = 5;
    /**
     * [6] top of the 16-bit units (UTF-16 string v2 UChars, URES_TABLE16, URES_ARRAY16),
     *     rounded up (new in formatVersion 2.0, ICU 4.4)
     */
    private static final int URES_INDEX_16BIT_TOP        = 6;
    /** [7] checksum of the pool bundle (new in formatVersion 2.0, ICU 4.4) */
    private static final int URES_INDEX_POOL_CHECKSUM    = 7;
    //ivate static final int URES_INDEX_TOP              = 8;

    /*
     * Nofallback attribute, attribute bit 0 in indexes[URES_INDEX_ATTRIBUTES].
     * New in formatVersion 1.2 (ICU 3.6).
     *
     * If set, then this resource bundle is a standalone bundle.
     * If not set, then the bundle participates in locale fallback, eventually
     * all the way to the root bundle.
     * If indexes[] is missing or too short, then the attribute cannot be determined
     * reliably. Dependency checking should ignore such bundles, and loading should
     * use fallbacks.
     */
    private static final int URES_ATT_NO_FALLBACK = 1;

    /*
     * Attributes for bundles that are, or use, a pool bundle.
     * A pool bundle provides key strings that are shared among several other bundles
     * to reduce their total size.
     * New in formatVersion 2 (ICU 4.4).
     */
    private static final int URES_ATT_IS_POOL_BUNDLE = 2;
    private static final int URES_ATT_USES_POOL_BUNDLE = 4;

    private static final CharBuffer EMPTY_16_BIT_UNITS = CharBuffer.wrap("\0");  // read-only

    /**
     * Objects with more value bytes are stored in SoftReferences.
     * Smaller objects (which are not much larger than a SoftReference)
     * are stored directly, avoiding the overhead of the reference.
     */
    static final int LARGE_SIZE = 24;

    private static final boolean DEBUG = false;

    private int /* formatVersion, */ dataVersion;

    // See the ResourceData struct in ICU4C/source/common/uresdata.h.
    /**
     * Buffer of all of the resource bundle bytes after the header.
     * (equivalent of C++ pRoot)
     */
    private ByteBuffer bytes;
    private byte[] keyBytes;
    private CharBuffer b16BitUnits;
    private ICUResourceBundleReader poolBundleReader;
    private int rootRes;
    private int localKeyLimit;
    private int poolStringIndexLimit;
    private int poolStringIndex16Limit;
    private boolean noFallback; /* see URES_ATT_NO_FALLBACK */
    private boolean isPoolBundle;
    private boolean usesPoolBundle;
    private int poolCheckSum;

    private ResourceCache resourceCache;

    private static ReaderCache CACHE = new ReaderCache();
    private static final ICUResourceBundleReader NULL_READER = new ICUResourceBundleReader();

    private static class ReaderInfo {
        final String baseName;
        final String localeID;
        final ClassLoader loader;

        ReaderInfo(String baseName, String localeID, ClassLoader loader) {
            this.baseName = (baseName == null) ? "" : baseName;
            this.localeID = (localeID == null) ? "" : localeID;
            this.loader = loader;
        }

        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (!(obj instanceof ReaderInfo)) {
                return false;
            }
            ReaderInfo info = (ReaderInfo)obj;
            return this.baseName.equals(info.baseName)
                    && this.localeID.equals(info.localeID)
                    && this.loader.equals(info.loader);
        }

        public int hashCode() {
            return baseName.hashCode() ^ localeID.hashCode() ^ loader.hashCode();
        }
    }

    private static class ReaderCache extends SoftCache<ReaderInfo, ICUResourceBundleReader, ReaderInfo> {
        /* (non-Javadoc)
         * @see com.ibm.icu.impl.CacheBase#createInstance(java.lang.Object, java.lang.Object)
         */
        @Override
        protected ICUResourceBundleReader createInstance(ReaderInfo key, ReaderInfo data) {
            String fullName = ICUResourceBundleReader.getFullName(data.baseName, data.localeID);
            try {
                ByteBuffer inBytes;
                if (data.baseName != null && data.baseName.startsWith(ICUData.ICU_BASE_NAME)) {
                    String itemPath = fullName.substring(ICUData.ICU_BASE_NAME.length() + 1);
                    inBytes = ICUBinary.getData(data.loader, fullName, itemPath);
                    if (inBytes == null) {
                        return NULL_READER;
                    }
                } else {
                    @SuppressWarnings("resource")  // Closed by getByteBufferFromInputStreamAndCloseStream().
                    InputStream stream = ICUData.getStream(data.loader, fullName);
                    if (stream == null) {
                        return NULL_READER;
                    }
                    inBytes = ICUBinary.getByteBufferFromInputStreamAndCloseStream(stream);
                }
                return new ICUResourceBundleReader(inBytes, data.baseName, data.localeID, data.loader);
            } catch (IOException ex) {
                throw new ICUUncheckedIOException("Data file " + fullName + " is corrupt - " + ex.getMessage(), ex);
            }
        }
    }

    /*
     * Default constructor, just used for NULL_READER.
     */
    private ICUResourceBundleReader() {
    }

    private ICUResourceBundleReader(ByteBuffer inBytes,
            String baseName, String localeID,
            ClassLoader loader) throws IOException {
        init(inBytes);

        // set pool bundle if necessary
        if (usesPoolBundle) {
            poolBundleReader = getReader(baseName, "pool", loader);
            if (!poolBundleReader.isPoolBundle) {
                throw new IllegalStateException("pool.res is not a pool bundle");
            }
            if (poolBundleReader.poolCheckSum != poolCheckSum) {
                throw new IllegalStateException("pool.res has a different checksum than this bundle");
            }
        }
    }

    static ICUResourceBundleReader getReader(String baseName, String localeID, ClassLoader root) {
        ReaderInfo info = new ReaderInfo(baseName, localeID, root);
        ICUResourceBundleReader reader = CACHE.getInstance(info, info);
        if (reader == NULL_READER) {
            return null;
        }
        return reader;
    }

    // See res_init() in ICU4C/source/common/uresdata.c.
    private void init(ByteBuffer inBytes) throws IOException {
        dataVersion = ICUBinary.readHeader(inBytes, DATA_FORMAT, IS_ACCEPTABLE);
        int majorFormatVersion = inBytes.get(16);
        bytes = ICUBinary.sliceWithOrder(inBytes);
        int dataLength = bytes.remaining();

        if(DEBUG) System.out.println("The ByteBuffer is direct (memory-mapped): " + bytes.isDirect());
        if(DEBUG) System.out.println("The available bytes in the buffer before reading the data: " + dataLength);

        rootRes = bytes.getInt(0);

        // Bundles with formatVersion 1.1 and later contain an indexes[] array.
        // We need it so that we can read the key string bytes up front, for lookup performance.

        // read the variable-length indexes[] array
        int indexes0 = getIndexesInt(URES_INDEX_LENGTH);
        int indexLength = indexes0 & 0xff;
        if(indexLength <= URES_INDEX_MAX_TABLE_LENGTH) {
            throw new ICUException("not enough indexes");
        }
        int bundleTop;
        if(dataLength < ((1 + indexLength) << 2) ||
                dataLength < ((bundleTop = getIndexesInt(URES_INDEX_BUNDLE_TOP)) << 2)) {
            throw new ICUException("not enough bytes");
        }
        int maxOffset = bundleTop - 1;

        if (majorFormatVersion >= 3) {
            // In formatVersion 1, the indexLength took up this whole int.
            // In version 2, bits 31..8 were reserved and always 0.
            // In version 3, they contain bits 23..0 of the poolStringIndexLimit.
            // Bits 27..24 are in indexes[URES_INDEX_ATTRIBUTES] bits 15..12.
            poolStringIndexLimit = indexes0 >>> 8;
        }
        if(indexLength > URES_INDEX_ATTRIBUTES) {
            // determine if this resource bundle falls back to a parent bundle
            // along normal locale ID fallback
            int att = getIndexesInt(URES_INDEX_ATTRIBUTES);
            noFallback = (att & URES_ATT_NO_FALLBACK) != 0;
            isPoolBundle = (att & URES_ATT_IS_POOL_BUNDLE) != 0;
            usesPoolBundle = (att & URES_ATT_USES_POOL_BUNDLE) != 0;
            poolStringIndexLimit |= (att & 0xf000) << 12;  // bits 15..12 -> 27..24
            poolStringIndex16Limit = att >>> 16;
        }

        int keysBottom = 1 + indexLength;
        int keysTop = getIndexesInt(URES_INDEX_KEYS_TOP);
        if(keysTop > keysBottom) {
            // Deserialize the key strings up front.
            // Faster table item search at the cost of slower startup and some heap memory.
            if(isPoolBundle) {
                // Shift the key strings down:
                // Pool bundle key strings are used with a 0-based index,
                // unlike regular bundles' key strings for which indexes
                // are based on the start of the bundle data.
                keyBytes = new byte[(keysTop - keysBottom) << 2];
                bytes.position(keysBottom << 2);
            } else {
                localKeyLimit = keysTop << 2;
                keyBytes = new byte[localKeyLimit];
            }
            bytes.get(keyBytes);
        }

        // Read the array of 16-bit units.
        if(indexLength > URES_INDEX_16BIT_TOP) {
            int _16BitTop = getIndexesInt(URES_INDEX_16BIT_TOP);
            if(_16BitTop > keysTop) {
                int num16BitUnits = (_16BitTop - keysTop) * 2;
                bytes.position(keysTop << 2);
                b16BitUnits = bytes.asCharBuffer();
                b16BitUnits.limit(num16BitUnits);
                maxOffset |= num16BitUnits - 1;
            } else {
                b16BitUnits = EMPTY_16_BIT_UNITS;
            }
        } else {
            b16BitUnits = EMPTY_16_BIT_UNITS;
        }

        if(indexLength > URES_INDEX_POOL_CHECKSUM) {
            poolCheckSum = getIndexesInt(URES_INDEX_POOL_CHECKSUM);
        }

        if(!isPoolBundle || b16BitUnits.length() > 1) {
            resourceCache = new ResourceCache(maxOffset);
        }

        // Reset the position for future .asCharBuffer() etc.
        bytes.position(0);
    }

    private int getIndexesInt(int i) {
        return bytes.getInt((1 + i) << 2);
    }

    VersionInfo getVersion() {
        return ICUBinary.getVersionInfoFromCompactInt(dataVersion);
    }

    int getRootResource() {
        return rootRes;
    }
    boolean getNoFallback() {
        return noFallback;
    }
    boolean getUsesPoolBundle() {
        return usesPoolBundle;
    }

    static int RES_GET_TYPE(int res) {
        return res >>> 28;
    }
    private static int RES_GET_OFFSET(int res) {
        return res & 0x0fffffff;
    }
    private int getResourceByteOffset(int offset) {
        return offset << 2;
    }
    /* get signed and unsigned integer values directly from the Resource handle */
    static int RES_GET_INT(int res) {
        return (res << 4) >> 4;
    }
    static int RES_GET_UINT(int res) {
        return res & 0x0fffffff;
    }
    static boolean URES_IS_ARRAY(int type) {
        return type == UResourceBundle.ARRAY || type == ICUResourceBundle.ARRAY16;
    }
    static boolean URES_IS_TABLE(int type) {
        return type==UResourceBundle.TABLE || type==ICUResourceBundle.TABLE16 || type==ICUResourceBundle.TABLE32;
    }

    private static final byte[] emptyBytes = new byte[0];
    private static final ByteBuffer emptyByteBuffer = ByteBuffer.allocate(0).asReadOnlyBuffer();
    private static final char[] emptyChars = new char[0];
    private static final int[] emptyInts = new int[0];
    private static final String emptyString = "";
    private static final Container EMPTY_ARRAY = new Container();
    private static final Table EMPTY_TABLE = new Table();

    private char[] getChars(int offset, int count) {
        char[] chars = new char[count];
        if (count <= 16) {
            for(int i = 0; i < count; offset += 2, ++i) {
                chars[i] = bytes.getChar(offset);
            }
        } else {
            CharBuffer temp = bytes.asCharBuffer();
            temp.position(offset / 2);
            temp.get(chars);
        }
        return chars;
    }
    private int getInt(int offset) {
        return bytes.getInt(offset);
    }
    private int[] getInts(int offset, int count) {
        int[] ints = new int[count];
        if (count <= 16) {
            for(int i = 0; i < count; offset += 4, ++i) {
                ints[i] = bytes.getInt(offset);
            }
        } else {
            IntBuffer temp = bytes.asIntBuffer();
            temp.position(offset / 4);
            temp.get(ints);
        }
        return ints;
    }
    private char[] getTable16KeyOffsets(int offset) {
        int length = b16BitUnits.charAt(offset++);
        if(length > 0) {
            char[] result = new char[length];
            if(length <= 16) {
                for(int i = 0; i < length; ++i) {
                    result[i] = b16BitUnits.charAt(offset++);
                }
            } else {
                CharBuffer temp = b16BitUnits.duplicate();
                temp.position(offset);
                temp.get(result);
            }
            return result;
        } else {
            return emptyChars;
        }
    }
    private char[] getTableKeyOffsets(int offset) {
        int length = bytes.getChar(offset);
        if(length > 0) {
            return getChars(offset + 2, length);
        } else {
            return emptyChars;
        }
    }
    private int[] getTable32KeyOffsets(int offset) {
        int length = getInt(offset);
        if(length > 0) {
            return getInts(offset + 4, length);
        } else {
            return emptyInts;
        }
    }

    private static String makeKeyStringFromBytes(byte[] keyBytes, int keyOffset) {
        StringBuilder sb = new StringBuilder();
        byte b;
        while((b = keyBytes[keyOffset]) != 0) {
            ++keyOffset;
            sb.append((char)b);
        }
        return sb.toString();
    }
    private String getKey16String(int keyOffset) {
        if(keyOffset < localKeyLimit) {
            return makeKeyStringFromBytes(keyBytes, keyOffset);
        } else {
            return makeKeyStringFromBytes(poolBundleReader.keyBytes, keyOffset - localKeyLimit);
        }
    }
    private String getKey32String(int keyOffset) {
        if(keyOffset >= 0) {
            return makeKeyStringFromBytes(keyBytes, keyOffset);
        } else {
            return makeKeyStringFromBytes(poolBundleReader.keyBytes, keyOffset & 0x7fffffff);
        }
    }
    private int compareKeys(CharSequence key, char keyOffset) {
        if(keyOffset < localKeyLimit) {
            return ICUBinary.compareKeys(key, keyBytes, keyOffset);
        } else {
            return ICUBinary.compareKeys(key, poolBundleReader.keyBytes, keyOffset - localKeyLimit);
        }
    }
    private int compareKeys32(CharSequence key, int keyOffset) {
        if(keyOffset >= 0) {
            return ICUBinary.compareKeys(key, keyBytes, keyOffset);
        } else {
            return ICUBinary.compareKeys(key, poolBundleReader.keyBytes, keyOffset & 0x7fffffff);
        }
    }

    /**
     * @return a string from the local bundle's b16BitUnits at the local offset
     */
    String getStringV2(int res) {
        // Use the pool bundle's resource cache for pool bundle strings;
        // use the local bundle's cache for local strings.
        // The cache requires a resource word with the proper type,
        // and with an offset that is local to this bundle so that the offset fits
        // within the maximum number of bits for which the cache was constructed.
        assert RES_GET_TYPE(res) == ICUResourceBundle.STRING_V2;
        int offset = RES_GET_OFFSET(res);
        assert offset != 0;  // handled by the caller
        Object value = resourceCache.get(res);
        if(value != null) {
            return (String)value;
        }
        String s;
        int first = b16BitUnits.charAt(offset);
        if((first&0xfffffc00)!=0xdc00) {  // C: if(!U16_IS_TRAIL(first)) {
            if(first==0) {
                return emptyString;  // Should not occur, but is not forbidden.
            }
            StringBuilder sb = new StringBuilder();
            sb.append((char)first);
            char c;
            while((c = b16BitUnits.charAt(++offset)) != 0) {
                sb.append(c);
            }
            s = sb.toString();
        } else {
            int length;
            if(first<0xdfef) {
                length=first&0x3ff;
                ++offset;
            } else if(first<0xdfff) {
                length=((first-0xdfef)<<16)|b16BitUnits.charAt(offset+1);
                offset+=2;
            } else {
                length=((int)b16BitUnits.charAt(offset+1)<<16)|b16BitUnits.charAt(offset+2);
                offset+=3;
            }
            // Cast up to CharSequence to insulate against the CharBuffer.subSequence() return type change
            // which makes code compiled for a newer JDK (7 and up) not run on an older one (6 and below).
            s = ((CharSequence) b16BitUnits).subSequence(offset, offset + length).toString();
        }
        return (String)resourceCache.putIfAbsent(res, s, s.length() * 2);
    }

    private String makeStringFromBytes(int offset, int length) {
        if (length <= 16) {
            StringBuilder sb = new StringBuilder(length);
            for (int i = 0; i < length; offset += 2, ++i) {
                sb.append(bytes.getChar(offset));
            }
            return sb.toString();
        } else {
            CharSequence cs = bytes.asCharBuffer();
            offset /= 2;
            return cs.subSequence(offset, offset + length).toString();
        }
    }

    String getString(int res) {
        int offset=RES_GET_OFFSET(res);
        if(res != offset /* RES_GET_TYPE(res) != URES_STRING */ &&
                RES_GET_TYPE(res) != ICUResourceBundle.STRING_V2) {
            return null;
        }
        if(offset == 0) {
            return emptyString;
        }
        if (res != offset) {  // STRING_V2
            if (offset < poolStringIndexLimit) {
                return poolBundleReader.getStringV2(res);
            } else {
                return getStringV2(res - poolStringIndexLimit);
            }
        }
        Object value = resourceCache.get(res);
        if(value != null) {
            return (String)value;
        }
        offset=getResourceByteOffset(offset);
        int length = getInt(offset);
        String s = makeStringFromBytes(offset+4, length);
        return (String)resourceCache.putIfAbsent(res, s, s.length() * 2);
    }

    String getAlias(int res) {
        int offset=RES_GET_OFFSET(res);
        int length;
        if(RES_GET_TYPE(res)==ICUResourceBundle.ALIAS) {
            if(offset==0) {
                return emptyString;
            } else {
                Object value = resourceCache.get(res);
                if(value != null) {
                    return (String)value;
                }
                offset=getResourceByteOffset(offset);
                length=getInt(offset);
                String s = makeStringFromBytes(offset + 4, length);
                return (String)resourceCache.putIfAbsent(res, s, length * 2);
            }
        } else {
            return null;
        }
    }

    byte[] getBinary(int res, byte[] ba) {
        int offset=RES_GET_OFFSET(res);
        int length;
        if(RES_GET_TYPE(res)==UResourceBundle.BINARY) {
            if(offset==0) {
                return emptyBytes;
            } else {
                offset=getResourceByteOffset(offset);
                length=getInt(offset);
                if(length==0) {
                    return emptyBytes;
                }
                // Not cached: The array would have to be cloned anyway because
                // the cache must not be writable via the returned reference.
                if(ba==null || ba.length!=length) {
                    ba=new byte[length];
                }
                offset += 4;
                if(length <= 16) {
                    for(int i = 0; i < length; ++i) {
                        ba[i] = bytes.get(offset++);
                    }
                } else {
                    ByteBuffer temp = bytes.duplicate();
                    temp.position(offset);
                    temp.get(ba);
                }
                return ba;
            }
        } else {
            return null;
        }
    }

    ByteBuffer getBinary(int res) {
        int offset=RES_GET_OFFSET(res);
        int length;
        if(RES_GET_TYPE(res)==UResourceBundle.BINARY) {
            if(offset==0) {
                // Don't just
                //   return emptyByteBuffer;
                // in case it matters whether the buffer's mark is defined or undefined.
                return emptyByteBuffer.duplicate();
            } else {
                // Not cached: The returned buffer is small (shares its bytes with the bundle)
                // and usually quickly discarded after use.
                // Also, even a cached buffer would have to be cloned because it is mutable
                // (position & mark).
                offset=getResourceByteOffset(offset);
                length=getInt(offset);
                if(length == 0) {
                    return emptyByteBuffer.duplicate();
                }
                offset += 4;
                ByteBuffer result = bytes.duplicate();
                result.position(offset).limit(offset + length);
                result = ICUBinary.sliceWithOrder(result);
                if(!result.isReadOnly()) {
                    result = result.asReadOnlyBuffer();
                }
                return result;
            }
        } else {
            return null;
        }
    }

    int[] getIntVector(int res) {
        int offset=RES_GET_OFFSET(res);
        int length;
        if(RES_GET_TYPE(res)==UResourceBundle.INT_VECTOR) {
            if(offset==0) {
                return emptyInts;
            } else {
                // Not cached: The array would have to be cloned anyway because
                // the cache must not be writable via the returned reference.
                offset=getResourceByteOffset(offset);
                length=getInt(offset);
                return getInts(offset+4, length);
            }
        } else {
            return null;
        }
    }

    Container getArray(int res) {
        int type=RES_GET_TYPE(res);
        if(!URES_IS_ARRAY(type)) {
            return null;
        }
        int offset=RES_GET_OFFSET(res);
        if(offset == 0) {
            return EMPTY_ARRAY;
        }
        Object value = resourceCache.get(res);
        if(value != null) {
            return (Container)value;
        }
        Container array = (type == UResourceBundle.ARRAY) ?
                new Array(this, offset) : new Array16(this, offset);
        return (Container)resourceCache.putIfAbsent(res, array, 0);
    }

    Table getTable(int res) {
        int type = RES_GET_TYPE(res);
        if(!URES_IS_TABLE(type)) {
            return null;
        }
        int offset = RES_GET_OFFSET(res);
        if(offset == 0) {
            return EMPTY_TABLE;
        }
        Object value = resourceCache.get(res);
        if(value != null) {
            return (Table)value;
        }
        Table table;
        int size;  // Use size = 0 to never use SoftReferences for Tables?
        if(type == UResourceBundle.TABLE) {
            table = new Table1632(this, offset);
            size = table.getSize() * 2;
        } else if(type == ICUResourceBundle.TABLE16) {
            table = new Table16(this, offset);
            size = table.getSize() * 2;
        } else /* type == ICUResourceBundle.TABLE32 */ {
            table = new Table32(this, offset);
            size = table.getSize() * 4;
        }
        return (Table)resourceCache.putIfAbsent(res, table, size);
    }

    // Container value classes --------------------------------------------- ***

    static class Container {
        protected int size;
        protected int itemsOffset;

        int getSize() {
            return size;
        }
        int getContainerResource(ICUResourceBundleReader reader, int index) {
            return ICUResourceBundle.RES_BOGUS;
        }
        protected int getContainer16Resource(ICUResourceBundleReader reader, int index) {
            if (index < 0 || size <= index) {
                return ICUResourceBundle.RES_BOGUS;
            }
            int res16 = reader.b16BitUnits.charAt(itemsOffset + index);
            if (res16 < reader.poolStringIndex16Limit) {
                // Pool string, nothing to do.
            } else {
                // Local string, adjust the 16-bit offset to a regular one,
                // with a larger pool string index limit.
                res16 = res16 - reader.poolStringIndex16Limit + reader.poolStringIndexLimit;
            }
            return (ICUResourceBundle.STRING_V2 << 28) | res16;
        }
        protected int getContainer32Resource(ICUResourceBundleReader reader, int index) {
            if (index < 0 || size <= index) {
                return ICUResourceBundle.RES_BOGUS;
            }
            return reader.getInt(itemsOffset + 4 * index);
        }
        int getResource(ICUResourceBundleReader reader, String resKey) {
            return getContainerResource(reader, Integer.parseInt(resKey));
        }
        Container() {
        }
    }
    private static final class Array extends Container {
        @Override
        int getContainerResource(ICUResourceBundleReader reader, int index) {
            return getContainer32Resource(reader, index);
        }
        Array(ICUResourceBundleReader reader, int offset) {
            offset = reader.getResourceByteOffset(offset);
            size = reader.getInt(offset);
            itemsOffset = offset + 4;
        }
    }
    private static final class Array16 extends Container {
        @Override
        int getContainerResource(ICUResourceBundleReader reader, int index) {
            return getContainer16Resource(reader, index);
        }
        Array16(ICUResourceBundleReader reader, int offset) {
            size = reader.b16BitUnits.charAt(offset);
            itemsOffset = offset + 1;
        }
    }
    static class Table extends Container {
        protected char[] keyOffsets;
        protected int[] key32Offsets;

        String getKey(ICUResourceBundleReader reader, int index) {
            if (index < 0 || size <= index) {
                return null;
            }
            return keyOffsets != null ?
                        reader.getKey16String(keyOffsets[index]) :
                        reader.getKey32String(key32Offsets[index]);
        }
        private static final int URESDATA_ITEM_NOT_FOUND = -1;
        int findTableItem(ICUResourceBundleReader reader, CharSequence key) {
            int mid, start, limit;
            int result;

            /* do a binary search for the key */
            start=0;
            limit=size;
            while(start<limit) {
                mid = (start + limit) >>> 1;
                if (keyOffsets != null) {
                    result = reader.compareKeys(key, keyOffsets[mid]);
                } else {
                    result = reader.compareKeys32(key, key32Offsets[mid]);
                }
                if (result < 0) {
                    limit = mid;
                } else if (result > 0) {
                    start = mid + 1;
                } else {
                    /* We found it! */
                    return mid;
                }
            }
            return URESDATA_ITEM_NOT_FOUND;  /* not found or table is empty. */
        }
        @Override
        int getResource(ICUResourceBundleReader reader, String resKey) {
            return getContainerResource(reader, findTableItem(reader, resKey));
        }
        Table() {
        }
    }
    private static final class Table1632 extends Table {
        @Override
        int getContainerResource(ICUResourceBundleReader reader, int index) {
            return getContainer32Resource(reader, index);
        }
        Table1632(ICUResourceBundleReader reader, int offset) {
            offset = reader.getResourceByteOffset(offset);
            keyOffsets = reader.getTableKeyOffsets(offset);
            size = keyOffsets.length;
            itemsOffset = offset + 2 * ((size + 2) & ~1);  // Skip padding for 4-alignment.
        }
    }
    private static final class Table16 extends Table {
        @Override
        int getContainerResource(ICUResourceBundleReader reader, int index) {
            return getContainer16Resource(reader, index);
        }
        Table16(ICUResourceBundleReader reader, int offset) {
            keyOffsets = reader.getTable16KeyOffsets(offset);
            size = keyOffsets.length;
            itemsOffset = offset + 1 + size;
        }
    }
    private static final class Table32 extends Table {
        @Override
        int getContainerResource(ICUResourceBundleReader reader, int index) {
            return getContainer32Resource(reader, index);
        }
        Table32(ICUResourceBundleReader reader, int offset) {
            offset = reader.getResourceByteOffset(offset);
            key32Offsets = reader.getTable32KeyOffsets(offset);
            size = key32Offsets.length;
            itemsOffset = offset + 4 * (1 + size);
        }
    }

    // Resource cache ------------------------------------------------------ ***

    /**
     * Cache of some of one resource bundle's resources.
     * Avoids creating multiple Java objects for the same resource items,
     * including multiple copies of their contents.
     *
     * <p>Mutable objects must not be cached and then returned to the caller
     * because the cache must not be writable via the returned reference.
     *
     * <p>Resources are mapped by their resource integers.
     * Empty resources with offset 0 cannot be mapped.
     * Integers need not and should not be cached.
     * Multiple .res items may share resource offsets (genrb eliminates some duplicates).
     *
     * <p>This cache uses int[] and Object[] arrays to minimize object creation
     * and avoid auto-boxing.
     *
     * <p>Large resource objects are stored in SoftReferences.
     *
     * <p>For few resources, a small table is used with binary search.
     * When more resources are cached, then the data structure changes to be faster
     * but also use more memory.
     */
    private static final class ResourceCache {
        // Number of items to be stored in a simple array with binary search and insertion sort.
        private static final int SIMPLE_LENGTH = 32;

        // When more than SIMPLE_LENGTH items are cached,
        // then switch to a trie-like tree of levels with different array lengths.
        private static final int ROOT_BITS = 7;
        private static final int NEXT_BITS = 6;

        // Simple table, used when length >= 0.
        private int[] keys = new int[SIMPLE_LENGTH];
        private Object[] values = new Object[SIMPLE_LENGTH];
        private int length;

        // Trie-like tree of levels, used when length < 0.
        private int maxOffsetBits;
        /**
         * Number of bits in each level, each stored in a nibble.
         */
        private int levelBitsList;
        private Level rootLevel;

        @SuppressWarnings("unchecked")
        private static final Object putIfCleared(Object[] values, int index, Object item, int size) {
            Object value = values[index];
            if(!(value instanceof SoftReference)) {
                assert size < LARGE_SIZE;  // Caller should be consistent for each resource.
                return value;
            }
            assert size >= LARGE_SIZE;
            value = ((SoftReference<Object>)value).get();
            if(value != null) {
                return value;
            }
            values[index] = new SoftReference<Object>(item);
            return item;
        }

        private static final class Level {
            int levelBitsList;
            int shift;
            int mask;
            int[] keys;
            Object[] values;

            Level(int levelBitsList, int shift) {
                this.levelBitsList = levelBitsList;
                this.shift = shift;
                int bits = levelBitsList & 0xf;
                assert bits != 0;
                int length = 1 << bits;
                mask = length - 1;
                keys = new int[length];
                values = new Object[length];
            }

            Object get(int key) {
                int index = (key >> shift) & mask;
                int k = keys[index];
                if(k == key) {
                    return values[index];
                }
                if(k == 0) {
                    Level level = (Level)values[index];
                    if(level != null) {
                        return level.get(key);
                    }
                }
                return null;
            }

            Object putIfAbsent(int key, Object item, int size) {
                int index = (key >> shift) & mask;
                int k = keys[index];
                if(k == key) {
                    return putIfCleared(values, index, item, size);
                }
                if(k == 0) {
                    Level level = (Level)values[index];
                    if(level != null) {
                        return level.putIfAbsent(key, item, size);
                    }
                    keys[index] = key;
                    values[index] = (size >= LARGE_SIZE) ? new SoftReference<Object>(item) : item;
                    return item;
                }
                // Collision: Add a child level, move the old item there,
                // and then insert the current item.
                Level level = new Level(levelBitsList >> 4, shift + (levelBitsList & 0xf));
                int i = (k >> level.shift) & level.mask;
                level.keys[i] = k;
                level.values[i] = values[index];
                keys[index] = 0;
                values[index] = level;
                return level.putIfAbsent(key, item, size);
            }
        }

        ResourceCache(int maxOffset) {
            assert maxOffset != 0;
            maxOffsetBits = 28;
            while(maxOffset <= 0x7ffffff) {
                maxOffset <<= 1;
                --maxOffsetBits;
            }
            int keyBits = maxOffsetBits + 2;  // +2 for mini type: at most 30 bits used in a key
            // Precompute for each level the number of bits it handles.
            if(keyBits <= ROOT_BITS) {
                levelBitsList = keyBits;
            } else if(keyBits < (ROOT_BITS + 3)) {
                levelBitsList = 0x30 | (keyBits - 3);
            } else {
                levelBitsList = ROOT_BITS;
                keyBits -= ROOT_BITS;
                int shift = 4;
                for(;;) {
                    if(keyBits <= NEXT_BITS) {
                        levelBitsList |= keyBits << shift;
                        break;
                    } else if(keyBits < (NEXT_BITS + 3)) {
                        levelBitsList |= (0x30 | (keyBits - 3)) << shift;
                        break;
                    } else {
                        levelBitsList |= NEXT_BITS << shift;
                        keyBits -= NEXT_BITS;
                        shift += 4;
                    }
                }
            }
        }

        /**
         * Turns a resource integer (with unused bits in the middle)
         * into a key with fewer bits (at most keyBits).
         */
        private int makeKey(int res) {
            // It is possible for resources of different types in the 16-bit array
            // to share a start offset; distinguish between those with a 2-bit value,
            // as a tie-breaker in the bits just above the highest possible offset.
            // It is not possible for "regular" resources of different types
            // to share a start offset with each other,
            // but offsets for 16-bit and "regular" resources overlap;
            // use 2-bit value 0 for "regular" resources.
            int type = RES_GET_TYPE(res);
            int miniType =
                    (type == ICUResourceBundle.STRING_V2) ? 1 :
                        (type == ICUResourceBundle.TABLE16) ? 3 :
                            (type == ICUResourceBundle.ARRAY16) ? 2 : 0;
            return RES_GET_OFFSET(res) | (miniType << maxOffsetBits);
        }

        private int findSimple(int key) {
            // With Java 6, return Arrays.binarySearch(keys, 0, length, key).
            int start = 0;
            int limit = length;
            while((limit - start) > 8) {
                int mid = (start + limit) / 2;
                if(key < keys[mid]) {
                    limit = mid;
                } else {
                    start = mid;
                }
            }
            // For a small number of items, linear search should be a little faster.
            while(start < limit) {
                int k = keys[start];
                if(key < k) {
                    return ~start;
                }
                if(key == k) {
                    return start;
                }
                ++start;
            }
            return ~start;
        }

        @SuppressWarnings("unchecked")
        synchronized Object get(int res) {
            // Integers and empty resources need not be cached.
            // The cache itself uses res=0 for "no match".
            assert RES_GET_OFFSET(res) != 0;
            Object value;
            if(length >= 0) {
                int index = findSimple(res);
                if(index >= 0) {
                    value = values[index];
                } else {
                    return null;
                }
            } else {
                value = rootLevel.get(makeKey(res));
                if(value == null) {
                    return null;
                }
            }
            if(value instanceof SoftReference) {
                value = ((SoftReference<Object>)value).get();
            }
            return value;  // null if the reference was cleared
        }

        synchronized Object putIfAbsent(int res, Object item, int size) {
            if(length >= 0) {
                int index = findSimple(res);
                if(index >= 0) {
                    return putIfCleared(values, index, item, size);
                } else if(length < SIMPLE_LENGTH) {
                    index = ~index;
                    if(index < length) {
                        System.arraycopy(keys, index, keys, index + 1, length - index);
                        System.arraycopy(values, index, values, index + 1, length - index);
                    }
                    ++length;
                    keys[index] = res;
                    values[index] = (size >= LARGE_SIZE) ? new SoftReference<Object>(item) : item;
                    return item;
                } else /* not found && length == SIMPLE_LENGTH */ {
                    // Grow to become trie-like.
                    rootLevel = new Level(levelBitsList, 0);
                    for(int i = 0; i < SIMPLE_LENGTH; ++i) {
                        rootLevel.putIfAbsent(makeKey(keys[i]), values[i], 0);
                    }
                    keys = null;
                    values = null;
                    length = -1;
                }
            }
            return rootLevel.putIfAbsent(makeKey(res), item, size);
        }
    }

    private static final String ICU_RESOURCE_SUFFIX = ".res";

    /**
     * Gets the full name of the resource with suffix.
     */
    public static String getFullName(String baseName, String localeName) {
        if (baseName == null || baseName.length() == 0) {
            if (localeName.length() == 0) {
                return localeName = ULocale.getDefault().toString();
            }
            return localeName + ICU_RESOURCE_SUFFIX;
        } else {
            if (baseName.indexOf('.') == -1) {
                if (baseName.charAt(baseName.length() - 1) != '/') {
                    return baseName + "/" + localeName + ICU_RESOURCE_SUFFIX;
                } else {
                    return baseName + localeName + ICU_RESOURCE_SUFFIX;
                }
            } else {
                baseName = baseName.replace('.', '/');
                if (localeName.length() == 0) {
                    return baseName + ICU_RESOURCE_SUFFIX;
                } else {
                    return baseName + "_" + localeName + ICU_RESOURCE_SUFFIX;
                }
            }
        }
    }
}
