}
int32_t NumberFormatterImpl::formatStatic(const MacroProps& macros, DecimalQuantity& inValue,
- NumberStringBuilder& outString, UErrorCode& status) {
+ FormattedStringBuilder& outString, UErrorCode& status) {
NumberFormatterImpl impl(macros, false, status);
MicroProps& micros = impl.preProcessUnsafe(inValue, status);
if (U_FAILURE(status)) { return 0; }
return length;
}
-int32_t NumberFormatterImpl::getPrefixSuffixStatic(const MacroProps& macros, int8_t signum,
+int32_t NumberFormatterImpl::getPrefixSuffixStatic(const MacroProps& macros, Signum signum,
StandardPlural::Form plural,
- NumberStringBuilder& outString, UErrorCode& status) {
+ FormattedStringBuilder& outString, UErrorCode& status) {
NumberFormatterImpl impl(macros, false, status);
return impl.getPrefixSuffixUnsafe(signum, plural, outString, status);
}
// The "unsafe" method simply re-uses fMicros, eliminating the extra copy operation.
// See MicroProps::processQuantity() for details.
-int32_t NumberFormatterImpl::format(DecimalQuantity& inValue, NumberStringBuilder& outString,
+int32_t NumberFormatterImpl::format(DecimalQuantity& inValue, FormattedStringBuilder& outString,
UErrorCode& status) const {
MicroProps micros;
preProcess(inValue, micros, status);
return fMicros;
}
-int32_t NumberFormatterImpl::getPrefixSuffix(int8_t signum, StandardPlural::Form plural,
- NumberStringBuilder& outString, UErrorCode& status) const {
+int32_t NumberFormatterImpl::getPrefixSuffix(Signum signum, StandardPlural::Form plural,
+ FormattedStringBuilder& outString, UErrorCode& status) const {
if (U_FAILURE(status)) { return 0; }
// #13453: DecimalFormat wants the affixes from the pattern only (modMiddle, aka pattern modifier).
// Safe path: use fImmutablePatternModifier.
return modifier->getPrefixLength();
}
-int32_t NumberFormatterImpl::getPrefixSuffixUnsafe(int8_t signum, StandardPlural::Form plural,
- NumberStringBuilder& outString, UErrorCode& status) {
+int32_t NumberFormatterImpl::getPrefixSuffixUnsafe(Signum signum, StandardPlural::Form plural,
+ FormattedStringBuilder& outString, UErrorCode& status) {
if (U_FAILURE(status)) { return 0; }
// #13453: DecimalFormat wants the affixes from the pattern only (modMiddle, aka pattern modifier).
// Unsafe path: use fPatternModifier.
if (macros.symbols.isDecimalFormatSymbols()) {
fMicros.symbols = macros.symbols.getDecimalFormatSymbols();
} else {
- fMicros.symbols = (ns != nullptr)?
+ auto newSymbols = (ns != nullptr)?
new DecimalFormatSymbols(macros.locale, *ns, status):
new DecimalFormatSymbols(macros.locale, status);
+ if (newSymbols == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
+ fMicros.symbols = newSymbols;
// Give ownership to the NumberFormatterImpl.
fSymbols.adoptInstead(fMicros.symbols);
}
if (info.exists) {
pattern = info.pattern;
// It's clunky to clone an object here, but this code is not frequently executed.
- auto* symbols = new DecimalFormatSymbols(*fMicros.symbols);
+ auto symbols = new DecimalFormatSymbols(*fMicros.symbols);
+ if (symbols == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
fMicros.symbols = symbols;
fSymbols.adoptInstead(symbols);
symbols->setSymbol(
pattern = utils::getPatternForStyle(macros.locale, nsName, patternStyle, status);
}
auto patternInfo = new ParsedPatternInfo();
+ if (patternInfo == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
fPatternInfo.adoptInstead(patternInfo);
PatternParser::parseToPatternInfo(UnicodeString(pattern), *patternInfo, status);
// Inner modifier (scientific notation)
if (macros.notation.fType == Notation::NTN_SCIENTIFIC) {
- fScientificHandler.adoptInstead(new ScientificHandler(¯os.notation, fMicros.symbols, chain));
+ auto newScientificHandler = new ScientificHandler(¯os.notation, fMicros.symbols, chain);
+ if (newScientificHandler == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
+ fScientificHandler.adoptInstead(newScientificHandler);
chain = fScientificHandler.getAlias();
} else {
// No inner modifier required
// Middle modifier (patterns, positive/negative, currency symbols, percent)
auto patternModifier = new MutablePatternModifier(false);
+ if (patternModifier == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
fPatternModifier.adoptInstead(patternModifier);
patternModifier->setPatternInfo(
macros.affixProvider != nullptr ? macros.affixProvider
if (macros.notation.fType == Notation::NTN_COMPACT) {
CompactType compactType = (isCurrency && unitWidth != UNUM_UNIT_WIDTH_FULL_NAME)
? CompactType::TYPE_CURRENCY : CompactType::TYPE_DECIMAL;
- fCompactHandler.adoptInstead(
- new CompactHandler(
- macros.notation.fUnion.compactStyle,
- macros.locale,
- nsName,
- compactType,
- resolvePluralRules(macros.rules, macros.locale, status),
- safe ? patternModifier : nullptr,
- chain,
- status));
+ auto newCompactHandler = new CompactHandler(
+ macros.notation.fUnion.compactStyle,
+ macros.locale,
+ nsName,
+ compactType,
+ resolvePluralRules(macros.rules, macros.locale, status),
+ safe ? patternModifier : nullptr,
+ chain,
+ status);
+ if (newCompactHandler == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return nullptr;
+ }
+ fCompactHandler.adoptInstead(newCompactHandler);
chain = fCompactHandler.getAlias();
}
return fRules.getAlias();
}
-int32_t NumberFormatterImpl::writeAffixes(const MicroProps& micros, NumberStringBuilder& string,
+int32_t NumberFormatterImpl::writeAffixes(const MicroProps& micros, FormattedStringBuilder& string,
int32_t start, int32_t end, UErrorCode& status) {
// Always apply the inner modifier (which is "strong").
int32_t length = micros.modInner->apply(string, start, end, status);
}
int32_t NumberFormatterImpl::writeNumber(const MicroProps& micros, DecimalQuantity& quantity,
- NumberStringBuilder& string, int32_t index,
+ FormattedStringBuilder& string, int32_t index,
UErrorCode& status) {
int32_t length = 0;
if (quantity.isInfinite()) {
// Add the fraction digits
length += writeFractionDigits(micros, quantity, string, length + index, status);
+
+ if (length == 0) {
+ // Force output of the digit for value 0
+ length += utils::insertDigitFromSymbols(
+ string, index, 0, *micros.symbols, UNUM_INTEGER_FIELD, status);
+ }
}
return length;
}
int32_t NumberFormatterImpl::writeIntegerDigits(const MicroProps& micros, DecimalQuantity& quantity,
- NumberStringBuilder& string, int32_t index,
+ FormattedStringBuilder& string, int32_t index,
UErrorCode& status) {
int length = 0;
int integerCount = quantity.getUpperDisplayMagnitude() + 1;
}
int32_t NumberFormatterImpl::writeFractionDigits(const MicroProps& micros, DecimalQuantity& quantity,
- NumberStringBuilder& string, int32_t index,
+ FormattedStringBuilder& string, int32_t index,
UErrorCode& status) {
int length = 0;
int fractionCount = -quantity.getLowerDisplayMagnitude();