KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ibm > icu > impl > UBiDiProps


1 /*
2 *******************************************************************************
3 *
4 * Copyright (C) 2004-2005, International Business Machines
5 * Corporation and others. All Rights Reserved.
6 *
7 *******************************************************************************
8 * file name: UBiDiProps.java
9 * encoding: US-ASCII
10 * tab size: 8 (not used)
11 * indentation:4
12 *
13 * created on: 2005jan16
14 * created by: Markus W. Scherer
15 *
16 * Low-level Unicode bidi/shaping properties access.
17 * Java port of ubidi_props.h/.c.
18 */

19
20 package com.ibm.icu.impl;
21
22 import java.io.InputStream JavaDoc;
23 import java.io.DataInputStream JavaDoc;
24 import java.io.BufferedInputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.util.MissingResourceException JavaDoc;
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     // constructors etc. --------------------------------------------------- ***
38

39     // port of ubidi_openProps()
40
public UBiDiProps() throws IOException JavaDoc{
41         InputStream JavaDoc is=ICUData.getStream(ICUResourceBundle.ICU_BUNDLE+"/"+DATA_FILE_NAME);
42         BufferedInputStream JavaDoc b=new BufferedInputStream JavaDoc(is, 4096 /* data buffer size */);
43         readData(b);
44         b.close();
45         is.close();
46
47     }
48
49     private void readData(InputStream JavaDoc is) throws IOException JavaDoc {
50         DataInputStream JavaDoc inputStream=new DataInputStream JavaDoc(is);
51
52         // read the header
53
unicodeVersion=ICUBinary.readHeader(inputStream, FMT, new IsAcceptable());
54
55         // read indexes[]
56
int i, count;
57         count=inputStream.readInt();
58         if(count<IX_INDEX_TOP) {
59             throw new IOException JavaDoc("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         // read the trie
69
trie=new CharTrie(inputStream, null);
70
71         // read mirrors[]
72
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         // read jgArray[]
81
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     // implement ICUBinary.Authenticate
89
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     // UBiDiProps singleton
98
private static UBiDiProps gBdp=null;
99
100     // port of ubidi_getSingleton()
101
public static final synchronized UBiDiProps getSingleton() throws IOException JavaDoc {
102         if(gBdp==null) {
103             gBdp=new UBiDiProps();
104         }
105         return gBdp;
106     }
107
108     // UBiDiProps dummy singleton
109
private static UBiDiProps gBdpDummy=null;
110
111     private UBiDiProps(boolean makeDummy) { // ignore makeDummy, only creates a unique signature
112
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); // dummy trie, always returns 0
117
}
118
119     /**
120      * Get a singleton dummy object, one that works with no real data.
121      * This can be used when the real data is not available.
122      * Using the dummy can reduce checks for available data after an initial failure.
123      * Port of ucase_getDummy().
124      */

125     public static final synchronized UBiDiProps getDummy() {
126         if(gBdpDummy==null) {
127             gBdpDummy=new UBiDiProps(true);
128         }
129         return gBdpDummy;
130     }
131
132     // set of property starts for UnicodeSet ------------------------------- ***
133

134     public final void addPropertyStarts(UnicodeSet set) {
135         int i, length;
136         int c, start, limit;
137
138         byte prev, jg;
139
140         /* add the start code point of each same-value range of the trie */
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         /* add the code points from the bidi mirroring table */
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         /* add the code points from the Joining_Group array where the value changes */
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             /* add the limit code point if the last value was not 0 (it is now start==limit) */
170             set.add(limit);
171         }
172
173         /* add code points with hardcoded properties, plus the ones following them */
174
175         /* (none right now) */
176     }
177
178     // property access functions ------------------------------------------- ***
179

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; /* undefined */
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             /* look for mirror code point in the mirrors[] table */
214             int m;
215             int i, length;
216             int c2;
217
218             length=indexes[IX_MIRROR_LENGTH];
219
220             /* linear search */
221             for(i=0; i<length; ++i) {
222                 m=mirrors[i];
223                 c2=getMirrorCodePoint(m);
224                 if(c==c2) {
225                     /* found c, return its mirror code point using the index in m */
226                     return getMirrorCodePoint(mirrors[getMirrorIndex(m)]);
227                 } else if(c<c2) {
228                     break;
229                 }
230             }
231
232             /* c not found, return it itself */
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     // data members -------------------------------------------------------- ***
262
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     // data format constants ----------------------------------------------- ***
271
private static final String JavaDoc DATA_NAME="ubidi";
272     private static final String JavaDoc DATA_TYPE="icu";
273     private static final String JavaDoc DATA_FILE_NAME=DATA_NAME+"."+DATA_TYPE;
274
275     /* format "BiDi" */
276     private static final byte FMT[]={ 0x42, 0x69, 0x44, 0x69 };
277
278     /* indexes into indexes[] */
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     // definitions for 16-bit bidi/shaping properties word ----------------- ***
291

292                           /* CLASS_SHIFT=0, */ /* bidi class: 5 bits (4..0) */
293     private static final int JT_SHIFT=5; /* joining type: 3 bits (7..5) */
294
295     /* private static final int _SHIFT=8, reserved: 2 bits (9..8) */
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; /* 'is mirrored' */
301     private static final int MIRROR_DELTA_SHIFT=13; /* bidi mirroring delta: 3 bits (15..13) */
302
303     private static final int MAX_JG_SHIFT=16; /* max JG value in indexes[MAX_VALUES_INDEX] bits 23..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     // definitions for 32-bit mirror table entry --------------------------- ***
322

323     /* the source Unicode code point takes 21 bits (20..0) */
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