001: /**
002: *******************************************************************************
003: * Copyright (C) 1996-2006, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *******************************************************************************
006: */package com.ibm.icu.impl;
007:
008: import java.io.InputStream;
009: import java.io.DataInputStream;
010: import java.io.IOException;
011: import com.ibm.icu.util.VersionInfo;
012:
013: /**
014: * <p>Internal reader class for ICU data file uprops.icu containing
015: * Unicode codepoint data.</p>
016: * <p>This class simply reads uprops.icu, authenticates that it is a valid
017: * ICU data file and split its contents up into blocks of data for use in
018: * <a href=UCharacterProperty.html>com.ibm.icu.impl.UCharacterProperty</a>.
019: * </p>
020: * <p>uprops.icu which is in big-endian format is jared together with this
021: * package.</p>
022: *
023: * Unicode character properties file format see
024: * (ICU4C)/source/tools/genprops/store.c
025: *
026: * @author Syn Wee Quek
027: * @since release 2.1, February 1st 2002
028: */
029: final class UCharacterPropertyReader implements ICUBinary.Authenticate {
030: // public methods ----------------------------------------------------
031:
032: public boolean isDataVersionAcceptable(byte version[]) {
033: return version[0] == DATA_FORMAT_VERSION_[0]
034: && version[2] == DATA_FORMAT_VERSION_[2]
035: && version[3] == DATA_FORMAT_VERSION_[3];
036: }
037:
038: // protected constructor ---------------------------------------------
039:
040: /**
041: * <p>Protected constructor.</p>
042: * @param inputStream ICU uprop.dat file input stream
043: * @exception IOException throw if data file fails authentication
044: * @draft 2.1
045: */
046: protected UCharacterPropertyReader(InputStream inputStream)
047: throws IOException {
048: m_unicodeVersion_ = ICUBinary.readHeader(inputStream,
049: DATA_FORMAT_ID_, this );
050: m_dataInputStream_ = new DataInputStream(inputStream);
051: }
052:
053: // protected methods -------------------------------------------------
054:
055: /**
056: * <p>Reads uprops.icu, parse it into blocks of data to be stored in
057: * UCharacterProperty.</P
058: * @param ucharppty UCharacterProperty instance
059: * @exception IOException thrown when data reading fails
060: * @draft 2.1
061: */
062: protected void read(UCharacterProperty ucharppty)
063: throws IOException {
064: // read the indexes
065: int count = INDEX_SIZE_;
066: m_propertyOffset_ = m_dataInputStream_.readInt();
067: count--;
068: m_exceptionOffset_ = m_dataInputStream_.readInt();
069: count--;
070: m_caseOffset_ = m_dataInputStream_.readInt();
071: count--;
072: m_additionalOffset_ = m_dataInputStream_.readInt();
073: count--;
074: m_additionalVectorsOffset_ = m_dataInputStream_.readInt();
075: count--;
076: m_additionalColumnsCount_ = m_dataInputStream_.readInt();
077: count--;
078: m_reservedOffset_ = m_dataInputStream_.readInt();
079: count--;
080: m_dataInputStream_.skipBytes(3 << 2);
081: count -= 3;
082: ucharppty.m_maxBlockScriptValue_ = m_dataInputStream_.readInt();
083: count--; // 10
084: ucharppty.m_maxJTGValue_ = m_dataInputStream_.readInt();
085: count--; // 11
086: m_dataInputStream_.skipBytes(count << 2);
087:
088: // read the trie index block
089: // m_props_index_ in terms of ints
090: ucharppty.m_trie_ = new CharTrie(m_dataInputStream_, null);
091:
092: // skip the 32 bit properties block
093: int size = m_exceptionOffset_ - m_propertyOffset_;
094: m_dataInputStream_.skipBytes(size * 4);
095:
096: // reads the 32 bit exceptions block
097: size = m_caseOffset_ - m_exceptionOffset_;
098: m_dataInputStream_.skipBytes(size * 4);
099:
100: // reads the 32 bit case block
101: size = (m_additionalOffset_ - m_caseOffset_) << 1;
102: m_dataInputStream_.skipBytes(size * 2);
103:
104: if (m_additionalColumnsCount_ > 0) {
105: // reads the additional property block
106: ucharppty.m_additionalTrie_ = new CharTrie(
107: m_dataInputStream_, null);
108:
109: // additional properties
110: size = m_reservedOffset_ - m_additionalVectorsOffset_;
111: ucharppty.m_additionalVectors_ = new int[size];
112: for (int i = 0; i < size; i++) {
113: ucharppty.m_additionalVectors_[i] = m_dataInputStream_
114: .readInt();
115: }
116: }
117:
118: m_dataInputStream_.close();
119: ucharppty.m_additionalColumnsCount_ = m_additionalColumnsCount_;
120: ucharppty.m_unicodeVersion_ = VersionInfo.getInstance(
121: (int) m_unicodeVersion_[0], (int) m_unicodeVersion_[1],
122: (int) m_unicodeVersion_[2], (int) m_unicodeVersion_[3]);
123: }
124:
125: // private variables -------------------------------------------------
126:
127: /**
128: * Index size
129: */
130: private static final int INDEX_SIZE_ = 16;
131:
132: /**
133: * ICU data file input stream
134: */
135: private DataInputStream m_dataInputStream_;
136:
137: /**
138: * Offset information in the indexes.
139: */
140: private int m_propertyOffset_;
141: private int m_exceptionOffset_;
142: private int m_caseOffset_;
143: private int m_additionalOffset_;
144: private int m_additionalVectorsOffset_;
145: private int m_additionalColumnsCount_;
146: private int m_reservedOffset_;
147: private byte m_unicodeVersion_[];
148:
149: /**
150: * Data format "UPro".
151: */
152: private static final byte DATA_FORMAT_ID_[] = { (byte) 0x55,
153: (byte) 0x50, (byte) 0x72, (byte) 0x6F };
154: /**
155: * Format version; this code works with all versions with the same major
156: * version number and the same Trie bit distribution.
157: */
158: private static final byte DATA_FORMAT_VERSION_[] = { (byte) 0x4,
159: (byte) 0, (byte) Trie.INDEX_STAGE_1_SHIFT_,
160: (byte) Trie.INDEX_STAGE_2_SHIFT_ };
161: }
|