]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/classes/core/src/com/ibm/icu/impl/USerializedSet.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / classes / core / src / com / ibm / icu / impl / USerializedSet.java
1 /*\r
2  *******************************************************************************\r
3  *   Copyright (C) 2002-2010, International Business Machines\r
4  *   Corporation and others.  All Rights Reserved.\r
5  *******************************************************************************\r
6 */\r
7 \r
8 package com.ibm.icu.impl;\r
9 /**\r
10  * @version     1.1\r
11  * @author     Markus W. Scherer\r
12  * Ram: Add documentation, remove unwanted methods, improve coverage.\r
13  */\r
14 \r
15 /**\r
16  * Simple class for handling serialized USet/UnicodeSet structures\r
17  * without object creation. See ICU4C icu/source/common/uset.c.\r
18  *\r
19  * @internal\r
20  */\r
21 public final class USerializedSet {\r
22     /**\r
23      * Fill in the given serialized set object.\r
24      * @param src pointer to start of array\r
25      * @param srcStart pointer to start of serialized data (length value)\r
26      * @return true if the given array is valid, otherwise false\r
27      */\r
28     public final boolean getSet(char src[], int srcStart) {\r
29         // leave most argument checking up to Java exceptions\r
30         array=null;\r
31         arrayOffset=bmpLength=length=0;\r
32 \r
33         length=src[srcStart++];\r
34         \r
35         \r
36         if((length&0x8000) >0) {\r
37             /* there are supplementary values */\r
38             length&=0x7fff;\r
39             if(src.length<(srcStart+1+length)) {\r
40                 length=0;\r
41                 throw new IndexOutOfBoundsException();\r
42             }\r
43             bmpLength=src[srcStart++];\r
44         } else {\r
45             /* only BMP values */\r
46             if(src.length<(srcStart+length)) {\r
47                 length=0;\r
48                 throw new IndexOutOfBoundsException();\r
49             }\r
50             bmpLength=length;\r
51         }\r
52         array = new char[length];\r
53         System.arraycopy(src,srcStart,array,0,length);\r
54         //arrayOffset=srcStart;\r
55         return true;\r
56     }\r
57     \r
58     /**\r
59      * Set the USerializedSet to contain the given character (and nothing\r
60      * else).\r
61      */\r
62     public final void setToOne(int c) {\r
63         if( 0x10ffff<c) {\r
64             return;\r
65         }\r
66 \r
67         if(c<0xffff) {\r
68             bmpLength=length=2;\r
69             array[0]=(char)c;\r
70             array[1]=(char)(c+1);\r
71         } else if(c==0xffff) {\r
72             bmpLength=1;\r
73             length=3;\r
74             array[0]=0xffff;\r
75             array[1]=1;\r
76             array[2]=0;\r
77         } else if(c<0x10ffff) {\r
78             bmpLength=0;\r
79             length=4;\r
80             array[0]=(char)(c>>16);\r
81             array[1]=(char)c;\r
82             ++c;\r
83             array[2]=(char)(c>>16);\r
84             array[3]=(char)c;\r
85         } else /* c==0x10ffff */ {\r
86             bmpLength=0;\r
87             length=2;\r
88             array[0]=0x10;\r
89             array[1]=0xffff;\r
90         }\r
91     }\r
92         \r
93     /**\r
94      * Returns a range of characters contained in the given serialized\r
95      * set.\r
96      * @param rangeIndex a non-negative integer in the range <code>0..\r
97      * getSerializedRangeCount()-1</code>\r
98      * @param range variable to receive the data in the range\r
99      * @return true if rangeIndex is valid, otherwise false\r
100      */\r
101     public final boolean getRange(int rangeIndex, int[] range) {\r
102         if( rangeIndex<0) {\r
103             return false;\r
104         }\r
105         if(array==null){\r
106             array = new char[8];\r
107         }\r
108         if(range==null || range.length <2){\r
109             throw new IllegalArgumentException();\r
110         }\r
111         rangeIndex*=2; /* address start/limit pairs */\r
112         if(rangeIndex<bmpLength) {\r
113             range[0]=array[rangeIndex++];\r
114             if(rangeIndex<bmpLength) {\r
115                 range[1]=array[rangeIndex]-1;\r
116             } else if(rangeIndex<length) {\r
117                 range[1]=((((int)array[rangeIndex])<<16)|array[rangeIndex+1])-1;\r
118             } else {\r
119                 range[1]=0x10ffff;\r
120             }\r
121             return true;\r
122         } else {\r
123             rangeIndex-=bmpLength;\r
124             rangeIndex*=2; /* address pairs of pairs of units */\r
125             int suppLength=length-bmpLength;\r
126             if(rangeIndex<suppLength) {\r
127                 int offset=arrayOffset+bmpLength;\r
128                 range[0]=(((int)array[offset+rangeIndex])<<16)|array[offset+rangeIndex+1];\r
129                 rangeIndex+=2;\r
130                 if(rangeIndex<suppLength) {\r
131                     range[1]=((((int)array[offset+rangeIndex])<<16)|array[offset+rangeIndex+1])-1;\r
132                 } else {\r
133                     range[1]=0x10ffff;\r
134                 }\r
135                 return true;\r
136             } else {\r
137                 return false;\r
138             }\r
139         }\r
140     }\r
141     \r
142     /**\r
143      * Returns true if the given USerializedSet contains the given\r
144      * character.\r
145      * @param c the character to test for\r
146      * @return true if set contains c\r
147      */\r
148     public final boolean contains(int c) {\r
149         \r
150         if(c>0x10ffff) {\r
151             return false;\r
152         }\r
153             \r
154         if(c<=0xffff) {\r
155             int i;\r
156             /* find c in the BMP part */\r
157             for(i=0; i<bmpLength && (char)c>=array[i]; ++i) {}\r
158             return ((i&1) != 0);\r
159         } else {\r
160             int i;\r
161             /* find c in the supplementary part */\r
162             char high=(char)(c>>16), low=(char)c;\r
163             for(i=bmpLength;\r
164                 i<length && (high>array[i] || (high==array[i] && low>=array[i+1]));\r
165                 i+=2) {}\r
166         \r
167             /* count pairs of 16-bit units even per BMP and check if the number of pairs is odd */\r
168             return (((i+bmpLength)&2)!=0);\r
169         }\r
170     }\r
171 \r
172     /**\r
173      * Returns the number of disjoint ranges of characters contained in\r
174      * the given serialized set.  Ignores any strings contained in the\r
175      * set.\r
176      * @return a non-negative integer counting the character ranges\r
177      * contained in set\r
178      */\r
179     public final int countRanges() {\r
180         return (bmpLength+(length-bmpLength)/2+1)/2;\r
181     }\r
182     \r
183     private char array[] = new char[8];\r
184     private int arrayOffset, bmpLength, length;\r
185 }\r