1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *****************************************************************************************
5 * Copyright (C) 2010-2012, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 *****************************************************************************************
10 #include "unicode/utypes.h"
12 #if !UCONFIG_NO_FORMATTING
14 #include "unicode/upluralrules.h"
15 #include "unicode/plurrule.h"
16 #include "unicode/locid.h"
17 #include "unicode/unistr.h"
18 #include "unicode/unum.h"
19 #include "unicode/numfmt.h"
20 #include "unicode/unumberformatter.h"
21 #include "number_decimalquantity.h"
22 #include "number_utypes.h"
29 * Given a number and a format, returns the keyword of the first applicable
30 * rule for the PluralRules object.
31 * @param rules The plural rules.
32 * @param obj The numeric object for which the rule should be determined.
33 * @param fmt The NumberFormat specifying how the number will be formatted
34 * (this can affect the plural form, e.g. "1 dollar" vs "1.0 dollars").
35 * @param status Input/output parameter. If at entry this indicates a
36 * failure status, the method returns immediately; otherwise
37 * this is set to indicate the outcome of the call.
38 * @return The keyword of the selected rule. Undefined in the case of an error.
40 UnicodeString
select(const PluralRules
&rules
, const Formattable
& obj
, const NumberFormat
& fmt
, UErrorCode
& status
) {
41 if (U_SUCCESS(status
)) {
42 const DecimalFormat
*decFmt
= dynamic_cast<const DecimalFormat
*>(&fmt
);
44 number::impl::DecimalQuantity dq
;
45 decFmt
->formatToDecimalQuantity(obj
, dq
, status
);
46 if (U_SUCCESS(status
)) {
47 return rules
.select(dq
);
50 double number
= obj
.getDouble(status
);
51 if (U_SUCCESS(status
)) {
52 return rules
.select(number
);
56 return UnicodeString();
61 U_CAPI UPluralRules
* U_EXPORT2
62 uplrules_open(const char *locale
, UErrorCode
*status
)
64 return uplrules_openForType(locale
, UPLURAL_TYPE_CARDINAL
, status
);
67 U_CAPI UPluralRules
* U_EXPORT2
68 uplrules_openForType(const char *locale
, UPluralType type
, UErrorCode
*status
)
70 return (UPluralRules
*)PluralRules::forLocale(Locale(locale
), type
, *status
);
74 uplrules_close(UPluralRules
*uplrules
)
76 delete (PluralRules
*)uplrules
;
79 U_CAPI
int32_t U_EXPORT2
80 uplrules_select(const UPluralRules
*uplrules
,
82 UChar
*keyword
, int32_t capacity
,
85 if (U_FAILURE(*status
)) {
88 if (keyword
== NULL
? capacity
!= 0 : capacity
< 0) {
89 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
92 UnicodeString result
= ((PluralRules
*)uplrules
)->select(number
);
93 return result
.extract(keyword
, capacity
, *status
);
96 U_CAPI
int32_t U_EXPORT2
97 uplrules_selectFormatted(const UPluralRules
*uplrules
,
98 const UFormattedNumber
* number
,
99 UChar
*keyword
, int32_t capacity
,
102 if (U_FAILURE(*status
)) {
105 if (keyword
== NULL
? capacity
!= 0 : capacity
< 0) {
106 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
109 const number::impl::DecimalQuantity
* dq
=
110 number::impl::validateUFormattedNumberToDecimalQuantity(number
, *status
);
111 if (U_FAILURE(*status
)) {
114 UnicodeString result
= ((PluralRules
*)uplrules
)->select(*dq
);
115 return result
.extract(keyword
, capacity
, *status
);
118 U_CAPI
int32_t U_EXPORT2
119 uplrules_selectWithFormat(const UPluralRules
*uplrules
,
121 const UNumberFormat
*fmt
,
122 UChar
*keyword
, int32_t capacity
,
125 if (U_FAILURE(*status
)) {
128 const PluralRules
* plrules
= reinterpret_cast<const PluralRules
*>(uplrules
);
129 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
130 if (plrules
== NULL
|| nf
== NULL
|| ((keyword
== NULL
)? capacity
!= 0 : capacity
< 0)) {
131 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
134 Formattable
obj(number
);
135 UnicodeString result
= select(*plrules
, obj
, *nf
, *status
);
136 return result
.extract(keyword
, capacity
, *status
);
139 U_CAPI UEnumeration
* U_EXPORT2
140 uplrules_getKeywords(const UPluralRules
*uplrules
,
143 if (U_FAILURE(*status
)) {
146 const PluralRules
* plrules
= reinterpret_cast<const PluralRules
*>(uplrules
);
147 if (plrules
== NULL
) {
148 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
151 StringEnumeration
*senum
= plrules
->getKeywords(*status
);
152 if (U_FAILURE(*status
)) {
156 *status
= U_MEMORY_ALLOCATION_ERROR
;
159 return uenum_openFromStringEnumeration(senum
, status
);
162 #endif /* #if !UCONFIG_NO_FORMATTING */