ICU-3301 create logical division in the code
X-SVN-Rev: 15399
This commit is contained in:
parent
4d51e9a494
commit
a66a65f7ff
@ -61,7 +61,7 @@ public class ICUResourceBundle extends UResourceBundle{
|
||||
* @draft ICU 3.0
|
||||
* @internal
|
||||
*/
|
||||
private static final int ALIAS=3;
|
||||
protected static final int ALIAS=3;
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
@ -70,7 +70,7 @@ public class ICUResourceBundle extends UResourceBundle{
|
||||
* @internal
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
private static final int TABLE32=4;
|
||||
protected static final int TABLE32=4;
|
||||
|
||||
/**
|
||||
* Resource type constant for a single 28-bit integer, interpreted as
|
||||
@ -92,10 +92,6 @@ public class ICUResourceBundle extends UResourceBundle{
|
||||
* @draft ICU 3.0
|
||||
*/
|
||||
public static final int INT_VECTOR=14;
|
||||
|
||||
private static final String ICU_RESOURCE_INDEX = "res_index";
|
||||
|
||||
private static final String DEFAULT_TAG = "default";
|
||||
|
||||
/**
|
||||
* Return the version number associated with this UResourceBundle as an
|
||||
@ -262,40 +258,12 @@ public class ICUResourceBundle extends UResourceBundle{
|
||||
if (obj == null)
|
||||
throw new MissingResourceException("Can't find resource for bundle "
|
||||
+this.getClass().getName()
|
||||
+", key "+key,
|
||||
+", key "+getKey(),
|
||||
this.getClass().getName(),
|
||||
key);
|
||||
getKey());
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
protected Object handleGetObject(String key){
|
||||
if(getType()==STRING){
|
||||
return getString();
|
||||
}
|
||||
ICUResourceBundle obj = handleGet(key);
|
||||
if(obj!=null){
|
||||
if(obj.getType()==STRING){
|
||||
return obj.getString();
|
||||
}
|
||||
try{
|
||||
if(obj.getType()==ARRAY){
|
||||
return obj.handleGetStringArray();
|
||||
}
|
||||
}catch(UResourceTypeMismatchException ex){
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
protected ICUResourceBundle handleGet(int index){
|
||||
return null;
|
||||
}
|
||||
protected ICUResourceBundle handleGet(String key){
|
||||
return null;
|
||||
}
|
||||
protected String[] handleGetStringArray(){
|
||||
return null;
|
||||
}
|
||||
// abstract UResourceBundle handleGetInt(int index);
|
||||
|
||||
/**
|
||||
@ -336,7 +304,7 @@ public class ICUResourceBundle extends UResourceBundle{
|
||||
*/
|
||||
public String getString(int index){
|
||||
ICUResourceBundle temp = get(index);
|
||||
if(temp.type==STRING){
|
||||
if(temp.getType()==STRING){
|
||||
return temp.getString();
|
||||
}
|
||||
throw new UResourceTypeMismatchException("");
|
||||
@ -496,29 +464,7 @@ public class ICUResourceBundle extends UResourceBundle{
|
||||
}
|
||||
return (String[])keywords.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param baseName
|
||||
* @param localeID
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
public static ICUResourceBundle createBundle(String baseName, String localeID, ClassLoader root){
|
||||
|
||||
ICUResourceBundleReader reader = new ICUResourceBundleReader(baseName, localeID, root);
|
||||
ByteBuffer rawData = reader.getData();
|
||||
long rootResource = (UNSIGNED_INT_MASK)& rawData.getInt(0);
|
||||
int type = RES_GET_TYPE(rootResource);
|
||||
if(type==TABLE){
|
||||
return ResourceTable.getTableInstance(rawData, baseName, localeID, null, rootResource, rootResource, true);
|
||||
}else if(type == TABLE32){
|
||||
return new ResourceTable32(rawData, baseName, localeID, null, rootResource, rootResource, true);
|
||||
}else{
|
||||
throw new RuntimeException("Invalid format error");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method performs multilevel fallback for fetching items from the bundle
|
||||
@ -551,41 +497,19 @@ public class ICUResourceBundle extends UResourceBundle{
|
||||
if(result == null){
|
||||
throw new MissingResourceException("Can't find resource for bundle "
|
||||
+this.getClass().getName()
|
||||
+", key "+key,
|
||||
+", key "+getType(),
|
||||
path,
|
||||
key);
|
||||
getKey());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// will throw type mismatch exception if the resource is not a string
|
||||
public String getStringWithFallback(String path) throws MissingResourceException {
|
||||
return getWithFallback(path).getString();
|
||||
return getWithFallback(path).getString();
|
||||
}
|
||||
|
||||
private ICUResourceBundle findResourceWithFallback(String path, ICUResourceBundle actualBundle) {
|
||||
ICUResourceBundle sub = null;
|
||||
while (actualBundle != null) {
|
||||
StringTokenizer st = new StringTokenizer(path, "/");
|
||||
ICUResourceBundle current = actualBundle;
|
||||
while (st.hasMoreTokens()) {
|
||||
String subKey = st.nextToken();
|
||||
sub = current.handleGet(subKey, null);
|
||||
if(sub==null){
|
||||
break;
|
||||
}
|
||||
current = sub;
|
||||
}
|
||||
if(sub!=null){
|
||||
//we found it
|
||||
break;
|
||||
}
|
||||
// if not try the parent bundle
|
||||
actualBundle = (ICUResourceBundle) actualBundle.parent;
|
||||
}
|
||||
return sub;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a resource bundle using the specified base name, locale, and class root.
|
||||
*
|
||||
@ -679,22 +603,77 @@ public class ICUResourceBundle extends UResourceBundle{
|
||||
}
|
||||
return locales;
|
||||
}
|
||||
|
||||
|
||||
public Enumeration getKeys(){
|
||||
Vector keys = new Vector();
|
||||
ICUResourceBundle item =null;
|
||||
for(int i=0; i<size; i++){
|
||||
item = get(i);
|
||||
keys.add(item.getKey());
|
||||
}
|
||||
return keys.elements();
|
||||
}
|
||||
|
||||
public ULocale getULocale(){
|
||||
return new ULocale(localeID);
|
||||
}
|
||||
public static ICUResourceBundle createBundle(String baseName, String localeID, ClassLoader root) {
|
||||
return ICUResourceBundleImpl.createBundle(baseName, localeID, root);
|
||||
}
|
||||
//====== protected members ==============
|
||||
protected int type = NONE;
|
||||
protected String key;
|
||||
protected int size = NONE;
|
||||
protected int size = 1;
|
||||
protected String resPath;
|
||||
protected boolean isTopLevel;
|
||||
|
||||
protected ICUResourceBundleReader reader;
|
||||
//protected byte[] version;
|
||||
protected ByteBuffer rawData;
|
||||
protected long resource;
|
||||
protected long rootResource;
|
||||
protected long resource = RES_BOGUS;
|
||||
protected boolean isTopLevel = false;
|
||||
|
||||
protected static final long UNSIGNED_INT_MASK = 0xffffffffL;
|
||||
// ========== privates ==========
|
||||
|
||||
protected static final long RES_BOGUS = 0xffffffff;
|
||||
|
||||
protected ICUResourceBundle handleGet(String key, Hashtable table){
|
||||
throw new UResourceTypeMismatchException("");
|
||||
}
|
||||
protected ICUResourceBundle handleGet(int index, Hashtable table){
|
||||
throw new UResourceTypeMismatchException("");
|
||||
}
|
||||
|
||||
|
||||
protected Object handleGetObject(String key){
|
||||
if(getType()==STRING){
|
||||
return getString();
|
||||
}
|
||||
ICUResourceBundle obj = handleGet(key);
|
||||
if(obj!=null){
|
||||
if(obj.getType()==STRING){
|
||||
return obj.getString();
|
||||
}
|
||||
try{
|
||||
if(obj.getType()==ARRAY){
|
||||
return obj.handleGetStringArray();
|
||||
}
|
||||
}catch(UResourceTypeMismatchException ex){
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
protected ICUResourceBundle handleGet(int index){
|
||||
return null;
|
||||
}
|
||||
protected ICUResourceBundle handleGet(String key){
|
||||
return null;
|
||||
}
|
||||
protected String[] handleGetStringArray(){
|
||||
return null;
|
||||
}
|
||||
|
||||
// ========== privates ==========
|
||||
private static final String ICU_RESOURCE_INDEX = "res_index";
|
||||
|
||||
private static final String DEFAULT_TAG = "default";
|
||||
|
||||
// Flag for enabling/disabling debugging code
|
||||
private static final boolean DEBUG = ICUDebug.enabled("localedata");
|
||||
|
||||
@ -808,504 +787,29 @@ public class ICUResourceBundle extends UResourceBundle{
|
||||
}
|
||||
|
||||
return ae;
|
||||
}
|
||||
}
|
||||
|
||||
private static final long RES_BOGUS = 0xffffffff;
|
||||
|
||||
protected static final int RES_GET_TYPE(long res){
|
||||
return (int)((res)>>28L);
|
||||
}
|
||||
protected static final int RES_GET_OFFSET(long res){
|
||||
return (int)((res&0x0fffffff)*4);
|
||||
}
|
||||
|
||||
/* get signed and unsigned integer values directly from the Resource handle */
|
||||
protected static final int RES_GET_INT(long res) {
|
||||
return (((int)((res)<<4L))>>4L);
|
||||
}
|
||||
protected static final long RES_GET_UINT(long res){
|
||||
long t = ((res)&0x0fffffffL);
|
||||
return t;
|
||||
}
|
||||
|
||||
protected static int countItems(final ByteBuffer rawData, final long res) {
|
||||
if(res!=RES_BOGUS) {
|
||||
switch(RES_GET_TYPE(res)) {
|
||||
case STRING:
|
||||
case BINARY:
|
||||
case ALIAS:
|
||||
case INT:
|
||||
case INT_VECTOR:
|
||||
return 1;
|
||||
case ARRAY:
|
||||
case TABLE32: {
|
||||
int offset = RES_GET_OFFSET(res);
|
||||
int value = rawData.getInt(offset);
|
||||
return value;
|
||||
}
|
||||
case TABLE: {
|
||||
int offset = RES_GET_OFFSET(res);
|
||||
int value = rawData.getChar(offset);
|
||||
return value;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public Enumeration getKeys(){
|
||||
Vector keys = new Vector();
|
||||
ICUResourceBundle item =null;
|
||||
for(int i=0; i<size; i++){
|
||||
item = get(i);
|
||||
keys.add(item.getKey());
|
||||
}
|
||||
return keys.elements();
|
||||
}
|
||||
protected ICUResourceBundle handleGet(String key, Hashtable table){
|
||||
throw new UResourceTypeMismatchException("");
|
||||
}
|
||||
protected ICUResourceBundle handleGet(int index, Hashtable table){
|
||||
throw new UResourceTypeMismatchException("");
|
||||
}
|
||||
protected ICUResourceBundle(ByteBuffer rawData, String baseName, String localeID,
|
||||
String key, long resource,long rootResource, int type,
|
||||
boolean isTopLevel ){
|
||||
this.rawData = rawData;
|
||||
this.key = key;
|
||||
this.resource = resource;
|
||||
this.rootResource = rootResource;
|
||||
this.type = type;
|
||||
this.isTopLevel = false;
|
||||
this.size = countItems(rawData, resource);
|
||||
this.baseName = baseName;
|
||||
this.localeID = localeID;
|
||||
//this.locale = new ULocale(localeID).toLocale();
|
||||
|
||||
}
|
||||
|
||||
public ULocale getULocale(){
|
||||
return new ULocale(localeID);
|
||||
}
|
||||
|
||||
|
||||
private static StringBuffer RES_GET_KEY(ByteBuffer rawData, int keyOffset){
|
||||
char ch = 0xFFFF; //sentinel
|
||||
StringBuffer key = new StringBuffer();
|
||||
while((ch=(char)rawData.get(keyOffset))!= 0){
|
||||
key.append(ch);
|
||||
keyOffset++;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
private static final int getIntOffset(int offset){
|
||||
return (offset*4);
|
||||
}
|
||||
private static final int getCharOffset(int offset){
|
||||
return (offset*2);
|
||||
}
|
||||
|
||||
private static final ICUResourceBundle createBundleObject(ByteBuffer rawData, String baseName, String localeID,
|
||||
String key, long resource, long rootResource,
|
||||
Hashtable table){
|
||||
if(resource!=RES_BOGUS) {
|
||||
switch(RES_GET_TYPE(resource)) {
|
||||
case STRING:{
|
||||
return new ResourceString(rawData, baseName, localeID, key, resource, rootResource);
|
||||
}
|
||||
case BINARY:{
|
||||
return new ResourceBinary(rawData, baseName, localeID, key, resource, rootResource);
|
||||
}
|
||||
case ALIAS:{
|
||||
return findResource(rawData, baseName, localeID, key, resource, table);
|
||||
}
|
||||
case INT:{
|
||||
return new ResourceInt(rawData, baseName, localeID, key, resource, rootResource);
|
||||
}
|
||||
case INT_VECTOR:{
|
||||
return new ResourceIntVector(rawData, baseName, localeID, key, resource, rootResource);
|
||||
}
|
||||
case ARRAY:{
|
||||
return new ResourceArray(rawData, baseName, localeID, key, resource, rootResource);
|
||||
}
|
||||
case TABLE32:{
|
||||
return new ResourceTable32(rawData, baseName, localeID, key, resource, rootResource, false);
|
||||
}
|
||||
case TABLE: {
|
||||
return new ResourceTable(rawData, baseName, localeID, key, resource, rootResource, false);
|
||||
}
|
||||
default:
|
||||
throw new InternalError("The resource type is unknown");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static String getTableKey(ByteBuffer rawData, int size, int currentOffset, int index, int type){
|
||||
switch(type){
|
||||
case TABLE32:{
|
||||
int charOffset = currentOffset+getIntOffset(index);
|
||||
int keyOffset = rawData.getInt(charOffset);
|
||||
return RES_GET_KEY(rawData,keyOffset).toString();
|
||||
}
|
||||
case TABLE:
|
||||
default:{
|
||||
int charOffset = currentOffset+getCharOffset(index);
|
||||
int keyOffset = rawData.getChar(charOffset);
|
||||
return RES_GET_KEY(rawData,keyOffset).toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
private static int findKey(ByteBuffer rawData, int size,
|
||||
int currentOffset, int type,
|
||||
String target){
|
||||
int mid = 0, start = 0, limit = size, rc;
|
||||
int lastMid = -1;
|
||||
//int myCharOffset = 0, keyOffset = 0;
|
||||
for (;;) {
|
||||
mid = ((start + limit) / 2);
|
||||
if (lastMid == mid) { /* Have we moved? */
|
||||
break; /* We haven't moved, and it wasn't found. */
|
||||
}
|
||||
lastMid = mid;
|
||||
|
||||
String comp = getTableKey(rawData, size,currentOffset,mid,type);
|
||||
rc = target.compareTo(comp);
|
||||
if (rc < 0) {
|
||||
limit = mid;
|
||||
} else if (rc > 0) {
|
||||
start = mid;
|
||||
} else {
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static class ResourceTable extends ICUResourceBundle{
|
||||
|
||||
public ICUResourceBundle handleGet(String key){
|
||||
return handleGet(key, null);
|
||||
}
|
||||
protected ICUResourceBundle handleGet(String key, Hashtable table){
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
// offset+0 contains number of entries
|
||||
// offset+1 contains the keyOffset
|
||||
int currentOffset = (offset)+getCharOffset(1);
|
||||
//int keyOffset = rawData.getChar(currentOffset);
|
||||
|
||||
/* do a binary search for the key */
|
||||
int foundOffset = findKey(rawData, size, currentOffset, type, key);
|
||||
if(foundOffset == -1){
|
||||
//throw new MissingResourceException(ICUResourceBundleReader.getFullName(baseName, localeID),
|
||||
// localeID,
|
||||
// key);
|
||||
return null;
|
||||
}
|
||||
currentOffset += getCharOffset(size+(~size&1))+getIntOffset(foundOffset);
|
||||
long resource = (UNSIGNED_INT_MASK) & rawData.getInt(currentOffset);
|
||||
return createBundleObject(rawData, baseName, localeID, key, resource, rootResource, table);
|
||||
|
||||
}
|
||||
public ICUResourceBundle handleGet(int index){
|
||||
return handleGet(index, null);
|
||||
}
|
||||
public ICUResourceBundle handleGet(int index, Hashtable table){
|
||||
if(index>size){
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
// offset+0 contains number of entries
|
||||
// offset+1 contains the keyOffset
|
||||
int currentOffset = (offset)+getCharOffset(1);
|
||||
String itemKey = getTableKey(rawData, size, currentOffset, index, type);
|
||||
|
||||
currentOffset += getCharOffset(size+(~size&1))+ getIntOffset(index) ;
|
||||
long resource = (UNSIGNED_INT_MASK) & rawData.getInt(currentOffset);
|
||||
|
||||
return createBundleObject(rawData, baseName, localeID, itemKey, resource, rootResource, table);
|
||||
}
|
||||
|
||||
private ResourceTable(ByteBuffer rawData, String baseName, String localeID, String key,
|
||||
long resource, long rootResource, boolean isRootResource ){
|
||||
super(rawData, baseName, localeID, key, resource, rootResource, TABLE, isRootResource);
|
||||
}
|
||||
|
||||
private static ResourceTable getTableInstance(ByteBuffer rawData, String baseName, String localeID, String key,
|
||||
long resource, long rootResource, boolean isRootResource ){
|
||||
|
||||
// kludge: %%ALIAS is such a hack! I can understand the
|
||||
// ICU4C legacy .. do we need to port it?
|
||||
ResourceTable table = new ResourceTable(rawData, baseName, localeID, key, resource, rootResource, isRootResource);
|
||||
//return table;
|
||||
|
||||
ICUResourceBundle b = table.handleGet(0);
|
||||
String itemKey = b.getKey();
|
||||
if(itemKey.equals("%%ALIAS")){
|
||||
String locale = b.getString();
|
||||
ICUResourceBundle actual = (ICUResourceBundle)UResourceBundle.getBundleInstance(baseName, locale);
|
||||
return (ResourceTable)actual;
|
||||
} else {
|
||||
return table;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ResourceTable32 extends ICUResourceBundle{
|
||||
|
||||
public ICUResourceBundle get(String key){
|
||||
return get(key, null);
|
||||
}
|
||||
public ICUResourceBundle get(String key, Hashtable table){
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
// offset+0 contains number of entries
|
||||
// offset+1 contains the keyOffset
|
||||
int currentOffset = (offset)+getIntOffset(1);
|
||||
//int keyOffset = rawData.getChar(currentOffset);
|
||||
|
||||
/* do a binary search for the key */
|
||||
int foundOffset = findKey(rawData, size, currentOffset, TABLE32, key);
|
||||
if(foundOffset == -1){
|
||||
throw new MissingResourceException("Could not find resource ",
|
||||
ICUResourceBundleReader.getFullName(baseName, localeID),
|
||||
key);
|
||||
}
|
||||
currentOffset += getIntOffset(size)+getIntOffset(foundOffset);
|
||||
long resource = (UNSIGNED_INT_MASK) & rawData.getInt(currentOffset);
|
||||
|
||||
return createBundleObject(rawData, baseName, localeID, key, resource, rootResource, table);
|
||||
}
|
||||
public ICUResourceBundle get(int index){
|
||||
return get(index, null);
|
||||
}
|
||||
public ICUResourceBundle get(int index, Hashtable table){
|
||||
if(index>size){
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
// offset+0 contains number of entries
|
||||
// offset+1 contains the keyOffset
|
||||
int currentOffset = (offset)+getIntOffset(1)+ getIntOffset(index);
|
||||
String itemKey = getTableKey(rawData, size, currentOffset, 0, TABLE32);
|
||||
|
||||
currentOffset += getIntOffset(size) ;
|
||||
long resource = (UNSIGNED_INT_MASK) & rawData.getInt(currentOffset);
|
||||
|
||||
return createBundleObject(rawData, baseName, localeID, itemKey, resource, rootResource, table);
|
||||
}
|
||||
private ResourceTable32(ByteBuffer rawData, String baseName, String localeID,String key,
|
||||
long resource, long rootResource, boolean isRootResource ){
|
||||
super(rawData, key, baseName, localeID, resource, rootResource, TABLE, isRootResource);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ResourceString extends ICUResourceBundle {
|
||||
private String value;
|
||||
public String getString(){
|
||||
return value;
|
||||
}
|
||||
private ResourceString(ByteBuffer rawData, String baseName, String localeID,
|
||||
String key, long resource, long rootResource ){
|
||||
super(rawData, baseName, localeID, key, resource, rootResource, STRING, false);
|
||||
value = getStringValue(rawData, resource);
|
||||
}
|
||||
}
|
||||
private static class ResourceInt extends ICUResourceBundle{
|
||||
public int getInt(){
|
||||
return RES_GET_INT(resource);
|
||||
}
|
||||
public int getUInt(){
|
||||
long ret = RES_GET_UINT(resource);
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
private ResourceInt(ByteBuffer rawData, String baseName, String localeID, String key,
|
||||
long resource, long rootResource){
|
||||
super(rawData, baseName, localeID, key, resource, rootResource, INT, false);
|
||||
}
|
||||
}
|
||||
private static class ResourceArray extends ICUResourceBundle{
|
||||
protected String[] handleGetStringArray(){
|
||||
String[] strings = new String[size];
|
||||
ICUResourceBundleIterator iter = getIterator();
|
||||
int i = 0;
|
||||
while(iter.hasNext()){
|
||||
strings[i++] = iter.next().getString();
|
||||
}
|
||||
return strings;
|
||||
}
|
||||
protected ICUResourceBundle handleGet(String index){
|
||||
return handleGet(index, null);
|
||||
}
|
||||
protected ICUResourceBundle handleGet(String index, Hashtable table){
|
||||
int val = getIndex(index);
|
||||
if(val>-1){
|
||||
return handleGet(val, table);
|
||||
}
|
||||
throw new UResourceTypeMismatchException("");
|
||||
}
|
||||
protected ICUResourceBundle handleGet(int index){
|
||||
return handleGet(index, null);
|
||||
}
|
||||
protected ICUResourceBundle handleGet(int index, Hashtable table){
|
||||
if(index > size){
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
int itemOffset = offset+getIntOffset(index+1);
|
||||
long itemResource = (UNSIGNED_INT_MASK)&rawData.getInt(itemOffset);
|
||||
return createBundleObject(rawData, baseName, localeID, null,itemResource, rootResource, table);
|
||||
}
|
||||
private ResourceArray(ByteBuffer rawData, String baseName, String localeID, String key,
|
||||
long resource, long rootResource ){
|
||||
super(rawData, baseName, localeID, key, resource, rootResource, ARRAY, false );
|
||||
}
|
||||
}
|
||||
private static class ResourceBinary extends ICUResourceBundle{
|
||||
private ByteBuffer value;
|
||||
public ByteBuffer getBinary(){
|
||||
value.rewind();
|
||||
return value;
|
||||
}
|
||||
private ByteBuffer getValue(){
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
int length = rawData.getInt(offset);
|
||||
int byteOffset = offset+getIntOffset(1);
|
||||
ByteBuffer val = ByteBuffer.allocate(length);
|
||||
for(int i=0; i<length; i++){
|
||||
val.put(rawData.get(byteOffset+i));
|
||||
}
|
||||
return val;
|
||||
}
|
||||
public ResourceBinary(ByteBuffer rawData, String baseName, String localeID, String key,
|
||||
long resource, long rootResource ){
|
||||
super(rawData, baseName, localeID, key, resource, rootResource, BINARY, false );
|
||||
value = getValue();
|
||||
}
|
||||
}
|
||||
private static class ResourceIntVector extends ICUResourceBundle{
|
||||
private int[] value;
|
||||
public int[] getIntVector(){
|
||||
return value;
|
||||
}
|
||||
private int[] getValue(){
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
int length = rawData.getInt(offset);
|
||||
int intOffset = offset+getIntOffset(1);
|
||||
int[] val = new int[length];
|
||||
for(int i=0; i<length; i++){
|
||||
val[i] = rawData.getInt(intOffset+getIntOffset(i));
|
||||
}
|
||||
return val;
|
||||
}
|
||||
public ResourceIntVector(ByteBuffer rawData, String baseName, String localeID, String key,
|
||||
long resource, long rootResource){
|
||||
super(rawData, baseName, localeID, key, resource, rootResource,INT_VECTOR, false );
|
||||
value = getValue();
|
||||
}
|
||||
}
|
||||
private static String getStringValue(ByteBuffer rawData, long resource){
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
int length = rawData.getInt(offset);
|
||||
int stringOffset = offset+getIntOffset(1);
|
||||
|
||||
StringBuffer val = new StringBuffer();
|
||||
for(int i=0; i<length; i++){
|
||||
val.append(rawData.getChar(stringOffset+getCharOffset(i)));
|
||||
}
|
||||
return val.toString();
|
||||
}
|
||||
|
||||
private static final char RES_PATH_SEP_CHAR ='/';
|
||||
private static final String ICUDATA = "ICUDATA";
|
||||
|
||||
private static int getIndex(String s){
|
||||
if(s.length()==1){
|
||||
char c = s.charAt(0);
|
||||
if(Character.isDigit(c)){
|
||||
return Integer.valueOf(s).intValue();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static ICUResourceBundle findResource(ByteBuffer rawData, String baseName,
|
||||
String localeID, String key, long resource,
|
||||
Hashtable table){
|
||||
String locale=null, keyPath=null;
|
||||
String bundleName;
|
||||
String resPath = getStringValue(rawData, resource);
|
||||
if(table==null){
|
||||
table = new Hashtable();
|
||||
}
|
||||
if(table.get(resPath)!= null){
|
||||
throw new IllegalArgumentException("Circular references in the resource bundles");
|
||||
}
|
||||
table.put(resPath,"");
|
||||
if(resPath.indexOf(RES_PATH_SEP_CHAR)==0){
|
||||
int i =resPath.indexOf(RES_PATH_SEP_CHAR,1);
|
||||
int j =resPath.indexOf(RES_PATH_SEP_CHAR,i+1);
|
||||
bundleName=resPath.substring(1,i);
|
||||
locale=resPath.substring(i+1);
|
||||
if(j!=-1){
|
||||
locale=resPath.substring(i+1,j);
|
||||
keyPath=resPath.substring(j+1,resPath.length());
|
||||
}
|
||||
//there is a path included
|
||||
if(bundleName.equals(ICUDATA)){
|
||||
bundleName = ICU_BASE_NAME;
|
||||
}
|
||||
|
||||
}else{
|
||||
//no path start with locale
|
||||
int i =resPath.indexOf(RES_PATH_SEP_CHAR);
|
||||
keyPath=resPath.substring(i+1);
|
||||
|
||||
if(i!=-1){
|
||||
locale = resPath.substring(0,i);
|
||||
}else{
|
||||
locale=keyPath;
|
||||
keyPath = null;//keyPath.substring(i, keyPath.length());
|
||||
}
|
||||
bundleName = baseName;
|
||||
|
||||
}
|
||||
|
||||
ICUResourceBundle bundle = null;
|
||||
if(locale==null){
|
||||
bundle = (ICUResourceBundle)getBundleInstance(bundleName, "", ICU_DATA_CLASS_LOADER, false);
|
||||
}else{
|
||||
bundle = (ICUResourceBundle)getBundleInstance(bundleName, locale, ICU_DATA_CLASS_LOADER, false);
|
||||
}
|
||||
|
||||
|
||||
private ICUResourceBundle findResourceWithFallback(String path, ICUResourceBundle actualBundle) {
|
||||
ICUResourceBundle sub = null;
|
||||
if(keyPath!=null){
|
||||
StringTokenizer st = new StringTokenizer(keyPath, "/");
|
||||
ICUResourceBundle current = bundle;
|
||||
while (actualBundle != null) {
|
||||
StringTokenizer st = new StringTokenizer(path, "/");
|
||||
ICUResourceBundle current = actualBundle;
|
||||
while (st.hasMoreTokens()) {
|
||||
String subKey = st.nextToken();
|
||||
sub = current.handleGet(subKey, table);
|
||||
sub = current.handleGet(subKey, null);
|
||||
if(sub==null){
|
||||
break;
|
||||
break;
|
||||
}
|
||||
current = sub;
|
||||
}
|
||||
}else{
|
||||
|
||||
// if the sub resource is not found
|
||||
// try fetching the sub resource with
|
||||
// the key of this alias resource
|
||||
sub = bundle.get(key);
|
||||
if(sub!=null){
|
||||
//we found it
|
||||
break;
|
||||
}
|
||||
// if not try the parent bundle
|
||||
actualBundle = (ICUResourceBundle) actualBundle.parent;
|
||||
}
|
||||
if(sub == null){
|
||||
throw new MissingResourceException(localeID, baseName, key);
|
||||
}
|
||||
sub.resPath = resPath;
|
||||
return sub;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
531
icu4j/src/com/ibm/icu/impl/ICUResourceBundleImpl.java
Normal file
531
icu4j/src/com/ibm/icu/impl/ICUResourceBundleImpl.java
Normal file
@ -0,0 +1,531 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 2004, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.impl;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Hashtable;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import com.ibm.icu.util.StringTokenizer;
|
||||
import com.ibm.icu.util.UResourceBundle;
|
||||
import com.ibm.icu.util.UResourceTypeMismatchException;
|
||||
/**
|
||||
* @author ram
|
||||
*/
|
||||
public class ICUResourceBundleImpl extends ICUResourceBundle {
|
||||
//protected byte[] version;
|
||||
private ByteBuffer rawData;
|
||||
private long rootResource;
|
||||
/**
|
||||
*
|
||||
* @param baseName
|
||||
* @param localeID
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
public static ICUResourceBundle createBundle(String baseName,
|
||||
String localeID, ClassLoader root) {
|
||||
ICUResourceBundleReader reader = new ICUResourceBundleReader(baseName, localeID, root);
|
||||
ByteBuffer rawData = reader.getData();
|
||||
long rootResource = (UNSIGNED_INT_MASK)& rawData.getInt(0);
|
||||
ICUResourceBundleImpl bundle = new ICUResourceBundleImpl(rawData, baseName, localeID, rootResource);
|
||||
return bundle.getBundle();
|
||||
}
|
||||
private ICUResourceBundle getBundle(){
|
||||
int type = RES_GET_TYPE(rootResource);
|
||||
|
||||
if(type==TABLE){
|
||||
// %%ALIAS is such a hack! I can understand the
|
||||
// ICU4C legacy .. do we need to port it?
|
||||
ResourceTable table = new ResourceTable(null, rootResource, true);
|
||||
|
||||
ICUResourceBundle b = table.handleGet(0);
|
||||
String itemKey = b.getKey();
|
||||
if(itemKey.equals("%%ALIAS")){
|
||||
String locale = b.getString();
|
||||
ICUResourceBundle actual = (ICUResourceBundle)UResourceBundle.getBundleInstance(baseName, locale);
|
||||
return (ResourceTable)actual;
|
||||
} else {
|
||||
return table;
|
||||
}
|
||||
|
||||
}else if(type == TABLE32){
|
||||
return new ResourceTable32(null, rootResource, true);
|
||||
}else{
|
||||
throw new RuntimeException("Invalid format error");
|
||||
}
|
||||
}
|
||||
private ICUResourceBundleImpl(ByteBuffer rawData, String baseName,
|
||||
String localeID, long rootResource) {
|
||||
this.rawData = rawData;
|
||||
this.rootResource = rootResource;
|
||||
this.baseName = baseName;
|
||||
this.localeID = localeID;
|
||||
}
|
||||
private static final int RES_GET_TYPE(long res) {
|
||||
return (int) ((res) >> 28L);
|
||||
}
|
||||
private static final int RES_GET_OFFSET(long res) {
|
||||
return (int) ((res & 0x0fffffff) * 4);
|
||||
}
|
||||
/* get signed and unsigned integer values directly from the Resource handle */
|
||||
private static final int RES_GET_INT(long res) {
|
||||
return (((int) ((res) << 4L)) >> 4L);
|
||||
}
|
||||
private static final long RES_GET_UINT(long res) {
|
||||
long t = ((res) & 0x0fffffffL);
|
||||
return t;
|
||||
}
|
||||
private static final StringBuffer RES_GET_KEY(ByteBuffer rawData, int keyOffset) {
|
||||
char ch = 0xFFFF; //sentinel
|
||||
StringBuffer key = new StringBuffer();
|
||||
while ((ch = (char) rawData.get(keyOffset)) != 0) {
|
||||
key.append(ch);
|
||||
keyOffset++;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
private static final int getIntOffset(int offset) {
|
||||
return (offset * 4);
|
||||
}
|
||||
private static final int getCharOffset(int offset) {
|
||||
return (offset * 2);
|
||||
}
|
||||
private final ICUResourceBundle createBundleObject(String key, long resource, Hashtable table) {
|
||||
if (resource != RES_BOGUS) {
|
||||
switch (RES_GET_TYPE(resource)) {
|
||||
case STRING :
|
||||
{
|
||||
return new ResourceString(key, resource);
|
||||
}
|
||||
case BINARY :
|
||||
{
|
||||
return new ResourceBinary(key, resource);
|
||||
}
|
||||
case ALIAS :
|
||||
{
|
||||
return findResource(key,resource, table);
|
||||
}
|
||||
case INT :
|
||||
{
|
||||
return new ResourceInt(key, resource);
|
||||
}
|
||||
case INT_VECTOR :
|
||||
{
|
||||
return new ResourceIntVector(key, resource);
|
||||
}
|
||||
case ARRAY :
|
||||
{
|
||||
return new ResourceArray(key, resource);
|
||||
}
|
||||
case TABLE32 :
|
||||
{
|
||||
return new ResourceTable32(key, resource);
|
||||
}
|
||||
case TABLE :
|
||||
{
|
||||
return new ResourceTable(key, resource);
|
||||
}
|
||||
default :
|
||||
throw new InternalError("The resource type is unknown");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static final String getTableKey(ByteBuffer rawData, int size, int currentOffset, int index, int type) {
|
||||
switch (type) {
|
||||
case TABLE32 :
|
||||
{
|
||||
int charOffset = currentOffset + getIntOffset(index);
|
||||
int keyOffset = rawData.getInt(charOffset);
|
||||
return RES_GET_KEY(rawData, keyOffset).toString();
|
||||
}
|
||||
case TABLE :
|
||||
default :
|
||||
{
|
||||
int charOffset = currentOffset + getCharOffset(index);
|
||||
int keyOffset = rawData.getChar(charOffset);
|
||||
return RES_GET_KEY(rawData, keyOffset).toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
private static int findKey(ByteBuffer rawData, int size, int currentOffset, int type, String target) {
|
||||
int mid = 0, start = 0, limit = size, rc;
|
||||
int lastMid = -1;
|
||||
//int myCharOffset = 0, keyOffset = 0;
|
||||
for (;;) {
|
||||
mid = ((start + limit) / 2);
|
||||
if (lastMid == mid) { /* Have we moved? */
|
||||
break; /* We haven't moved, and it wasn't found. */
|
||||
}
|
||||
lastMid = mid;
|
||||
String comp = getTableKey(rawData, size, currentOffset, mid, type);
|
||||
rc = target.compareTo(comp);
|
||||
if (rc < 0) {
|
||||
limit = mid;
|
||||
} else if (rc > 0) {
|
||||
start = mid;
|
||||
} else {
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
private ResourceBundle parent(){
|
||||
return parent;
|
||||
}
|
||||
private String baseName(){
|
||||
return baseName;
|
||||
}
|
||||
private String localeID(){
|
||||
return localeID;
|
||||
}
|
||||
private class ResourceTable extends ICUResourceBundle {
|
||||
|
||||
public ICUResourceBundle handleGet(String key) {
|
||||
return handleGet(key, null);
|
||||
}
|
||||
protected ICUResourceBundle handleGet(String key, Hashtable table) {
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
// offset+0 contains number of entries
|
||||
// offset+1 contains the keyOffset
|
||||
int currentOffset = (offset) + getCharOffset(1);
|
||||
//int keyOffset = rawData.getChar(currentOffset);
|
||||
/* do a binary search for the key */
|
||||
int foundOffset = findKey(rawData, size, currentOffset, type, key);
|
||||
if (foundOffset == -1) {
|
||||
//throw new MissingResourceException(ICUResourceBundleReader.getFullName(baseName, localeID),
|
||||
// localeID,
|
||||
// key);
|
||||
return null;
|
||||
}
|
||||
currentOffset += getCharOffset(size + (~size & 1))
|
||||
+ getIntOffset(foundOffset);
|
||||
long resource = (UNSIGNED_INT_MASK) & rawData.getInt(currentOffset);
|
||||
return createBundleObject(key, resource, table);
|
||||
}
|
||||
public ICUResourceBundle handleGet(int index) {
|
||||
return handleGet(index, null);
|
||||
}
|
||||
public ICUResourceBundle handleGet(int index, Hashtable table) {
|
||||
if (index > size) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
// offset+0 contains number of entries
|
||||
// offset+1 contains the keyOffset
|
||||
int currentOffset = (offset) + getCharOffset(1);
|
||||
String itemKey = getTableKey(rawData, size, currentOffset, index,
|
||||
type);
|
||||
currentOffset += getCharOffset(size + (~size & 1))
|
||||
+ getIntOffset(index);
|
||||
long resource = (UNSIGNED_INT_MASK) & rawData.getInt(currentOffset);
|
||||
return createBundleObject(itemKey, resource, table);
|
||||
}
|
||||
private int countItems(){
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
int value = rawData.getChar(offset);
|
||||
return value;
|
||||
}
|
||||
private ResourceTable(String key, long resource) {
|
||||
this(key, resource, false);
|
||||
}
|
||||
private ResourceTable(String key, long resource, boolean isTopLevel) {
|
||||
this.key = key;
|
||||
this.resource = resource;
|
||||
this.isTopLevel = isTopLevel;
|
||||
this.size = countItems();
|
||||
this.baseName = baseName();
|
||||
this.localeID = localeID();
|
||||
this.parent = parent();
|
||||
}
|
||||
}
|
||||
private class ResourceTable32 extends ICUResourceBundle {
|
||||
|
||||
public ICUResourceBundle get(String key) {
|
||||
return get(key, null);
|
||||
}
|
||||
public ICUResourceBundle get(String key, Hashtable table) {
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
// offset+0 contains number of entries
|
||||
// offset+1 contains the keyOffset
|
||||
int currentOffset = (offset) + getIntOffset(1);
|
||||
//int keyOffset = rawData.getChar(currentOffset);
|
||||
/* do a binary search for the key */
|
||||
int foundOffset = findKey(rawData, size, currentOffset, TABLE32,
|
||||
key);
|
||||
if (foundOffset == -1) {
|
||||
throw new MissingResourceException(
|
||||
"Could not find resource ",
|
||||
ICUResourceBundleReader.getFullName(baseName, localeID),
|
||||
key);
|
||||
}
|
||||
currentOffset += getIntOffset(size) + getIntOffset(foundOffset);
|
||||
long resource = (UNSIGNED_INT_MASK) & rawData.getInt(currentOffset);
|
||||
return createBundleObject(key, resource, table);
|
||||
}
|
||||
public ICUResourceBundle get(int index) {
|
||||
return get(index, null);
|
||||
}
|
||||
public ICUResourceBundle get(int index, Hashtable table) {
|
||||
if (index > size) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
// offset+0 contains number of entries
|
||||
// offset+1 contains the keyOffset
|
||||
int currentOffset = (offset) + getIntOffset(1)
|
||||
+ getIntOffset(index);
|
||||
String itemKey = getTableKey(rawData, size, currentOffset, 0,
|
||||
TABLE32);
|
||||
currentOffset += getIntOffset(size);
|
||||
long resource = (UNSIGNED_INT_MASK) & rawData.getInt(currentOffset);
|
||||
return createBundleObject(itemKey, resource, table);
|
||||
}
|
||||
private int countItems(){
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
int value = rawData.getInt(offset);
|
||||
return value;
|
||||
}
|
||||
private ResourceTable32(String key, long resource, boolean isTopLevel) {
|
||||
this.resource = resource;
|
||||
this.key = key;
|
||||
this.type = TABLE;//Mask the table32's real type
|
||||
this.isTopLevel = isTopLevel;
|
||||
this.size = countItems();
|
||||
this.baseName = baseName();
|
||||
this.localeID = localeID();
|
||||
this.parent = parent();;
|
||||
}
|
||||
private ResourceTable32(String key, long resource) {
|
||||
this(key, resource, false);
|
||||
}
|
||||
}
|
||||
private class ResourceString extends ICUResourceBundle {
|
||||
private String value;
|
||||
public String getString(){
|
||||
return value;
|
||||
}
|
||||
private ResourceString(String key, long resource) {
|
||||
value = getStringValue(resource);
|
||||
this.key = key;
|
||||
this.resource = resource;
|
||||
this.type = RES_GET_TYPE(resource);
|
||||
this.baseName = baseName();
|
||||
this.localeID = localeID();
|
||||
this.parent = parent();
|
||||
}
|
||||
}
|
||||
private class ResourceInt extends ICUResourceBundle {
|
||||
public int getInt() {
|
||||
return RES_GET_INT(resource);
|
||||
}
|
||||
public int getUInt() {
|
||||
long ret = RES_GET_UINT(resource);
|
||||
return (int) ret;
|
||||
}
|
||||
private ResourceInt(String key, long resource) {
|
||||
this.key = key;
|
||||
this.resource = resource;
|
||||
this.type = RES_GET_TYPE(resource);
|
||||
this.baseName = baseName();
|
||||
this.localeID = localeID();
|
||||
this.parent = parent();
|
||||
}
|
||||
}
|
||||
private class ResourceArray extends ICUResourceBundle {
|
||||
protected String[] handleGetStringArray() {
|
||||
String[] strings = new String[size];
|
||||
ICUResourceBundleIterator iter = getIterator();
|
||||
int i = 0;
|
||||
while (iter.hasNext()) {
|
||||
strings[i++] = iter.next().getString();
|
||||
}
|
||||
return strings;
|
||||
}
|
||||
protected ICUResourceBundle handleGet(String index) {
|
||||
return handleGet(index, null);
|
||||
}
|
||||
protected ICUResourceBundle handleGet(String index, Hashtable table) {
|
||||
int val = getIndex(index);
|
||||
if (val > -1) {
|
||||
return handleGet(val, table);
|
||||
}
|
||||
throw new UResourceTypeMismatchException("");
|
||||
}
|
||||
protected ICUResourceBundle handleGet(int index) {
|
||||
return handleGet(index, null);
|
||||
}
|
||||
protected ICUResourceBundle handleGet(int index, Hashtable table) {
|
||||
if (index > size) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
int itemOffset = offset + getIntOffset(index + 1);
|
||||
long itemResource = (UNSIGNED_INT_MASK)
|
||||
& rawData.getInt(itemOffset);
|
||||
return createBundleObject( null, itemResource, table);
|
||||
}
|
||||
private int countItems(){
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
int value = rawData.getInt(offset);
|
||||
return value;
|
||||
}
|
||||
private ResourceArray(String key, long resource) {
|
||||
this.resource = resource;
|
||||
this.key = key;
|
||||
this.type = RES_GET_TYPE(resource);
|
||||
this.size = countItems();
|
||||
this.baseName = baseName();
|
||||
this.localeID = localeID();
|
||||
this.parent = parent();
|
||||
|
||||
}
|
||||
}
|
||||
private class ResourceBinary extends ICUResourceBundle {
|
||||
private ByteBuffer value;
|
||||
public ByteBuffer getBinary() {
|
||||
value.rewind();
|
||||
return value;
|
||||
}
|
||||
private ByteBuffer getValue() {
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
int length = rawData.getInt(offset);
|
||||
int byteOffset = offset + getIntOffset(1);
|
||||
ByteBuffer val = ByteBuffer.allocate(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
val.put(rawData.get(byteOffset + i));
|
||||
}
|
||||
return val;
|
||||
}
|
||||
public ResourceBinary(String key, long resource) {
|
||||
this.resource = resource;
|
||||
this.key = key;
|
||||
this.type = RES_GET_TYPE(resource);
|
||||
this.baseName = baseName();
|
||||
this.localeID = localeID();
|
||||
this.parent = parent();
|
||||
value = getValue();
|
||||
}
|
||||
}
|
||||
private class ResourceIntVector extends ICUResourceBundle {
|
||||
private int[] value;
|
||||
public int[] getIntVector() {
|
||||
return value;
|
||||
}
|
||||
private int[] getValue() {
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
int length = rawData.getInt(offset);
|
||||
int intOffset = offset + getIntOffset(1);
|
||||
int[] val = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
val[i] = rawData.getInt(intOffset + getIntOffset(i));
|
||||
}
|
||||
return val;
|
||||
}
|
||||
public ResourceIntVector(String key, long resource) {
|
||||
this.key = key;
|
||||
this.resource = resource;
|
||||
this.size = 1;
|
||||
this.type = RES_GET_TYPE(resource);
|
||||
value = getValue();
|
||||
this.baseName = baseName();
|
||||
this.localeID = localeID();
|
||||
this.parent = parent();
|
||||
}
|
||||
}
|
||||
private String getStringValue(long resource) {
|
||||
int offset = RES_GET_OFFSET(resource);
|
||||
int length = rawData.getInt(offset);
|
||||
int stringOffset = offset + getIntOffset(1);
|
||||
StringBuffer val = new StringBuffer();
|
||||
for (int i = 0; i < length; i++) {
|
||||
val.append(rawData.getChar(stringOffset + getCharOffset(i)));
|
||||
}
|
||||
return val.toString();
|
||||
}
|
||||
private static final char RES_PATH_SEP_CHAR = '/';
|
||||
private static final String ICUDATA = "ICUDATA";
|
||||
private static final int getIndex(String s) {
|
||||
if (s.length() == 1) {
|
||||
char c = s.charAt(0);
|
||||
if (Character.isDigit(c)) {
|
||||
return Integer.valueOf(s).intValue();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
private ICUResourceBundle findResource(String key, long resource, Hashtable table) {
|
||||
String locale = null, keyPath = null;
|
||||
String bundleName;
|
||||
String resPath = getStringValue(resource);
|
||||
if (table == null) {
|
||||
table = new Hashtable();
|
||||
}
|
||||
if (table.get(resPath) != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Circular references in the resource bundles");
|
||||
}
|
||||
table.put(resPath, "");
|
||||
if (resPath.indexOf(RES_PATH_SEP_CHAR) == 0) {
|
||||
int i = resPath.indexOf(RES_PATH_SEP_CHAR, 1);
|
||||
int j = resPath.indexOf(RES_PATH_SEP_CHAR, i + 1);
|
||||
bundleName = resPath.substring(1, i);
|
||||
locale = resPath.substring(i + 1);
|
||||
if (j != -1) {
|
||||
locale = resPath.substring(i + 1, j);
|
||||
keyPath = resPath.substring(j + 1, resPath.length());
|
||||
}
|
||||
//there is a path included
|
||||
if (bundleName.equals(ICUDATA)) {
|
||||
bundleName = ICU_BASE_NAME;
|
||||
}
|
||||
} else {
|
||||
//no path start with locale
|
||||
int i = resPath.indexOf(RES_PATH_SEP_CHAR);
|
||||
keyPath = resPath.substring(i + 1);
|
||||
if (i != -1) {
|
||||
locale = resPath.substring(0, i);
|
||||
} else {
|
||||
locale = keyPath;
|
||||
keyPath = null;//keyPath.substring(i, keyPath.length());
|
||||
}
|
||||
bundleName = baseName;
|
||||
}
|
||||
ICUResourceBundle bundle = null;
|
||||
if (locale == null) {
|
||||
bundle = (ICUResourceBundle) getBundleInstance(bundleName, "",
|
||||
ICU_DATA_CLASS_LOADER, false);
|
||||
} else {
|
||||
bundle = (ICUResourceBundle) getBundleInstance(bundleName, locale,
|
||||
ICU_DATA_CLASS_LOADER, false);
|
||||
}
|
||||
ICUResourceBundle sub = null;
|
||||
if (keyPath != null) {
|
||||
StringTokenizer st = new StringTokenizer(keyPath, "/");
|
||||
ICUResourceBundle current = bundle;
|
||||
while (st.hasMoreTokens()) {
|
||||
String subKey = st.nextToken();
|
||||
sub = current.handleGet(subKey, table);
|
||||
if (sub == null) {
|
||||
break;
|
||||
}
|
||||
current = sub;
|
||||
}
|
||||
} else {
|
||||
// if the sub resource is not found
|
||||
// try fetching the sub resource with
|
||||
// the key of this alias resource
|
||||
sub = bundle.get(key);
|
||||
}
|
||||
if (sub == null) {
|
||||
throw new MissingResourceException(localeID, baseName, key);
|
||||
}
|
||||
sub.resPath = resPath;
|
||||
return sub;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user