From f292628ed7f4e2dc7a04811a4257eb1d3b5e4c02 Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Thu, 7 Apr 2016 00:18:33 +0000 Subject: [PATCH] ICU-12446 Resource sink size: move into new enter(size) method X-SVN-Rev: 38606 --- icu4c/source/common/resource.cpp | 14 +++++--- icu4c/source/common/resource.h | 38 +++++++++++++------- icu4c/source/common/uresdata.cpp | 52 +++++----------------------- icu4c/source/i18n/dayperiodrules.cpp | 10 +++--- icu4c/source/i18n/dtitvinf.cpp | 6 ++-- icu4c/source/i18n/dtptngen.cpp | 25 +++++++------ icu4c/source/i18n/measfmt.cpp | 9 ++--- icu4c/source/i18n/reldatefmt.cpp | 9 ++--- 8 files changed, 67 insertions(+), 96 deletions(-) diff --git a/icu4c/source/common/resource.cpp b/icu4c/source/common/resource.cpp index 7a4c4181bf8..c8c02f033f5 100644 --- a/icu4c/source/common/resource.cpp +++ b/icu4c/source/common/resource.cpp @@ -1,6 +1,6 @@ /* ******************************************************************************* -* Copyright (C) 2015, International Business Machines +* Copyright (C) 2015-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * resource.cpp @@ -22,16 +22,18 @@ ResourceValue::~ResourceValue() {} ResourceArraySink::~ResourceArraySink() {} +void ResourceArraySink::enter(int32_t /*size*/, UErrorCode & /*errorCode*/) {} + void ResourceArraySink::put( int32_t /*index*/, const ResourceValue & /*value*/, UErrorCode & /*errorCode*/) {} ResourceArraySink *ResourceArraySink::getOrCreateArraySink( - int32_t /*index*/, int32_t /*size*/, UErrorCode & /*errorCode*/) { + int32_t /*index*/, UErrorCode & /*errorCode*/) { return NULL; } ResourceTableSink *ResourceArraySink::getOrCreateTableSink( - int32_t /*index*/, int32_t /*initialSize*/, UErrorCode & /*errorCode*/) { + int32_t /*index*/, UErrorCode & /*errorCode*/) { return NULL; } @@ -40,18 +42,20 @@ void ResourceArraySink::leave(UErrorCode & /*errorCode*/) {} ResourceTableSink::~ResourceTableSink() {} +void ResourceTableSink::enter(int32_t /*size*/, UErrorCode & /*errorCode*/) {} + void ResourceTableSink::put( const char * /*key*/, const ResourceValue & /*value*/, UErrorCode & /*errorCode*/) {} void ResourceTableSink::putNoFallback(const char * /*key*/, UErrorCode & /*errorCode*/) {} ResourceArraySink *ResourceTableSink::getOrCreateArraySink( - const char * /*key*/, int32_t /*size*/, UErrorCode & /*errorCode*/) { + const char * /*key*/, UErrorCode & /*errorCode*/) { return NULL; } ResourceTableSink *ResourceTableSink::getOrCreateTableSink( - const char * /*key*/, int32_t /*initialSize*/, UErrorCode & /*errorCode*/) { + const char * /*key*/, UErrorCode & /*errorCode*/) { return NULL; } diff --git a/icu4c/source/common/resource.h b/icu4c/source/common/resource.h index 042e298b798..20e3e270d5d 100644 --- a/icu4c/source/common/resource.h +++ b/icu4c/source/common/resource.h @@ -1,6 +1,6 @@ /* ******************************************************************************* -* Copyright (C) 2015, International Business Machines +* Copyright (C) 2015-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * resource.h @@ -120,6 +120,16 @@ public: ResourceArraySink() {} virtual ~ResourceArraySink(); + /** + * "Enters" the array. + * Called just before enumerating the array's resource items. + * The size can be used to allocate storage for the items. + * It may differ between child and parent bundles. + * + * @param size number of array items + */ + virtual void enter(int32_t size, UErrorCode &errorCode); + /** * Adds a value from a resource array. * @@ -137,11 +147,9 @@ public: * This sink (not the caller) owns the nested sink. * * @param index of the resource array item - * @param size number of array items * @return nested-array sink, or NULL */ - virtual ResourceArraySink *getOrCreateArraySink( - int32_t index, int32_t size, UErrorCode &errorCode); + virtual ResourceArraySink *getOrCreateArraySink(int32_t index, UErrorCode &errorCode); /** * Returns a nested resource table at the array index as another sink. @@ -152,11 +160,9 @@ public: * This sink (not the caller) owns the nested sink. * * @param index of the resource array item - * @param initialSize size hint for creating the sink if necessary * @return nested-table sink, or NULL */ - virtual ResourceTableSink *getOrCreateTableSink( - int32_t index, int32_t initialSize, UErrorCode &errorCode); + virtual ResourceTableSink *getOrCreateTableSink(int32_t index, UErrorCode &errorCode); /** * "Leaves" the array. @@ -182,6 +188,16 @@ public: ResourceTableSink() {} virtual ~ResourceTableSink(); + /** + * "Enters" the table. + * Called just before enumerating the table's resource items. + * The size can be used to allocate storage for the items. + * It usually differs between child and parent bundles. + * + * @param size number of table items + */ + virtual void enter(int32_t size, UErrorCode &errorCode); + /** * Adds a key-value pair from a resource table. * @@ -210,11 +226,9 @@ public: * This sink (not the caller) owns the nested sink. * * @param key resource key string - * @param size number of array items * @return nested-array sink, or NULL */ - virtual ResourceArraySink *getOrCreateArraySink( - const char *key, int32_t size, UErrorCode &errorCode); + virtual ResourceArraySink *getOrCreateArraySink(const char *key, UErrorCode &errorCode); /** * Returns a nested resource table for the key as another sink. @@ -225,11 +239,9 @@ public: * This sink (not the caller) owns the nested sink. * * @param key resource key string - * @param initialSize size hint for creating the sink if necessary * @return nested-table sink, or NULL */ - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t initialSize, UErrorCode &errorCode); + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode &errorCode); /** * "Leaves" the table. diff --git a/icu4c/source/common/uresdata.cpp b/icu4c/source/common/uresdata.cpp index d88053bd611..90034ca2416 100644 --- a/icu4c/source/common/uresdata.cpp +++ b/icu4c/source/common/uresdata.cpp @@ -463,42 +463,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() {} @@ -735,6 +699,8 @@ ures_getAllTableItems(const ResourceData *pResData, Resource table, errorCode = U_RESOURCE_TYPE_MISMATCH; return; } + sink.enter(length, errorCode); + if(U_FAILURE(errorCode)) { return; } for (int32_t i = 0; i < length; ++i) { const char *key; @@ -751,14 +717,12 @@ ures_getAllTableItems(const ResourceData *pResData, Resource table, } 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); + icu::ResourceArraySink *subSink = sink.getOrCreateArraySink(key, 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); + icu::ResourceTableSink *subSink = sink.getOrCreateTableSink(key, errorCode); if (subSink != NULL) { ures_getAllTableItems(pResData, res, value, *subSink, errorCode); } @@ -831,6 +795,8 @@ ures_getAllArrayItems(const ResourceData *pResData, Resource array, errorCode = U_RESOURCE_TYPE_MISMATCH; return; } + sink.enter(length, errorCode); + if(U_FAILURE(errorCode)) { return; } for (int32_t i = 0; i < length; ++i) { Resource res; @@ -841,14 +807,12 @@ ures_getAllArrayItems(const ResourceData *pResData, Resource array, } 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); + icu::ResourceArraySink *subSink = sink.getOrCreateArraySink(i, 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); + icu::ResourceTableSink *subSink = sink.getOrCreateTableSink(i, errorCode); if (subSink != NULL) { ures_getAllTableItems(pResData, res, value, *subSink, errorCode); } diff --git a/icu4c/source/i18n/dayperiodrules.cpp b/icu4c/source/i18n/dayperiodrules.cpp index fb8ae8147f8..3146d7d9a29 100644 --- a/icu4c/source/i18n/dayperiodrules.cpp +++ b/icu4c/source/i18n/dayperiodrules.cpp @@ -51,7 +51,7 @@ struct DayPeriodRulesDataSink : public ResourceTableSink { virtual ~DayPeriodRulesDataSink(); // Entry point. - virtual ResourceTableSink *getOrCreateTableSink(const char *key, int32_t, UErrorCode &errorCode) { + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode &errorCode) { if (U_FAILURE(errorCode)) { return NULL; } if (uprv_strcmp(key, "locales") == 0) { @@ -88,7 +88,7 @@ struct DayPeriodRulesDataSink : public ResourceTableSink { RulesSink(DayPeriodRulesDataSink &outer) : outer(outer) {} virtual ~RulesSink(); - virtual ResourceTableSink *getOrCreateTableSink(const char *key, int32_t, UErrorCode &errorCode) { + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode &errorCode) { if (U_FAILURE(errorCode)) { return NULL; } outer.ruleSetNum = parseSetNum(key, errorCode); @@ -102,7 +102,7 @@ struct DayPeriodRulesDataSink : public ResourceTableSink { RuleSetSink(DayPeriodRulesDataSink &outer) : outer(outer) {} virtual ~RuleSetSink(); - virtual ResourceTableSink *getOrCreateTableSink(const char *key, int32_t, UErrorCode &errorCode) { + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode &errorCode) { if (U_FAILURE(errorCode)) { return NULL; } outer.period = DayPeriodRules::getDayPeriodFromString(key); @@ -138,7 +138,7 @@ struct DayPeriodRulesDataSink : public ResourceTableSink { outer.addCutoff(type, value.getUnicodeString(errorCode), errorCode); } - virtual ResourceArraySink *getOrCreateArraySink(const char *key, int32_t, UErrorCode &errorCode) { + virtual ResourceArraySink *getOrCreateArraySink(const char *key, UErrorCode &errorCode) { if (U_FAILURE(errorCode)) { return NULL; } outer.cutoffType = getCutoffTypeFromString(key); return &outer.cutoffSink; @@ -318,7 +318,7 @@ struct DayPeriodRulesDataSink : public ResourceTableSink { struct DayPeriodRulesCountSink : public ResourceTableSink { virtual ~DayPeriodRulesCountSink(); - virtual ResourceTableSink *getOrCreateTableSink(const char *key, int32_t, UErrorCode &errorCode) { + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode &errorCode) { if (U_FAILURE(errorCode)) { return NULL; } int32_t setNum = DayPeriodRulesDataSink::parseSetNum(key, errorCode); diff --git a/icu4c/source/i18n/dtitvinf.cpp b/icu4c/source/i18n/dtitvinf.cpp index 4553159e6c5..2f1e0ed2636 100644 --- a/icu4c/source/i18n/dtitvinf.cpp +++ b/icu4c/source/i18n/dtitvinf.cpp @@ -234,8 +234,7 @@ struct DateIntervalSink : public ResourceTableSink { SkeletonSink(DateIntervalSink &sink) : outer(sink) {} virtual ~SkeletonSink(); - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t, UErrorCode &errorCode) { + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode &errorCode) { if (U_SUCCESS(errorCode)) { outer.currentSkeleton = key; return &outer.patternSink; @@ -340,8 +339,7 @@ struct DateIntervalSink : public ResourceTableSink { } } - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t, UErrorCode &errorCode) { + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode &errorCode) { // Check if it's the intervalFormat table if (U_SUCCESS(errorCode) && uprv_strcmp(key, gIntervalDateTimePatternTag) == 0) { return &skeletonSink; diff --git a/icu4c/source/i18n/dtptngen.cpp b/icu4c/source/i18n/dtptngen.cpp index 2a6b35b5118..c75d01bb5be 100644 --- a/icu4c/source/i18n/dtptngen.cpp +++ b/icu4c/source/i18n/dtptngen.cpp @@ -440,7 +440,7 @@ struct AllowedHourFormatsSink : public ResourceTableSink { virtual ~AllowedHourFormatsSink(); // Entry point. - virtual ResourceTableSink *getOrCreateTableSink(const char *key, int32_t, UErrorCode &status) { + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode &status) { if (U_FAILURE(status)) { return NULL; } locale = key; @@ -467,18 +467,9 @@ struct AllowedHourFormatsSink : public ResourceTableSink { } } - virtual ResourceArraySink *getOrCreateArraySink(const char *key, int32_t size, UErrorCode &status) { - if (U_FAILURE(status)) { return NULL; } - - if (uprv_strcmp(key, "allowed") == 0) { - outer.allowedFormats = static_cast(uprv_malloc((size + 1) * sizeof(int32_t))); - outer.allowedFormatsLength = size; - if (outer.allowedFormats == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } else { - return &outer.allowedListSink; - } + virtual ResourceArraySink *getOrCreateArraySink(const char *key, UErrorCode &status) { + if (U_SUCCESS(status) && uprv_strcmp(key, "allowed") == 0) { + return &outer.allowedListSink; } return NULL; } @@ -497,6 +488,14 @@ struct AllowedHourFormatsSink : public ResourceTableSink { AllowedListSink(AllowedHourFormatsSink &outer) : outer(outer) {} virtual ~AllowedListSink(); + virtual void enter(int32_t size, UErrorCode &status) { + if (U_FAILURE(status)) { return; } + outer.allowedFormats = static_cast(uprv_malloc((size + 1) * sizeof(int32_t))); + outer.allowedFormatsLength = size; + if (outer.allowedFormats == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + } + } virtual void put(int32_t index, const ResourceValue &value, UErrorCode &status) { if (U_FAILURE(status)) { return; } diff --git a/icu4c/source/i18n/measfmt.cpp b/icu4c/source/i18n/measfmt.cpp index 9480275dd06..38d8588f8a1 100644 --- a/icu4c/source/i18n/measfmt.cpp +++ b/icu4c/source/i18n/measfmt.cpp @@ -260,8 +260,7 @@ struct UnitDataSink : public ResourceTableSink { struct UnitSubtypeSink : public ResourceTableSink { UnitSubtypeSink(UnitDataSink &sink) : outer(sink) {} ~UnitSubtypeSink(); - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t /* initialSize */, UErrorCode &errorCode) { + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode &errorCode) { if (U_FAILURE(errorCode)) { return NULL; } outer.unitIndex = MeasureUnit::internalGetIndexForTypeAndSubtype(outer.type, key); if (outer.unitIndex >= 0) { @@ -296,8 +295,7 @@ struct UnitDataSink : public ResourceTableSink { struct UnitTypeSink : public ResourceTableSink { UnitTypeSink(UnitDataSink &sink) : outer(sink) {} ~UnitTypeSink(); - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t /* initialSize */, UErrorCode &errorCode) { + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode &errorCode) { if (U_FAILURE(errorCode)) { return NULL; } if (uprv_strcmp(key, "currency") == 0) { // Skip. @@ -342,8 +340,7 @@ struct UnitDataSink : public ResourceTableSink { } cacheData.widthFallback[sourceWidth] = targetWidth; } - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t /* initialSize */, UErrorCode &errorCode) { + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode &errorCode) { if (U_SUCCESS(errorCode) && (width = widthFromKey(key)) != UMEASFMT_WIDTH_COUNT) { return &typeSink; } diff --git a/icu4c/source/i18n/reldatefmt.cpp b/icu4c/source/i18n/reldatefmt.cpp index ad4eb188d70..2304f17d408 100644 --- a/icu4c/source/i18n/reldatefmt.cpp +++ b/icu4c/source/i18n/reldatefmt.cpp @@ -344,8 +344,7 @@ struct RelDateTimeFmtDataSink : public ResourceTableSink { RelativeTimeSink(RelDateTimeFmtDataSink &sink) : outer(sink) {} ~RelativeTimeSink(); - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t /* initialSize */, UErrorCode& errorCode) { + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode& errorCode) { if (U_FAILURE(errorCode)) { return NULL; } outer.relUnitIndex = relUnitFromGeneric(outer.genericUnit); if (outer.relUnitIndex < 0) { @@ -442,8 +441,7 @@ struct RelDateTimeFmtDataSink : public ResourceTableSink { } } - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t /* initialSize */, UErrorCode &errorCode) { + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode &errorCode) { if (U_FAILURE(errorCode)) { return NULL; } if (uprv_strcmp(key, "relative") == 0) { return &outer.relativeSink; @@ -601,8 +599,7 @@ struct RelDateTimeFmtDataSink : public ResourceTableSink { } // Top level sink - virtual ResourceTableSink *getOrCreateTableSink( - const char *key, int32_t /* initialSize */, UErrorCode& /* errorCode */) { + virtual ResourceTableSink *getOrCreateTableSink(const char *key, UErrorCode& /* errorCode */) { style= styleFromString(key); int32_t unitSize = uprv_strlen(key) - styleSuffixLength(style); genericUnit = unitOrNegativeFromString(key, unitSize);