#include "resource.h"
-#include "unicode/utypes.h"
-#include "unicode/uobject.h"
-#include "unicode/ures.h"
-
U_NAMESPACE_BEGIN
ResourceValue::~ResourceValue() {}
ResourceSink::~ResourceSink() {}
-ResourceTableSink::~ResourceTableSink() {}
-
-void ResourceTableSink::put(
- const char * /*key*/, const ResourceValue & /*value*/, UErrorCode & /*errorCode*/) {}
-
-void ResourceTableSink::putNoFallback(const char * /*key*/, UErrorCode & /*errorCode*/) {}
-
-ResourceTableSink *ResourceTableSink::getOrCreateTableSink(
- const char * /*key*/, UErrorCode & /*errorCode*/) {
- return NULL;
-}
-
U_NAMESPACE_END
U_NAMESPACE_BEGIN
-class ResourceTableSink;
class ResourceValue;
// Note: In C++, we use const char * pointers for keys,
ResourceSink &operator=(const ResourceSink &); // no assignment operator
};
-/**
- * Sink for ICU resource table contents.
- * The base class does nothing.
- *
- * Nested arrays and tables are stored as nested sinks,
- * never put() as ResourceValue items.
- */
-class U_COMMON_API ResourceTableSink : public UObject {
-public:
- ResourceTableSink() {}
- virtual ~ResourceTableSink();
-
- /**
- * Adds a key-value pair from a resource table.
- *
- * @param key resource key string
- * @param value resource value
- */
- virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode);
-
- /**
- * Adds a no-fallback/no-inheritance marker for this key.
- * Used for CLDR no-fallback data values of (three empty-set symbols)=={2205, 2205, 2205}
- * when enumerating tables with fallback from the specific resource bundle to root.
- *
- * The default implementation does nothing.
- *
- * @param key to be removed
- */
- virtual void putNoFallback(const char *key, UErrorCode &errorCode);
-
- /**
- * Returns a nested resource table for the key as another sink.
- * Creates the sink if none exists for the key.
- * Returns NULL if nested tables are not supported.
- * The default implementation always returns NULL.
- *
- * This sink (not the caller) owns the nested sink.
- *
- * @param key resource key string
- * @return nested-table sink, or NULL
- */
- virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode &errorCode);
-
-private:
- ResourceTableSink(const ResourceTableSink &); // no copy constructor
- ResourceTableSink &operator=(const ResourceTableSink &); // no assignment operator
-};
-
U_NAMESPACE_END
#endif
#define ures_findResource U_ICU_ENTRY_POINT_RENAME(ures_findResource)
#define ures_findSubResource U_ICU_ENTRY_POINT_RENAME(ures_findSubResource)
#define ures_getAllItemsWithFallback U_ICU_ENTRY_POINT_RENAME(ures_getAllItemsWithFallback)
-#define ures_getAllTableItems U_ICU_ENTRY_POINT_RENAME(ures_getAllTableItems)
-#define ures_getAllTableItemsWithFallback U_ICU_ENTRY_POINT_RENAME(ures_getAllTableItemsWithFallback)
#define ures_getBinary U_ICU_ENTRY_POINT_RENAME(ures_getBinary)
#define ures_getByIndex U_ICU_ENTRY_POINT_RENAME(ures_getByIndex)
#define ures_getByKey U_ICU_ENTRY_POINT_RENAME(ures_getByKey)
void getAllItemsWithFallback(
const UResourceBundle *bundle, ResourceDataValue &value,
- ResourceSink *sink,
- ResourceTableSink *tableSink,
+ ResourceSink &sink,
UErrorCode &errorCode) {
if (U_FAILURE(errorCode)) { return; }
// We recursively enumerate child-first,
value.pResData = &bundle->fResData;
UResourceDataEntry *parentEntry = bundle->fData->fParent;
UBool hasParent = parentEntry != NULL && U_SUCCESS(parentEntry->fBogus);
- UResType expectedType;
- if (sink != NULL) {
- expectedType = URES_NONE;
- value.setResource(bundle->fRes);
- sink->put(bundle->fKey, value, !hasParent, errorCode);
- } else {
- expectedType = URES_TABLE;
- if (ures_getType(bundle) == expectedType) {
- //tableSink != NULL
- ures_getAllTableItems(&bundle->fResData, bundle->fRes, value, *tableSink, errorCode);
- }
- }
+ value.setResource(bundle->fRes);
+ sink.put(bundle->fKey, value, !hasParent, errorCode);
if (hasParent) {
// We might try to query the sink whether
// any fallback from the parent bundle is still possible.
rb = ures_getByKeyWithFallback(&parentBundle, bundle->fResPath,
&containerBundle, &pathErrorCode);
}
- if (U_SUCCESS(pathErrorCode) && (expectedType == URES_NONE || ures_getType(rb) == expectedType)) {
- getAllItemsWithFallback(rb, value, sink, tableSink, errorCode);
+ if (U_SUCCESS(pathErrorCode)) {
+ getAllItemsWithFallback(rb, value, sink, errorCode);
}
ures_close(&containerBundle);
ures_close(&parentBundle);
}
}
-void getAllItemsWithFallback(
- const UResourceBundle *bundle, const char *path,
- ResourceSink *sink,
- ResourceTableSink *tableSink,
- UErrorCode &errorCode) {
+} // namespace
+
+U_CAPI void U_EXPORT2
+ures_getAllItemsWithFallback(const UResourceBundle *bundle, const char *path,
+ icu::ResourceSink &sink, UErrorCode &errorCode) {
if (U_FAILURE(errorCode)) { return; }
if (path == NULL) {
errorCode = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
}
- if (sink == NULL) {
- UResType expectedType = URES_TABLE;
- if (ures_getType(rb) != expectedType) {
- errorCode = U_RESOURCE_TYPE_MISMATCH;
- ures_close(&stackBundle);
- return;
- }
- }
// Get all table items with fallback.
ResourceDataValue value;
- getAllItemsWithFallback(rb, value, sink, tableSink, errorCode);
+ getAllItemsWithFallback(rb, value, sink, errorCode);
ures_close(&stackBundle);
}
-} // namespace
-
-U_CAPI void U_EXPORT2
-ures_getAllItemsWithFallback(const UResourceBundle *bundle, const char *path,
- icu::ResourceSink &sink, UErrorCode &errorCode) {
- getAllItemsWithFallback(bundle, path, &sink, NULL, errorCode);
-}
-
-U_CAPI void U_EXPORT2
-ures_getAllTableItemsWithFallback(const UResourceBundle *bundle, const char *path,
- ResourceTableSink &sink, UErrorCode &errorCode) {
- getAllItemsWithFallback(bundle, path, NULL, &sink, errorCode);
-}
-
U_CAPI UResourceBundle* U_EXPORT2 ures_getByKey(const UResourceBundle *resB, const char* inKey, UResourceBundle *fillIn, UErrorCode *status) {
Resource res = RES_BOGUS;
UResourceDataEntry *realData = NULL;
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;
- }
- if(U_FAILURE(errorCode)) { return; }
-
- for (int32_t i = 0; i < length; ++i) {
- const char *key;
- if (keys16 != NULL) {
- key=RES_GET_KEY16(pResData, keys16[i]);
- } else {
- key=RES_GET_KEY32(pResData, keys32[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)) {
- // ICU ticket #12634: This original version of the enumeration code
- // is going away. getOrCreateArraySink(key) was unused and has been removed.
- } else if (URES_IS_TABLE(type)) {
- icu::ResourceTableSink *subSink = sink.getOrCreateTableSink(key, 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; }
- }
-}
UBool icu::ResourceTable::getKeyAndValue(int32_t i,
const char *&key, icu::ResourceValue &value) const {
U_NAMESPACE_END
-/**
- * @param value will be set during enumeration; input contents is ignored
- * @param sink receives all table item key-value pairs
- */
-U_CFUNC void
-ures_getAllTableItems(const ResourceData *pResData, Resource table,
- icu::ResourceDataValue &value, icu::ResourceTableSink &sink,
- UErrorCode &errorCode);
-
#endif /* __cplusplus */
/**
ures_getAllItemsWithFallback(const UResourceBundle *bundle, const char *path,
icu::ResourceSink &sink, UErrorCode &errorCode);
-U_CAPI void U_EXPORT2
-ures_getAllTableItemsWithFallback(const UResourceBundle *bundle, const char *path,
- icu::ResourceTableSink &sink, UErrorCode &errorCode);
-
#endif /* __cplusplus */
/**