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