/* ********************************************************************** * Copyright (c) 2002-2014, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * Author: Alan Liu * Created: November 5 2002 * Since: ICU 2.4 * 2010nov19 Markus Scherer Rewrite for formatVersion 2. ********************************************************************** */ package com.ibm.icu.impl; import java.io.IOException; import java.nio.ByteBuffer; import java.util.MissingResourceException; import com.ibm.icu.lang.UProperty; import com.ibm.icu.util.BytesTrie; /** * Wrapper for the pnames.icu binary data file. This data file is * imported from icu4c. It contains property and property value * aliases from the UCD files PropertyAliases.txt and * PropertyValueAliases.txt. The file is built by the icu4c tool * genpname. It must be an ASCII big-endian file to be * usable in icu4j. * * This class performs two functions. * * (1) It can import the flat binary data into usable objects. * * (2) It provides an API to access the tree of objects. * * Needless to say, this class is tightly coupled to the binary format * of icu4c's pnames.icu file. * * Each time a UPropertyAliases is constructed, the pnames.icu file is * read, parsed, and data structures assembled. Clients should create one * singleton instance and cache it. * * @author Alan Liu * @since ICU 2.4 */ public final class UPropertyAliases { // Byte offsets from the start of the data, after the generic header. private static final int IX_VALUE_MAPS_OFFSET=0; private static final int IX_BYTE_TRIES_OFFSET=1; private static final int IX_NAME_GROUPS_OFFSET=2; private static final int IX_RESERVED3_OFFSET=3; // private static final int IX_RESERVED4_OFFSET=4; // private static final int IX_TOTAL_SIZE=5; // Other values. // private static final int IX_MAX_NAME_LENGTH=6; // private static final int IX_RESERVED7=7; // private static final int IX_COUNT=8; //---------------------------------------------------------------- // Runtime data. This is an unflattened representation of the // data in pnames.icu. private int[] valueMaps; private byte[] bytesTries; private String nameGroups; private static final class IsAcceptable implements ICUBinary.Authenticate { // @Override when we switch to Java 6 public boolean isDataVersionAcceptable(byte version[]) { return version[0]==2; } } private static final IsAcceptable IS_ACCEPTABLE=new IsAcceptable(); private static final int DATA_FORMAT=0x706E616D; // "pnam" private void load(ByteBuffer bytes) throws IOException { //dataVersion=ICUBinary.readHeaderAndDataVersion(bytes, DATA_FORMAT, IS_ACCEPTABLE); ICUBinary.readHeader(bytes, DATA_FORMAT, IS_ACCEPTABLE); int indexesLength=bytes.getInt()/4; // inIndexes[IX_VALUE_MAPS_OFFSET]/4 if(indexesLength<8) { // formatVersion 2 initially has 8 indexes throw new IOException("pnames.icu: not enough indexes"); } int[] inIndexes=new int[indexesLength]; inIndexes[0]=indexesLength*4; for(int i=1; i0; --numRanges) { // Read and skip the start and limit of this range. int start=valueMaps[i]; int limit=valueMaps[i+1]; i+=2; if(property0; --numRanges) { // Read and skip the start and limit of this range. int start=valueMaps[valueMapIndex]; int limit=valueMaps[valueMapIndex+1]; valueMapIndex+=2; if(value0; --nameIndex) { while(0!=nameGroups.charAt(nameGroupsIndex++)) {} } // Find the end of this name. int nameStart=nameGroupsIndex; while(0!=nameGroups.charAt(nameGroupsIndex)) { ++nameGroupsIndex; } if(nameStart==nameGroupsIndex) { return null; // no name (Property[Value]Aliases.txt has "n/a") } return nameGroups.substring(nameStart, nameGroupsIndex); } private static int asciiToLowercase(int c) { return 'A'<=c && c<='Z' ? c+0x20 : c; } private boolean containsName(BytesTrie trie, CharSequence name) { BytesTrie.Result result=BytesTrie.Result.NO_VALUE; for(int i=0; i0. The * comparison is that described as "loose" matching in the * Property*Aliases.txt files. */ public static int compare(String stra, String strb) { // Note: This implementation is a literal copy of // uprv_comparePropertyNames. It can probably be improved. int istra=0, istrb=0, rc; int cstra=0, cstrb=0; for (;;) { /* Ignore delimiters '-', '_', and ASCII White_Space */ while (istra