3 *******************************************************************************
\r
4 * Copyright (C) 2004-2009, International Business Machines Corporation and *
\r
5 * others. All Rights Reserved. *
\r
6 *******************************************************************************
\r
8 package com.ibm.icu.impl;
\r
10 import java.util.HashMap;
\r
11 import java.util.MissingResourceException;
\r
13 import com.ibm.icu.util.ULocale;
\r
14 import com.ibm.icu.util.UResourceBundle;
\r
15 import com.ibm.icu.util.UResourceBundleIterator;
\r
16 import com.ibm.icu.util.UResourceTypeMismatchException;
\r
18 //#if defined(FOUNDATION10) || defined(J2SE13) || defined(ECLIPSE_FRAGMENT)
\r
20 import java.nio.ByteBuffer;
\r
23 class ICUResourceBundleImpl {
\r
25 static final class ResourceArray extends ICUResourceBundle {
\r
26 protected String[] handleGetStringArray() {
\r
27 String[] strings = new String[size];
\r
28 UResourceBundleIterator iter = getIterator();
\r
30 while (iter.hasNext()) {
\r
31 strings[i++] = iter.next().getString();
\r
38 public String[] getStringArray() {
\r
39 return handleGetStringArray();
\r
42 protected UResourceBundle handleGetImpl(String indexStr, HashMap table, UResourceBundle requested,
\r
43 int[] index, boolean[] isAlias) {
\r
44 index[0] = getIndex(indexStr);
\r
45 if (index[0] > -1) {
\r
46 return handleGetImpl(index[0], table, requested, isAlias);
\r
48 throw new UResourceTypeMismatchException("Could not get the correct value for index: "+ index);
\r
51 protected UResourceBundle handleGetImpl(int index, HashMap table, UResourceBundle requested,
\r
52 boolean[] isAlias) {
\r
54 throw new IndexOutOfBoundsException();
\r
56 int offset = RES_GET_OFFSET(resource);
\r
57 int itemOffset = offset + getIntOffset(index + 1);
\r
58 long itemResource = (UNSIGNED_INT_MASK) & ICUResourceBundle.getInt(rawData,itemOffset);
\r
59 String path = (isTopLevel == true) ? Integer.toString(index) : resPath + "/" + index;
\r
61 return createBundleObject(Integer.toString(index), itemResource, path, table, requested, this, isAlias);
\r
63 private int countItems() {
\r
64 int offset = RES_GET_OFFSET(resource);
\r
65 int value = getInt(rawData,offset);
\r
68 ResourceArray(String key, String resPath, long resource, ICUResourceBundle bundle) {
\r
69 assign(this, bundle);
\r
70 this.resource = resource;
\r
72 this.size = countItems();
\r
73 this.resPath = resPath;
\r
74 createLookupCache(); // Use bundle cache to access array entries
\r
77 static final class ResourceBinary extends ICUResourceBundle {
\r
78 private byte[] value;
\r
79 public ByteBuffer getBinary() {
\r
80 return ByteBuffer.wrap(value);
\r
82 public byte [] getBinary(byte []ba) {
\r
85 private byte[] getValue() {
\r
86 int offset = RES_GET_OFFSET(resource);
\r
87 int length = ICUResourceBundle.getInt(rawData,offset);
\r
88 int byteOffset = offset + getIntOffset(1);
\r
89 byte[] dst = new byte[length];
\r
90 //if (ASSERT) Assert.assrt("byteOffset+length < rawData.length", byteOffset+length < rawData.length);
\r
91 System.arraycopy(rawData, byteOffset, dst, 0, length);
\r
94 ResourceBinary(String key, String resPath, long resource, ICUResourceBundle bundle) {
\r
95 assign(this, bundle);
\r
96 this.resource = resource;
\r
98 this.resPath = resPath;
\r
103 static final class ResourceInt extends ICUResourceBundle {
\r
104 public int getInt() {
\r
105 return RES_GET_INT(resource);
\r
107 public int getUInt() {
\r
108 long ret = RES_GET_UINT(resource);
\r
111 ResourceInt(String key, String resPath, long resource, ICUResourceBundle bundle) {
\r
112 assign(this, bundle);
\r
114 this.resource = resource;
\r
115 this.resPath = resPath;
\r
119 static final class ResourceString extends ICUResourceBundle {
\r
120 private String value;
\r
121 public String getString() {
\r
124 ResourceString(String key, String resPath, long resource, ICUResourceBundle bundle) {
\r
125 assign(this, bundle);
\r
126 value = getStringValue(resource);
\r
128 this.resource = resource;
\r
129 this.resPath = resPath;
\r
133 static final class ResourceIntVector extends ICUResourceBundle {
\r
134 private int[] value;
\r
135 public int[] getIntVector() {
\r
138 private int[] getValue() {
\r
139 int offset = RES_GET_OFFSET(resource);
\r
140 int length = ICUResourceBundle.getInt(rawData,offset);
\r
141 int intOffset = offset + getIntOffset(1);
\r
142 int[] val = new int[length];
\r
143 //int byteLength = getIntOffset(length);
\r
145 //if (ASSERT) Assert.assrt("(intOffset+byteLength)<rawData.length", (intOffset+byteLength)<rawData.length);
\r
147 for(int i=0; i<length;i++){
\r
148 val[i]=ICUResourceBundle.getInt(rawData, intOffset+getIntOffset(i));
\r
152 ResourceIntVector(String key, String resPath, long resource, ICUResourceBundle bundle) {
\r
153 assign(this, bundle);
\r
155 this.resource = resource;
\r
157 this.resPath = resPath;
\r
158 value = getValue();
\r
162 static final class ResourceTable extends ICUResourceBundle {
\r
164 protected UResourceBundle handleGetImpl(String resKey, HashMap table, UResourceBundle requested,
\r
165 int[] index, boolean[] isAlias) {
\r
169 int offset = RES_GET_OFFSET(resource);
\r
170 // offset+0 contains number of entries
\r
171 // offset+1 contains the keyOffset
\r
172 int currentOffset = (offset) + getCharOffset(1);
\r
173 //int keyOffset = rawData.getChar(currentOffset);
\r
174 /* do a binary search for the key */
\r
175 index[0] = findKey(size, currentOffset, this, resKey);
\r
176 if (index[0] == -1) {
\r
177 //throw new MissingResourceException(ICUResourceBundleReader.getFullName(baseName, localeID),
\r
182 currentOffset += getCharOffset(size + (~size & 1))
\r
183 + getIntOffset(index[0]);
\r
184 long resOffset = (UNSIGNED_INT_MASK) & ICUResourceBundle.getInt(rawData, currentOffset);
\r
185 String path = (isTopLevel == true) ? resKey : resPath + "/" + resKey;
\r
187 return createBundleObject(resKey, resOffset, path, table, requested, this, isAlias);
\r
190 public int getOffset(int currentOffset, int index) {
\r
191 return getChar(rawData, currentOffset + getCharOffset(index));
\r
193 protected UResourceBundle handleGetImpl(int index, HashMap table, UResourceBundle requested,
\r
194 boolean[] isAlias) {
\r
195 if (index > size) {
\r
196 throw new IndexOutOfBoundsException();
\r
198 int offset = RES_GET_OFFSET(resource);
\r
199 // offset+0 contains number of entries
\r
200 // offset+1 contains the keyOffset
\r
201 int currentOffset = (offset) + getCharOffset(1);
\r
202 int betterOffset = getOffset(currentOffset, index);
\r
203 String itemKey = RES_GET_KEY(rawData, betterOffset).toString();
\r
204 currentOffset += getCharOffset(size + (~size & 1))
\r
205 + getIntOffset(index);
\r
206 long resOffset = (UNSIGNED_INT_MASK) & ICUResourceBundle.getInt(rawData,currentOffset);
\r
207 String path = (isTopLevel == true) ? itemKey : resPath + "/" + itemKey;
\r
209 return createBundleObject(itemKey, resOffset, path, table, requested, this, isAlias);
\r
211 private int countItems() {
\r
212 int offset = RES_GET_OFFSET(resource);
\r
213 int value = getChar(rawData,offset);
\r
216 ResourceTable(String key, String resPath, long resource, ICUResourceBundle bundle) {
\r
217 this(key, resPath, resource, bundle, false);
\r
219 ResourceTable(ICUResourceBundleReader reader, String baseName, String localeID, ClassLoader loader) {
\r
221 this.rawData = reader.getData();
\r
222 this.rootResource = (UNSIGNED_INT_MASK) & reader.getRootResource();
\r
223 this.noFallback = reader.getNoFallback();
\r
224 this.baseName = baseName;
\r
225 this.localeID = localeID;
\r
226 this.ulocale = new ULocale(localeID);
\r
227 this.loader = loader;
\r
228 initialize(null, "", rootResource, null, isTopLevel);
\r
230 void initialize(String resKey, String resourcePath, long resOffset,
\r
231 ICUResourceBundle bundle, boolean topLevel){
\r
233 assign(this, bundle);
\r
236 resource = resOffset;
\r
237 isTopLevel = topLevel;
\r
238 size = countItems();
\r
239 resPath = resourcePath;
\r
240 createLookupCache(); // Use bundle cache to access nested resources
\r
242 ResourceTable(String key, String resPath, long resource,
\r
243 ICUResourceBundle bundle, boolean isTopLevel) {
\r
244 initialize(key, resPath, resource, bundle, isTopLevel);
\r
247 static final class ResourceTable32 extends ICUResourceBundle{
\r
249 protected UResourceBundle handleGetImpl(String resKey, HashMap table, UResourceBundle requested,
\r
250 int[] index, boolean[] isAlias) {
\r
251 int offset = RES_GET_OFFSET(resource);
\r
252 // offset+0 contains number of entries
\r
253 // offset+1 contains the keyOffset
\r
254 int currentOffset = (offset) + getIntOffset(1);
\r
255 //int keyOffset = rawData.getChar(currentOffset);
\r
256 /* do a binary search for the key */
\r
257 index[0] = findKey(size, currentOffset, this, resKey);
\r
258 if (index[0] == -1) {
\r
259 throw new MissingResourceException(
\r
260 "Could not find resource ",
\r
261 ICUResourceBundleReader.getFullName(baseName, localeID),
\r
264 currentOffset += getIntOffset(size) + getIntOffset(index[0]);
\r
265 long resOffset = (UNSIGNED_INT_MASK) & ICUResourceBundle.getInt(rawData,currentOffset);
\r
266 String path = (isTopLevel == true) ? resKey : resPath + "/" + resKey;
\r
268 return createBundleObject(resKey, resOffset, path, table, requested, this, isAlias);
\r
271 public int getOffset(int currentOffset, int index) {
\r
272 return ICUResourceBundle.getInt(rawData, currentOffset + getIntOffset(index));
\r
274 protected UResourceBundle handleGetImpl(int index, HashMap table, UResourceBundle requested,
\r
275 boolean[] isAlias) {
\r
279 if (index > size) {
\r
280 throw new IndexOutOfBoundsException();
\r
282 int offset = RES_GET_OFFSET(resource);
\r
283 // offset+0 contains number of entries
\r
284 // offset+1 contains the keyOffset
\r
285 int currentOffset = (offset) + getIntOffset(1)
\r
286 + getIntOffset(index);
\r
287 int betterOffset = getOffset(currentOffset, 0);
\r
288 String itemKey = RES_GET_KEY(rawData, betterOffset).toString();
\r
289 currentOffset += getIntOffset(size);
\r
290 long resOffset = (UNSIGNED_INT_MASK) & ICUResourceBundle.getInt(rawData,currentOffset);
\r
291 String path = (isTopLevel == true) ? Integer.toString(index) : resPath + "/" + index;
\r
293 return createBundleObject(itemKey, resOffset, path, table, requested, this, isAlias);
\r
295 private int countItems() {
\r
296 int offset = RES_GET_OFFSET(resource);
\r
297 int value = ICUResourceBundle.getInt(rawData, offset);
\r
300 ResourceTable32(String key, String resPath, long resource, ICUResourceBundle bundle) {
\r
301 this(key, resPath, resource, bundle, false);
\r
303 ResourceTable32(ICUResourceBundleReader reader, String baseName, String localeID, ClassLoader loader) {
\r
305 this.rawData = reader.getData();
\r
306 this.rootResource = (UNSIGNED_INT_MASK) & reader.getRootResource();
\r
307 this.noFallback = reader.getNoFallback();
\r
308 this.baseName = baseName;
\r
309 this.localeID = localeID;
\r
310 this.ulocale = new ULocale(localeID);
\r
311 this.loader = loader;
\r
312 initialize(null, "", rootResource, null, isTopLevel);
\r
314 void initialize(String resKey, String resourcePath, long resOffset,
\r
315 ICUResourceBundle bundle, boolean topLevel){
\r
317 assign(this, bundle);
\r
320 resource = resOffset;
\r
321 isTopLevel = topLevel;
\r
322 size = countItems();
\r
323 resPath = resourcePath;
\r
324 createLookupCache(); // Use bundle cache to access nested resources
\r
326 ResourceTable32(String key, String resPath, long resource,
\r
327 ICUResourceBundle bundle, boolean isTopLevel) {
\r
328 initialize(key, resPath, resource, bundle, isTopLevel);
\r