123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- // © 2018 and later: Unicode, Inc. and others.
- // License & terms of use: http://www.unicode.org/copyright.html
- #include "unicode/utypes.h"
- #if !UCONFIG_NO_FORMATTING
- // Allow implicit conversion from char16_t* to UnicodeString for this file:
- // Helpful in toString methods and elsewhere.
- #define UNISTR_FROM_STRING_EXPLICIT
- #include "fphdlimp.h"
- #include "number_utypes.h"
- #include "numparse_types.h"
- #include "formattedval_impl.h"
- #include "numrange_impl.h"
- #include "number_decnum.h"
- #include "unicode/numberrangeformatter.h"
- #include "unicode/unumberrangeformatter.h"
- using namespace icu;
- using namespace icu::number;
- using namespace icu::number::impl;
- U_NAMESPACE_BEGIN
- namespace number {
- namespace impl {
- /**
- * Implementation class for UNumberRangeFormatter. Wraps a LocalizedRangeNumberFormatter.
- */
- struct UNumberRangeFormatterData : public UMemory,
- // Magic number as ASCII == "NRF" (NumberRangeFormatter)
- public IcuCApiHelper<UNumberRangeFormatter, UNumberRangeFormatterData, 0x4E524600> {
- LocalizedNumberRangeFormatter fFormatter;
- };
- struct UFormattedNumberRangeImpl;
- // Magic number as ASCII == "FDN" (FormatteDNumber)
- typedef IcuCApiHelper<UFormattedNumberRange, UFormattedNumberRangeImpl, 0x46444E00> UFormattedNumberRangeApiHelper;
- struct UFormattedNumberRangeImpl : public UFormattedValueImpl, public UFormattedNumberRangeApiHelper {
- UFormattedNumberRangeImpl();
- ~UFormattedNumberRangeImpl();
- FormattedNumberRange fImpl;
- UFormattedNumberRangeData fData;
- };
- UFormattedNumberRangeImpl::UFormattedNumberRangeImpl()
- : fImpl(&fData) {
- fFormattedValue = &fImpl;
- }
- UFormattedNumberRangeImpl::~UFormattedNumberRangeImpl() {
- // Disown the data from fImpl so it doesn't get deleted twice
- fImpl.fData = nullptr;
- }
- } // namespace impl
- } // namespace number
- U_NAMESPACE_END
- UPRV_FORMATTED_VALUE_CAPI_NO_IMPLTYPE_AUTO_IMPL(
- UFormattedNumberRange,
- UFormattedNumberRangeImpl,
- UFormattedNumberRangeApiHelper,
- unumrf)
- const UFormattedNumberRangeData* number::impl::validateUFormattedNumberRange(
- const UFormattedNumberRange* uresult, UErrorCode& status) {
- auto* result = UFormattedNumberRangeApiHelper::validate(uresult, status);
- if (U_FAILURE(status)) {
- return nullptr;
- }
- return &result->fData;
- }
- U_CAPI UNumberRangeFormatter* U_EXPORT2
- unumrf_openForSkeletonWithCollapseAndIdentityFallback(
- const char16_t* skeleton,
- int32_t skeletonLen,
- UNumberRangeCollapse collapse,
- UNumberRangeIdentityFallback identityFallback,
- const char* locale,
- UParseError* perror,
- UErrorCode* ec) {
- auto* impl = new UNumberRangeFormatterData();
- 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);
- UParseError tempParseError;
- impl->fFormatter = NumberRangeFormatter::withLocale(locale)
- .numberFormatterBoth(NumberFormatter::forSkeleton(skeletonString, (perror == nullptr) ? tempParseError : *perror, *ec))
- .collapse(collapse)
- .identityFallback(identityFallback);
- return impl->exportForC();
- }
- U_CAPI void U_EXPORT2
- unumrf_formatDoubleRange(
- const UNumberRangeFormatter* uformatter,
- double first,
- double second,
- UFormattedNumberRange* uresult,
- UErrorCode* ec) {
- const UNumberRangeFormatterData* formatter = UNumberRangeFormatterData::validate(uformatter, *ec);
- auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec);
- if (U_FAILURE(*ec)) { return; }
- result->fData.resetString();
- result->fData.quantity1.clear();
- result->fData.quantity2.clear();
- result->fData.quantity1.setToDouble(first);
- result->fData.quantity2.setToDouble(second);
- formatter->fFormatter.formatImpl(result->fData, first == second, *ec);
- }
- U_CAPI void U_EXPORT2
- unumrf_formatDecimalRange(
- const UNumberRangeFormatter* uformatter,
- const char* first, int32_t firstLen,
- const char* second, int32_t secondLen,
- UFormattedNumberRange* uresult,
- UErrorCode* ec) {
- const UNumberRangeFormatterData* formatter = UNumberRangeFormatterData::validate(uformatter, *ec);
- auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec);
- if (U_FAILURE(*ec)) { return; }
- result->fData.resetString();
- result->fData.quantity1.clear();
- result->fData.quantity2.clear();
- result->fData.quantity1.setToDecNumber({first, firstLen}, *ec);
- result->fData.quantity2.setToDecNumber({second, secondLen}, *ec);
- formatter->fFormatter.formatImpl(result->fData, first == second, *ec);
- }
- U_CAPI UNumberRangeIdentityResult U_EXPORT2
- unumrf_resultGetIdentityResult(
- const UFormattedNumberRange* uresult,
- UErrorCode* ec) {
- auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec);
- if (U_FAILURE(*ec)) {
- return UNUM_IDENTITY_RESULT_COUNT;
- }
- return result->fData.identityResult;
- }
- U_CAPI int32_t U_EXPORT2
- unumrf_resultGetFirstDecimalNumber(
- const UFormattedNumberRange* uresult,
- char* dest,
- int32_t destCapacity,
- UErrorCode* ec) {
- const auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec);
- if (U_FAILURE(*ec)) {
- return 0;
- }
- DecNum decnum;
- return result->fData.quantity1.toDecNum(decnum, *ec)
- .toCharString(*ec)
- .extract(dest, destCapacity, *ec);
- }
- U_CAPI int32_t U_EXPORT2
- unumrf_resultGetSecondDecimalNumber(
- const UFormattedNumberRange* uresult,
- char* dest,
- int32_t destCapacity,
- UErrorCode* ec) {
- const auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec);
- if (U_FAILURE(*ec)) {
- return 0;
- }
- DecNum decnum;
- return result->fData.quantity2
- .toDecNum(decnum, *ec)
- .toCharString(*ec)
- .extract(dest, destCapacity, *ec);
- }
- U_CAPI void U_EXPORT2
- unumrf_close(UNumberRangeFormatter* f) {
- UErrorCode localStatus = U_ZERO_ERROR;
- const UNumberRangeFormatterData* impl = UNumberRangeFormatterData::validate(f, localStatus);
- delete impl;
- }
- #endif /* #if !UCONFIG_NO_FORMATTING */
|