|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
/* |
|
******************************************************************************* |
|
* |
|
* 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 sun.text.normalizer; |
|
|
|
import java.io.IOException; |
|
import java.nio.ByteBuffer; |
|
import java.util.MissingResourceException; |
|
|
|
public final class UBiDiProps { |
|
// constructors etc. --------------------------------------------------- *** |
|
|
|
|
|
private UBiDiProps() throws IOException{ |
|
ByteBuffer bytes=ICUBinary.getRequiredData(DATA_FILE_NAME); |
|
readData(bytes); |
|
} |
|
|
|
private void readData(ByteBuffer bytes) throws IOException { |
|
|
|
ICUBinary.readHeader(bytes, FMT, new IsAcceptable()); |
|
|
|
|
|
int i, count; |
|
count=bytes.getInt(); |
|
if(count<IX_TOP) { |
|
throw new IOException("indexes[0] too small in "+DATA_FILE_NAME); |
|
} |
|
indexes=new int[count]; |
|
|
|
indexes[0]=count; |
|
for(i=1; i<count; ++i) { |
|
indexes[i]=bytes.getInt(); |
|
} |
|
|
|
|
|
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"); |
|
} |
|
|
|
ICUBinary.skipBytes(bytes, expectedTrieLength-trieLength); |
|
|
|
|
|
count=indexes[IX_MIRROR_LENGTH]; |
|
if(count>0) { |
|
mirrors=new int[count]; |
|
for(i=0; i<count; ++i) { |
|
mirrors[i]=bytes.getInt(); |
|
} |
|
} |
|
|
|
|
|
count=indexes[IX_JG_LIMIT]-indexes[IX_JG_START]; |
|
jgArray=new byte[count]; |
|
for(i=0; i<count; ++i) { |
|
jgArray[i]=bytes.get(); |
|
} |
|
|
|
|
|
count=indexes[IX_JG_LIMIT2]-indexes[IX_JG_START2]; |
|
jgArray2=new byte[count]; |
|
for(i=0; i<count; ++i) { |
|
jgArray2[i]=bytes.get(); |
|
} |
|
} |
|
|
|
|
|
private static final class IsAcceptable implements ICUBinary.Authenticate { |
|
public boolean isDataVersionAcceptable(byte version[]) { |
|
return version[0]==2; |
|
} |
|
} |
|
|
|
// property access functions ------------------------------------------- *** |
|
|
|
public final int getClass(int c) { |
|
return getClassFromProps(trie.get(c)); |
|
} |
|
|
|
private final int getMirror(int c, int props) { |
|
int delta=getMirrorDeltaFromProps(props); |
|
if(delta!=ESC_MIRROR_DELTA) { |
|
return c+delta; |
|
} else { |
|
|
|
int m; |
|
int i, length; |
|
int c2; |
|
|
|
length=indexes[IX_MIRROR_LENGTH]; |
|
|
|
|
|
for(i=0; i<length; ++i) { |
|
m=mirrors[i]; |
|
c2=getMirrorCodePoint(m); |
|
if(c==c2) { |
|
|
|
return getMirrorCodePoint(mirrors[getMirrorIndex(m)]); |
|
} else if(c<c2) { |
|
break; |
|
} |
|
} |
|
|
|
|
|
return c; |
|
} |
|
} |
|
|
|
public final int getMirror(int c) { |
|
int props=trie.get(c); |
|
return getMirror(c, props); |
|
} |
|
|
|
public final int getJoiningType(int c) { |
|
return (trie.get(c)&JT_MASK)>>JT_SHIFT; |
|
} |
|
|
|
public final int getJoiningGroup(int c) { |
|
int start, limit; |
|
|
|
start=indexes[IX_JG_START]; |
|
limit=indexes[IX_JG_LIMIT]; |
|
if(start<=c && c<limit) { |
|
return (int)jgArray[c-start]&0xff; |
|
} |
|
start=indexes[IX_JG_START2]; |
|
limit=indexes[IX_JG_LIMIT2]; |
|
if(start<=c && c<limit) { |
|
return (int)jgArray2[c-start]&0xff; |
|
} |
|
return UCharacter.JoiningGroup.NO_JOINING_GROUP; |
|
} |
|
|
|
public final int getPairedBracketType(int c) { |
|
return (trie.get(c)&BPT_MASK)>>BPT_SHIFT; |
|
} |
|
|
|
public final int getPairedBracket(int c) { |
|
int props=trie.get(c); |
|
if((props&BPT_MASK)==0) { |
|
return c; |
|
} else { |
|
return getMirror(c, props); |
|
} |
|
} |
|
|
|
|
|
private int indexes[]; |
|
private int mirrors[]; |
|
private byte jgArray[]; |
|
private byte jgArray2[]; |
|
|
|
private Trie2_16 trie; |
|
|
|
|
|
private static final String DATA_FILE_NAME = "/sun/text/resources/ubidi.icu"; |
|
|
|
|
|
private static final int FMT=0x42694469; |
|
|
|
|
|
private static final int IX_TRIE_SIZE=2; |
|
private static final int IX_MIRROR_LENGTH=3; |
|
|
|
private static final int IX_JG_START=4; |
|
private static final int IX_JG_LIMIT=5; |
|
private static final int IX_JG_START2=6; |
|
private static final int IX_JG_LIMIT2=7; |
|
|
|
private static final int IX_TOP=16; |
|
|
|
// definitions for 16-bit bidi/shaping properties word ----------------- *** |
|
|
|
/* CLASS_SHIFT=0, */ |
|
private static final int JT_SHIFT=5; /* joining type: 3 bits (7..5) */ |
|
|
|
private static final int BPT_SHIFT=8; /* Bidi_Paired_Bracket_Type(bpt): 2 bits (9..8) */ |
|
|
|
private static final int MIRROR_DELTA_SHIFT=13; /* bidi mirroring delta: 3 bits (15..13) */ |
|
|
|
private static final int CLASS_MASK= 0x0000001f; |
|
private static final int JT_MASK= 0x000000e0; |
|
private static final int BPT_MASK= 0x00000300; |
|
|
|
private static final int getClassFromProps(int props) { |
|
return props&CLASS_MASK; |
|
} |
|
private static final boolean getFlagFromProps(int props, int shift) { |
|
return ((props>>shift)&1)!=0; |
|
} |
|
private static final int getMirrorDeltaFromProps(int props) { |
|
return (short)props>>MIRROR_DELTA_SHIFT; |
|
} |
|
|
|
private static final int ESC_MIRROR_DELTA=-4; |
|
|
|
// definitions for 32-bit mirror table entry --------------------------- *** |
|
|
|
|
|
private static final int MIRROR_INDEX_SHIFT=21; |
|
|
|
private static final int getMirrorCodePoint(int m) { |
|
return m&0x1fffff; |
|
} |
|
private static final int getMirrorIndex(int m) { |
|
return m>>>MIRROR_INDEX_SHIFT; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public static final UBiDiProps INSTANCE; |
|
|
|
// This static initializer block must be placed after |
|
|
|
static { |
|
try { |
|
INSTANCE = new UBiDiProps(); |
|
} catch (IOException e) { |
|
throw new MissingResourceException(e.getMessage(),DATA_FILE_NAME,""); |
|
} |
|
} |
|
} |