16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 1997-2013, International Business Machines Corporation and    *
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* others. All Rights Reserved.                                                *
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* File FMTABLE.CPP
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Modification History:
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Date        Name        Description
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   03/25/97    clhuang     Initial Implementation.
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org********************************************************************************
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h"
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_FORMATTING
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <math.h>
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/fmtable.h"
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h"
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/measure.h"
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/curramt.h"
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uformattable.h"
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "charstr.h"
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h"
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h"
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "decNumber.h"
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "digitlst.h"
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// *****************************************************************************
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// class Formattable
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// *****************************************************************************
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(Formattable)
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "fmtableimp.h"
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// NOTE: As of 3.0, there are limitations to the UObject API.  It does
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// not (yet) support cloning, operator=, nor operator==.  To
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// work around this, I implement some simple inlines here.  Later
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// these can be modified or removed.  [alan]
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// NOTE: These inlines assume that all fObjects are in fact instances
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// of the Measure class, which is true as of 3.0.  [alan]
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Return TRUE if *a == *b.
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic inline UBool objectEquals(const UObject* a, const UObject* b) {
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // LATER: return *a == *b;
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return *((const Measure*) a) == *((const Measure*) b);
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Return a clone of *a.
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic inline UObject* objectClone(const UObject* a) {
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // LATER: return a->clone();
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ((const Measure*) a)->clone();
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Return TRUE if *a is an instance of Measure.
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic inline UBool instanceOfMeasure(const UObject* a) {
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return dynamic_cast<const Measure*>(a) != NULL;
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Creates a new Formattable array and copies the values from the specified
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * original.
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param array the original array
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param count the original array count
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return the new Formattable array.
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic Formattable* createArrayCopy(const Formattable* array, int32_t count) {
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Formattable *result = new Formattable[count];
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (result != NULL) {
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (int32_t i=0; i<count; ++i)
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            result[i] = array[i]; // Don't memcpy!
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Set 'ec' to 'err' only if 'ec' is not already set to a failing UErrorCode.
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void setError(UErrorCode& ec, UErrorCode err) {
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_SUCCESS(ec)) {
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ec = err;
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//  Common initialization code, shared by constructors.
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//  Put everything into a known state.
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid  Formattable::init() {
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fInt64 = 0;
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kLong;
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fDecimalStr = NULL;
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fDecimalNum = NULL;
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fBogus.setToBogus();
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// default constructor.
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Creates a formattable object with a long value 0.
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::Formattable() {
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init();
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Creates a formattable object with a Date instance.
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::Formattable(UDate date, ISDATE /*isDate*/)
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init();
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kDate;
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fDate = date;
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Creates a formattable object with a double value.
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::Formattable(double value)
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init();
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kDouble;
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fDouble = value;
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Creates a formattable object with an int32_t value.
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::Formattable(int32_t value)
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init();
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fInt64 = value;
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Creates a formattable object with an int64_t value.
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::Formattable(int64_t value)
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init();
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kInt64;
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fInt64 = value;
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Creates a formattable object with a decimal number value from a string.
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::Formattable(const StringPiece &number, UErrorCode &status) {
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init();
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    setDecimalNumber(number, status);
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Creates a formattable object with a UnicodeString instance.
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::Formattable(const UnicodeString& stringToCopy)
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init();
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kString;
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fString = new UnicodeString(stringToCopy);
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Creates a formattable object with a UnicodeString* value.
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// (adopting symantics)
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::Formattable(UnicodeString* stringToAdopt)
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init();
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kString;
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fString = stringToAdopt;
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::Formattable(UObject* objectToAdopt)
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init();
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kObject;
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fObject = objectToAdopt;
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::Formattable(const Formattable* arrayToCopy, int32_t count)
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    :   UObject(), fType(kArray)
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init();
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kArray;
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fArrayAndCount.fArray = createArrayCopy(arrayToCopy, count);
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fArrayAndCount.fCount = count;
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// copy constructor
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::Formattable(const Formattable &source)
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     :  UObject(*this)
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init();
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    *this = source;
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// assignment operator
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable&
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::operator=(const Formattable& source)
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (this != &source)
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Disposes the current formattable value/setting.
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        dispose();
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Sets the correct data type for this value.
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fType = source.fType;
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        switch (fType)
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case kArray:
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Sets each element in the array one by one and records the array count.
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fValue.fArrayAndCount.fCount = source.fValue.fArrayAndCount.fCount;
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fValue.fArrayAndCount.fArray = createArrayCopy(source.fValue.fArrayAndCount.fArray,
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                                           source.fValue.fArrayAndCount.fCount);
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case kString:
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Sets the string value.
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fValue.fString = new UnicodeString(*source.fValue.fString);
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case kDouble:
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Sets the double value.
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fValue.fDouble = source.fValue.fDouble;
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case kLong:
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case kInt64:
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Sets the long value.
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fValue.fInt64 = source.fValue.fInt64;
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case kDate:
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Sets the Date value.
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fValue.fDate = source.fValue.fDate;
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case kObject:
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fValue.fObject = objectClone(source.fValue.fObject);
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UErrorCode status = U_ZERO_ERROR;
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (source.fDecimalNum != NULL) {
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          fDecimalNum = new DigitList(*source.fDecimalNum); // TODO: use internal digit list
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (source.fDecimalStr != NULL) {
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fDecimalStr = new CharString(*source.fDecimalStr, status);
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (U_FAILURE(status)) {
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                delete fDecimalStr;
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                fDecimalStr = NULL;
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return *this;
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::operator==(const Formattable& that) const
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i;
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (this == &that) return TRUE;
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Returns FALSE if the data types are different.
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fType != that.fType) return FALSE;
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Compares the actual data values.
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool equal = TRUE;
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch (fType) {
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case kDate:
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        equal = (fValue.fDate == that.fValue.fDate);
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case kDouble:
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        equal = (fValue.fDouble == that.fValue.fDouble);
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case kLong:
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case kInt64:
2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        equal = (fValue.fInt64 == that.fValue.fInt64);
2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case kString:
2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        equal = (*(fValue.fString) == *(that.fValue.fString));
2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case kArray:
3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fValue.fArrayAndCount.fCount != that.fValue.fArrayAndCount.fCount) {
3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            equal = FALSE;
3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Checks each element for equality.
3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (i=0; i<fValue.fArrayAndCount.fCount; ++i) {
3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (fValue.fArrayAndCount.fArray[i] != that.fValue.fArrayAndCount.fArray[i]) {
3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                equal = FALSE;
3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                break;
3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case kObject:
3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fValue.fObject == NULL || that.fValue.fObject == NULL) {
3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            equal = FALSE;
3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            equal = objectEquals(fValue.fObject, that.fValue.fObject);
3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // TODO:  compare digit lists if numeric.
3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return equal;
3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::~Formattable()
3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dispose();
3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Formattable::dispose()
3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Deletes the data value if necessary.
3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch (fType) {
3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case kString:
3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete fValue.fString;
3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case kArray:
3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete[] fValue.fArrayAndCount.fArray;
3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case kObject:
3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete fValue.fObject;
3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    default:
3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kLong;
3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fInt64 = 0;
3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete fDecimalStr;
3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fDecimalStr = NULL;
3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    FmtStackData *stackData = (FmtStackData*)fStackData;
3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(fDecimalNum != &(stackData->stackDecimalNum)) {
3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      delete fDecimalNum;
3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      fDecimalNum->~DigitList(); // destruct, don't deallocate
3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fDecimalNum = NULL;
3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable *
3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::clone() const {
3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return new Formattable(*this);
3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Gets the data type of this Formattable object.
3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::Type
3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::getType() const
3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return fType;
3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::isNumeric() const {
3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch (fType) {
3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case kDouble:
3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case kLong:
3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case kInt64:
3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return TRUE;
3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    default:
3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t
3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//Formattable::getLong(UErrorCode* status) const
3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::getLong(UErrorCode& status) const
3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch (fType) {
4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case Formattable::kLong:
4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return (int32_t)fValue.fInt64;
4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case Formattable::kInt64:
4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fValue.fInt64 > INT32_MAX) {
4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_INVALID_FORMAT_ERROR;
4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return INT32_MAX;
4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if (fValue.fInt64 < INT32_MIN) {
4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_INVALID_FORMAT_ERROR;
4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return INT32_MIN;
4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return (int32_t)fValue.fInt64;
4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case Formattable::kDouble:
4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fValue.fDouble > INT32_MAX) {
4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_INVALID_FORMAT_ERROR;
4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return INT32_MAX;
4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if (fValue.fDouble < INT32_MIN) {
4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_INVALID_FORMAT_ERROR;
4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return INT32_MIN;
4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return (int32_t)fValue.fDouble; // loses fraction
4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case Formattable::kObject:
4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fValue.fObject == NULL) {
4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_MEMORY_ALLOCATION_ERROR;
4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // TODO Later replace this with instanceof call
4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (instanceOfMeasure(fValue.fObject)) {
4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return ((const Measure*) fValue.fObject)->
4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                getNumber().getLong(status);
4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    default:
4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        status = U_INVALID_FORMAT_ERROR;
4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Maximum int that can be represented exactly in a double.  (53 bits)
4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//    Larger ints may be rounded to a near-by value as not all are representable.
4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// TODO:  move this constant elsewhere, possibly configure it for different
4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//        floating point formats, if any non-standard ones are still in use.
4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int64_t U_DOUBLE_MAX_EXACT_INT = 9007199254740992LL;
4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint64_t
4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::getInt64(UErrorCode& status) const
4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch (fType) {
4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case Formattable::kLong:
4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case Formattable::kInt64:
4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return fValue.fInt64;
4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case Formattable::kDouble:
4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fValue.fDouble > (double)U_INT64_MAX) {
4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_INVALID_FORMAT_ERROR;
4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return U_INT64_MAX;
4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if (fValue.fDouble < (double)U_INT64_MIN) {
4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_INVALID_FORMAT_ERROR;
4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return U_INT64_MIN;
4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if (fabs(fValue.fDouble) > U_DOUBLE_MAX_EXACT_INT && fDecimalNum != NULL) {
4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int64_t val = fDecimalNum->getInt64();
4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (val != 0) {
4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return val;
4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                status = U_INVALID_FORMAT_ERROR;
4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return fValue.fDouble > 0 ? U_INT64_MAX : U_INT64_MIN;
4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return (int64_t)fValue.fDouble;
4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case Formattable::kObject:
4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fValue.fObject == NULL) {
4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_MEMORY_ALLOCATION_ERROR;
4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (instanceOfMeasure(fValue.fObject)) {
4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return ((const Measure*) fValue.fObject)->
4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                getNumber().getInt64(status);
4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    default:
4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        status = U_INVALID_FORMAT_ERROR;
4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdouble
4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::getDouble(UErrorCode& status) const
4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch (fType) {
5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case Formattable::kLong:
5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case Formattable::kInt64: // loses precision
5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return (double)fValue.fInt64;
5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case Formattable::kDouble:
5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return fValue.fDouble;
5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case Formattable::kObject:
5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fValue.fObject == NULL) {
5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_MEMORY_ALLOCATION_ERROR;
5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // TODO Later replace this with instanceof call
5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (instanceOfMeasure(fValue.fObject)) {
5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return ((const Measure*) fValue.fObject)->
5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                getNumber().getDouble(status);
5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    default:
5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        status = U_INVALID_FORMAT_ERROR;
5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UObject*
5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::getObject() const {
5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (fType == kObject) ? fValue.fObject : NULL;
5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Sets the value to a double value d.
5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::setDouble(double d)
5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dispose();
5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kDouble;
5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fDouble = d;
5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Sets the value to a long value l.
5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::setLong(int32_t l)
5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dispose();
5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kLong;
5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fInt64 = l;
5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Sets the value to an int64 value ll.
5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::setInt64(int64_t ll)
5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dispose();
5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kInt64;
5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fInt64 = ll;
5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Sets the value to a Date instance d.
5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::setDate(UDate d)
5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dispose();
5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kDate;
5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fDate = d;
5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Sets the value to a string value stringToCopy.
5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::setString(const UnicodeString& stringToCopy)
5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dispose();
5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kString;
5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fString = new UnicodeString(stringToCopy);
5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Sets the value to an array of Formattable objects.
5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::setArray(const Formattable* array, int32_t count)
5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dispose();
5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kArray;
5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fArrayAndCount.fArray = createArrayCopy(array, count);
5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fArrayAndCount.fCount = count;
5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Adopts the stringToAdopt value.
5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::adoptString(UnicodeString* stringToAdopt)
5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dispose();
6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kString;
6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fString = stringToAdopt;
6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Adopts the array value and its count.
6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::adoptArray(Formattable* array, int32_t count)
6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dispose();
6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kArray;
6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fArrayAndCount.fArray = array;
6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fArrayAndCount.fCount = count;
6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::adoptObject(UObject* objectToAdopt) {
6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dispose();
6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fType = kObject;
6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fValue.fObject = objectToAdopt;
6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::getString(UnicodeString& result, UErrorCode& status) const
6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fType != kString) {
6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        setError(status, U_INVALID_FORMAT_ERROR);
6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result.setToBogus();
6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fValue.fString == NULL) {
6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            setError(status, U_MEMORY_ALLOCATION_ERROR);
6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            result = *fValue.fString;
6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UnicodeString&
6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::getString(UErrorCode& status) const
6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fType != kString) {
6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        setError(status, U_INVALID_FORMAT_ERROR);
6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return *getBogus();
6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fValue.fString == NULL) {
6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        setError(status, U_MEMORY_ALLOCATION_ERROR);
6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return *getBogus();
6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return *fValue.fString;
6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::getString(UErrorCode& status)
6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fType != kString) {
6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        setError(status, U_INVALID_FORMAT_ERROR);
6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return *getBogus();
6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fValue.fString == NULL) {
6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    	setError(status, U_MEMORY_ALLOCATION_ERROR);
6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    	return *getBogus();
6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return *fValue.fString;
6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst Formattable*
6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::getArray(int32_t& count, UErrorCode& status) const
6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fType != kArray) {
6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        setError(status, U_INVALID_FORMAT_ERROR);
6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count = 0;
6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return NULL;
6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    count = fValue.fArrayAndCount.fCount;
6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return fValue.fArrayAndCount.fArray;
6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// -------------------------------------
6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Gets the bogus string, ensures mondo bogosity.
6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString*
6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::getBogus() const
6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (UnicodeString*)&fBogus; /* cast away const :-( */
6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------
6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgStringPiece Formattable::getDecimalNumber(UErrorCode &status) {
6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return "";
6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fDecimalStr != NULL) {
6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      return fDecimalStr->toStringPiece();
7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    CharString *decimalStr = internalGetCharString(status);
7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(decimalStr == NULL) {
7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      return ""; // getDecimalNumber returns "" for error cases
7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      return decimalStr->toStringPiece();
7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCharString *Formattable::internalGetCharString(UErrorCode &status) {
7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(fDecimalStr == NULL) {
7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      if (fDecimalNum == NULL) {
7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // No decimal number for the formattable yet.  Which means the value was
7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // set directly by the user as an int, int64 or double.  If the value came
7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // from parsing, or from the user setting a decimal number, fDecimalNum
7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // would already be set.
7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        //
7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fDecimalNum = new DigitList; // TODO: use internal digit list
7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fDecimalNum == NULL) {
7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          status = U_MEMORY_ALLOCATION_ERROR;
7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          return NULL;
7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        switch (fType) {
7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case kDouble:
7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          fDecimalNum->set(this->getDouble());
7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          break;
7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case kLong:
7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          fDecimalNum->set(this->getLong());
7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          break;
7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case kInt64:
7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          fDecimalNum->set(this->getInt64());
7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          break;
7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        default:
7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          // The formattable's value is not a numeric type.
7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          status = U_INVALID_STATE_ERROR;
7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          return NULL;
7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      }
7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      fDecimalStr = new CharString;
7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      if (fDecimalStr == NULL) {
7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        status = U_MEMORY_ALLOCATION_ERROR;
7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return NULL;
7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      }
7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      fDecimalNum->getDecimal(*fDecimalStr, status);
7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return fDecimalStr;
7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgDigitList *
7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::getInternalDigitList() {
7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  FmtStackData *stackData = (FmtStackData*)fStackData;
7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if(fDecimalNum != &(stackData->stackDecimalNum)) {
7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete fDecimalNum;
7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fDecimalNum = new (&(stackData->stackDecimalNum), kOnStack) DigitList();
7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  } else {
7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fDecimalNum->clear();
7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return fDecimalNum;
7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ---------------------------------------
7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::adoptDigitList(DigitList *dl) {
7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if(fDecimalNum==dl) {
7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fDecimalNum = NULL; // don't delete
7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  dispose();
7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  fDecimalNum = dl;
7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if(dl==NULL) { // allow adoptDigitList(NULL) to clear
7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return;
7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Set the value into the Union of simple type values.
7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Cannot use the set() functions because they would delete the fDecimalNum value,
7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fDecimalNum->fitsIntoLong(FALSE)) {
7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fType = kLong;
7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fValue.fInt64 = fDecimalNum->getLong();
7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if (fDecimalNum->fitsIntoInt64(FALSE)) {
7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fType = kInt64;
7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fValue.fInt64 = fDecimalNum->getInt64();
7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fType = kDouble;
7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fValue.fDouble = fDecimalNum->getDouble();
7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ---------------------------------------
7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable::setDecimalNumber(const StringPiece &numberString, UErrorCode &status) {
7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dispose();
8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Copy the input string and nul-terminate it.
8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    //    The decNumber library requires nul-terminated input.  StringPiece input
8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    //    is not guaranteed nul-terminated.  Too bad.
8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    //    CharString automatically adds the nul.
8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    DigitList *dnum = new DigitList(); // TODO: use getInternalDigitList
8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (dnum == NULL) {
8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        status = U_MEMORY_ALLOCATION_ERROR;
8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dnum->set(CharString(numberString, status).toStringPiece(), status);
8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete dnum;
8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;   // String didn't contain a decimal number.
8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    adoptDigitList(dnum);
8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Note that we do not hang on to the caller's input string.
8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // If we are asked for the string, we will regenerate one from fDecimalNum.
8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if 0
8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//----------------------------------------------------
8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// console I/O
8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//----------------------------------------------------
8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#ifdef _DEBUG
8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <iostream>
8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgusing namespace std;
8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/datefmt.h"
8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unistrm.h"
8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass FormattableStreamer /* not : public UObject because all methods are static */ {
8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic:
8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static void streamOut(ostream& stream, const Formattable& obj);
8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprivate:
8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    FormattableStreamer() {} // private - forbid instantiation
8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// This is for debugging purposes only.  This will send a displayable
8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// form of the Formattable object to the output stream.
8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattableStreamer::streamOut(ostream& stream, const Formattable& obj)
8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static DateFormat *defDateFormat = 0;
8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeString buffer;
8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch(obj.getType()) {
8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case Formattable::kDate :
8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Creates a DateFormat instance for formatting the
8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Date instance.
8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (defDateFormat == 0) {
8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                defDateFormat = DateFormat::createInstance();
8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            defDateFormat->format(obj.getDate(), buffer);
8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            stream << buffer;
8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case Formattable::kDouble :
8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Output the double as is.
8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            stream << obj.getDouble() << 'D';
8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case Formattable::kLong :
8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Output the double as is.
8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            stream << obj.getLong() << 'L';
8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case Formattable::kString:
8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Output the double as is.  Please see UnicodeString console
8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // I/O routine for more details.
8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            stream << '"' << obj.getString(buffer) << '"';
8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case Formattable::kArray:
8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t i, count;
8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            const Formattable* array;
8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            array = obj.getArray(count);
8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            stream << '[';
8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Recursively calling the console I/O routine for each element in the array.
8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            for (i=0; i<count; ++i) {
8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                FormattableStreamer::streamOut(stream, array[i]);
8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                stream << ( (i==(count-1)) ? "" : ", " );
8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            stream << ']';
8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        default:
8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Not a recognizable Formattable object.
8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            stream << "INVALID_Formattable";
8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stream.flush();
8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END
8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* ---- UFormattable implementation ---- */
8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_USE
9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_DRAFT UFormattable* U_EXPORT2
9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgufmt_open(UErrorCode *status) {
9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if( U_FAILURE(*status) ) {
9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return NULL;
9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  UFormattable *fmt = (new Formattable())->toUFormattable();
9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if( fmt == NULL ) {
9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    *status = U_MEMORY_ALLOCATION_ERROR;
9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return fmt;
9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_DRAFT void U_EXPORT2
9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgufmt_close(UFormattable *fmt) {
9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  Formattable *obj = Formattable::fromUFormattable(fmt);
9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  delete obj;
9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_INTERNAL UFormattableType U_EXPORT2
9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgufmt_getType(const UFormattable *fmt, UErrorCode *status) {
9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if(U_FAILURE(*status)) {
9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (UFormattableType)UFMT_COUNT;
9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  const Formattable *obj = Formattable::fromUFormattable(fmt);
9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return (UFormattableType)obj->getType();
9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_INTERNAL UBool U_EXPORT2
9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgufmt_isNumeric(const UFormattable *fmt) {
9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  const Formattable *obj = Formattable::fromUFormattable(fmt);
9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return obj->isNumeric();
9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_DRAFT UDate U_EXPORT2
9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgufmt_getDate(const UFormattable *fmt, UErrorCode *status) {
9406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  const Formattable *obj = Formattable::fromUFormattable(fmt);
9416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return obj->getDate(*status);
9436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_DRAFT double U_EXPORT2
9466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgufmt_getDouble(UFormattable *fmt, UErrorCode *status) {
9476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  Formattable *obj = Formattable::fromUFormattable(fmt);
9486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return obj->getDouble(*status);
9506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_DRAFT int32_t U_EXPORT2
9536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgufmt_getLong(UFormattable *fmt, UErrorCode *status) {
9546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  Formattable *obj = Formattable::fromUFormattable(fmt);
9556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return obj->getLong(*status);
9576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_DRAFT const void *U_EXPORT2
9616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgufmt_getObject(const UFormattable *fmt, UErrorCode *status) {
9626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  const Formattable *obj = Formattable::fromUFormattable(fmt);
9636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  const void *ret = obj->getObject();
9656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if( ret==NULL &&
9666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      (obj->getType() != Formattable::kObject) &&
9676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      U_SUCCESS( *status )) {
9686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    *status = U_INVALID_FORMAT_ERROR;
9696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
9706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return ret;
9716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_DRAFT const UChar* U_EXPORT2
9746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgufmt_getUChars(UFormattable *fmt, int32_t *len, UErrorCode *status) {
9756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  Formattable *obj = Formattable::fromUFormattable(fmt);
9766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // avoid bogosity by checking the type first.
9786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if( obj->getType() != Formattable::kString ) {
9796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if( U_SUCCESS(*status) ){
9806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      *status = U_INVALID_FORMAT_ERROR;
9816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
9826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return NULL;
9836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
9846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // This should return a valid string
9866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  UnicodeString &str = obj->getString(*status);
9876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if( U_SUCCESS(*status) && len != NULL ) {
9886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    *len = str.length();
9896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
9906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return str.getTerminatedBuffer();
9916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_DRAFT int32_t U_EXPORT2
9946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgufmt_getArrayLength(const UFormattable* fmt, UErrorCode *status) {
9956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  const Formattable *obj = Formattable::fromUFormattable(fmt);
9966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  int32_t count;
9986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  (void)obj->getArray(count, *status);
9996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return count;
10006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
10016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_DRAFT UFormattable * U_EXPORT2
10036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgufmt_getArrayItemByIndex(UFormattable* fmt, int32_t n, UErrorCode *status) {
10046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  Formattable *obj = Formattable::fromUFormattable(fmt);
10056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  int32_t count;
10066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  (void)obj->getArray(count, *status);
10076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if(U_FAILURE(*status)) {
10086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return NULL;
10096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  } else if(n<0 || n>=count) {
10106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    setError(*status, U_INDEX_OUTOFBOUNDS_ERROR);
10116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return NULL;
10126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  } else {
10136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (*obj)[n].toUFormattable(); // returns non-const Formattable
10146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
10156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
10166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_DRAFT const char * U_EXPORT2
10186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgufmt_getDecNumChars(UFormattable *fmt, int32_t *len, UErrorCode *status) {
10196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if(U_FAILURE(*status)) {
10206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return "";
10216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
10226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  Formattable *obj = Formattable::fromUFormattable(fmt);
10236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  CharString *charString = obj->internalGetCharString(*status);
10246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if(U_FAILURE(*status)) {
10256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return "";
10266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
10276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if(charString == NULL) {
10286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    *status = U_MEMORY_ALLOCATION_ERROR;
10296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return "";
10306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  } else {
10316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(len!=NULL) {
10326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      *len = charString->length();
10336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return charString->data();
10356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
10366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
10376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_DRAFT int64_t U_EXPORT2
10396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgufmt_getInt64(UFormattable *fmt, UErrorCode *status) {
10406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  Formattable *obj = Formattable::fromUFormattable(fmt);
10416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return obj->getInt64(*status);
10426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
10436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_FORMATTING */
10456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//eof
1047