]>
Commit | Line | Data |
---|---|---|
b75a7d8f A |
1 | /* |
2 | ******************************************************************************* | |
374ca955 | 3 | * Copyright (C) 1997-2004, International Business Machines Corporation and * |
b75a7d8f A |
4 | * others. All Rights Reserved. * |
5 | ******************************************************************************* | |
6 | * | |
7 | * File FMTABLE.CPP | |
8 | * | |
9 | * Modification History: | |
10 | * | |
11 | * Date Name Description | |
12 | * 03/25/97 clhuang Initial Implementation. | |
13 | ******************************************************************************** | |
14 | */ | |
15 | ||
16 | #include "unicode/utypes.h" | |
17 | ||
18 | #if !UCONFIG_NO_FORMATTING | |
19 | ||
20 | #include "unicode/fmtable.h" | |
374ca955 A |
21 | #include "unicode/ustring.h" |
22 | #include "unicode/measure.h" | |
23 | #include "unicode/curramt.h" | |
b75a7d8f A |
24 | #include "cmemory.h" |
25 | ||
26 | // ***************************************************************************** | |
27 | // class Formattable | |
28 | // ***************************************************************************** | |
29 | ||
30 | U_NAMESPACE_BEGIN | |
31 | ||
374ca955 A |
32 | UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Formattable) |
33 | ||
34 | //-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. | |
35 | ||
36 | // NOTE: As of 3.0, there are limitations to the UObject API. It does | |
37 | // not (yet) support cloning, operator=, nor operator==. RTTI is also | |
38 | // restricted in that subtype testing is not (yet) implemented. To | |
39 | // work around this, I implement some simple inlines here. Later | |
40 | // these can be modified or removed. [alan] | |
41 | ||
42 | // NOTE: These inlines assume that all fObjects are in fact instances | |
43 | // of the Measure class, which is true as of 3.0. [alan] | |
44 | ||
45 | // Return TRUE if *a == *b. | |
46 | inline UBool objectEquals(const UObject* a, const UObject* b) { | |
47 | // LATER: return *a == *b; | |
48 | return *((const Measure*) a) == *((const Measure*) b); | |
49 | } | |
50 | ||
51 | // Return a clone of *a. | |
52 | inline UObject* objectClone(const UObject* a) { | |
53 | // LATER: return a->clone(); | |
54 | return ((const Measure*) a)->clone(); | |
55 | } | |
56 | ||
57 | // Return TRUE if *a is an instance of Measure. | |
58 | inline UBool instanceOfMeasure(const UObject* a) { | |
59 | // LATER: return a->instanceof(Measure::getStaticClassID()); | |
60 | return a->getDynamicClassID() == | |
61 | CurrencyAmount::getStaticClassID(); | |
62 | } | |
63 | ||
64 | //-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. | |
65 | ||
66 | /** | |
67 | * Set 'ec' to 'err' only if 'ec' is not already set to a failing UErrorCode. | |
68 | */ | |
69 | inline void setError(UErrorCode& ec, UErrorCode err) { | |
70 | if (U_SUCCESS(ec)) { | |
71 | ec = err; | |
72 | } | |
73 | } | |
b75a7d8f A |
74 | |
75 | // ------------------------------------- | |
76 | // default constructor. | |
77 | // Creates a formattable object with a long value 0. | |
78 | ||
79 | Formattable::Formattable() | |
80 | : UObject(), fType(kLong) | |
81 | { | |
374ca955 A |
82 | fBogus.setToBogus(); |
83 | fValue.fInt64 = 0; | |
b75a7d8f A |
84 | } |
85 | ||
86 | // ------------------------------------- | |
87 | // Creates a formattable object with a Date instance. | |
88 | ||
89 | Formattable::Formattable(UDate date, ISDATE /*isDate*/) | |
90 | : UObject(), fType(kDate) | |
91 | { | |
374ca955 | 92 | fBogus.setToBogus(); |
b75a7d8f A |
93 | fValue.fDate = date; |
94 | } | |
95 | ||
96 | // ------------------------------------- | |
97 | // Creates a formattable object with a double value. | |
98 | ||
99 | Formattable::Formattable(double value) | |
100 | : UObject(), fType(kDouble) | |
101 | { | |
374ca955 | 102 | fBogus.setToBogus(); |
b75a7d8f A |
103 | fValue.fDouble = value; |
104 | } | |
105 | ||
106 | // ------------------------------------- | |
107 | // Creates a formattable object with a long value. | |
108 | ||
109 | Formattable::Formattable(int32_t value) | |
110 | : UObject(), fType(kLong) | |
111 | { | |
374ca955 A |
112 | fBogus.setToBogus(); |
113 | fValue.fInt64 = value; | |
114 | } | |
115 | ||
116 | // ------------------------------------- | |
117 | // Creates a formattable object with a long value. | |
118 | ||
119 | Formattable::Formattable(int64_t value) | |
120 | : UObject(), fType(kInt64) | |
121 | { | |
122 | fBogus.setToBogus(); | |
123 | fValue.fInt64 = value; | |
b75a7d8f A |
124 | } |
125 | ||
126 | // ------------------------------------- | |
127 | // Creates a formattable object with a char* string. | |
128 | ||
129 | Formattable::Formattable(const char* stringToCopy) | |
130 | : UObject(), fType(kString) | |
131 | { | |
374ca955 | 132 | fBogus.setToBogus(); |
b75a7d8f A |
133 | fValue.fString = new UnicodeString(stringToCopy); |
134 | } | |
135 | ||
136 | // ------------------------------------- | |
137 | // Creates a formattable object with a UnicodeString instance. | |
138 | ||
139 | Formattable::Formattable(const UnicodeString& stringToCopy) | |
140 | : UObject(), fType(kString) | |
141 | { | |
374ca955 | 142 | fBogus.setToBogus(); |
b75a7d8f A |
143 | fValue.fString = new UnicodeString(stringToCopy); |
144 | } | |
145 | ||
146 | // ------------------------------------- | |
147 | // Creates a formattable object with a UnicodeString* value. | |
148 | // (adopting symantics) | |
149 | ||
150 | Formattable::Formattable(UnicodeString* stringToAdopt) | |
151 | : UObject(), fType(kString) | |
152 | { | |
374ca955 | 153 | fBogus.setToBogus(); |
b75a7d8f A |
154 | fValue.fString = stringToAdopt; |
155 | } | |
156 | ||
374ca955 A |
157 | Formattable::Formattable(UObject* objectToAdopt) |
158 | : UObject(), fType(kObject) | |
159 | { | |
160 | fBogus.setToBogus(); | |
161 | fValue.fObject = objectToAdopt; | |
162 | } | |
163 | ||
b75a7d8f A |
164 | // ------------------------------------- |
165 | ||
166 | Formattable::Formattable(const Formattable* arrayToCopy, int32_t count) | |
167 | : UObject(), fType(kArray) | |
168 | { | |
374ca955 | 169 | fBogus.setToBogus(); |
b75a7d8f A |
170 | fValue.fArrayAndCount.fArray = createArrayCopy(arrayToCopy, count); |
171 | fValue.fArrayAndCount.fCount = count; | |
172 | } | |
173 | ||
174 | // ------------------------------------- | |
175 | // copy constructor | |
176 | ||
177 | Formattable::Formattable(const Formattable &source) | |
178 | : UObject(source), fType(kLong) | |
179 | { | |
374ca955 | 180 | fBogus.setToBogus(); |
b75a7d8f A |
181 | *this = source; |
182 | } | |
183 | ||
184 | // ------------------------------------- | |
185 | // assignment operator | |
186 | ||
187 | Formattable& | |
188 | Formattable::operator=(const Formattable& source) | |
189 | { | |
190 | if (this != &source) | |
191 | { | |
192 | // Disposes the current formattable value/setting. | |
193 | dispose(); | |
194 | ||
195 | // Sets the correct data type for this value. | |
196 | fType = source.fType; | |
197 | switch (fType) | |
198 | { | |
199 | case kArray: | |
200 | // Sets each element in the array one by one and records the array count. | |
201 | fValue.fArrayAndCount.fCount = source.fValue.fArrayAndCount.fCount; | |
202 | fValue.fArrayAndCount.fArray = createArrayCopy(source.fValue.fArrayAndCount.fArray, | |
203 | source.fValue.fArrayAndCount.fCount); | |
204 | break; | |
205 | case kString: | |
206 | // Sets the string value. | |
207 | fValue.fString = new UnicodeString(*source.fValue.fString); | |
208 | break; | |
209 | case kDouble: | |
210 | // Sets the double value. | |
211 | fValue.fDouble = source.fValue.fDouble; | |
212 | break; | |
213 | case kLong: | |
374ca955 | 214 | case kInt64: |
b75a7d8f | 215 | // Sets the long value. |
374ca955 | 216 | fValue.fInt64 = source.fValue.fInt64; |
b75a7d8f A |
217 | break; |
218 | case kDate: | |
219 | // Sets the Date value. | |
220 | fValue.fDate = source.fValue.fDate; | |
221 | break; | |
374ca955 A |
222 | case kObject: |
223 | fValue.fObject = objectClone(source.fValue.fObject); | |
224 | break; | |
b75a7d8f A |
225 | } |
226 | } | |
227 | return *this; | |
228 | } | |
229 | ||
230 | // ------------------------------------- | |
231 | ||
232 | UBool | |
233 | Formattable::operator==(const Formattable& that) const | |
234 | { | |
374ca955 A |
235 | int32_t i; |
236 | ||
b75a7d8f A |
237 | if (this == &that) return TRUE; |
238 | ||
239 | // Returns FALSE if the data types are different. | |
240 | if (fType != that.fType) return FALSE; | |
241 | ||
242 | // Compares the actual data values. | |
374ca955 | 243 | UBool equal = TRUE; |
b75a7d8f A |
244 | switch (fType) { |
245 | case kDate: | |
374ca955 A |
246 | equal = (fValue.fDate == that.fValue.fDate); |
247 | break; | |
b75a7d8f | 248 | case kDouble: |
374ca955 A |
249 | equal = (fValue.fDouble == that.fValue.fDouble); |
250 | break; | |
b75a7d8f | 251 | case kLong: |
374ca955 A |
252 | case kInt64: |
253 | equal = (fValue.fInt64 == that.fValue.fInt64); | |
254 | break; | |
b75a7d8f | 255 | case kString: |
374ca955 A |
256 | equal = (*(fValue.fString) == *(that.fValue.fString)); |
257 | break; | |
b75a7d8f | 258 | case kArray: |
374ca955 A |
259 | if (fValue.fArrayAndCount.fCount != that.fValue.fArrayAndCount.fCount) { |
260 | equal = FALSE; | |
261 | break; | |
262 | } | |
b75a7d8f | 263 | // Checks each element for equality. |
374ca955 A |
264 | for (i=0; i<fValue.fArrayAndCount.fCount; ++i) { |
265 | if (fValue.fArrayAndCount.fArray[i] != that.fValue.fArrayAndCount.fArray[i]) { | |
266 | equal = FALSE; | |
267 | break; | |
268 | } | |
269 | } | |
270 | break; | |
271 | case kObject: | |
272 | equal = objectEquals(fValue.fObject, that.fValue.fObject); | |
b75a7d8f A |
273 | break; |
274 | } | |
374ca955 A |
275 | |
276 | return equal; | |
b75a7d8f A |
277 | } |
278 | ||
279 | // ------------------------------------- | |
280 | ||
281 | Formattable::~Formattable() | |
282 | { | |
283 | dispose(); | |
284 | } | |
285 | ||
286 | // ------------------------------------- | |
287 | ||
288 | void Formattable::dispose() | |
289 | { | |
290 | // Deletes the data value if necessary. | |
291 | switch (fType) { | |
292 | case kString: | |
293 | delete fValue.fString; | |
294 | break; | |
295 | case kArray: | |
296 | delete[] fValue.fArrayAndCount.fArray; | |
297 | break; | |
374ca955 A |
298 | case kObject: |
299 | delete fValue.fObject; | |
300 | break; | |
301 | default: | |
b75a7d8f A |
302 | break; |
303 | } | |
304 | } | |
305 | ||
374ca955 A |
306 | Formattable * |
307 | Formattable::clone() const { | |
308 | return new Formattable(*this); | |
309 | } | |
310 | ||
b75a7d8f A |
311 | // ------------------------------------- |
312 | // Gets the data type of this Formattable object. | |
313 | Formattable::Type | |
314 | Formattable::getType() const | |
315 | { | |
316 | return fType; | |
317 | } | |
318 | ||
374ca955 A |
319 | UBool |
320 | Formattable::isNumeric() const { | |
321 | switch (fType) { | |
322 | case kDouble: | |
323 | case kLong: | |
324 | case kInt64: | |
325 | return TRUE; | |
326 | default: | |
327 | return FALSE; | |
328 | } | |
329 | } | |
330 | ||
331 | // ------------------------------------- | |
332 | int32_t | |
333 | //Formattable::getLong(UErrorCode* status) const | |
334 | Formattable::getLong(UErrorCode& status) const | |
335 | { | |
336 | if (U_FAILURE(status)) { | |
337 | return 0; | |
338 | } | |
339 | ||
340 | switch (fType) { | |
341 | case Formattable::kLong: | |
342 | return (int32_t)fValue.fInt64; | |
343 | case Formattable::kInt64: | |
344 | if (fValue.fInt64 > INT32_MAX) { | |
345 | status = U_INVALID_FORMAT_ERROR; | |
346 | return INT32_MAX; | |
347 | } else if (fValue.fInt64 < INT32_MIN) { | |
348 | status = U_INVALID_FORMAT_ERROR; | |
349 | return INT32_MIN; | |
350 | } else { | |
351 | return (int32_t)fValue.fInt64; | |
352 | } | |
353 | case Formattable::kDouble: | |
354 | if (fValue.fDouble > INT32_MAX) { | |
355 | status = U_INVALID_FORMAT_ERROR; | |
356 | return INT32_MAX; | |
357 | } else if (fValue.fDouble < INT32_MIN) { | |
358 | status = U_INVALID_FORMAT_ERROR; | |
359 | return INT32_MIN; | |
360 | } else { | |
361 | return (int32_t)fValue.fDouble; // loses fraction | |
362 | } | |
363 | case Formattable::kObject: | |
364 | // TODO Later replace this with instanceof call | |
365 | if (instanceOfMeasure(fValue.fObject)) { | |
366 | return ((const Measure*) fValue.fObject)-> | |
367 | getNumber().getLong(status); | |
368 | } | |
369 | default: | |
370 | status = U_INVALID_FORMAT_ERROR; | |
371 | return 0; | |
372 | } | |
373 | } | |
374 | ||
375 | // ------------------------------------- | |
376 | int64_t | |
377 | Formattable::getInt64(UErrorCode& status) const | |
378 | { | |
379 | if (U_FAILURE(status)) { | |
380 | return 0; | |
381 | } | |
382 | ||
383 | switch (fType) { | |
384 | case Formattable::kLong: | |
385 | case Formattable::kInt64: | |
386 | return fValue.fInt64; | |
387 | case Formattable::kDouble: | |
388 | if (fValue.fDouble > U_INT64_MAX) { | |
389 | status = U_INVALID_FORMAT_ERROR; | |
390 | return U_INT64_MAX; | |
391 | } else if (fValue.fDouble < U_INT64_MIN) { | |
392 | status = U_INVALID_FORMAT_ERROR; | |
393 | return U_INT64_MIN; | |
394 | } else { | |
395 | return (int64_t)fValue.fDouble; | |
396 | } | |
397 | case Formattable::kObject: | |
398 | // TODO Later replace this with instanceof call | |
399 | if (instanceOfMeasure(fValue.fObject)) { | |
400 | return ((const Measure*) fValue.fObject)-> | |
401 | getNumber().getInt64(status); | |
402 | } | |
403 | default: | |
404 | status = U_INVALID_FORMAT_ERROR; | |
405 | return 0; | |
406 | } | |
407 | } | |
408 | ||
409 | // ------------------------------------- | |
410 | double | |
411 | Formattable::getDouble(UErrorCode& status) const | |
412 | { | |
413 | if (U_FAILURE(status)) { | |
414 | return 0; | |
415 | } | |
416 | ||
417 | switch (fType) { | |
418 | case Formattable::kLong: | |
419 | case Formattable::kInt64: // loses precision | |
420 | return (double)fValue.fInt64; | |
421 | case Formattable::kDouble: | |
422 | return fValue.fDouble; | |
423 | case Formattable::kObject: | |
424 | // TODO Later replace this with instanceof call | |
425 | if (instanceOfMeasure(fValue.fObject)) { | |
426 | return ((const Measure*) fValue.fObject)-> | |
427 | getNumber().getDouble(status); | |
428 | } | |
429 | default: | |
430 | status = U_INVALID_FORMAT_ERROR; | |
431 | return 0; | |
432 | } | |
433 | } | |
434 | ||
435 | const UObject* | |
436 | Formattable::getObject() const { | |
437 | return (fType == kObject) ? fValue.fObject : NULL; | |
438 | } | |
439 | ||
b75a7d8f A |
440 | // ------------------------------------- |
441 | // Sets the value to a double value d. | |
442 | ||
443 | void | |
444 | Formattable::setDouble(double d) | |
445 | { | |
446 | dispose(); | |
447 | fType = kDouble; | |
448 | fValue.fDouble = d; | |
449 | } | |
450 | ||
451 | // ------------------------------------- | |
452 | // Sets the value to a long value l. | |
453 | ||
454 | void | |
455 | Formattable::setLong(int32_t l) | |
456 | { | |
457 | dispose(); | |
458 | fType = kLong; | |
374ca955 A |
459 | fValue.fInt64 = l; |
460 | } | |
461 | ||
462 | // ------------------------------------- | |
463 | // Sets the value to an int64 value ll. | |
464 | ||
465 | void | |
466 | Formattable::setInt64(int64_t ll) | |
467 | { | |
468 | dispose(); | |
469 | fType = kInt64; | |
470 | fValue.fInt64 = ll; | |
b75a7d8f A |
471 | } |
472 | ||
473 | // ------------------------------------- | |
474 | // Sets the value to a Date instance d. | |
475 | ||
476 | void | |
477 | Formattable::setDate(UDate d) | |
478 | { | |
479 | dispose(); | |
480 | fType = kDate; | |
481 | fValue.fDate = d; | |
482 | } | |
483 | ||
484 | // ------------------------------------- | |
485 | // Sets the value to a string value stringToCopy. | |
486 | ||
487 | void | |
488 | Formattable::setString(const UnicodeString& stringToCopy) | |
489 | { | |
490 | dispose(); | |
491 | fType = kString; | |
492 | fValue.fString = new UnicodeString(stringToCopy); | |
493 | } | |
494 | ||
495 | // ------------------------------------- | |
496 | // Sets the value to an array of Formattable objects. | |
497 | ||
498 | void | |
499 | Formattable::setArray(const Formattable* array, int32_t count) | |
500 | { | |
501 | dispose(); | |
502 | fType = kArray; | |
503 | fValue.fArrayAndCount.fArray = createArrayCopy(array, count); | |
504 | fValue.fArrayAndCount.fCount = count; | |
505 | } | |
506 | ||
507 | // ------------------------------------- | |
508 | // Adopts the stringToAdopt value. | |
509 | ||
510 | void | |
511 | Formattable::adoptString(UnicodeString* stringToAdopt) | |
512 | { | |
513 | dispose(); | |
514 | fType = kString; | |
515 | fValue.fString = stringToAdopt; | |
516 | } | |
517 | ||
518 | // ------------------------------------- | |
519 | // Adopts the array value and its count. | |
520 | ||
521 | void | |
522 | Formattable::adoptArray(Formattable* array, int32_t count) | |
523 | { | |
524 | dispose(); | |
525 | fType = kArray; | |
526 | fValue.fArrayAndCount.fArray = array; | |
527 | fValue.fArrayAndCount.fCount = count; | |
528 | } | |
529 | ||
374ca955 A |
530 | void |
531 | Formattable::adoptObject(UObject* objectToAdopt) { | |
532 | dispose(); | |
533 | fType = kObject; | |
534 | fValue.fObject = objectToAdopt; | |
535 | } | |
536 | ||
537 | // ------------------------------------- | |
538 | UnicodeString& | |
539 | Formattable::getString(UnicodeString& result, UErrorCode& status) const | |
540 | { | |
541 | if (fType != kString) { | |
542 | setError(status, U_INVALID_FORMAT_ERROR); | |
543 | result.setToBogus(); | |
544 | } else { | |
545 | result = *fValue.fString; | |
546 | } | |
547 | return result; | |
548 | } | |
549 | ||
550 | // ------------------------------------- | |
551 | const UnicodeString& | |
552 | Formattable::getString(UErrorCode& status) const | |
553 | { | |
554 | if (fType != kString) { | |
555 | setError(status, U_INVALID_FORMAT_ERROR); | |
556 | return *getBogus(); | |
557 | } | |
558 | return *fValue.fString; | |
559 | } | |
560 | ||
561 | // ------------------------------------- | |
562 | UnicodeString& | |
563 | Formattable::getString(UErrorCode& status) | |
564 | { | |
565 | if (fType != kString) { | |
566 | setError(status, U_INVALID_FORMAT_ERROR); | |
567 | return *getBogus(); | |
568 | } | |
569 | return *fValue.fString; | |
570 | } | |
571 | ||
572 | // ------------------------------------- | |
573 | const Formattable* | |
574 | Formattable::getArray(int32_t& count, UErrorCode& status) const | |
575 | { | |
576 | if (fType != kArray) { | |
577 | setError(status, U_INVALID_FORMAT_ERROR); | |
578 | count = 0; | |
579 | return NULL; | |
580 | } | |
581 | count = fValue.fArrayAndCount.fCount; | |
582 | return fValue.fArrayAndCount.fArray; | |
583 | } | |
584 | ||
585 | // ------------------------------------- | |
586 | // Gets the bogus string, ensures mondo bogosity. | |
587 | ||
588 | UnicodeString* | |
589 | Formattable::getBogus() const | |
590 | { | |
591 | return (UnicodeString*)&fBogus; /* cast away const :-( */ | |
592 | } | |
593 | ||
b75a7d8f A |
594 | #if 0 |
595 | //---------------------------------------------------- | |
596 | // console I/O | |
597 | //---------------------------------------------------- | |
598 | #ifdef _DEBUG | |
599 | ||
600 | #if U_IOSTREAM_SOURCE >= 199711 | |
601 | #include <iostream> | |
602 | using namespace std; | |
603 | #elif U_IOSTREAM_SOURCE >= 198506 | |
604 | #include <iostream.h> | |
605 | #endif | |
606 | ||
607 | #include "unicode/datefmt.h" | |
608 | #include "unistrm.h" | |
609 | ||
610 | class FormattableStreamer /* not : public UObject because all methods are static */ { | |
611 | public: | |
612 | static void streamOut(ostream& stream, const Formattable& obj); | |
613 | ||
614 | private: | |
615 | FormattableStreamer() {} // private - forbid instantiation | |
616 | }; | |
617 | ||
618 | // This is for debugging purposes only. This will send a displayable | |
619 | // form of the Formattable object to the output stream. | |
620 | ||
621 | void | |
622 | FormattableStreamer::streamOut(ostream& stream, const Formattable& obj) | |
623 | { | |
624 | static DateFormat *defDateFormat = 0; | |
625 | ||
626 | UnicodeString buffer; | |
627 | switch(obj.getType()) { | |
628 | case Formattable::kDate : | |
629 | // Creates a DateFormat instance for formatting the | |
630 | // Date instance. | |
631 | if (defDateFormat == 0) { | |
632 | defDateFormat = DateFormat::createInstance(); | |
633 | } | |
634 | defDateFormat->format(obj.getDate(), buffer); | |
635 | stream << buffer; | |
636 | break; | |
637 | case Formattable::kDouble : | |
638 | // Output the double as is. | |
639 | stream << obj.getDouble() << 'D'; | |
640 | break; | |
641 | case Formattable::kLong : | |
642 | // Output the double as is. | |
643 | stream << obj.getLong() << 'L'; | |
644 | break; | |
645 | case Formattable::kString: | |
646 | // Output the double as is. Please see UnicodeString console | |
647 | // I/O routine for more details. | |
648 | stream << '"' << obj.getString(buffer) << '"'; | |
649 | break; | |
650 | case Formattable::kArray: | |
651 | int32_t i, count; | |
652 | const Formattable* array; | |
653 | array = obj.getArray(count); | |
654 | stream << '['; | |
655 | // Recursively calling the console I/O routine for each element in the array. | |
656 | for (i=0; i<count; ++i) { | |
657 | FormattableStreamer::streamOut(stream, array[i]); | |
658 | stream << ( (i==(count-1)) ? "" : ", " ); | |
659 | } | |
660 | stream << ']'; | |
661 | break; | |
662 | default: | |
663 | // Not a recognizable Formattable object. | |
664 | stream << "INVALID_Formattable"; | |
665 | } | |
666 | stream.flush(); | |
667 | } | |
668 | #endif | |
669 | ||
670 | #endif | |
671 | ||
672 | U_NAMESPACE_END | |
673 | ||
674 | #endif /* #if !UCONFIG_NO_FORMATTING */ | |
675 | ||
676 | //eof |