mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-06 14:05:32 +00:00
ICU-21763 UVector cleanup in Formatting Code
Revise uses of UVector in Formatting related code to better handle memory allocation failures. This is one of an ongoing series of commits to address similar problems with UVector usage throughout ICU. The changes primarily involve switching uses of UVector::addElementX() to the new adoptElement() or addElement() functions, as appropriate, and using LocalPointers for tracking memory ownership.
This commit is contained in:
parent
f37a5e0090
commit
904cf62457
8 changed files with 39 additions and 61 deletions
|
@ -1574,26 +1574,20 @@ struct CalendarDataSink : public ResourceSink {
|
|||
errorCode);
|
||||
if (U_FAILURE(errorCode)) { return; }
|
||||
}
|
||||
LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode);
|
||||
resourcesToVisitNext->addElementX(aliasRelativePathCopy.getAlias(), errorCode);
|
||||
LocalPointer<UnicodeString> aliasRelativePathCopy(aliasRelativePath.clone(), errorCode);
|
||||
resourcesToVisitNext->adoptElement(aliasRelativePathCopy.orphan(), errorCode);
|
||||
if (U_FAILURE(errorCode)) { return; }
|
||||
// Only release ownership after resourcesToVisitNext takes it (no error happened):
|
||||
aliasRelativePathCopy.orphan();
|
||||
continue;
|
||||
|
||||
} else if (aliasType == SAME_CALENDAR) {
|
||||
// Register same-calendar alias
|
||||
if (arrays.get(aliasRelativePath) == NULL && maps.get(aliasRelativePath) == NULL) {
|
||||
LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode);
|
||||
aliasPathPairs.addElementX(aliasRelativePathCopy.getAlias(), errorCode);
|
||||
LocalPointer<UnicodeString> aliasRelativePathCopy(aliasRelativePath.clone(), errorCode);
|
||||
aliasPathPairs.adoptElement(aliasRelativePathCopy.orphan(), errorCode);
|
||||
if (U_FAILURE(errorCode)) { return; }
|
||||
// Only release ownership after aliasPathPairs takes it (no error happened):
|
||||
aliasRelativePathCopy.orphan();
|
||||
LocalPointer<UnicodeString> keyUStringCopy(new UnicodeString(keyUString), errorCode);
|
||||
aliasPathPairs.addElementX(keyUStringCopy.getAlias(), errorCode);
|
||||
LocalPointer<UnicodeString> keyUStringCopy(keyUString.clone(), errorCode);
|
||||
aliasPathPairs.adoptElement(keyUStringCopy.orphan(), errorCode);
|
||||
if (U_FAILURE(errorCode)) { return; }
|
||||
// Only release ownership after aliasPathPairs takes it (no error happened):
|
||||
keyUStringCopy.orphan();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -1760,16 +1754,12 @@ struct CalendarDataSink : public ResourceSink {
|
|||
if (U_FAILURE(errorCode)) { return; }
|
||||
if (aliasType == SAME_CALENDAR) {
|
||||
// Store the alias path and the current path on aliasPathPairs
|
||||
LocalPointer<UnicodeString> aliasRelativePathCopy(new UnicodeString(aliasRelativePath), errorCode);
|
||||
aliasPathPairs.addElementX(aliasRelativePathCopy.getAlias(), errorCode);
|
||||
LocalPointer<UnicodeString> aliasRelativePathCopy(aliasRelativePath.clone(), errorCode);
|
||||
aliasPathPairs.adoptElement(aliasRelativePathCopy.orphan(), errorCode);
|
||||
if (U_FAILURE(errorCode)) { return; }
|
||||
// Only release ownership after aliasPathPairs takes it (no error happened):
|
||||
aliasRelativePathCopy.orphan();
|
||||
LocalPointer<UnicodeString> pathCopy(new UnicodeString(path), errorCode);
|
||||
aliasPathPairs.addElementX(pathCopy.getAlias(), errorCode);
|
||||
LocalPointer<UnicodeString> pathCopy(path.clone(), errorCode);
|
||||
aliasPathPairs.adoptElement(pathCopy.orphan(), errorCode);
|
||||
if (U_FAILURE(errorCode)) { return; }
|
||||
// Only release ownership after aliasPathPairs takes it (no error happened):
|
||||
pathCopy.orphan();
|
||||
|
||||
// Drop the latest key on the path and continue
|
||||
path.retainBetween(0, pathLength);
|
||||
|
|
|
@ -2788,16 +2788,17 @@ DTSkeletonEnumeration::DTSkeletonEnumeration(PatternMap& patternMap, dtStrEnum t
|
|||
break;
|
||||
}
|
||||
if ( !isCanonicalItem(s) ) {
|
||||
LocalPointer<UnicodeString> newElem(new UnicodeString(s), status);
|
||||
LocalPointer<UnicodeString> newElem(s.clone(), status);
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
fSkeletons->addElementX(newElem.getAlias(), status);
|
||||
fSkeletons->addElement(newElem.getAlias(), status);
|
||||
if (U_FAILURE(status)) {
|
||||
fSkeletons.adoptInstead(nullptr);
|
||||
return;
|
||||
}
|
||||
newElem.orphan(); // fSkeletons vector now owns the UnicodeString.
|
||||
newElem.orphan(); // fSkeletons vector now owns the UnicodeString (although it
|
||||
// does not use a deleter function to manage the ownership).
|
||||
}
|
||||
curElem = curElem->next.getAlias();
|
||||
}
|
||||
|
@ -2865,12 +2866,13 @@ DTRedundantEnumeration::add(const UnicodeString& pattern, UErrorCode& status) {
|
|||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
fPatterns->addElementX(newElem.getAlias(), status);
|
||||
fPatterns->addElement(newElem.getAlias(), status);
|
||||
if (U_FAILURE(status)) {
|
||||
fPatterns.adoptInstead(nullptr);
|
||||
return;
|
||||
}
|
||||
newElem.orphan(); // fPatterns now owns the string.
|
||||
newElem.orphan(); // fPatterns now owns the string, although a UVector
|
||||
// deleter function is not used to manage that ownership.
|
||||
}
|
||||
|
||||
const UnicodeString*
|
||||
|
|
|
@ -854,19 +854,21 @@ StringEnumeration*
|
|||
MessageFormat::getFormatNames(UErrorCode& status) {
|
||||
if (U_FAILURE(status)) return NULL;
|
||||
|
||||
UVector *fFormatNames = new UVector(status);
|
||||
LocalPointer<UVector> formatNames(new UVector(status), status);
|
||||
if (U_FAILURE(status)) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
fFormatNames->setDeleter(uprv_deleteUObject);
|
||||
formatNames->setDeleter(uprv_deleteUObject);
|
||||
|
||||
for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) {
|
||||
fFormatNames->addElementX(new UnicodeString(getArgName(partIndex + 1)), status);
|
||||
LocalPointer<UnicodeString> name(getArgName(partIndex + 1).clone(), status);
|
||||
formatNames->adoptElement(name.orphan(), status);
|
||||
if (U_FAILURE(status)) return nullptr;
|
||||
}
|
||||
|
||||
StringEnumeration* nameEnumerator = new FormatNameEnumeration(fFormatNames, status);
|
||||
return nameEnumerator;
|
||||
LocalPointer<StringEnumeration> nameEnumerator(
|
||||
new FormatNameEnumeration(std::move(formatNames), status), status);
|
||||
return U_SUCCESS(status) ? nameEnumerator.orphan() : nullptr;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
|
@ -1912,9 +1914,9 @@ void MessageFormat::DummyFormat::parseObject(const UnicodeString&,
|
|||
}
|
||||
|
||||
|
||||
FormatNameEnumeration::FormatNameEnumeration(UVector *fNameList, UErrorCode& /*status*/) {
|
||||
FormatNameEnumeration::FormatNameEnumeration(LocalPointer<UVector> nameList, UErrorCode& /*status*/) {
|
||||
pos=0;
|
||||
fFormatNames = fNameList;
|
||||
fFormatNames = std::move(nameList);
|
||||
}
|
||||
|
||||
const UnicodeString*
|
||||
|
@ -1936,7 +1938,6 @@ FormatNameEnumeration::count(UErrorCode& /*status*/) const {
|
|||
}
|
||||
|
||||
FormatNameEnumeration::~FormatNameEnumeration() {
|
||||
delete fFormatNames;
|
||||
}
|
||||
|
||||
MessageFormat::PluralSelectorProvider::PluralSelectorProvider(const MessageFormat &mf, UPluralType t)
|
||||
|
|
|
@ -26,7 +26,7 @@ U_NAMESPACE_BEGIN
|
|||
|
||||
class FormatNameEnumeration : public StringEnumeration {
|
||||
public:
|
||||
FormatNameEnumeration(UVector *fFormatNames, UErrorCode& status);
|
||||
FormatNameEnumeration(LocalPointer<UVector> fFormatNames, UErrorCode& status);
|
||||
virtual ~FormatNameEnumeration();
|
||||
static UClassID U_EXPORT2 getStaticClassID(void);
|
||||
virtual UClassID getDynamicClassID(void) const override;
|
||||
|
@ -35,7 +35,7 @@ public:
|
|||
virtual int32_t count(UErrorCode& status) const override;
|
||||
private:
|
||||
int32_t pos;
|
||||
UVector *fFormatNames;
|
||||
LocalPointer<UVector> fFormatNames;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -157,8 +157,8 @@ void CompactData::getUniquePatterns(UVector &output, UErrorCode &status) const {
|
|||
}
|
||||
|
||||
// The string was not found; add it to the UVector.
|
||||
// ANDY: This requires a const_cast. Why?
|
||||
output.addElementX(const_cast<UChar *>(pattern), status);
|
||||
// Note: must cast off const from pattern to store it in a UVector, which expects (void *)
|
||||
output.addElement(const_cast<UChar *>(pattern), status);
|
||||
|
||||
continue_outer:
|
||||
continue;
|
||||
|
|
|
@ -313,12 +313,7 @@ U_CFUNC void initNumsysNames(UErrorCode &status) {
|
|||
}
|
||||
const char *nsName = ures_getKey(nsCurrent.getAlias());
|
||||
LocalPointer<UnicodeString> newElem(new UnicodeString(nsName, -1, US_INV), status);
|
||||
if (U_SUCCESS(status)) {
|
||||
numsysNames->addElementX(newElem.getAlias(), status);
|
||||
if (U_SUCCESS(status)) {
|
||||
newElem.orphan(); // on success, the numsysNames vector owns newElem.
|
||||
}
|
||||
}
|
||||
numsysNames->adoptElement(newElem.orphan(), status);
|
||||
}
|
||||
|
||||
ures_close(numberingSystemsInfo);
|
||||
|
|
|
@ -1548,14 +1548,9 @@ PluralKeywordEnumeration::PluralKeywordEnumeration(RuleChain *header, UErrorCode
|
|||
UBool addKeywordOther = TRUE;
|
||||
RuleChain *node = header;
|
||||
while (node != nullptr) {
|
||||
auto newElem = new UnicodeString(node->fKeyword);
|
||||
if (newElem == nullptr) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
fKeywordNames.addElementX(newElem, status);
|
||||
LocalPointer<UnicodeString> newElem(node->fKeyword.clone(), status);
|
||||
fKeywordNames.adoptElement(newElem.orphan(), status);
|
||||
if (U_FAILURE(status)) {
|
||||
delete newElem;
|
||||
return;
|
||||
}
|
||||
if (0 == node->fKeyword.compare(PLURAL_KEYWORD_OTHER, 5)) {
|
||||
|
@ -1565,14 +1560,9 @@ PluralKeywordEnumeration::PluralKeywordEnumeration(RuleChain *header, UErrorCode
|
|||
}
|
||||
|
||||
if (addKeywordOther) {
|
||||
auto newElem = new UnicodeString(PLURAL_KEYWORD_OTHER);
|
||||
if (newElem == nullptr) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
fKeywordNames.addElementX(newElem, status);
|
||||
LocalPointer<UnicodeString> newElem(new UnicodeString(PLURAL_KEYWORD_OTHER), status);
|
||||
fKeywordNames.adoptElement(newElem.orphan(), status);
|
||||
if (U_FAILURE(status)) {
|
||||
delete newElem;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -320,14 +320,14 @@ void
|
|||
TimeUnitFormat::setup(UErrorCode& err) {
|
||||
initDataMembers(err);
|
||||
|
||||
UVector pluralCounts(0, uhash_compareUnicodeString, 6, err);
|
||||
UVector pluralCounts(nullptr, uhash_compareUnicodeString, 6, err);
|
||||
LocalPointer<StringEnumeration> keywords(getPluralRules().getKeywords(err), err);
|
||||
if (U_FAILURE(err)) {
|
||||
return;
|
||||
}
|
||||
UnicodeString* pluralCount;
|
||||
while ((pluralCount = const_cast<UnicodeString*>(keywords->snext(err))) != NULL) {
|
||||
pluralCounts.addElementX(pluralCount, err);
|
||||
pluralCounts.addElement(pluralCount, err);
|
||||
}
|
||||
readFromCurrentLocale(UTMUTFMT_FULL_STYLE, gUnitsTag, pluralCounts, err);
|
||||
checkConsistency(UTMUTFMT_FULL_STYLE, gUnitsTag, err);
|
||||
|
|
Loading…
Add table
Reference in a new issue