summaryrefslogtreecommitdiff
path: root/deps/icu-small/source/i18n/number_capi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'deps/icu-small/source/i18n/number_capi.cpp')
-rw-r--r--deps/icu-small/source/i18n/number_capi.cpp147
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