diff options
Diffstat (limited to 'deps/icu-small/source/i18n/number_capi.cpp')
-rw-r--r-- | deps/icu-small/source/i18n/number_capi.cpp | 147 |
1 files changed, 70 insertions, 77 deletions
diff --git a/deps/icu-small/source/i18n/number_capi.cpp b/deps/icu-small/source/i18n/number_capi.cpp index 37ad8bd76f..712e0a6631 100644 --- a/deps/icu-small/source/i18n/number_capi.cpp +++ b/deps/icu-small/source/i18n/number_capi.cpp @@ -12,6 +12,7 @@ #include "fphdlimp.h" #include "number_utypes.h" #include "numparse_types.h" +#include "formattedval_impl.h" #include "unicode/numberformatter.h" #include "unicode/unumberformatter.h" @@ -20,67 +21,63 @@ using namespace icu::number; using namespace icu::number::impl; -////////////////////////////////// -/// C API CONVERSION FUNCTIONS /// -////////////////////////////////// +U_NAMESPACE_BEGIN +namespace number { +namespace impl { -UNumberFormatterData* UNumberFormatterData::validate(UNumberFormatter* input, UErrorCode& status) { - auto* constInput = static_cast<const UNumberFormatter*>(input); - auto* validated = validate(constInput, status); - return const_cast<UNumberFormatterData*>(validated); -} +/** + * Implementation class for UNumberFormatter. Wraps a LocalizedNumberFormatter. + */ +struct UNumberFormatterData : public UMemory, + // Magic number as ASCII == "NFR" (NumberFormatteR) + public IcuCApiHelper<UNumberFormatter, UNumberFormatterData, 0x4E465200> { + LocalizedNumberFormatter fFormatter; +}; -const UNumberFormatterData* -UNumberFormatterData::validate(const UNumberFormatter* input, UErrorCode& status) { - if (U_FAILURE(status)) { - return nullptr; - } - if (input == nullptr) { - status = U_ILLEGAL_ARGUMENT_ERROR; - return nullptr; - } - auto* impl = reinterpret_cast<const UNumberFormatterData*>(input); - if (impl->fMagic != UNumberFormatterData::kMagic) { - status = U_INVALID_FORMAT_ERROR; - return nullptr; - } - return impl; +struct UFormattedNumberImpl; + +// Magic number as ASCII == "FDN" (FormatteDNumber) +typedef IcuCApiHelper<UFormattedNumber, UFormattedNumberImpl, 0x46444E00> UFormattedNumberApiHelper; + +struct UFormattedNumberImpl : public UFormattedValueImpl, public UFormattedNumberApiHelper { + UFormattedNumberImpl(); + ~UFormattedNumberImpl(); + + FormattedNumber fImpl; + UFormattedNumberData fData; +}; + +UFormattedNumberImpl::UFormattedNumberImpl() + : fImpl(&fData) { + fFormattedValue = &fImpl; } -UNumberFormatter* UNumberFormatterData::exportForC() { - return reinterpret_cast<UNumberFormatter*>(this); +UFormattedNumberImpl::~UFormattedNumberImpl() { + // Disown the data from fImpl so it doesn't get deleted twice + fImpl.fData = nullptr; } -UFormattedNumberData* UFormattedNumberData::validate(UFormattedNumber* input, UErrorCode& status) { - auto* constInput = static_cast<const UFormattedNumber*>(input); - auto* validated = validate(constInput, status); - return const_cast<UFormattedNumberData*>(validated); } +} +U_NAMESPACE_END + + +UPRV_FORMATTED_VALUE_CAPI_NO_IMPLTYPE_AUTO_IMPL( + UFormattedNumber, + UFormattedNumberImpl, + UFormattedNumberApiHelper, + unumf) + -const UFormattedNumberData* -UFormattedNumberData::validate(const UFormattedNumber* input, UErrorCode& status) { +const DecimalQuantity* icu::number::impl::validateUFormattedNumberToDecimalQuantity( + const UFormattedNumber* uresult, UErrorCode& status) { + auto* result = UFormattedNumberApiHelper::validate(uresult, status); if (U_FAILURE(status)) { return nullptr; } - if (input == nullptr) { - status = U_ILLEGAL_ARGUMENT_ERROR; - return nullptr; - } - auto* impl = reinterpret_cast<const UFormattedNumberData*>(input); - if (impl->fMagic != UFormattedNumberData::kMagic) { - status = U_INVALID_FORMAT_ERROR; - return nullptr; - } - return impl; + return &result->fData.quantity; } -UFormattedNumber* UFormattedNumberData::exportForC() { - return reinterpret_cast<UFormattedNumber*>(this); -} - -///////////////////////////////////// -/// END CAPI CONVERSION FUNCTIONS /// -///////////////////////////////////// U_CAPI UNumberFormatter* U_EXPORT2 @@ -97,13 +94,17 @@ unumf_openForSkeletonAndLocale(const UChar* skeleton, int32_t skeletonLen, const return impl->exportForC(); } -U_CAPI UFormattedNumber* U_EXPORT2 -unumf_openResult(UErrorCode* ec) { - auto* impl = new UFormattedNumberData(); +U_CAPI UNumberFormatter* U_EXPORT2 +unumf_openForSkeletonAndLocaleWithError(const UChar* skeleton, int32_t skeletonLen, const char* locale, + UParseError* perror, UErrorCode* ec) { + auto* impl = new UNumberFormatterData(); if (impl == nullptr) { *ec = U_MEMORY_ALLOCATION_ERROR; return nullptr; } + // Readonly-alias constructor (first argument is whether we are NUL-terminated) + UnicodeString skeletonString(skeletonLen == -1, skeleton, skeletonLen); + impl->fFormatter = NumberFormatter::forSkeleton(skeletonString, *perror, *ec).locale(locale); return impl->exportForC(); } @@ -111,43 +112,43 @@ U_CAPI void U_EXPORT2 unumf_formatInt(const UNumberFormatter* uformatter, int64_t value, UFormattedNumber* uresult, UErrorCode* ec) { const UNumberFormatterData* formatter = UNumberFormatterData::validate(uformatter, *ec); - UFormattedNumberData* result = UFormattedNumberData::validate(uresult, *ec); + auto* result = UFormattedNumberApiHelper::validate(uresult, *ec); if (U_FAILURE(*ec)) { return; } - result->string.clear(); - result->quantity.setToLong(value); - formatter->fFormatter.formatImpl(result, *ec); + result->fData.getStringRef().clear(); + result->fData.quantity.setToLong(value); + formatter->fFormatter.formatImpl(&result->fData, *ec); } U_CAPI void U_EXPORT2 unumf_formatDouble(const UNumberFormatter* uformatter, double value, UFormattedNumber* uresult, UErrorCode* ec) { const UNumberFormatterData* formatter = UNumberFormatterData::validate(uformatter, *ec); - UFormattedNumberData* result = UFormattedNumberData::validate(uresult, *ec); + auto* result = UFormattedNumberApiHelper::validate(uresult, *ec); if (U_FAILURE(*ec)) { return; } - result->string.clear(); - result->quantity.setToDouble(value); - formatter->fFormatter.formatImpl(result, *ec); + result->fData.getStringRef().clear(); + result->fData.quantity.setToDouble(value); + formatter->fFormatter.formatImpl(&result->fData, *ec); } U_CAPI void U_EXPORT2 unumf_formatDecimal(const UNumberFormatter* uformatter, const char* value, int32_t valueLen, UFormattedNumber* uresult, UErrorCode* ec) { const UNumberFormatterData* formatter = UNumberFormatterData::validate(uformatter, *ec); - UFormattedNumberData* result = UFormattedNumberData::validate(uresult, *ec); + auto* result = UFormattedNumberApiHelper::validate(uresult, *ec); if (U_FAILURE(*ec)) { return; } - result->string.clear(); - result->quantity.setToDecNumber({value, valueLen}, *ec); + result->fData.getStringRef().clear(); + result->fData.quantity.setToDecNumber({value, valueLen}, *ec); if (U_FAILURE(*ec)) { return; } - formatter->fFormatter.formatImpl(result, *ec); + formatter->fFormatter.formatImpl(&result->fData, *ec); } U_CAPI int32_t U_EXPORT2 unumf_resultToString(const UFormattedNumber* uresult, UChar* buffer, int32_t bufferCapacity, UErrorCode* ec) { - const UFormattedNumberData* result = UFormattedNumberData::validate(uresult, *ec); + const auto* result = UFormattedNumberApiHelper::validate(uresult, *ec); if (U_FAILURE(*ec)) { return 0; } if (buffer == nullptr ? bufferCapacity != 0 : bufferCapacity < 0) { @@ -155,12 +156,12 @@ unumf_resultToString(const UFormattedNumber* uresult, UChar* buffer, int32_t buf return 0; } - return result->string.toTempUnicodeString().extract(buffer, bufferCapacity, *ec); + return result->fImpl.toTempString(*ec).extract(buffer, bufferCapacity, *ec); } U_CAPI UBool U_EXPORT2 unumf_resultNextFieldPosition(const UFormattedNumber* uresult, UFieldPosition* ufpos, UErrorCode* ec) { - const UFormattedNumberData* result = UFormattedNumberData::validate(uresult, *ec); + const auto* result = UFormattedNumberApiHelper::validate(uresult, *ec); if (U_FAILURE(*ec)) { return FALSE; } if (ufpos == nullptr) { @@ -172,7 +173,7 @@ unumf_resultNextFieldPosition(const UFormattedNumber* uresult, UFieldPosition* u fp.setField(ufpos->field); fp.setBeginIndex(ufpos->beginIndex); fp.setEndIndex(ufpos->endIndex); - bool retval = result->string.nextFieldPosition(fp, *ec); + bool retval = result->fImpl.nextFieldPosition(fp, *ec); ufpos->beginIndex = fp.getBeginIndex(); ufpos->endIndex = fp.getEndIndex(); // NOTE: MSVC sometimes complains when implicitly converting between bool and UBool @@ -182,7 +183,7 @@ unumf_resultNextFieldPosition(const UFormattedNumber* uresult, UFieldPosition* u U_CAPI void U_EXPORT2 unumf_resultGetAllFieldPositions(const UFormattedNumber* uresult, UFieldPositionIterator* ufpositer, UErrorCode* ec) { - const UFormattedNumberData* result = UFormattedNumberData::validate(uresult, *ec); + const auto* result = UFormattedNumberApiHelper::validate(uresult, *ec); if (U_FAILURE(*ec)) { return; } if (ufpositer == nullptr) { @@ -191,15 +192,7 @@ unumf_resultGetAllFieldPositions(const UFormattedNumber* uresult, UFieldPosition } auto* fpi = reinterpret_cast<FieldPositionIterator*>(ufpositer); - FieldPositionIteratorHandler fpih(fpi, *ec); - result->string.getAllFieldPositions(fpih, *ec); -} - -U_CAPI void U_EXPORT2 -unumf_closeResult(UFormattedNumber* uresult) { - UErrorCode localStatus = U_ZERO_ERROR; - const UFormattedNumberData* impl = UFormattedNumberData::validate(uresult, localStatus); - delete impl; + result->fImpl.getAllFieldPositions(*fpi, *ec); } U_CAPI void U_EXPORT2 |