ICU-10944 Add ByteBuffer support for properties classes.

Updates UBiDiProps, UCaseProps, UCharacterProperty and UPropertyAliases.

R=markus.icu@gmail.com

Review URL: https://codereview.appspot.com/112020044

X-SVN-Rev: 36038
This commit is contained in:
Fredrik Roubert 2014-07-15 20:55:59 +00:00
parent 4aea6c889a
commit 463c0aa318
4 changed files with 103 additions and 124 deletions

View File

@ -1,28 +1,27 @@
/*
*******************************************************************************
*
* Copyright (C) 2004-2014, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
* file name: UBiDiProps.java
* encoding: US-ASCII
* tab size: 8 (not used)
* indentation:4
*
* created on: 2005jan16
* created by: Markus W. Scherer
*
* Low-level Unicode bidi/shaping properties access.
* Java port of ubidi_props.h/.c.
*/
*******************************************************************************
*
* Copyright (C) 2004-2014, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
* file name: UBiDiProps.java
* encoding: US-ASCII
* tab size: 8 (not used)
* indentation:4
*
* created on: 2005jan16
* created by: Markus W. Scherer
*
* Low-level Unicode bidi/shaping properties access.
* Java port of ubidi_props.h/.c.
*/
package com.ibm.icu.impl;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.Iterator;
import com.ibm.icu.lang.UCharacter;
@ -36,21 +35,17 @@ public final class UBiDiProps {
// port of ubidi_openProps()
private UBiDiProps() throws IOException{
InputStream is=ICUData.getStream(ICUResourceBundle.ICU_BUNDLE+"/"+DATA_FILE_NAME);
BufferedInputStream b=new BufferedInputStream(is, 4096 /* data buffer size */);
readData(b);
b.close();
is.close();
ByteBuffer bytes=ICUBinary.getByteBufferFromInputStream(is);
readData(bytes);
}
private void readData(InputStream is) throws IOException {
DataInputStream inputStream=new DataInputStream(is);
private void readData(ByteBuffer bytes) throws IOException {
// read the header
ICUBinary.readHeader(inputStream, FMT, new IsAcceptable());
ICUBinary.readHeader(bytes, FMT, new IsAcceptable());
// read indexes[]
int i, count;
count=inputStream.readInt();
count=bytes.getInt();
if(count<IX_TOP) {
throw new IOException("indexes[0] too small in "+DATA_FILE_NAME);
}
@ -58,25 +53,25 @@ public final class UBiDiProps {
indexes[0]=count;
for(i=1; i<count; ++i) {
indexes[i]=inputStream.readInt();
indexes[i]=bytes.getInt();
}
// read the trie
trie=Trie2_16.createFromSerialized(inputStream);
trie=Trie2_16.createFromSerialized(bytes);
int expectedTrieLength=indexes[IX_TRIE_SIZE];
int trieLength=trie.getSerializedLength();
if(trieLength>expectedTrieLength) {
throw new IOException(DATA_FILE_NAME+": not enough bytes for the trie");
}
// skip padding after trie bytes
inputStream.skipBytes(expectedTrieLength-trieLength);
ICUBinary.skipBytes(bytes, expectedTrieLength-trieLength);
// read mirrors[]
count=indexes[IX_MIRROR_LENGTH];
if(count>0) {
mirrors=new int[count];
for(i=0; i<count; ++i) {
mirrors[i]=inputStream.readInt();
mirrors[i]=bytes.getInt();
}
}
@ -84,14 +79,14 @@ public final class UBiDiProps {
count=indexes[IX_JG_LIMIT]-indexes[IX_JG_START];
jgArray=new byte[count];
for(i=0; i<count; ++i) {
jgArray[i]=inputStream.readByte();
jgArray[i]=bytes.get();
}
// read jgArray2[]
count=indexes[IX_JG_LIMIT2]-indexes[IX_JG_START2];
jgArray2=new byte[count];
for(i=0; i<count; ++i) {
jgArray2[i]=inputStream.readByte();
jgArray2[i]=bytes.get();
}
}
@ -275,7 +270,7 @@ public final class UBiDiProps {
private static final String DATA_FILE_NAME=DATA_NAME+"."+DATA_TYPE;
/* format "BiDi" */
private static final byte FMT[]={ 0x42, 0x69, 0x44, 0x69 };
private static final int FMT=0x42694469;
/* indexes into indexes[] */
//private static final int IX_INDEX_TOP=0;

View File

@ -1,28 +1,27 @@
/*
*******************************************************************************
*
* Copyright (C) 2004-2014, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
* file name: UCaseProps.java
* encoding: US-ASCII
* tab size: 8 (not used)
* indentation:4
*
* created on: 2005jan29
* created by: Markus W. Scherer
*
* Low-level Unicode character/string case mapping code.
* Java port of ucase.h/.c.
*/
*******************************************************************************
*
* Copyright (C) 2004-2014, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
* file name: UCaseProps.java
* encoding: US-ASCII
* tab size: 8 (not used)
* indentation:4
*
* created on: 2005jan29
* created by: Markus W. Scherer
*
* Low-level Unicode character/string case mapping code.
* Java port of ucase.h/.c.
*/
package com.ibm.icu.impl;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.Iterator;
import com.ibm.icu.lang.UCharacter;
@ -39,21 +38,17 @@ public final class UCaseProps {
// port of ucase_openProps()
private UCaseProps() throws IOException {
InputStream is=ICUData.getRequiredStream(ICUResourceBundle.ICU_BUNDLE+"/"+DATA_FILE_NAME);
BufferedInputStream b=new BufferedInputStream(is, 4096 /* data buffer size */);
readData(b);
b.close();
is.close();
ByteBuffer bytes=ICUBinary.getByteBufferFromInputStream(is);
readData(bytes);
}
private final void readData(InputStream is) throws IOException {
DataInputStream inputStream=new DataInputStream(is);
private final void readData(ByteBuffer bytes) throws IOException {
// read the header
ICUBinary.readHeader(inputStream, FMT, new IsAcceptable());
ICUBinary.readHeader(bytes, FMT, new IsAcceptable());
// read indexes[]
int i, count;
count=inputStream.readInt();
count=bytes.getInt();
if(count<IX_TOP) {
throw new IOException("indexes[0] too small in "+DATA_FILE_NAME);
}
@ -61,25 +56,25 @@ public final class UCaseProps {
indexes[0]=count;
for(i=1; i<count; ++i) {
indexes[i]=inputStream.readInt();
indexes[i]=bytes.getInt();
}
// read the trie
trie=Trie2_16.createFromSerialized(inputStream);
trie=Trie2_16.createFromSerialized(bytes);
int expectedTrieLength=indexes[IX_TRIE_SIZE];
int trieLength=trie.getSerializedLength();
if(trieLength>expectedTrieLength) {
throw new IOException(DATA_FILE_NAME+": not enough bytes for the trie");
}
// skip padding after trie bytes
inputStream.skipBytes(expectedTrieLength-trieLength);
ICUBinary.skipBytes(bytes, expectedTrieLength-trieLength);
// read exceptions[]
count=indexes[IX_EXC_LENGTH];
if(count>0) {
exceptions=new char[count];
for(i=0; i<count; ++i) {
exceptions[i]=inputStream.readChar();
exceptions[i]=bytes.getChar();
}
}
@ -88,7 +83,7 @@ public final class UCaseProps {
if(count>0) {
unfold=new char[count];
for(i=0; i<count; ++i) {
unfold[i]=inputStream.readChar();
unfold[i]=bytes.getChar();
}
}
}
@ -1323,7 +1318,7 @@ public final class UCaseProps {
private static final String DATA_FILE_NAME=DATA_NAME+"."+DATA_TYPE;
/* format "cAsE" */
private static final byte FMT[]={ 0x63, 0x41, 0x53, 0x45 };
private static final int FMT=0x63415345;
/* indexes into indexes[] */
//private static final int IX_INDEX_TOP=0;

View File

@ -1,16 +1,15 @@
/**
*******************************************************************************
* Copyright (C) 1996-2014, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
/*
*******************************************************************************
* Copyright (C) 1996-2014, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
package com.ibm.icu.impl;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.MissingResourceException;
@ -973,11 +972,6 @@ public final class UCharacterProperty
*/
private static final String DATA_FILE_NAME_ = ICUResourceBundle.ICU_BUNDLE+"/uprops.icu";
/**
* Default buffer size of datafile
*/
private static final int DATA_BUFFER_SIZE_ = 25000;
/**
* Shift value for lead surrogate to form a supplementary character.
*/
@ -1191,53 +1185,52 @@ public final class UCharacterProperty
// jar access
InputStream is = ICUData.getRequiredStream(DATA_FILE_NAME_);
BufferedInputStream bis = new BufferedInputStream(is, DATA_BUFFER_SIZE_);
m_unicodeVersion_ = ICUBinary.readHeaderAndDataVersion(bis, DATA_FORMAT, new IsAcceptable());
DataInputStream ds = new DataInputStream(bis);
ByteBuffer bytes=ICUBinary.getByteBufferFromInputStream(is);
m_unicodeVersion_ = ICUBinary.readHeaderAndDataVersion(bytes, DATA_FORMAT, new IsAcceptable());
// Read or skip the 16 indexes.
int propertyOffset = ds.readInt();
/* exceptionOffset = */ ds.readInt();
/* caseOffset = */ ds.readInt();
int additionalOffset = ds.readInt();
int additionalVectorsOffset = ds.readInt();
m_additionalColumnsCount_ = ds.readInt();
int scriptExtensionsOffset = ds.readInt();
int reservedOffset7 = ds.readInt();
/* reservedOffset8 = */ ds.readInt();
/* dataTopOffset = */ ds.readInt();
m_maxBlockScriptValue_ = ds.readInt();
m_maxJTGValue_ = ds.readInt();
ds.skipBytes((16 - 12) << 2);
int propertyOffset = bytes.getInt();
/* exceptionOffset = */ bytes.getInt();
/* caseOffset = */ bytes.getInt();
int additionalOffset = bytes.getInt();
int additionalVectorsOffset = bytes.getInt();
m_additionalColumnsCount_ = bytes.getInt();
int scriptExtensionsOffset = bytes.getInt();
int reservedOffset7 = bytes.getInt();
/* reservedOffset8 = */ bytes.getInt();
/* dataTopOffset = */ bytes.getInt();
m_maxBlockScriptValue_ = bytes.getInt();
m_maxJTGValue_ = bytes.getInt();
ICUBinary.skipBytes(bytes, (16 - 12) << 2);
// read the main properties trie
m_trie_ = Trie2_16.createFromSerialized(ds);
m_trie_ = Trie2_16.createFromSerialized(bytes);
int expectedTrieLength = (propertyOffset - 16) * 4;
int trieLength = m_trie_.getSerializedLength();
if(trieLength > expectedTrieLength) {
throw new IOException("uprops.icu: not enough bytes for main trie");
}
// skip padding after trie bytes
ds.skipBytes(expectedTrieLength - trieLength);
ICUBinary.skipBytes(bytes, expectedTrieLength - trieLength);
// skip unused intervening data structures
ds.skipBytes((additionalOffset - propertyOffset) * 4);
ICUBinary.skipBytes(bytes, (additionalOffset - propertyOffset) * 4);
if(m_additionalColumnsCount_ > 0) {
// reads the additional property block
m_additionalTrie_ = Trie2_16.createFromSerialized(ds);
m_additionalTrie_ = Trie2_16.createFromSerialized(bytes);
expectedTrieLength = (additionalVectorsOffset-additionalOffset)*4;
trieLength = m_additionalTrie_.getSerializedLength();
if(trieLength > expectedTrieLength) {
throw new IOException("uprops.icu: not enough bytes for additional-properties trie");
}
// skip padding after trie bytes
ds.skipBytes(expectedTrieLength - trieLength);
ICUBinary.skipBytes(bytes, expectedTrieLength - trieLength);
// additional properties
int size = scriptExtensionsOffset - additionalVectorsOffset;
m_additionalVectors_ = new int[size];
for (int i = 0; i < size; i ++) {
m_additionalVectors_[i] = ds.readInt();
m_additionalVectors_[i] = bytes.getInt();
}
}
@ -1246,10 +1239,9 @@ public final class UCharacterProperty
if(numChars > 0) {
m_scriptExtensions_ = new char[numChars];
for(int i = 0; i < numChars; ++i) {
m_scriptExtensions_[i] = ds.readChar();
m_scriptExtensions_[i] = bytes.getChar();
}
}
is.close();
}
private static final class IsAcceptable implements ICUBinary.Authenticate {
@ -1258,7 +1250,7 @@ public final class UCharacterProperty
return version[0] == 7;
}
}
private static final byte DATA_FORMAT[] = { 0x55, 0x50, 0x72, 0x6F }; // "UPro"
private static final int DATA_FORMAT = 0x5550726F; // "UPro"
// private methods -------------------------------------------------------

View File

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (c) 2002-2011, International Business Machines
* Copyright (c) 2002-2014, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
* Author: Alan Liu
@ -12,10 +12,9 @@
package com.ibm.icu.impl;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.MissingResourceException;
import com.ibm.icu.lang.UProperty;
@ -74,21 +73,19 @@ public final class UPropertyAliases {
}
}
private static final IsAcceptable IS_ACCEPTABLE=new IsAcceptable();
private static final byte DATA_FORMAT[]={ 0x70, 0x6E, 0x61, 0x6D }; // "pnam"
private static final int DATA_FORMAT=0x706E616D; // "pnam"
private void load(InputStream data) throws IOException {
BufferedInputStream bis=new BufferedInputStream(data);
//dataVersion=ICUBinary.readHeaderAndDataVersion(bis, DATA_FORMAT, IS_ACCEPTABLE);
ICUBinary.readHeader(bis, DATA_FORMAT, IS_ACCEPTABLE);
DataInputStream ds=new DataInputStream(bis);
int indexesLength=ds.readInt()/4; // inIndexes[IX_VALUE_MAPS_OFFSET]/4
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; i<indexesLength; ++i) {
inIndexes[i]=ds.readInt();
inIndexes[i]=bytes.getInt();
}
// Read the valueMaps.
@ -97,7 +94,7 @@ public final class UPropertyAliases {
int numInts=(nextOffset-offset)/4;
valueMaps=new int[numInts];
for(int i=0; i<numInts; ++i) {
valueMaps[i]=ds.readInt();
valueMaps[i]=bytes.getInt();
}
// Read the bytesTries.
@ -105,7 +102,7 @@ public final class UPropertyAliases {
nextOffset=inIndexes[IX_NAME_GROUPS_OFFSET];
int numBytes=nextOffset-offset;
bytesTries=new byte[numBytes];
ds.readFully(bytesTries);
bytes.get(bytesTries);
// Read the nameGroups and turn them from ASCII bytes into a Java String.
offset=nextOffset;
@ -113,15 +110,15 @@ public final class UPropertyAliases {
numBytes=nextOffset-offset;
StringBuilder sb=new StringBuilder(numBytes);
for(int i=0; i<numBytes; ++i) {
sb.append((char)ds.readByte());
sb.append((char)bytes.get());
}
nameGroups=sb.toString();
data.close();
}
private UPropertyAliases() throws IOException {
load(ICUData.getRequiredStream(ICUResourceBundle.ICU_BUNDLE+"/pnames.icu"));
InputStream stream = ICUData.getRequiredStream(ICUResourceBundle.ICU_BUNDLE+"/pnames.icu");
ByteBuffer bytes = ICUBinary.getByteBufferFromInputStream(stream);
load(bytes);
}
private int findProperty(int property) {