1 19 20 package com.ibm.icu.impl; 21 22 import java.io.InputStream ; 23 import java.io.DataInputStream ; 24 import java.io.BufferedInputStream ; 25 import java.io.IOException ; 26 import java.util.MissingResourceException ; 27 28 import com.ibm.icu.util.VersionInfo; 29 import com.ibm.icu.util.RangeValueIterator; 30 31 import com.ibm.icu.text.UnicodeSet; 32 33 import com.ibm.icu.lang.UCharacter; 34 import com.ibm.icu.lang.UProperty; 35 36 public final class UBiDiProps { 37 39 public UBiDiProps() throws IOException { 41 InputStream is=ICUData.getStream(ICUResourceBundle.ICU_BUNDLE+"/"+DATA_FILE_NAME); 42 BufferedInputStream b=new BufferedInputStream (is, 4096 ); 43 readData(b); 44 b.close(); 45 is.close(); 46 47 } 48 49 private void readData(InputStream is) throws IOException { 50 DataInputStream inputStream=new DataInputStream (is); 51 52 unicodeVersion=ICUBinary.readHeader(inputStream, FMT, new IsAcceptable()); 54 55 int i, count; 57 count=inputStream.readInt(); 58 if(count<IX_INDEX_TOP) { 59 throw new IOException ("indexes[0] too small in "+DATA_FILE_NAME); 60 } 61 indexes=new int[count]; 62 63 indexes[0]=count; 64 for(i=1; i<count; ++i) { 65 indexes[i]=inputStream.readInt(); 66 } 67 68 trie=new CharTrie(inputStream, null); 70 71 count=indexes[IX_MIRROR_LENGTH]; 73 if(count>0) { 74 mirrors=new int[count]; 75 for(i=0; i<count; ++i) { 76 mirrors[i]=inputStream.readInt(); 77 } 78 } 79 80 count=indexes[IX_JG_LIMIT]-indexes[IX_JG_START]; 82 jgArray=new byte[count]; 83 for(i=0; i<count; ++i) { 84 jgArray[i]=inputStream.readByte(); 85 } 86 } 87 88 private final class IsAcceptable implements ICUBinary.Authenticate { 90 public boolean isDataVersionAcceptable(byte version[]) { 91 formatVersion=version; 92 return version[0]==1 && 93 version[2]==Trie.INDEX_STAGE_1_SHIFT_ && version[3]==Trie.INDEX_STAGE_2_SHIFT_; 94 } 95 } 96 97 private static UBiDiProps gBdp=null; 99 100 public static final synchronized UBiDiProps getSingleton() throws IOException { 102 if(gBdp==null) { 103 gBdp=new UBiDiProps(); 104 } 105 return gBdp; 106 } 107 108 private static UBiDiProps gBdpDummy=null; 110 111 private UBiDiProps(boolean makeDummy) { formatVersion=new byte[] { 1, 0, Trie.INDEX_STAGE_1_SHIFT_, Trie.INDEX_STAGE_2_SHIFT_ }; 113 unicodeVersion=new byte[] { 2, 0, 0, 0 }; 114 indexes=new int[IX_TOP]; 115 indexes[0]=IX_TOP; 116 trie=new CharTrie(0, 0, null); } 118 119 125 public static final synchronized UBiDiProps getDummy() { 126 if(gBdpDummy==null) { 127 gBdpDummy=new UBiDiProps(true); 128 } 129 return gBdpDummy; 130 } 131 132 134 public final void addPropertyStarts(UnicodeSet set) { 135 int i, length; 136 int c, start, limit; 137 138 byte prev, jg; 139 140 141 TrieIterator iter=new TrieIterator(trie); 142 RangeValueIterator.Element element=new RangeValueIterator.Element(); 143 144 while(iter.next(element)){ 145 set.add(element.start); 146 } 147 148 149 length=indexes[IX_MIRROR_LENGTH]; 150 for(i=0; i<length; ++i) { 151 c=getMirrorCodePoint(mirrors[i]); 152 set.add(c, c+1); 153 } 154 155 156 start=indexes[IX_JG_START]; 157 limit=indexes[IX_JG_LIMIT]; 158 length=limit-start; 159 prev=0; 160 for(i=0; i<length; ++i) { 161 jg=jgArray[i]; 162 if(jg!=prev) { 163 set.add(start); 164 prev=jg; 165 } 166 ++start; 167 } 168 if(prev!=0) { 169 170 set.add(limit); 171 } 172 173 174 175 176 } 177 178 180 public final int getMaxValue(int which) { 181 int max; 182 183 max=indexes[IX_MAX_VALUES]; 184 switch(which) { 185 case UProperty.BIDI_CLASS: 186 return (max&CLASS_MASK); 187 case UProperty.JOINING_GROUP: 188 return (max&MAX_JG_MASK)>>MAX_JG_SHIFT; 189 case UProperty.JOINING_TYPE: 190 return (max&JT_MASK)>>JT_SHIFT; 191 default: 192 return -1; 193 } 194 } 195 196 public final int getClass(int c) { 197 return getClassFromProps(trie.getCodePointValue(c)); 198 } 199 200 public final boolean isMirrored(int c) { 201 return getFlagFromProps(trie.getCodePointValue(c), IS_MIRRORED_SHIFT); 202 } 203 204 public final int getMirror(int c) { 205 int props; 206 int delta; 207 208 props=trie.getCodePointValue(c); 209 delta=((short)props)>>MIRROR_DELTA_SHIFT; 210 if(delta!=ESC_MIRROR_DELTA) { 211 return c+delta; 212 } else { 213 214 int m; 215 int i, length; 216 int c2; 217 218 length=indexes[IX_MIRROR_LENGTH]; 219 220 221 for(i=0; i<length; ++i) { 222 m=mirrors[i]; 223 c2=getMirrorCodePoint(m); 224 if(c==c2) { 225 226 return getMirrorCodePoint(mirrors[getMirrorIndex(m)]); 227 } else if(c<c2) { 228 break; 229 } 230 } 231 232 233 return c; 234 } 235 } 236 237 public final boolean isBidiControl(int c) { 238 return getFlagFromProps(trie.getCodePointValue(c), BIDI_CONTROL_SHIFT); 239 } 240 241 public final boolean isJoinControl(int c) { 242 return getFlagFromProps(trie.getCodePointValue(c), JOIN_CONTROL_SHIFT); 243 } 244 245 public final int getJoiningType(int c) { 246 return (trie.getCodePointValue(c)&JT_MASK)>>JT_SHIFT; 247 } 248 249 public final int getJoiningGroup(int c) { 250 int start, limit; 251 252 start=indexes[IX_JG_START]; 253 limit=indexes[IX_JG_LIMIT]; 254 if(start<=c && c<limit) { 255 return (int)jgArray[c-start]&0xff; 256 } else { 257 return UCharacter.JoiningGroup.NO_JOINING_GROUP; 258 } 259 } 260 261 private int indexes[]; 263 private int mirrors[]; 264 private byte jgArray[]; 265 266 private CharTrie trie; 267 private byte formatVersion[]; 268 private byte unicodeVersion[]; 269 270 private static final String DATA_NAME="ubidi"; 272 private static final String DATA_TYPE="icu"; 273 private static final String DATA_FILE_NAME=DATA_NAME+"."+DATA_TYPE; 274 275 276 private static final byte FMT[]={ 0x42, 0x69, 0x44, 0x69 }; 277 278 279 private static final int IX_INDEX_TOP=0; 280 private static final int IX_LENGTH=1; 281 private static final int IX_TRIE_SIZE=2; 282 private static final int IX_MIRROR_LENGTH=3; 283 284 private static final int IX_JG_START=4; 285 private static final int IX_JG_LIMIT=5; 286 287 private static final int IX_MAX_VALUES=15; 288 private static final int IX_TOP=16; 289 290 292 293 private static final int JT_SHIFT=5; 294 295 296 297 private static final int JOIN_CONTROL_SHIFT=10; 298 private static final int BIDI_CONTROL_SHIFT=11; 299 300 private static final int IS_MIRRORED_SHIFT=12; 301 private static final int MIRROR_DELTA_SHIFT=13; 302 303 private static final int MAX_JG_SHIFT=16; 304 305 private static final int CLASS_MASK= 0x0000001f; 306 private static final int JT_MASK= 0x000000e0; 307 308 private static final int MAX_JG_MASK= 0x00ff0000; 309 310 private static final int getClassFromProps(int props) { 311 return props&CLASS_MASK; 312 } 313 private static final boolean getFlagFromProps(int props, int shift) { 314 return ((props>>shift)&1)!=0; 315 } 316 317 private static final int ESC_MIRROR_DELTA=-4; 318 private static final int MIN_MIRROR_DELTA=-3; 319 private static final int MAX_MIRROR_DELTA=3; 320 321 323 324 private static final int MIRROR_INDEX_SHIFT=21; 325 private static final int MAX_MIRROR_INDEX=0x7ff; 326 327 private static final int getMirrorCodePoint(int m) { 328 return m&0x1fffff; 329 } 330 private static final int getMirrorIndex(int m) { 331 return m>>>MIRROR_INDEX_SHIFT; 332 } 333 } 334 | Popular Tags |