Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Unified Diff: source/common/uresbund.cpp

Issue 1621943002: ICU 56 step 4: Apply post-56 fixes for measure/date format (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@56goog
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/common/simplepatternformatter.cpp ('k') | source/common/uresdata.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/common/uresbund.cpp
diff --git a/source/common/uresbund.cpp b/source/common/uresbund.cpp
index e74afb8a483db2ed251c39a82de835ca216901f4..b2d071a09f93835b9f5a3d0fd4ce69e738b53993 100644
--- a/source/common/uresbund.cpp
+++ b/source/common/uresbund.cpp
@@ -1882,6 +1882,121 @@ ures_getByKeyWithFallback(const UResourceBundle *resB,
return fillIn;
}
+namespace {
+
+void getAllContainerItemsWithFallback(
+ const UResourceBundle *bundle, ResourceDataValue &value,
+ ResourceArraySink *arraySink, ResourceTableSink *tableSink,
+ UErrorCode &errorCode) {
+ if (U_FAILURE(errorCode)) { return; }
+ // We recursively enumerate child-first,
+ // only storing parent items in the absence of child items.
+ // We store a placeholder value for the no-fallback/no-inheritance marker
+ // to prevent a parent item from being stored.
+ //
+ // It would be possible to recursively enumerate parent-first,
+ // overriding parent items with child items.
+ // When we see the no-fallback/no-inheritance marker,
+ // then we would remove the parent's item.
+ // We would deserialize parent values even though they are overridden in a child bundle.
+ UResType expectedType = arraySink != NULL ? URES_ARRAY : URES_TABLE;
+ if (ures_getType(bundle) == expectedType) {
+ value.pResData = &bundle->fResData;
+ if (arraySink != NULL) {
+ ures_getAllArrayItems(&bundle->fResData, bundle->fRes, value, *arraySink, errorCode);
+ } else /* tableSink != NULL */ {
+ ures_getAllTableItems(&bundle->fResData, bundle->fRes, value, *tableSink, errorCode);
+ }
+ }
+ UResourceDataEntry *entry = bundle->fData->fParent;
+ if (entry != NULL && U_SUCCESS(entry->fBogus)) {
+ // We might try to query the sink whether
+ // any fallback from the parent bundle is still possible.
+
+ // Turn the parent UResourceDataEntry into a UResourceBundle,
+ // much like in ures_openWithType().
+ // TODO: See if we can refactor ures_getByKeyWithFallback()
+ // and pull out an inner function that takes and returns a UResourceDataEntry
+ // so that we need not create UResourceBundle objects.
+ UResourceBundle parentBundle;
+ ures_initStackObject(&parentBundle);
+ parentBundle.fTopLevelData = parentBundle.fData = entry;
+ // TODO: What is the difference between bundle fData and fTopLevelData?
+ uprv_memcpy(&parentBundle.fResData, &entry->fData, sizeof(ResourceData));
+ // TODO: Try to replace bundle.fResData with just using bundle.fData->fData.
+ parentBundle.fHasFallback = !parentBundle.fResData.noFallback;
+ parentBundle.fIsTopLevel = TRUE;
+ parentBundle.fRes = parentBundle.fResData.rootRes;
+ parentBundle.fSize = res_countArrayItems(&(parentBundle.fResData), parentBundle.fRes);
+ parentBundle.fIndex = -1;
+ entryIncrease(entry);
+
+ // Look up the container item in the parent bundle.
+ UResourceBundle containerBundle;
+ ures_initStackObject(&containerBundle);
+ const UResourceBundle *rb;
+ if (bundle->fResPath == NULL || *bundle->fResPath == 0) {
+ rb = &parentBundle;
+ } else {
+ rb = ures_getByKeyWithFallback(&parentBundle, bundle->fResPath,
+ &containerBundle, &errorCode);
+ }
+ if (U_SUCCESS(errorCode) && ures_getType(rb) == expectedType) {
+ getAllContainerItemsWithFallback(rb, value,
+ arraySink, tableSink, errorCode);
+ }
+ ures_close(&containerBundle);
+ ures_close(&parentBundle);
+ }
+}
+
+void getAllContainerItemsWithFallback(
+ const UResourceBundle *bundle, const char *path,
+ ResourceArraySink *arraySink, ResourceTableSink *tableSink,
+ UErrorCode &errorCode) {
+ if (U_FAILURE(errorCode)) { return; }
+ if (path == NULL) {
+ errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+ UResourceBundle stackBundle;
+ ures_initStackObject(&stackBundle);
+ const UResourceBundle *rb;
+ if (*path == 0) {
+ // empty path
+ rb = bundle;
+ } else {
+ rb = ures_getByKeyWithFallback(bundle, path, &stackBundle, &errorCode);
+ if (U_FAILURE(errorCode)) {
+ ures_close(&stackBundle);
+ return;
+ }
+ }
+ UResType expectedType = arraySink != NULL ? URES_ARRAY : URES_TABLE;
+ if (ures_getType(rb) != expectedType) {
+ errorCode = U_RESOURCE_TYPE_MISMATCH;
+ ures_close(&stackBundle);
+ return;
+ }
+ // Get all table items with fallback.
+ ResourceDataValue value;
+ getAllContainerItemsWithFallback(rb, value, arraySink, tableSink, errorCode);
+ ures_close(&stackBundle);
+}
+
+} // namespace
+
+U_CAPI void U_EXPORT2
+ures_getAllArrayItemsWithFallback(const UResourceBundle *bundle, const char *path,
+ ResourceArraySink &sink, UErrorCode &errorCode) {
+ getAllContainerItemsWithFallback(bundle, path, &sink, NULL, errorCode);
+}
+
+U_CAPI void U_EXPORT2
+ures_getAllTableItemsWithFallback(const UResourceBundle *bundle, const char *path,
+ ResourceTableSink &sink, UErrorCode &errorCode) {
+ getAllContainerItemsWithFallback(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;
« no previous file with comments | « source/common/simplepatternformatter.cpp ('k') | source/common/uresdata.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698