All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ibm.icu.impl.UPropertyAliases Maven / Gradle / Ivy

There is a newer version: 2.12.15
Show newest version
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 **********************************************************************
 * 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 when we switch to Java 6
        @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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy