com.ibm.icu.impl.UPropertyAliases Maven / Gradle / Ivy
The newest version!
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
**********************************************************************
* Copyright (c) 2002-2015, 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
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