150 lines
4.7 KiB
C++
150 lines
4.7 KiB
C++
|
// © 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 "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;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
U_NAMESPACE_END
|
||
|
|
||
|
|
||
|
UPRV_FORMATTED_VALUE_CAPI_NO_IMPLTYPE_AUTO_IMPL(
|
||
|
UFormattedNumberRange,
|
||
|
UFormattedNumberRangeImpl,
|
||
|
UFormattedNumberRangeApiHelper,
|
||
|
unumrf)
|
||
|
|
||
|
|
||
|
U_CAPI UNumberRangeFormatter* U_EXPORT2
|
||
|
unumrf_openForSkeletonWithCollapseAndIdentityFallback(
|
||
|
const UChar* 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);
|
||
|
impl->fFormatter = NumberRangeFormatter::withLocale(locale)
|
||
|
.numberFormatterBoth(NumberFormatter::forSkeleton(skeletonString, *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.getStringRef().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.getStringRef().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 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 */
|