ICU-21230 Add status to MaybeStackArray(int32_t newCapacity), plumb it through.

This commit is contained in:
Hugo van der Merwe 2020-08-20 15:05:58 +02:00
parent c8aa800735
commit 0387d1b988
9 changed files with 40 additions and 49 deletions

View File

@ -297,12 +297,16 @@ public:
* Automatically allocates the heap array if the argument is larger than the stack capacity.
* Intended for use when an approximate capacity is known at compile time but the true
* capacity is not known until runtime.
*
* WARNING: does not report errors upon memory allocation failure, after
* which capacity will be stackCapacity, not the requested newCapacity.
*/
MaybeStackArray(int32_t newCapacity) : MaybeStackArray() {
if (capacity < newCapacity) { resize(newCapacity); }
MaybeStackArray(int32_t newCapacity, UErrorCode status) : MaybeStackArray() {
if (U_FAILURE(status)) {
return;
}
if (capacity < newCapacity) {
if (resize(newCapacity) == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
}
}
}
/**
* Destructor deletes the array (if owned).

View File

@ -436,11 +436,8 @@ LocaleMatcher::LocaleMatcher(const Builder &builder, UErrorCode &errorCode) :
int32_t suppLength = 0;
// Determine insertion order.
// Add locales immediately that are equivalent to the default.
MaybeStackArray<int8_t, 100> order(supportedLocalesLength);
if (order.getAlias() == nullptr) {
errorCode = U_MEMORY_ALLOCATION_ERROR;
return;
}
MaybeStackArray<int8_t, 100> order(supportedLocalesLength, errorCode);
if (U_FAILURE(errorCode)) { return; }
int32_t numParadigms = 0;
for (int32_t i = 0; i < supportedLocalesLength; ++i) {
const Locale &locale = *supportedLocales[i];

View File

@ -702,7 +702,7 @@ UnicodeString& ListFormatter::format_(
int32_t prefixLength = 0;
// for n items, there are 2 * (n + 1) boundary including 0 and the upper
// edge.
MaybeStackArray<int32_t, 10> offsets((handler != nullptr) ? 2 * (nItems + 1): 0);
MaybeStackArray<int32_t, 10> offsets((handler != nullptr) ? 2 * (nItems + 1) : 0, errorCode);
if (nItems == 2) {
joinStringsAndReplace(
data->patternHandler->getTwoPattern(items[1]),

View File

@ -20,6 +20,7 @@
#include "charstr.h"
#include "number_utils.h"
#include "uassert.h"
#include "util.h"
using namespace icu;
using namespace icu::number;
@ -634,7 +635,10 @@ void DecimalQuantity::toDecNum(DecNum& output, UErrorCode& status) const {
// Use the BCD constructor. We need to do a little bit of work to convert, though.
// The decNumber constructor expects most-significant first, but we store least-significant first.
MaybeStackArray<uint8_t, 20> ubcd(precision);
MaybeStackArray<uint8_t, 20> ubcd(precision, status);
if (U_FAILURE(status)) {
return;
}
for (int32_t m = 0; m < precision; m++) {
ubcd[precision - m - 1] = static_cast<uint8_t>(getDigitPos(m));
}
@ -1324,7 +1328,11 @@ bool DecimalQuantity::operator==(const DecimalQuantity& other) const {
}
UnicodeString DecimalQuantity::toString() const {
MaybeStackArray<char, 30> digits(precision + 1);
UErrorCode localStatus = U_ZERO_ERROR;
MaybeStackArray<char, 30> digits(precision + 1, localStatus);
if (U_FAILURE(localStatus)) {
return ICU_Utility::makeBogusString();
}
for (int32_t i = 0; i < precision; i++) {
digits[i] = getDigitPos(precision - i - 1) + '0';
}

View File

@ -258,7 +258,10 @@ void DecNum::toString(ByteSink& output, UErrorCode& status) const {
}
// "string must be at least dn->digits+14 characters long"
int32_t minCapacity = fData.getAlias()->digits + 14;
MaybeStackArray<char, 30> buffer(minCapacity);
MaybeStackArray<char, 30> buffer(minCapacity, status);
if (U_FAILURE(status)) {
return;
}
uprv_decNumberToString(fData, buffer.getAlias());
output.Append(buffer.getAlias(), static_cast<int32_t>(uprv_strlen(buffer.getAlias())));
}

View File

@ -127,8 +127,8 @@ void AffixPatternMatcherBuilder::addMatcher(NumberParseMatcher& matcher) {
fMatchers[fMatchersLen++] = &matcher;
}
AffixPatternMatcher AffixPatternMatcherBuilder::build() {
return AffixPatternMatcher(fMatchers, fMatchersLen, fPattern);
AffixPatternMatcher AffixPatternMatcherBuilder::build(UErrorCode& status) {
return AffixPatternMatcher(fMatchers, fMatchersLen, fPattern, status);
}
AffixTokenMatcherWarehouse::AffixTokenMatcherWarehouse(const AffixTokenMatcherSetupData* setupData)
@ -209,12 +209,13 @@ AffixPatternMatcher AffixPatternMatcher::fromAffixPattern(const UnicodeString& a
AffixPatternMatcherBuilder builder(affixPattern, tokenWarehouse, ignorables);
AffixUtils::iterateWithConsumer(affixPattern, builder, status);
return builder.build();
return builder.build(status);
}
AffixPatternMatcher::AffixPatternMatcher(MatcherArray& matchers, int32_t matchersLen,
const UnicodeString& pattern)
: ArraySeriesMatcher(matchers, matchersLen), fPattern(pattern) {}
const UnicodeString& pattern, UErrorCode& status)
: ArraySeriesMatcher(matchers, matchersLen), fPattern(pattern, status) {
}
UnicodeString AffixPatternMatcher::getPattern() const {
return fPattern.toAliasedUnicodeString();
@ -446,28 +447,3 @@ UnicodeString AffixMatcher::toString() const {
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -128,7 +128,7 @@ class AffixPatternMatcherBuilder : public TokenConsumer, public MutableMatcherCo
void consumeToken(::icu::number::impl::AffixPatternType type, UChar32 cp, UErrorCode& status) override;
/** NOTE: You can build only once! */
AffixPatternMatcher build();
AffixPatternMatcher build(UErrorCode& status);
private:
ArraySeriesMatcher::MatcherArray fMatchers;
@ -160,7 +160,8 @@ class U_I18N_API AffixPatternMatcher : public ArraySeriesMatcher {
private:
CompactUnicodeString<4> fPattern;
AffixPatternMatcher(MatcherArray& matchers, int32_t matchersLen, const UnicodeString& pattern);
AffixPatternMatcher(MatcherArray& matchers, int32_t matchersLen, const UnicodeString& pattern,
UErrorCode& status);
friend class AffixPatternMatcherBuilder;
};

View File

@ -64,8 +64,9 @@ class CompactUnicodeString {
fBuffer[0] = 0;
}
CompactUnicodeString(const UnicodeString& text)
: fBuffer(text.length() + 1) {
CompactUnicodeString(const UnicodeString& text, UErrorCode& status)
: fBuffer(text.length() + 1, status) {
if (U_FAILURE(status)) { return; }
uprv_memcpy(fBuffer.getAlias(), text.getBuffer(), sizeof(UChar) * text.length());
fBuffer[text.length()] = 0;
}

View File

@ -196,7 +196,8 @@ void NumberParserTest::testSeriesMatcher() {
PercentMatcher m3(symbols);
IgnorablesMatcher m4(0);
ArraySeriesMatcher::MatcherArray matchers(5);
ArraySeriesMatcher::MatcherArray matchers(5, status);
status.assertSuccess();
matchers[0] = &m0;
matchers[1] = &m1;
matchers[2] = &m2;