com.ibm.icu.impl.UPropertyAliases Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of icu4j Show documentation
Show all versions of icu4j Show documentation
International Component for Unicode for Java (ICU4J) is a mature, widely used Java library
providing Unicode and Globalization support
// © 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