summaryrefslogtreecommitdiff
path: root/deps/icu-small/source/common/uresdata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'deps/icu-small/source/common/uresdata.cpp')
-rw-r--r--deps/icu-small/source/common/uresdata.cpp347
1 files changed, 179 insertions, 168 deletions
diff --git a/deps/icu-small/source/common/uresdata.cpp b/deps/icu-small/source/common/uresdata.cpp
index 00231d7fc2..f775bcdffb 100644
--- a/deps/icu-small/source/common/uresdata.cpp
+++ b/deps/icu-small/source/common/uresdata.cpp
@@ -1,3 +1,5 @@
+// Copyright (C) 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
* Copyright (C) 1999-2016, International Business Machines Corporation
@@ -380,6 +382,36 @@ UBool isNoInheritanceMarker(const ResourceData *pResData, Resource res) {
return FALSE;
}
+int32_t getStringArray(const ResourceData *pResData, const icu::ResourceArray &array,
+ icu::UnicodeString *dest, int32_t capacity,
+ UErrorCode &errorCode) {
+ if(U_FAILURE(errorCode)) {
+ return 0;
+ }
+ if(dest == NULL ? capacity != 0 : capacity < 0) {
+ errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+ return 0;
+ }
+ int32_t length = array.getSize();
+ if(length == 0) {
+ return 0;
+ }
+ if(length > capacity) {
+ errorCode = U_BUFFER_OVERFLOW_ERROR;
+ return length;
+ }
+ for(int32_t i = 0; i < length; ++i) {
+ int32_t sLength;
+ const UChar *s = res_getString(pResData, array.internalGetResource(pResData, i), &sLength);
+ if(s == NULL) {
+ errorCode = U_RESOURCE_TYPE_MISMATCH;
+ return 0;
+ }
+ dest[i].setTo(TRUE, s, sLength);
+ }
+ return length;
+}
+
} // namespace
U_CAPI const UChar * U_EXPORT2
@@ -463,42 +495,6 @@ res_countArrayItems(const ResourceData *pResData, Resource res) {
}
}
-namespace {
-
-int32_t getArrayLength(const ResourceData *pResData, Resource res) {
- uint32_t offset=RES_GET_OFFSET(res);
- if(offset == 0) {
- return 0;
- }
- int32_t type = RES_GET_TYPE(res);
- if(type == URES_ARRAY) {
- return *(pResData->pRoot+offset);
- } else if(type == URES_ARRAY16) {
- return pResData->p16BitUnits[offset];
- } else {
- return 0;
- }
-}
-
-int32_t getTableLength(const ResourceData *pResData, Resource res) {
- uint32_t offset=RES_GET_OFFSET(res);
- if(offset == 0) {
- return 0;
- }
- int32_t type = RES_GET_TYPE(res);
- if(type == URES_TABLE) {
- return *((const uint16_t *)(pResData->pRoot+offset));
- } else if(type == URES_TABLE16) {
- return pResData->p16BitUnits[offset];
- } else if(type == URES_TABLE32) {
- return *(pResData->pRoot+offset);
- } else {
- return 0;
- }
-}
-
-} // namespace
-
U_NAMESPACE_BEGIN
ResourceDataValue::~ResourceDataValue() {}
@@ -571,6 +567,130 @@ const uint8_t *ResourceDataValue::getBinary(int32_t &length, UErrorCode &errorCo
return b;
}
+ResourceArray ResourceDataValue::getArray(UErrorCode &errorCode) const {
+ if(U_FAILURE(errorCode)) {
+ return ResourceArray();
+ }
+ const uint16_t *items16 = NULL;
+ const Resource *items32 = NULL;
+ uint32_t offset=RES_GET_OFFSET(res);
+ int32_t length = 0;
+ switch(RES_GET_TYPE(res)) {
+ case URES_ARRAY:
+ if (offset!=0) { // empty if offset==0
+ items32 = (const Resource *)pResData->pRoot+offset;
+ length = *items32++;
+ }
+ break;
+ case URES_ARRAY16:
+ items16 = pResData->p16BitUnits+offset;
+ length = *items16++;
+ break;
+ default:
+ errorCode = U_RESOURCE_TYPE_MISMATCH;
+ return ResourceArray();
+ }
+ return ResourceArray(items16, items32, length);
+}
+
+ResourceTable ResourceDataValue::getTable(UErrorCode &errorCode) const {
+ if(U_FAILURE(errorCode)) {
+ return ResourceTable();
+ }
+ const uint16_t *keys16 = NULL;
+ const int32_t *keys32 = NULL;
+ const uint16_t *items16 = NULL;
+ const Resource *items32 = NULL;
+ uint32_t offset = RES_GET_OFFSET(res);
+ int32_t length = 0;
+ switch(RES_GET_TYPE(res)) {
+ case URES_TABLE:
+ if (offset != 0) { // empty if offset==0
+ keys16 = (const uint16_t *)(pResData->pRoot+offset);
+ length = *keys16++;
+ items32 = (const Resource *)(keys16+length+(~length&1));
+ }
+ break;
+ case URES_TABLE16:
+ keys16 = pResData->p16BitUnits+offset;
+ length = *keys16++;
+ items16 = keys16 + length;
+ break;
+ case URES_TABLE32:
+ if (offset != 0) { // empty if offset==0
+ keys32 = pResData->pRoot+offset;
+ length = *keys32++;
+ items32 = (const Resource *)keys32 + length;
+ }
+ break;
+ default:
+ errorCode = U_RESOURCE_TYPE_MISMATCH;
+ return ResourceTable();
+ }
+ return ResourceTable(keys16, keys32, items16, items32, length);
+}
+
+UBool ResourceDataValue::isNoInheritanceMarker() const {
+ return ::isNoInheritanceMarker(pResData, res);
+}
+
+int32_t ResourceDataValue::getStringArray(UnicodeString *dest, int32_t capacity,
+ UErrorCode &errorCode) const {
+ return ::getStringArray(pResData, getArray(errorCode), dest, capacity, errorCode);
+}
+
+int32_t ResourceDataValue::getStringArrayOrStringAsArray(UnicodeString *dest, int32_t capacity,
+ UErrorCode &errorCode) const {
+ if(URES_IS_ARRAY(res)) {
+ return ::getStringArray(pResData, getArray(errorCode), dest, capacity, errorCode);
+ }
+ if(U_FAILURE(errorCode)) {
+ return 0;
+ }
+ if(dest == NULL ? capacity != 0 : capacity < 0) {
+ errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+ return 0;
+ }
+ if(capacity < 1) {
+ errorCode = U_BUFFER_OVERFLOW_ERROR;
+ return 1;
+ }
+ int32_t sLength;
+ const UChar *s = res_getString(pResData, res, &sLength);
+ if(s != NULL) {
+ dest[0].setTo(TRUE, s, sLength);
+ return 1;
+ }
+ errorCode = U_RESOURCE_TYPE_MISMATCH;
+ return 0;
+}
+
+UnicodeString ResourceDataValue::getStringOrFirstOfArray(UErrorCode &errorCode) const {
+ UnicodeString us;
+ if(U_FAILURE(errorCode)) {
+ return us;
+ }
+ int32_t sLength;
+ const UChar *s = res_getString(pResData, res, &sLength);
+ if(s != NULL) {
+ us.setTo(TRUE, s, sLength);
+ return us;
+ }
+ ResourceArray array = getArray(errorCode);
+ if(U_FAILURE(errorCode)) {
+ return us;
+ }
+ if(array.getSize() > 0) {
+ s = res_getString(pResData, array.internalGetResource(pResData, 0), &sLength);
+ if(s != NULL) {
+ us.setTo(TRUE, s, sLength);
+ return us;
+ }
+ }
+ errorCode = U_RESOURCE_TYPE_MISMATCH;
+ return us;
+}
+
U_NAMESPACE_END
static Resource
@@ -691,91 +811,26 @@ res_getResource(const ResourceData *pResData, const char *key) {
return res_getTableItemByKey(pResData, pResData->rootRes, &idx, &realKey);
}
-// TODO: Ported from Java, but enumerating at this low level may prevent us
-// from doing necessary things, like resolving aliases,
-// which need access to higher-level UResourceBundle code.
-// Consider porting the low-level Container/Array/Table classes from Java,
-// with getters for keys and values,
-// and doing the enumeration in the higher-level code on top of those accessors.
-U_CFUNC void
-ures_getAllTableItems(const ResourceData *pResData, Resource table,
- icu::ResourceDataValue &value, icu::ResourceTableSink &sink,
- UErrorCode &errorCode) {
- if(U_FAILURE(errorCode)) { return; }
- const uint16_t *keys16 = NULL;
- const int32_t *keys32 = NULL;
- const uint16_t *items16 = NULL;
- const Resource *items32 = NULL;
- uint32_t offset = RES_GET_OFFSET(table);
- int32_t length = 0;
- switch(RES_GET_TYPE(table)) {
- case URES_TABLE: {
- if (offset != 0) { /* empty if offset==0 */
- keys16 = (const uint16_t *)(pResData->pRoot+offset);
- length = *keys16++;
- items32 = (const Resource *)(keys16+length+(~length&1));
- }
- break;
- }
- case URES_TABLE16: {
- keys16 = pResData->p16BitUnits+offset;
- length = *keys16++;
- items16 = keys16 + length;
- break;
- }
- case URES_TABLE32: {
- if (offset != 0) { /* empty if offset==0 */
- keys32 = pResData->pRoot+offset;
- length = *keys32++;
- items32 = (const Resource *)keys32 + length;
- }
- break;
- }
- default:
- errorCode = U_RESOURCE_TYPE_MISMATCH;
- return;
- }
- for (int32_t i = 0; i < length; ++i) {
- const char *key;
+UBool icu::ResourceTable::getKeyAndValue(int32_t i,
+ const char *&key, icu::ResourceValue &value) const {
+ if(0 <= i && i < length) {
+ icu::ResourceDataValue &rdValue = static_cast<icu::ResourceDataValue &>(value);
if (keys16 != NULL) {
- key=RES_GET_KEY16(pResData, keys16[i]);
+ key = RES_GET_KEY16(rdValue.pResData, keys16[i]);
} else {
- key=RES_GET_KEY32(pResData, keys32[i]);
+ key = RES_GET_KEY32(rdValue.pResData, keys32[i]);
}
Resource res;
if (items16 != NULL) {
- res = makeResourceFrom16(pResData, items16[i]);
+ res = makeResourceFrom16(rdValue.pResData, items16[i]);
} else {
res = items32[i];
}
- int32_t type = RES_GET_TYPE(res);
- if (URES_IS_ARRAY(type)) {
- int32_t numItems = getArrayLength(pResData, res);
- icu::ResourceArraySink *subSink = sink.getOrCreateArraySink(key, numItems, errorCode);
- if (subSink != NULL) {
- ures_getAllArrayItems(pResData, res, value, *subSink, errorCode);
- }
- } else if (URES_IS_TABLE(type)) {
- int32_t numItems = getTableLength(pResData, res);
- icu::ResourceTableSink *subSink = sink.getOrCreateTableSink(key, numItems, errorCode);
- if (subSink != NULL) {
- ures_getAllTableItems(pResData, res, value, *subSink, errorCode);
- }
- /* TODO: settle on how to deal with aliases, port to Java
- } else if (type == URES_ALIAS) {
- // aliases not handled in resource enumeration
- errorCode = U_UNSUPPORTED_ERROR;
- return; */
- } else if (isNoInheritanceMarker(pResData, res)) {
- sink.putNoFallback(key, errorCode);
- } else {
- value.setResource(res);
- sink.put(key, value, errorCode);
- }
- if(U_FAILURE(errorCode)) { return; }
+ rdValue.setResource(res);
+ return TRUE;
}
- sink.leave(errorCode);
+ return FALSE;
}
U_CAPI Resource U_EXPORT2
@@ -805,65 +860,21 @@ res_getArrayItem(const ResourceData *pResData, Resource array, int32_t indexR) {
return RES_BOGUS;
}
-U_CFUNC void
-ures_getAllArrayItems(const ResourceData *pResData, Resource array,
- icu::ResourceDataValue &value, icu::ResourceArraySink &sink,
- UErrorCode &errorCode) {
- if(U_FAILURE(errorCode)) { return; }
- const uint16_t *items16 = NULL;
- const Resource *items32 = NULL;
- uint32_t offset=RES_GET_OFFSET(array);
- int32_t length = 0;
- switch(RES_GET_TYPE(array)) {
- case URES_ARRAY: {
- if (offset!=0) { /* empty if offset==0 */
- items32 = (const Resource *)pResData->pRoot+offset;
- length = *items32++;
- }
- break;
- }
- case URES_ARRAY16: {
- items16 = pResData->p16BitUnits+offset;
- length = *items16++;
- break;
- }
- default:
- errorCode = U_RESOURCE_TYPE_MISMATCH;
- return;
+uint32_t icu::ResourceArray::internalGetResource(const ResourceData *pResData, int32_t i) const {
+ if (items16 != NULL) {
+ return makeResourceFrom16(pResData, items16[i]);
+ } else {
+ return items32[i];
}
+}
- for (int32_t i = 0; i < length; ++i) {
- Resource res;
- if (items16 != NULL) {
- res = makeResourceFrom16(pResData, items16[i]);
- } else {
- res = items32[i];
- }
- int32_t type = RES_GET_TYPE(res);
- if (URES_IS_ARRAY(type)) {
- int32_t numItems = getArrayLength(pResData, res);
- icu::ResourceArraySink *subSink = sink.getOrCreateArraySink(i, numItems, errorCode);
- if (subSink != NULL) {
- ures_getAllArrayItems(pResData, res, value, *subSink, errorCode);
- }
- } else if (URES_IS_TABLE(type)) {
- int32_t numItems = getTableLength(pResData, res);
- icu::ResourceTableSink *subSink = sink.getOrCreateTableSink(i, numItems, errorCode);
- if (subSink != NULL) {
- ures_getAllTableItems(pResData, res, value, *subSink, errorCode);
- }
- /* TODO: settle on how to deal with aliases, port to Java
- } else if (type == URES_ALIAS) {
- // aliases not handled in resource enumeration
- errorCode = U_UNSUPPORTED_ERROR;
- return; */
- } else {
- value.setResource(res);
- sink.put(i, value, errorCode);
- }
- if(U_FAILURE(errorCode)) { return; }
+UBool icu::ResourceArray::getValue(int32_t i, icu::ResourceValue &value) const {
+ if(0 <= i && i < length) {
+ icu::ResourceDataValue &rdValue = static_cast<icu::ResourceDataValue &>(value);
+ rdValue.setResource(internalGetResource(rdValue.pResData, i));
+ return TRUE;
}
- sink.leave(errorCode);
+ return FALSE;
}
U_CFUNC Resource
@@ -974,7 +985,7 @@ typedef struct Row {
int32_t keyIndex, sortIndex;
} Row;
-static int32_t
+static int32_t U_CALLCONV
ures_compareRows(const void *context, const void *left, const void *right) {
const char *keyChars=(const char *)context;
return (int32_t)uprv_strcmp(keyChars+((const Row *)left)->keyIndex,