blob: 546b479f371c773431f203190d8d20f15d32c085 [file] [log] [blame]
/**
*******************************************************************************
* Copyright (C) 1996-2001, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/text/Attic/UGenPropReader.java,v $
* $Date: 2001/08/22 22:38:30 $
* $Revision: 1.6 $
*
*******************************************************************************
*/
package com.ibm.text;
import java.io.DataInputStream;
import java.util.Arrays;
import java.io.IOException;
/**
* Internal reader class reading binary data from uprops.dat created by ICU
* programs genprops.
* It arranges the header and index data apart into meaningful data before
* populating <a href=UCharacterPropDB.html>UCharacterPropDB</a>. UGenPropReader
* does not have or require the ability to decipher the rest of the data in
* uprop.dat and hence stores it as a block of data in an array of char in
* <a href=UCharacterPropDB.html>UCharacterPropDB</a>. The ability to decipher
* the block of data lies in <a href=UCharacterProp.html>UCharacterProp</a>.
* For more information about the format of uprops.dat refer to
* <a href=oss.software.ibm.com/icu4j/icu4jhtml/com/ibm/icu/text/readme.html>
* ReadMe</a>.<br>
* uprops.dat which is in big-endian format is jared together with this package.
* @author Syn Wee Quek
* @since oct0200
*/
final class UGenPropReader extends UGenReader
{
// private variables ===========================================
/**
* Index size
*/
private static final int INDEX_SIZE_ = 8;
/**
* Elements in the index where addresses are in number of chars.
* Size is basically the count and does not depend on the type.
*/
private char m_stage2indexsize_;
private char m_stage3indexsize_;
private int m_exception_;
private char m_stage3_;
private int m_prop_;
private int m_case_;
private char m_end_;
/**
* Size of actual number of bits used in surrogate unicode character
*/
private static final int USED_SURROGATE_BIT_SIZE_ = 21;
/**
* File format version that this class understands.
* No guarantees are made if a older version is used
*/
private static final byte DATA_FORMAT_ID_[] = {(byte)0x55, (byte)0x50,
(byte)0x72, (byte)0x6F};
private static final byte DATA_FORMAT_VERSION_[] =
{(byte)0x1, (byte)0x3, (byte)0x0, (byte)0x0};
/**
* Corrupted error string
*/
private static final String CORRUPTED_DATA_ERROR_ =
"Data corrupted in character property data file";
// constructor =============================================
/**
* Constructor
*/
protected UGenPropReader()
{
}
// protected methods ==================================================
/**
* Read and fills up UCharacterPptyDB.
* If unsuccessful false will be returned
* @param input data stream
* @param data data instance
* @exception thrown when data reading fails
*/
protected void read(DataInputStream input, UCharacterPropertyDB data)
throws IOException
{
if (!(super.read(input, data) &&
// read the indexes
readIndex(input, data) &&
// read the stages block
readStage(input, data) &&
// read the property data
readProperty(input, data) &&
// read the exception data
readException(input, data) &&
// read the case data
readCase(input,data))) {
throw new IOException(CORRUPTED_DATA_ERROR_);
}
}
/**
* Checking the file for the correct format
* @param dataformatid
* @param dataformatversion
* @return true if the file format version is correct
*/
protected boolean authenticate(byte dataformatid[],
byte dataformatversion[])
{
return Arrays.equals(DATA_FORMAT_ID_, dataformatid) &&
Arrays.equals(DATA_FORMAT_VERSION_, dataformatversion);
}
/**
* Gets the size of the file format version
* @return size of file format version in bytes
*/
protected int getFileFormatVersionSize()
{
return DATA_FORMAT_VERSION_.length;
}
/**
* Gets the size of the file format id
* @return size of file format id in bytes
*/
protected int getFileFormatIDSize()
{
return DATA_FORMAT_ID_.length;
}
// private methods ===================================================
/**
* Read the INDEX_SIZE_ indexes and updates the instance of
* UCharacterPropertyDB with the processed shifts and mask
* @param input data stream
* @param data instance of UCharacterPropertyDB
* @return true if successfully read
* @exception thrown when there's an IOException
*/
private boolean readIndex(DataInputStream input, UCharacterPropertyDB data)
throws IOException
{
int count = INDEX_SIZE_;
m_stage2indexsize_ = input.readChar();
count --;
m_stage3indexsize_ = input.readChar();
count --;
m_exception_ = input.readChar();
count --;
m_stage3_ = input.readChar();
count --;
m_prop_ = input.readChar();
count --;
m_case_ = input.readChar();
count --;
m_end_ = input.readChar();
count --;
input.skipBytes(count << 1);
return data.setInfo(m_stage3indexsize_ + m_stage2indexsize_,
(int)m_stage3indexsize_,
(1 << m_stage2indexsize_) - 1,
(1 << m_stage3indexsize_) - 1);
}
/**
* Read the stages block and updates the instance of UCharacterPropertyDB
* with the stages data
* @param input data stream
* @param data instance of UCharacterPropertyDB
* @return true if successfully read
* @exception thrown when data reading fails
*/
private boolean readStage(DataInputStream input, UCharacterPropertyDB data)
throws IOException
{
// size of the 3 stages
int stagesize = (m_prop_ << 1) - INDEX_SIZE_;
char array[] = new char[stagesize];
int props = m_prop_ - INDEX_SIZE_;
// setting up the propery index for stage 1 to 3
for (int count = 0; count < stagesize; count ++)
{
array[count] = (char)(input.readChar() - INDEX_SIZE_);
// testing empty spaces
// if (max < array[count] && count < 0x440) {
// max = array[count];
//}
// setting up the property index for stage 3
// uprops.dat contain data that includes the address from the top of
// index to property data. since the blocks are split up, so now i have
// to subtract the excess address from it.
if (count >= m_stage3_ - INDEX_SIZE_) {
array[count] -= props;
}
}
// System.out.println("\nstage 3 " + (int)m_stage3_);
// System.out.println("stage 2 top " + (max - 0x440 - INDEX_SIZE_));
// System.out.println("calculated stage 3 " + max);
// setting up the stages block in the instance of UCharacterPropertyDB
return data.setStage(array);
}
/**
* Read the propery data block and updates the instance of
* UCharacterPropertyDB with the data
* @param input data stream
* @param data instance of UCharacterPropertyDB
* @return true if successfully read
* @exception thrown when data reading fails
*/
private boolean readProperty(DataInputStream input,
UCharacterPropertyDB data) throws IOException
{
// getting size of the property block
int size = m_exception_ - m_prop_;
int ppty[] = new int[size];
for (int i = 0; i < size; i ++) {
ppty[i] = input.readInt();
}
// setting up the property block in the instance of UCharacterPropertyDB
return data.setProperty(ppty);
}
/**
* Read the character case data block and updates the instance of
* UCharacterPropertyDB with the data
* @param input data stream
* @param data instance of UCharacterPropertyDB
* @return true if successfully read
* @exception thrown when data reading fails
*/
private boolean readCase(DataInputStream input,
UCharacterPropertyDB data) throws IOException
{
// getting size of the case block
int size = (m_end_ - m_case_) << 1;
char casetable[] = new char[size];
for (int i = 0; i < size; i ++) {
casetable[i] = input.readChar();
}
// setting up the case block in the instance of UCharacterPropertyDB
return data.setCase(casetable);
}
/**
* Read the exception data block and updates the instance of
* UCharacterPropertyDB with the data
* @param input data stream
* @param data instance of UCharacterPropertyDB
* @return true if successfully read
* @exception thrown when data reading fails
*/
private boolean readException(DataInputStream input,
UCharacterPropertyDB data) throws IOException
{
int size = m_case_ - m_exception_;
int exception[] = new int[size];
for (int i = 0; i < size; i ++) {
exception[i] = input.readInt();
}
// setting up the property block in the instance of UCharacterPropertyDB
return data.setException(exception);
}
}