]>
Commit | Line | Data |
---|---|---|
b75a7d8f A |
1 | /* |
2 | ******************************************************************************* | |
4388f060 | 3 | * Copyright (C) 1996-2012, International Business Machines |
b75a7d8f A |
4 | * Corporation and others. All Rights Reserved. |
5 | ******************************************************************************* | |
6 | * Modification History: | |
7 | * | |
8 | * Date Name Description | |
9 | * 06/24/99 helena Integrated Alan's NF enhancements and Java2 bug fixes | |
10 | ******************************************************************************* | |
11 | */ | |
12 | ||
13 | #include "unicode/utypes.h" | |
14 | ||
15 | #if !UCONFIG_NO_FORMATTING | |
16 | ||
17 | #include "unicode/unum.h" | |
18 | ||
19 | #include "unicode/uloc.h" | |
20 | #include "unicode/numfmt.h" | |
21 | #include "unicode/decimfmt.h" | |
22 | #include "unicode/rbnf.h" | |
23 | #include "unicode/ustring.h" | |
24 | #include "unicode/fmtable.h" | |
25 | #include "unicode/dcfmtsym.h" | |
374ca955 | 26 | #include "unicode/curramt.h" |
4388f060 | 27 | #include "unicode/localpointer.h" |
374ca955 | 28 | #include "uassert.h" |
b75a7d8f | 29 | #include "cpputils.h" |
729e4ab9 | 30 | #include "cstring.h" |
b75a7d8f | 31 | |
b75a7d8f | 32 | |
374ca955 | 33 | U_NAMESPACE_USE |
b75a7d8f A |
34 | |
35 | ||
36 | U_CAPI UNumberFormat* U_EXPORT2 | |
37 | unum_open( UNumberFormatStyle style, | |
38 | const UChar* pattern, | |
39 | int32_t patternLength, | |
40 | const char* locale, | |
41 | UParseError* parseErr, | |
4388f060 A |
42 | UErrorCode* status) { |
43 | if(U_FAILURE(*status)) { | |
44 | return NULL; | |
374ca955 A |
45 | } |
46 | ||
4388f060 | 47 | NumberFormat *retVal = NULL; |
374ca955 A |
48 | |
49 | switch(style) { | |
50 | case UNUM_DECIMAL: | |
374ca955 | 51 | case UNUM_CURRENCY: |
374ca955 | 52 | case UNUM_PERCENT: |
374ca955 | 53 | case UNUM_SCIENTIFIC: |
4388f060 | 54 | retVal = NumberFormat::createInstance(Locale(locale), style, *status); |
b75a7d8f A |
55 | break; |
56 | ||
374ca955 A |
57 | case UNUM_PATTERN_DECIMAL: { |
58 | UParseError tErr; | |
59 | /* UnicodeString can handle the case when patternLength = -1. */ | |
60 | const UnicodeString pat(pattern, patternLength); | |
374ca955 A |
61 | |
62 | if(parseErr==NULL){ | |
63 | parseErr = &tErr; | |
64 | } | |
65 | ||
4388f060 A |
66 | DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale(locale), *status); |
67 | if(syms == NULL) { | |
374ca955 | 68 | *status = U_MEMORY_ALLOCATION_ERROR; |
4388f060 | 69 | return NULL; |
374ca955 | 70 | } |
729e4ab9 A |
71 | if (U_FAILURE(*status)) { |
72 | delete syms; | |
4388f060 | 73 | return NULL; |
729e4ab9 | 74 | } |
374ca955 | 75 | |
4388f060 A |
76 | retVal = new DecimalFormat(pat, syms, *parseErr, *status); |
77 | if(retVal == NULL) { | |
374ca955 A |
78 | delete syms; |
79 | } | |
4388f060 | 80 | } break; |
374ca955 | 81 | |
b75a7d8f | 82 | #if U_HAVE_RBNF |
374ca955 A |
83 | case UNUM_PATTERN_RULEBASED: { |
84 | UParseError tErr; | |
85 | /* UnicodeString can handle the case when patternLength = -1. */ | |
86 | const UnicodeString pat(pattern, patternLength); | |
87 | ||
88 | if(parseErr==NULL){ | |
89 | parseErr = &tErr; | |
90 | } | |
91 | ||
4388f060 | 92 | retVal = new RuleBasedNumberFormat(pat, Locale(locale), *parseErr, *status); |
374ca955 A |
93 | } break; |
94 | ||
95 | case UNUM_SPELLOUT: | |
4388f060 | 96 | retVal = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale(locale), *status); |
374ca955 | 97 | break; |
b75a7d8f | 98 | |
374ca955 | 99 | case UNUM_ORDINAL: |
4388f060 | 100 | retVal = new RuleBasedNumberFormat(URBNF_ORDINAL, Locale(locale), *status); |
374ca955 | 101 | break; |
b75a7d8f | 102 | |
374ca955 | 103 | case UNUM_DURATION: |
4388f060 | 104 | retVal = new RuleBasedNumberFormat(URBNF_DURATION, Locale(locale), *status); |
374ca955 | 105 | break; |
729e4ab9 A |
106 | |
107 | case UNUM_NUMBERING_SYSTEM: | |
4388f060 | 108 | retVal = new RuleBasedNumberFormat(URBNF_NUMBERING_SYSTEM, Locale(locale), *status); |
729e4ab9 | 109 | break; |
374ca955 A |
110 | #endif |
111 | ||
112 | default: | |
113 | *status = U_UNSUPPORTED_ERROR; | |
4388f060 | 114 | return NULL; |
374ca955 | 115 | } |
b75a7d8f | 116 | |
4388f060 | 117 | if(retVal == NULL && U_SUCCESS(*status)) { |
b75a7d8f | 118 | *status = U_MEMORY_ALLOCATION_ERROR; |
374ca955 | 119 | } |
b75a7d8f | 120 | |
4388f060 | 121 | return reinterpret_cast<UNumberFormat *>(retVal); |
b75a7d8f A |
122 | } |
123 | ||
124 | U_CAPI void U_EXPORT2 | |
125 | unum_close(UNumberFormat* fmt) | |
126 | { | |
374ca955 | 127 | delete (NumberFormat*) fmt; |
b75a7d8f A |
128 | } |
129 | ||
130 | U_CAPI UNumberFormat* U_EXPORT2 | |
131 | unum_clone(const UNumberFormat *fmt, | |
132 | UErrorCode *status) | |
133 | { | |
374ca955 A |
134 | if(U_FAILURE(*status)) |
135 | return 0; | |
136 | ||
137 | Format *res = 0; | |
729e4ab9 A |
138 | const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt); |
139 | const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf); | |
140 | if (df != NULL) { | |
141 | res = df->clone(); | |
374ca955 | 142 | } else { |
729e4ab9 A |
143 | const RuleBasedNumberFormat* rbnf = dynamic_cast<const RuleBasedNumberFormat*>(nf); |
144 | U_ASSERT(rbnf != NULL); | |
145 | res = rbnf->clone(); | |
374ca955 | 146 | } |
b75a7d8f | 147 | |
374ca955 A |
148 | if(res == 0) { |
149 | *status = U_MEMORY_ALLOCATION_ERROR; | |
150 | return 0; | |
151 | } | |
152 | ||
153 | return (UNumberFormat*) res; | |
b75a7d8f A |
154 | } |
155 | ||
156 | U_CAPI int32_t U_EXPORT2 | |
157 | unum_format( const UNumberFormat* fmt, | |
374ca955 | 158 | int32_t number, |
b75a7d8f | 159 | UChar* result, |
374ca955 | 160 | int32_t resultLength, |
b75a7d8f | 161 | UFieldPosition *pos, |
374ca955 | 162 | UErrorCode* status) |
b75a7d8f | 163 | { |
374ca955 A |
164 | return unum_formatInt64(fmt, number, result, resultLength, pos, status); |
165 | } | |
b75a7d8f | 166 | |
374ca955 A |
167 | U_CAPI int32_t U_EXPORT2 |
168 | unum_formatInt64(const UNumberFormat* fmt, | |
169 | int64_t number, | |
170 | UChar* result, | |
171 | int32_t resultLength, | |
172 | UFieldPosition *pos, | |
173 | UErrorCode* status) | |
174 | { | |
175 | if(U_FAILURE(*status)) | |
176 | return -1; | |
177 | ||
178 | UnicodeString res; | |
179 | if(!(result==NULL && resultLength==0)) { | |
180 | // NULL destination for pure preflighting: empty dummy string | |
181 | // otherwise, alias the destination buffer | |
182 | res.setTo(result, 0, resultLength); | |
183 | } | |
184 | ||
185 | FieldPosition fp; | |
186 | ||
187 | if(pos != 0) | |
188 | fp.setField(pos->field); | |
189 | ||
190 | ((const NumberFormat*)fmt)->format(number, res, fp); | |
191 | ||
192 | if(pos != 0) { | |
193 | pos->beginIndex = fp.getBeginIndex(); | |
194 | pos->endIndex = fp.getEndIndex(); | |
195 | } | |
196 | ||
197 | return res.extract(result, resultLength, *status); | |
b75a7d8f A |
198 | } |
199 | ||
200 | U_CAPI int32_t U_EXPORT2 | |
201 | unum_formatDouble( const UNumberFormat* fmt, | |
202 | double number, | |
203 | UChar* result, | |
204 | int32_t resultLength, | |
205 | UFieldPosition *pos, /* 0 if ignore */ | |
206 | UErrorCode* status) | |
207 | { | |
208 | ||
209 | if(U_FAILURE(*status)) return -1; | |
210 | ||
211 | UnicodeString res; | |
212 | if(!(result==NULL && resultLength==0)) { | |
213 | // NULL destination for pure preflighting: empty dummy string | |
214 | // otherwise, alias the destination buffer | |
215 | res.setTo(result, 0, resultLength); | |
216 | } | |
217 | ||
218 | FieldPosition fp; | |
219 | ||
220 | if(pos != 0) | |
221 | fp.setField(pos->field); | |
222 | ||
374ca955 | 223 | ((const NumberFormat*)fmt)->format(number, res, fp); |
b75a7d8f A |
224 | |
225 | if(pos != 0) { | |
226 | pos->beginIndex = fp.getBeginIndex(); | |
227 | pos->endIndex = fp.getEndIndex(); | |
228 | } | |
229 | ||
230 | return res.extract(result, resultLength, *status); | |
231 | } | |
232 | ||
729e4ab9 A |
233 | |
234 | U_DRAFT int32_t U_EXPORT2 | |
235 | unum_formatDecimal(const UNumberFormat* fmt, | |
236 | const char * number, | |
237 | int32_t length, | |
238 | UChar* result, | |
239 | int32_t resultLength, | |
240 | UFieldPosition *pos, /* 0 if ignore */ | |
241 | UErrorCode* status) { | |
242 | ||
243 | if(U_FAILURE(*status)) { | |
244 | return -1; | |
245 | } | |
246 | if ((result == NULL && resultLength != 0) || resultLength < 0) { | |
247 | *status = U_ILLEGAL_ARGUMENT_ERROR; | |
248 | return -1; | |
249 | } | |
250 | ||
251 | FieldPosition fp; | |
252 | if(pos != 0) { | |
253 | fp.setField(pos->field); | |
254 | } | |
255 | ||
256 | if (length < 0) { | |
257 | length = uprv_strlen(number); | |
258 | } | |
259 | StringPiece numSP(number, length); | |
260 | Formattable numFmtbl(numSP, *status); | |
261 | ||
262 | UnicodeString resultStr; | |
263 | if (resultLength > 0) { | |
264 | // Alias the destination buffer. | |
265 | resultStr.setTo(result, 0, resultLength); | |
266 | } | |
267 | ((const NumberFormat*)fmt)->format(numFmtbl, resultStr, fp, *status); | |
268 | if(pos != 0) { | |
269 | pos->beginIndex = fp.getBeginIndex(); | |
270 | pos->endIndex = fp.getEndIndex(); | |
271 | } | |
272 | return resultStr.extract(result, resultLength, *status); | |
273 | } | |
274 | ||
275 | ||
276 | ||
277 | ||
46f4442e | 278 | U_CAPI int32_t U_EXPORT2 |
374ca955 A |
279 | unum_formatDoubleCurrency(const UNumberFormat* fmt, |
280 | double number, | |
281 | UChar* currency, | |
282 | UChar* result, | |
283 | int32_t resultLength, | |
284 | UFieldPosition* pos, /* ignored if 0 */ | |
285 | UErrorCode* status) { | |
286 | if (U_FAILURE(*status)) return -1; | |
287 | ||
288 | UnicodeString res; | |
289 | if (!(result==NULL && resultLength==0)) { | |
290 | // NULL destination for pure preflighting: empty dummy string | |
291 | // otherwise, alias the destination buffer | |
292 | res.setTo(result, 0, resultLength); | |
293 | } | |
294 | ||
295 | FieldPosition fp; | |
296 | if (pos != 0) { | |
297 | fp.setField(pos->field); | |
298 | } | |
46f4442e A |
299 | CurrencyAmount *tempCurrAmnt = new CurrencyAmount(number, currency, *status); |
300 | // Check for null pointer. | |
301 | if (tempCurrAmnt == NULL) { | |
302 | *status = U_MEMORY_ALLOCATION_ERROR; | |
303 | return -1; | |
304 | } | |
305 | Formattable n(tempCurrAmnt); | |
374ca955 A |
306 | ((const NumberFormat*)fmt)->format(n, res, fp, *status); |
307 | ||
308 | if (pos != 0) { | |
309 | pos->beginIndex = fp.getBeginIndex(); | |
310 | pos->endIndex = fp.getEndIndex(); | |
311 | } | |
312 | ||
313 | return res.extract(result, resultLength, *status); | |
314 | } | |
315 | ||
316 | static void | |
317 | parseRes(Formattable& res, | |
318 | const UNumberFormat* fmt, | |
319 | const UChar* text, | |
320 | int32_t textLength, | |
321 | int32_t *parsePos /* 0 = start */, | |
374ca955 A |
322 | UErrorCode *status) |
323 | { | |
324 | if(U_FAILURE(*status)) | |
325 | return; | |
326 | ||
4388f060 | 327 | const UnicodeString src((UBool)(textLength == -1), text, textLength); |
374ca955 A |
328 | ParsePosition pp; |
329 | ||
330 | if(parsePos != 0) | |
331 | pp.setIndex(*parsePos); | |
332 | ||
4388f060 | 333 | ((const NumberFormat*)fmt)->parse(src, res, pp); |
374ca955 | 334 | |
46f4442e A |
335 | if(pp.getErrorIndex() != -1) { |
336 | *status = U_PARSE_ERROR; | |
337 | if(parsePos != 0) { | |
374ca955 | 338 | *parsePos = pp.getErrorIndex(); |
374ca955 | 339 | } |
46f4442e A |
340 | } else if(parsePos != 0) { |
341 | *parsePos = pp.getIndex(); | |
374ca955 A |
342 | } |
343 | } | |
344 | ||
b75a7d8f A |
345 | U_CAPI int32_t U_EXPORT2 |
346 | unum_parse( const UNumberFormat* fmt, | |
347 | const UChar* text, | |
348 | int32_t textLength, | |
349 | int32_t *parsePos /* 0 = start */, | |
350 | UErrorCode *status) | |
351 | { | |
374ca955 | 352 | Formattable res; |
4388f060 | 353 | parseRes(res, fmt, text, textLength, parsePos, status); |
374ca955 A |
354 | return res.getLong(*status); |
355 | } | |
b75a7d8f | 356 | |
374ca955 A |
357 | U_CAPI int64_t U_EXPORT2 |
358 | unum_parseInt64( const UNumberFormat* fmt, | |
359 | const UChar* text, | |
360 | int32_t textLength, | |
361 | int32_t *parsePos /* 0 = start */, | |
362 | UErrorCode *status) | |
363 | { | |
364 | Formattable res; | |
4388f060 | 365 | parseRes(res, fmt, text, textLength, parsePos, status); |
374ca955 | 366 | return res.getInt64(*status); |
b75a7d8f A |
367 | } |
368 | ||
369 | U_CAPI double U_EXPORT2 | |
370 | unum_parseDouble( const UNumberFormat* fmt, | |
371 | const UChar* text, | |
372 | int32_t textLength, | |
373 | int32_t *parsePos /* 0 = start */, | |
374 | UErrorCode *status) | |
375 | { | |
374ca955 | 376 | Formattable res; |
4388f060 | 377 | parseRes(res, fmt, text, textLength, parsePos, status); |
374ca955 A |
378 | return res.getDouble(*status); |
379 | } | |
b75a7d8f | 380 | |
729e4ab9 A |
381 | U_CAPI int32_t U_EXPORT2 |
382 | unum_parseDecimal(const UNumberFormat* fmt, | |
383 | const UChar* text, | |
384 | int32_t textLength, | |
385 | int32_t *parsePos /* 0 = start */, | |
386 | char *outBuf, | |
387 | int32_t outBufLength, | |
388 | UErrorCode *status) | |
389 | { | |
390 | if (U_FAILURE(*status)) { | |
391 | return -1; | |
392 | } | |
393 | if ((outBuf == NULL && outBufLength != 0) || outBufLength < 0) { | |
394 | *status = U_ILLEGAL_ARGUMENT_ERROR; | |
395 | return -1; | |
396 | } | |
397 | Formattable res; | |
4388f060 | 398 | parseRes(res, fmt, text, textLength, parsePos, status); |
729e4ab9 A |
399 | StringPiece sp = res.getDecimalNumber(*status); |
400 | if (U_FAILURE(*status)) { | |
401 | return -1; | |
402 | } else if (sp.size() > outBufLength) { | |
403 | *status = U_BUFFER_OVERFLOW_ERROR; | |
404 | } else if (sp.size() == outBufLength) { | |
405 | uprv_strncpy(outBuf, sp.data(), sp.size()); | |
406 | *status = U_STRING_NOT_TERMINATED_WARNING; | |
407 | } else { | |
4388f060 | 408 | U_ASSERT(outBufLength > 0); |
729e4ab9 A |
409 | uprv_strcpy(outBuf, sp.data()); |
410 | } | |
411 | return sp.size(); | |
412 | } | |
413 | ||
46f4442e | 414 | U_CAPI double U_EXPORT2 |
374ca955 A |
415 | unum_parseDoubleCurrency(const UNumberFormat* fmt, |
416 | const UChar* text, | |
417 | int32_t textLength, | |
418 | int32_t* parsePos, /* 0 = start */ | |
419 | UChar* currency, | |
420 | UErrorCode* status) { | |
4388f060 | 421 | double doubleVal = 0.0; |
374ca955 | 422 | currency[0] = 0; |
4388f060 A |
423 | if (U_FAILURE(*status)) { |
424 | return doubleVal; | |
b75a7d8f | 425 | } |
4388f060 A |
426 | const UnicodeString src((UBool)(textLength == -1), text, textLength); |
427 | ParsePosition pp; | |
428 | if (parsePos != NULL) { | |
429 | pp.setIndex(*parsePos); | |
430 | } | |
431 | *status = U_PARSE_ERROR; // assume failure, reset if succeed | |
432 | LocalPointer<CurrencyAmount> currAmt(((const NumberFormat*)fmt)->parseCurrency(src, pp)); | |
433 | if (pp.getErrorIndex() != -1) { | |
434 | if (parsePos != NULL) { | |
435 | *parsePos = pp.getErrorIndex(); | |
436 | } | |
437 | } else { | |
438 | if (parsePos != NULL) { | |
439 | *parsePos = pp.getIndex(); | |
440 | } | |
441 | if (pp.getIndex() > 0) { | |
442 | *status = U_ZERO_ERROR; | |
443 | u_strcpy(currency, currAmt->getISOCurrency()); | |
444 | doubleVal = currAmt->getNumber().getDouble(*status); | |
445 | } | |
446 | } | |
447 | return doubleVal; | |
b75a7d8f A |
448 | } |
449 | ||
450 | U_CAPI const char* U_EXPORT2 | |
451 | unum_getAvailable(int32_t index) | |
452 | { | |
374ca955 | 453 | return uloc_getAvailable(index); |
b75a7d8f A |
454 | } |
455 | ||
456 | U_CAPI int32_t U_EXPORT2 | |
457 | unum_countAvailable() | |
458 | { | |
374ca955 | 459 | return uloc_countAvailable(); |
b75a7d8f A |
460 | } |
461 | ||
462 | U_CAPI int32_t U_EXPORT2 | |
463 | unum_getAttribute(const UNumberFormat* fmt, | |
464 | UNumberFormatAttribute attr) | |
465 | { | |
729e4ab9 | 466 | const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt); |
4388f060 A |
467 | if ( attr == UNUM_LENIENT_PARSE ) { |
468 | // Supported for all subclasses | |
469 | return nf->isLenient(); | |
470 | } | |
471 | // The remaining attributea are only supported for DecimalFormat | |
729e4ab9 A |
472 | const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf); |
473 | if (df != NULL) { | |
374ca955 A |
474 | switch(attr) { |
475 | case UNUM_PARSE_INT_ONLY: | |
476 | return df->isParseIntegerOnly(); | |
477 | ||
478 | case UNUM_GROUPING_USED: | |
479 | return df->isGroupingUsed(); | |
480 | ||
481 | case UNUM_DECIMAL_ALWAYS_SHOWN: | |
482 | return df->isDecimalSeparatorAlwaysShown(); | |
483 | ||
484 | case UNUM_MAX_INTEGER_DIGITS: | |
485 | return df->getMaximumIntegerDigits(); | |
486 | ||
487 | case UNUM_MIN_INTEGER_DIGITS: | |
488 | return df->getMinimumIntegerDigits(); | |
489 | ||
490 | case UNUM_INTEGER_DIGITS: | |
491 | // TBD: what should this return? | |
492 | return df->getMinimumIntegerDigits(); | |
493 | ||
494 | case UNUM_MAX_FRACTION_DIGITS: | |
495 | return df->getMaximumFractionDigits(); | |
496 | ||
497 | case UNUM_MIN_FRACTION_DIGITS: | |
498 | return df->getMinimumFractionDigits(); | |
499 | ||
500 | case UNUM_FRACTION_DIGITS: | |
501 | // TBD: what should this return? | |
502 | return df->getMinimumFractionDigits(); | |
503 | ||
504 | case UNUM_SIGNIFICANT_DIGITS_USED: | |
505 | return df->areSignificantDigitsUsed(); | |
506 | ||
507 | case UNUM_MAX_SIGNIFICANT_DIGITS: | |
508 | return df->getMaximumSignificantDigits(); | |
509 | ||
510 | case UNUM_MIN_SIGNIFICANT_DIGITS: | |
511 | return df->getMinimumSignificantDigits(); | |
512 | ||
513 | case UNUM_MULTIPLIER: | |
514 | return df->getMultiplier(); | |
515 | ||
516 | case UNUM_GROUPING_SIZE: | |
517 | return df->getGroupingSize(); | |
518 | ||
519 | case UNUM_ROUNDING_MODE: | |
520 | return df->getRoundingMode(); | |
521 | ||
522 | case UNUM_FORMAT_WIDTH: | |
523 | return df->getFormatWidth(); | |
524 | ||
525 | case UNUM_PADDING_POSITION: | |
526 | return df->getPadPosition(); | |
527 | ||
528 | case UNUM_SECONDARY_GROUPING_SIZE: | |
529 | return df->getSecondaryGroupingSize(); | |
729e4ab9 | 530 | |
374ca955 A |
531 | default: |
532 | /* enums out of sync? unsupported enum? */ | |
533 | break; | |
534 | } | |
b75a7d8f | 535 | } |
374ca955 | 536 | |
b75a7d8f A |
537 | return -1; |
538 | } | |
539 | ||
540 | U_CAPI void U_EXPORT2 | |
541 | unum_setAttribute( UNumberFormat* fmt, | |
542 | UNumberFormatAttribute attr, | |
543 | int32_t newValue) | |
544 | { | |
729e4ab9 | 545 | NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt); |
4388f060 A |
546 | if ( attr == UNUM_LENIENT_PARSE ) { |
547 | // Supported for all subclasses | |
548 | return nf->setLenient(newValue != 0); | |
549 | } | |
550 | // The remaining attributea are only supported for DecimalFormat | |
729e4ab9 A |
551 | DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf); |
552 | if (df != NULL) { | |
374ca955 A |
553 | switch(attr) { |
554 | case UNUM_PARSE_INT_ONLY: | |
555 | df->setParseIntegerOnly(newValue!=0); | |
556 | break; | |
557 | ||
558 | case UNUM_GROUPING_USED: | |
559 | df->setGroupingUsed(newValue!=0); | |
560 | break; | |
561 | ||
562 | case UNUM_DECIMAL_ALWAYS_SHOWN: | |
563 | df->setDecimalSeparatorAlwaysShown(newValue!=0); | |
564 | break; | |
565 | ||
566 | case UNUM_MAX_INTEGER_DIGITS: | |
567 | df->setMaximumIntegerDigits(newValue); | |
568 | break; | |
569 | ||
570 | case UNUM_MIN_INTEGER_DIGITS: | |
571 | df->setMinimumIntegerDigits(newValue); | |
572 | break; | |
573 | ||
574 | case UNUM_INTEGER_DIGITS: | |
575 | df->setMinimumIntegerDigits(newValue); | |
576 | df->setMaximumIntegerDigits(newValue); | |
577 | break; | |
578 | ||
579 | case UNUM_MAX_FRACTION_DIGITS: | |
580 | df->setMaximumFractionDigits(newValue); | |
581 | break; | |
582 | ||
583 | case UNUM_MIN_FRACTION_DIGITS: | |
584 | df->setMinimumFractionDigits(newValue); | |
585 | break; | |
586 | ||
587 | case UNUM_FRACTION_DIGITS: | |
588 | df->setMinimumFractionDigits(newValue); | |
589 | df->setMaximumFractionDigits(newValue); | |
590 | break; | |
591 | ||
592 | case UNUM_SIGNIFICANT_DIGITS_USED: | |
593 | df->setSignificantDigitsUsed(newValue!=0); | |
594 | break; | |
595 | ||
596 | case UNUM_MAX_SIGNIFICANT_DIGITS: | |
597 | df->setMaximumSignificantDigits(newValue); | |
598 | break; | |
599 | ||
600 | case UNUM_MIN_SIGNIFICANT_DIGITS: | |
601 | df->setMinimumSignificantDigits(newValue); | |
602 | break; | |
603 | ||
604 | case UNUM_MULTIPLIER: | |
605 | df->setMultiplier(newValue); | |
606 | break; | |
607 | ||
608 | case UNUM_GROUPING_SIZE: | |
609 | df->setGroupingSize(newValue); | |
610 | break; | |
611 | ||
612 | case UNUM_ROUNDING_MODE: | |
613 | df->setRoundingMode((DecimalFormat::ERoundingMode)newValue); | |
614 | break; | |
615 | ||
616 | case UNUM_FORMAT_WIDTH: | |
617 | df->setFormatWidth(newValue); | |
618 | break; | |
619 | ||
620 | case UNUM_PADDING_POSITION: | |
621 | /** The position at which padding will take place. */ | |
622 | df->setPadPosition((DecimalFormat::EPadPosition)newValue); | |
623 | break; | |
624 | ||
625 | case UNUM_SECONDARY_GROUPING_SIZE: | |
626 | df->setSecondaryGroupingSize(newValue); | |
627 | break; | |
729e4ab9 | 628 | |
374ca955 A |
629 | default: |
630 | /* Shouldn't get here anyway */ | |
631 | break; | |
632 | } | |
b75a7d8f A |
633 | } |
634 | } | |
635 | ||
636 | U_CAPI double U_EXPORT2 | |
637 | unum_getDoubleAttribute(const UNumberFormat* fmt, | |
638 | UNumberFormatAttribute attr) | |
639 | { | |
729e4ab9 A |
640 | const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt); |
641 | const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf); | |
642 | if (df != NULL && attr == UNUM_ROUNDING_INCREMENT) { | |
643 | return df->getRoundingIncrement(); | |
374ca955 A |
644 | } else { |
645 | return -1.0; | |
646 | } | |
b75a7d8f A |
647 | } |
648 | ||
649 | U_CAPI void U_EXPORT2 | |
650 | unum_setDoubleAttribute( UNumberFormat* fmt, | |
651 | UNumberFormatAttribute attr, | |
652 | double newValue) | |
653 | { | |
729e4ab9 A |
654 | NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt); |
655 | DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf); | |
656 | if (df != NULL && attr == UNUM_ROUNDING_INCREMENT) { | |
657 | df->setRoundingIncrement(newValue); | |
374ca955 | 658 | } |
b75a7d8f A |
659 | } |
660 | ||
661 | U_CAPI int32_t U_EXPORT2 | |
662 | unum_getTextAttribute(const UNumberFormat* fmt, | |
663 | UNumberFormatTextAttribute tag, | |
664 | UChar* result, | |
665 | int32_t resultLength, | |
666 | UErrorCode* status) | |
667 | { | |
374ca955 A |
668 | if(U_FAILURE(*status)) |
669 | return -1; | |
670 | ||
671 | UnicodeString res; | |
672 | if(!(result==NULL && resultLength==0)) { | |
673 | // NULL destination for pure preflighting: empty dummy string | |
674 | // otherwise, alias the destination buffer | |
675 | res.setTo(result, 0, resultLength); | |
676 | } | |
b75a7d8f | 677 | |
729e4ab9 A |
678 | const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt); |
679 | const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf); | |
680 | if (df != NULL) { | |
374ca955 A |
681 | switch(tag) { |
682 | case UNUM_POSITIVE_PREFIX: | |
683 | df->getPositivePrefix(res); | |
684 | break; | |
685 | ||
686 | case UNUM_POSITIVE_SUFFIX: | |
687 | df->getPositiveSuffix(res); | |
688 | break; | |
689 | ||
690 | case UNUM_NEGATIVE_PREFIX: | |
691 | df->getNegativePrefix(res); | |
692 | break; | |
693 | ||
694 | case UNUM_NEGATIVE_SUFFIX: | |
695 | df->getNegativeSuffix(res); | |
696 | break; | |
697 | ||
698 | case UNUM_PADDING_CHARACTER: | |
699 | res = df->getPadCharacterString(); | |
700 | break; | |
701 | ||
702 | case UNUM_CURRENCY_CODE: | |
703 | res = UnicodeString(df->getCurrency()); | |
704 | break; | |
705 | ||
706 | default: | |
707 | *status = U_UNSUPPORTED_ERROR; | |
708 | return -1; | |
709 | } | |
710 | } else { | |
729e4ab9 A |
711 | const RuleBasedNumberFormat* rbnf = dynamic_cast<const RuleBasedNumberFormat*>(nf); |
712 | U_ASSERT(rbnf != NULL); | |
374ca955 A |
713 | if (tag == UNUM_DEFAULT_RULESET) { |
714 | res = rbnf->getDefaultRuleSetName(); | |
715 | } else if (tag == UNUM_PUBLIC_RULESETS) { | |
716 | int32_t count = rbnf->getNumberOfRuleSetNames(); | |
717 | for (int i = 0; i < count; ++i) { | |
718 | res += rbnf->getRuleSetName(i); | |
719 | res += (UChar)0x003b; // semicolon | |
720 | } | |
721 | } else { | |
722 | *status = U_UNSUPPORTED_ERROR; | |
723 | return -1; | |
724 | } | |
725 | } | |
b75a7d8f | 726 | |
374ca955 | 727 | return res.extract(result, resultLength, *status); |
b75a7d8f A |
728 | } |
729 | ||
730 | U_CAPI void U_EXPORT2 | |
731 | unum_setTextAttribute( UNumberFormat* fmt, | |
732 | UNumberFormatTextAttribute tag, | |
733 | const UChar* newValue, | |
734 | int32_t newValueLength, | |
735 | UErrorCode *status) | |
736 | { | |
374ca955 A |
737 | if(U_FAILURE(*status)) |
738 | return; | |
729e4ab9 | 739 | |
4388f060 | 740 | UnicodeString val(newValue, newValueLength); |
729e4ab9 A |
741 | NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt); |
742 | DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf); | |
743 | if (df != NULL) { | |
374ca955 A |
744 | switch(tag) { |
745 | case UNUM_POSITIVE_PREFIX: | |
746 | df->setPositivePrefix(val); | |
747 | break; | |
748 | ||
749 | case UNUM_POSITIVE_SUFFIX: | |
750 | df->setPositiveSuffix(val); | |
751 | break; | |
752 | ||
753 | case UNUM_NEGATIVE_PREFIX: | |
754 | df->setNegativePrefix(val); | |
755 | break; | |
756 | ||
757 | case UNUM_NEGATIVE_SUFFIX: | |
758 | df->setNegativeSuffix(val); | |
759 | break; | |
760 | ||
761 | case UNUM_PADDING_CHARACTER: | |
4388f060 | 762 | df->setPadCharacter(val); |
374ca955 A |
763 | break; |
764 | ||
765 | case UNUM_CURRENCY_CODE: | |
4388f060 | 766 | df->setCurrency(val.getTerminatedBuffer(), *status); |
374ca955 A |
767 | break; |
768 | ||
769 | default: | |
770 | *status = U_UNSUPPORTED_ERROR; | |
771 | break; | |
772 | } | |
773 | } else { | |
729e4ab9 A |
774 | RuleBasedNumberFormat* rbnf = dynamic_cast<RuleBasedNumberFormat*>(nf); |
775 | U_ASSERT(rbnf != NULL); | |
374ca955 | 776 | if (tag == UNUM_DEFAULT_RULESET) { |
4388f060 | 777 | rbnf->setDefaultRuleSet(val, *status); |
374ca955 | 778 | } else { |
729e4ab9 | 779 | *status = U_UNSUPPORTED_ERROR; |
374ca955 A |
780 | } |
781 | } | |
b75a7d8f A |
782 | } |
783 | ||
784 | U_CAPI int32_t U_EXPORT2 | |
785 | unum_toPattern( const UNumberFormat* fmt, | |
786 | UBool isPatternLocalized, | |
787 | UChar* result, | |
788 | int32_t resultLength, | |
789 | UErrorCode* status) | |
790 | { | |
374ca955 A |
791 | if(U_FAILURE(*status)) |
792 | return -1; | |
793 | ||
794 | UnicodeString pat; | |
795 | if(!(result==NULL && resultLength==0)) { | |
796 | // NULL destination for pure preflighting: empty dummy string | |
797 | // otherwise, alias the destination buffer | |
798 | pat.setTo(result, 0, resultLength); | |
799 | } | |
b75a7d8f | 800 | |
729e4ab9 A |
801 | const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt); |
802 | const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf); | |
803 | if (df != NULL) { | |
374ca955 A |
804 | if(isPatternLocalized) |
805 | df->toLocalizedPattern(pat); | |
806 | else | |
807 | df->toPattern(pat); | |
808 | } else { | |
729e4ab9 A |
809 | const RuleBasedNumberFormat* rbnf = dynamic_cast<const RuleBasedNumberFormat*>(nf); |
810 | U_ASSERT(rbnf != NULL); | |
811 | pat = rbnf->getRules(); | |
374ca955 A |
812 | } |
813 | return pat.extract(result, resultLength, *status); | |
b75a7d8f A |
814 | } |
815 | ||
816 | U_CAPI int32_t U_EXPORT2 | |
374ca955 | 817 | unum_getSymbol(const UNumberFormat *fmt, |
b75a7d8f A |
818 | UNumberFormatSymbol symbol, |
819 | UChar *buffer, | |
820 | int32_t size, | |
374ca955 A |
821 | UErrorCode *status) |
822 | { | |
823 | if(status==NULL || U_FAILURE(*status)) { | |
824 | return 0; | |
825 | } | |
4388f060 | 826 | if(fmt==NULL || symbol< 0 || symbol>=UNUM_FORMAT_SYMBOL_COUNT) { |
374ca955 A |
827 | *status=U_ILLEGAL_ARGUMENT_ERROR; |
828 | return 0; | |
829 | } | |
729e4ab9 A |
830 | const NumberFormat *nf = reinterpret_cast<const NumberFormat *>(fmt); |
831 | const DecimalFormat *dcf = dynamic_cast<const DecimalFormat *>(nf); | |
832 | if (dcf == NULL) { | |
374ca955 A |
833 | *status = U_UNSUPPORTED_ERROR; |
834 | return 0; | |
835 | } | |
b75a7d8f | 836 | |
729e4ab9 | 837 | return dcf-> |
b75a7d8f A |
838 | getDecimalFormatSymbols()-> |
839 | getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbol). | |
840 | extract(buffer, size, *status); | |
841 | } | |
842 | ||
843 | U_CAPI void U_EXPORT2 | |
844 | unum_setSymbol(UNumberFormat *fmt, | |
845 | UNumberFormatSymbol symbol, | |
846 | const UChar *value, | |
847 | int32_t length, | |
374ca955 | 848 | UErrorCode *status) |
b75a7d8f | 849 | { |
374ca955 A |
850 | if(status==NULL || U_FAILURE(*status)) { |
851 | return; | |
852 | } | |
4388f060 | 853 | if(fmt==NULL || symbol< 0 || symbol>=UNUM_FORMAT_SYMBOL_COUNT || value==NULL || length<-1) { |
374ca955 A |
854 | *status=U_ILLEGAL_ARGUMENT_ERROR; |
855 | return; | |
856 | } | |
729e4ab9 A |
857 | NumberFormat *nf = reinterpret_cast<NumberFormat *>(fmt); |
858 | DecimalFormat *dcf = dynamic_cast<DecimalFormat *>(nf); | |
859 | if (dcf == NULL) { | |
374ca955 A |
860 | *status = U_UNSUPPORTED_ERROR; |
861 | return; | |
862 | } | |
863 | ||
729e4ab9 | 864 | DecimalFormatSymbols symbols(*dcf->getDecimalFormatSymbols()); |
374ca955 A |
865 | symbols.setSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbol, |
866 | UnicodeString(value, length)); /* UnicodeString can handle the case when length = -1. */ | |
729e4ab9 | 867 | dcf->setDecimalFormatSymbols(symbols); |
b75a7d8f | 868 | } |
b75a7d8f A |
869 | |
870 | U_CAPI void U_EXPORT2 | |
729e4ab9 | 871 | unum_applyPattern( UNumberFormat *fmt, |
b75a7d8f A |
872 | UBool localized, |
873 | const UChar *pattern, | |
874 | int32_t patternLength, | |
875 | UParseError *parseError, | |
876 | UErrorCode* status) | |
877 | { | |
374ca955 A |
878 | UErrorCode tStatus = U_ZERO_ERROR; |
879 | UParseError tParseError; | |
880 | ||
881 | if(parseError == NULL){ | |
882 | parseError = &tParseError; | |
883 | } | |
884 | ||
885 | if(status==NULL){ | |
886 | status = &tStatus; | |
887 | } | |
888 | ||
889 | int32_t len = (patternLength == -1 ? u_strlen(pattern) : patternLength); | |
890 | const UnicodeString pat((UChar*)pattern, len, len); | |
729e4ab9 | 891 | |
374ca955 | 892 | // Verify if the object passed is a DecimalFormat object |
729e4ab9 A |
893 | NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt); |
894 | DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf); | |
895 | if (df != NULL) { | |
374ca955 | 896 | if(localized) { |
729e4ab9 | 897 | df->applyLocalizedPattern(pat,*parseError, *status); |
374ca955 | 898 | } else { |
729e4ab9 | 899 | df->applyPattern(pat,*parseError, *status); |
374ca955 A |
900 | } |
901 | } else { | |
902 | *status = U_UNSUPPORTED_ERROR; | |
b75a7d8f | 903 | return; |
374ca955 A |
904 | } |
905 | } | |
906 | ||
907 | U_CAPI const char* U_EXPORT2 | |
908 | unum_getLocaleByType(const UNumberFormat *fmt, | |
909 | ULocDataLocaleType type, | |
910 | UErrorCode* status) | |
911 | { | |
912 | if (fmt == NULL) { | |
913 | if (U_SUCCESS(*status)) { | |
914 | *status = U_ILLEGAL_ARGUMENT_ERROR; | |
915 | } | |
916 | return NULL; | |
917 | } | |
918 | return ((const Format*)fmt)->getLocaleID(type, *status); | |
b75a7d8f A |
919 | } |
920 | ||
921 | #endif /* #if !UCONFIG_NO_FORMATTING */ |