12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */ 22ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* 32ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ********************************************************************** 42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Copyright (c) 2002-2015, International Business Machines 52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Corporation and others. All Rights Reserved. 62ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ********************************************************************** 72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Author: Alan Liu 82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Created: November 5 2002 92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Since: ICU 2.4 102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2010nov19 Markus Scherer Rewrite for formatVersion 2. 112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ********************************************************************** 122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.impl; 152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.io.IOException; 172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.nio.ByteBuffer; 182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.MissingResourceException; 192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.lang.UProperty; 212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.BytesTrie; 222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/** 242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Wrapper for the pnames.icu binary data file. This data file is 252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * imported from icu4c. It contains property and property value 262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * aliases from the UCD files PropertyAliases.txt and 272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * PropertyValueAliases.txt. The file is built by the icu4c tool 282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * genpname. It must be an ASCII big-endian file to be 292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * usable in icu4j. 302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This class performs two functions. 322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (1) It can import the flat binary data into usable objects. 342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (2) It provides an API to access the tree of objects. 362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Needless to say, this class is tightly coupled to the binary format 382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * of icu4c's pnames.icu file. 392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Each time a UPropertyAliases is constructed, the pnames.icu file is 412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * read, parsed, and data structures assembled. Clients should create one 422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * singleton instance and cache it. 432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @author Alan Liu 45836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide Only a subset of ICU is exposed in Android 462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic final class UPropertyAliases { 482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Byte offsets from the start of the data, after the generic header. 492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int IX_VALUE_MAPS_OFFSET=0; 502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int IX_BYTE_TRIES_OFFSET=1; 512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int IX_NAME_GROUPS_OFFSET=2; 522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int IX_RESERVED3_OFFSET=3; 532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // private static final int IX_RESERVED4_OFFSET=4; 542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // private static final int IX_TOTAL_SIZE=5; 552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Other values. 572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // private static final int IX_MAX_NAME_LENGTH=6; 582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // private static final int IX_RESERVED7=7; 592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // private static final int IX_COUNT=8; 602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //---------------------------------------------------------------- 622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Runtime data. This is an unflattened representation of the 632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // data in pnames.icu. 642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int[] valueMaps; 662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private byte[] bytesTries; 672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String nameGroups; 682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final class IsAcceptable implements ICUBinary.Authenticate { 702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // @Override when we switch to Java 6 712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean isDataVersionAcceptable(byte version[]) { 722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return version[0]==2; 732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final IsAcceptable IS_ACCEPTABLE=new IsAcceptable(); 762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int DATA_FORMAT=0x706E616D; // "pnam" 772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void load(ByteBuffer bytes) throws IOException { 792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //dataVersion=ICUBinary.readHeaderAndDataVersion(bytes, DATA_FORMAT, IS_ACCEPTABLE); 802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ICUBinary.readHeader(bytes, DATA_FORMAT, IS_ACCEPTABLE); 812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int indexesLength=bytes.getInt()/4; // inIndexes[IX_VALUE_MAPS_OFFSET]/4 822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(indexesLength<8) { // formatVersion 2 initially has 8 indexes 832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IOException("pnames.icu: not enough indexes"); 842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int[] inIndexes=new int[indexesLength]; 862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller inIndexes[0]=indexesLength*4; 872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for(int i=1; i<indexesLength; ++i) { 882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller inIndexes[i]=bytes.getInt(); 892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Read the valueMaps. 922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int offset=inIndexes[IX_VALUE_MAPS_OFFSET]; 932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int nextOffset=inIndexes[IX_BYTE_TRIES_OFFSET]; 942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int numInts=(nextOffset-offset)/4; 952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller valueMaps=ICUBinary.getInts(bytes, numInts, 0); 962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Read the bytesTries. 982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller offset=nextOffset; 992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller nextOffset=inIndexes[IX_NAME_GROUPS_OFFSET]; 1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int numBytes=nextOffset-offset; 1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bytesTries=new byte[numBytes]; 1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bytes.get(bytesTries); 1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Read the nameGroups and turn them from ASCII bytes into a Java String. 1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller offset=nextOffset; 1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller nextOffset=inIndexes[IX_RESERVED3_OFFSET]; 1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numBytes=nextOffset-offset; 1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder sb=new StringBuilder(numBytes); 1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for(int i=0; i<numBytes; ++i) { 1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller sb.append((char)bytes.get()); 1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller nameGroups=sb.toString(); 1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private UPropertyAliases() throws IOException { 1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ByteBuffer bytes = ICUBinary.getRequiredData("pnames.icu"); 1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller load(bytes); 1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int findProperty(int property) { 1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int i=1; // valueMaps index, initially after numRanges 1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for(int numRanges=valueMaps[0]; numRanges>0; --numRanges) { 1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Read and skip the start and limit of this range. 1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int start=valueMaps[i]; 1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int limit=valueMaps[i+1]; 1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i+=2; 1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(property<start) { 1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(property<limit) { 1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return i+(property-start)*2; 1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i+=(limit-start)*2; // Skip all entries for this range. 1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return 0; 1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int findPropertyValueNameGroup(int valueMapIndex, int value) { 1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(valueMapIndex==0) { 1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return 0; // The property does not have named values. 1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++valueMapIndex; // Skip the BytesTrie offset. 1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int numRanges=valueMaps[valueMapIndex++]; 1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(numRanges<0x10) { 1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Ranges of values. 1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for(; numRanges>0; --numRanges) { 1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Read and skip the start and limit of this range. 1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int start=valueMaps[valueMapIndex]; 1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int limit=valueMaps[valueMapIndex+1]; 1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller valueMapIndex+=2; 1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(value<start) { 1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(value<limit) { 1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return valueMaps[valueMapIndex+value-start]; 1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller valueMapIndex+=limit-start; // Skip all entries for this range. 1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // List of values. 1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int valuesStart=valueMapIndex; 1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int nameGroupOffsetsStart=valueMapIndex+numRanges-0x10; 1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int v=valueMaps[valueMapIndex]; 1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(value<v) { 1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(value==v) { 1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return valueMaps[nameGroupOffsetsStart+valueMapIndex-valuesStart]; 1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while(++valueMapIndex<nameGroupOffsetsStart); 1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return 0; 1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String getName(int nameGroupsIndex, int nameIndex) { 1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int numNames=nameGroups.charAt(nameGroupsIndex++); 1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(nameIndex<0 || numNames<=nameIndex) { 1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalIcuArgumentException("Invalid property (value) name choice"); 1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Skip nameIndex names. 1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for(; nameIndex>0; --nameIndex) { 1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while(0!=nameGroups.charAt(nameGroupsIndex++)) {} 1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Find the end of this name. 1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int nameStart=nameGroupsIndex; 1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while(0!=nameGroups.charAt(nameGroupsIndex)) { 1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++nameGroupsIndex; 1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(nameStart==nameGroupsIndex) { 1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; // no name (Property[Value]Aliases.txt has "n/a") 1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return nameGroups.substring(nameStart, nameGroupsIndex); 1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static int asciiToLowercase(int c) { 1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return 'A'<=c && c<='Z' ? c+0x20 : c; 1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private boolean containsName(BytesTrie trie, CharSequence name) { 2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller BytesTrie.Result result=BytesTrie.Result.NO_VALUE; 2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for(int i=0; i<name.length(); ++i) { 2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int c=name.charAt(i); 2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Ignore delimiters '-', '_', and ASCII White_Space. 2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(c=='-' || c=='_' || c==' ' || (0x09<=c && c<=0x0d)) { 2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller continue; 2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(!result.hasNext()) { 2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller c=asciiToLowercase(c); 2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result=trie.next(c); 2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return result.hasValue(); 2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //---------------------------------------------------------------- 2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Public API 2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final UPropertyAliases INSTANCE; 2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller static { 2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller INSTANCE = new UPropertyAliases(); 2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch(IOException e) { 2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ///CLOVER:OFF 2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller MissingResourceException mre = new MissingResourceException( 2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "Could not construct UPropertyAliases. Missing pnames.icu", "", ""); 2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller mre.initCause(e); 2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw mre; 2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ///CLOVER:ON 2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns a property name given a property enum. 2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Multiple names may be available for each property; 2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the nameChoice selects among them. 2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String getPropertyName(int property, int nameChoice) { 2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int valueMapIndex=findProperty(property); 2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(valueMapIndex==0) { 2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException( 2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "Invalid property enum "+property+" (0x"+Integer.toHexString(property)+")"); 2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return getName(valueMaps[valueMapIndex], nameChoice); 2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns a value name given a property enum and a value enum. 2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Multiple names may be available for each value; 2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the nameChoice selects among them. 2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String getPropertyValueName(int property, int value, int nameChoice) { 2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int valueMapIndex=findProperty(property); 2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(valueMapIndex==0) { 2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException( 2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "Invalid property enum "+property+" (0x"+Integer.toHexString(property)+")"); 2592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int nameGroupOffset=findPropertyValueNameGroup(valueMaps[valueMapIndex+1], value); 2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(nameGroupOffset==0) { 2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException( 2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "Property "+property+" (0x"+Integer.toHexString(property)+ 2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ") does not have named values"); 2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return getName(nameGroupOffset, nameChoice); 2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int getPropertyOrValueEnum(int bytesTrieOffset, CharSequence alias) { 2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller BytesTrie trie=new BytesTrie(bytesTries, bytesTrieOffset); 2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(containsName(trie, alias)) { 2722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return trie.getValue(); 2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return UProperty.UNDEFINED; 2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns a property enum given one of its property names. 2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If the property name is not known, this method returns 2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * UProperty.UNDEFINED. 2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getPropertyEnum(CharSequence alias) { 2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return getPropertyOrValueEnum(0, alias); 2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns a value enum given a property enum and one of its value names. 2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getPropertyValueEnum(int property, CharSequence alias) { 2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int valueMapIndex=findProperty(property); 2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(valueMapIndex==0) { 2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException( 2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "Invalid property enum "+property+" (0x"+Integer.toHexString(property)+")"); 2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller valueMapIndex=valueMaps[valueMapIndex+1]; 2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(valueMapIndex==0) { 2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException( 2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "Property "+property+" (0x"+Integer.toHexString(property)+ 3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ") does not have named values"); 3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // valueMapIndex is the start of the property's valueMap, 3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // where the first word is the BytesTrie offset. 3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return getPropertyOrValueEnum(valueMaps[valueMapIndex], alias); 3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns a value enum given a property enum and one of its value names. Does not throw. 3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return value enum, or UProperty.UNDEFINED if not defined for that property 3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getPropertyValueEnumNoThrow(int property, CharSequence alias) { 3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int valueMapIndex=findProperty(property); 3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(valueMapIndex==0) { 3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return UProperty.UNDEFINED; 3152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller valueMapIndex=valueMaps[valueMapIndex+1]; 3172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(valueMapIndex==0) { 3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return UProperty.UNDEFINED; 3192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // valueMapIndex is the start of the property's valueMap, 3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // where the first word is the BytesTrie offset. 3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return getPropertyOrValueEnum(valueMaps[valueMapIndex], alias); 3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Compare two property names, returning <0, 0, or >0. The 3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * comparison is that described as "loose" matching in the 3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Property*Aliases.txt files. 3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static int compare(String stra, String strb) { 3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Note: This implementation is a literal copy of 3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // uprv_comparePropertyNames. It can probably be improved. 3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int istra=0, istrb=0, rc; 3342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int cstra=0, cstrb=0; 3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) { 3362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* Ignore delimiters '-', '_', and ASCII White_Space */ 3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (istra<stra.length()) { 3382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cstra = stra.charAt(istra); 3392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller switch (cstra) { 3402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case '-': case '_': case ' ': case '\t': 3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case '\n': case 0xb/*\v*/: case '\f': case '\r': 3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++istra; 3432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller continue; 3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (istrb<strb.length()) { 3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cstrb = strb.charAt(istrb); 3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller switch (cstrb) { 3512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case '-': case '_': case ' ': case '\t': 3522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case '\n': case 0xb/*\v*/: case '\f': case '\r': 3532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++istrb; 3542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller continue; 3552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 3572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* If we reach the ends of both strings then they match */ 3602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean endstra = istra==stra.length(); 3612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean endstrb = istrb==strb.length(); 3622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (endstra) { 3632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (endstrb) return 0; 3642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cstra = 0; 3652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (endstrb) { 3662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cstrb = 0; 3672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rc = asciiToLowercase(cstra) - asciiToLowercase(cstrb); 3702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rc != 0) { 3712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return rc; 3722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++istra; 3752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++istrb; 3762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller} 379