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