2 *******************************************************************************
\r
3 * Copyright (C) 1996-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.impl;
\r
9 import java.io.DataInputStream;
\r
10 import java.io.IOException;
\r
11 import java.io.InputStream;
\r
12 import java.util.Arrays;
\r
15 * <p>Internal reader class for ICU data file uname.dat containing
\r
16 * Unicode codepoint name data.</p>
\r
17 * <p>This class simply reads unames.icu, authenticates that it is a valid
\r
18 * ICU data file and split its contents up into blocks of data for use in
\r
19 * <a href=UCharacterName.html>com.ibm.icu.impl.UCharacterName</a>.
\r
21 * <p>unames.icu which is in big-endian format is jared together with this
\r
23 * @author Syn Wee Quek
\r
24 * @since release 2.1, February 1st 2002
\r
27 final class UCharacterNameReader implements ICUBinary.Authenticate
\r
29 // public methods ----------------------------------------------------
\r
31 public boolean isDataVersionAcceptable(byte version[])
\r
33 return version[0] == DATA_FORMAT_VERSION_[0];
\r
36 // protected constructor ---------------------------------------------
\r
39 * <p>Protected constructor.</p>
\r
40 * @param inputStream ICU uprop.dat file input stream
\r
41 * @exception IOException throw if data file fails authentication
\r
43 protected UCharacterNameReader(InputStream inputStream)
\r
46 ICUBinary.readHeader(inputStream, DATA_FORMAT_ID_, this);
\r
47 m_dataInputStream_ = new DataInputStream(inputStream);
\r
50 // protected methods -------------------------------------------------
\r
53 * Read and break up the stream of data passed in as arguments
\r
54 * and fills up UCharacterName.
\r
55 * If unsuccessful false will be returned.
\r
56 * @param data instance of datablock
\r
57 * @exception IOException thrown when there's a data error.
\r
59 protected void read(UCharacterName data) throws IOException
\r
62 m_tokenstringindex_ = m_dataInputStream_.readInt();
\r
63 m_groupindex_ = m_dataInputStream_.readInt();
\r
64 m_groupstringindex_ = m_dataInputStream_.readInt();
\r
65 m_algnamesindex_ = m_dataInputStream_.readInt();
\r
68 int count = m_dataInputStream_.readChar();
\r
69 char token[] = new char[count];
\r
70 for (char i = 0; i < count; i ++) {
\r
71 token[i] = m_dataInputStream_.readChar();
\r
73 int size = m_groupindex_ - m_tokenstringindex_;
\r
74 byte tokenstr[] = new byte[size];
\r
75 m_dataInputStream_.readFully(tokenstr);
\r
76 data.setToken(token, tokenstr);
\r
78 // reading the group information records
\r
79 count = m_dataInputStream_.readChar();
\r
80 data.setGroupCountSize(count, GROUP_INFO_SIZE_);
\r
81 count *= GROUP_INFO_SIZE_;
\r
82 char group[] = new char[count];
\r
83 for (int i = 0; i < count; i ++) {
\r
84 group[i] = m_dataInputStream_.readChar();
\r
87 size = m_algnamesindex_ - m_groupstringindex_;
\r
88 byte groupstring[] = new byte[size];
\r
89 m_dataInputStream_.readFully(groupstring);
\r
91 data.setGroup(group, groupstring);
\r
93 count = m_dataInputStream_.readInt();
\r
94 UCharacterName.AlgorithmName alg[] =
\r
95 new UCharacterName.AlgorithmName[count];
\r
97 for (int i = 0; i < count; i ++)
\r
99 UCharacterName.AlgorithmName an = readAlg();
\r
101 throw new IOException("unames.icu read error: Algorithmic names creation error");
\r
105 data.setAlgorithm(alg);
\r
109 * <p>Checking the file for the correct format.</p>
\r
110 * @param dataformatid
\r
111 * @param dataformatversion
\r
112 * @return true if the file format version is correct
\r
115 protected boolean authenticate(byte dataformatid[],
\r
116 byte dataformatversion[])
\r
118 return Arrays.equals(DATA_FORMAT_ID_, dataformatid) &&
\r
119 Arrays.equals(DATA_FORMAT_VERSION_, dataformatversion);
\r
123 // private variables -------------------------------------------------
\r
126 * Data input stream for names
\r
128 private DataInputStream m_dataInputStream_;
\r
130 * Size of the group information block in number of char
\r
132 private static final int GROUP_INFO_SIZE_ = 3;
\r
135 * Index of the offset information
\r
137 private int m_tokenstringindex_;
\r
138 private int m_groupindex_;
\r
139 private int m_groupstringindex_;
\r
140 private int m_algnamesindex_;
\r
143 * Size of an algorithmic name information group
\r
144 * start code point size + end code point size + type size + variant size +
\r
145 * size of data size
\r
147 private static final int ALG_INFO_SIZE_ = 12;
\r
150 * File format version and id that this class understands.
\r
151 * No guarantees are made if a older version is used
\r
153 private static final byte DATA_FORMAT_VERSION_[] =
\r
154 {(byte)0x1, (byte)0x0, (byte)0x0, (byte)0x0};
\r
155 private static final byte DATA_FORMAT_ID_[] = {(byte)0x75, (byte)0x6E,
\r
156 (byte)0x61, (byte)0x6D};
\r
158 // private methods ---------------------------------------------------
\r
161 * Reads an individual record of AlgorithmNames
\r
162 * @return an instance of AlgorithNames if read is successful otherwise null
\r
163 * @exception IOException thrown when file read error occurs or data is corrupted
\r
165 private UCharacterName.AlgorithmName readAlg() throws IOException
\r
167 UCharacterName.AlgorithmName result =
\r
168 new UCharacterName.AlgorithmName();
\r
169 int rangestart = m_dataInputStream_.readInt();
\r
170 int rangeend = m_dataInputStream_.readInt();
\r
171 byte type = m_dataInputStream_.readByte();
\r
172 byte variant = m_dataInputStream_.readByte();
\r
173 if (!result.setInfo(rangestart, rangeend, type, variant)) {
\r
177 int size = m_dataInputStream_.readChar();
\r
178 if (type == UCharacterName.AlgorithmName.TYPE_1_)
\r
180 char factor[] = new char[variant];
\r
181 for (int j = 0; j < variant; j ++) {
\r
182 factor[j] = m_dataInputStream_.readChar();
\r
185 result.setFactor(factor);
\r
186 size -= (variant << 1);
\r
189 StringBuilder prefix = new StringBuilder();
\r
190 char c = (char)(m_dataInputStream_.readByte() & 0x00FF);
\r
194 c = (char)(m_dataInputStream_.readByte() & 0x00FF);
\r
197 result.setPrefix(prefix.toString());
\r
199 size -= (ALG_INFO_SIZE_ + prefix.length() + 1);
\r
203 byte string[] = new byte[size];
\r
204 m_dataInputStream_.readFully(string);
\r
205 result.setFactorString(string);
\r