// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
* Copyright (C) 1997-2016, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*
* File FMTABLE.CPP
*
* Modification History:
*
*   Date        Name        Description
*   03/25/97    clhuang     Initial Implementation.
********************************************************************************
*/

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include <cstdlib>
#include <math.h>
#include "unicode/fmtable.h"
#include "unicode/ustring.h"
#include "unicode/measure.h"
#include "unicode/curramt.h"
#include "unicode/uformattable.h"
#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
#include "fmtableimp.h"
#include "number_decimalquantity.h"

// *****************************************************************************
// class Formattable
// *****************************************************************************

U_NAMESPACE_BEGIN

UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Formattable)

using number::impl::DecimalQuantity;


//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.

// NOTE: As of 3.0, there are limitations to the UObject API.  It does
// not (yet) support cloning, operator=, nor operator==.  To
// work around this, I implement some simple inlines here.  Later
// these can be modified or removed.  [alan]

// NOTE: These inlines assume that all fObjects are in fact instances
// of the Measure class, which is true as of 3.0.  [alan]

// Return TRUE if *a == *b.
static inline UBool objectEquals(const UObject* a, const UObject* b) {
    // LATER: return *a == *b;
    return *((const Measure*) a) == *((const Measure*) b);
}

// Return a clone of *a.
static inline UObject* objectClone(const UObject* a) {
    // LATER: return a->clone();
    return ((const Measure*) a)->clone();
}

// Return TRUE if *a is an instance of Measure.
static inline UBool instanceOfMeasure(const UObject* a) {
    return dynamic_cast<const Measure*>(a) != NULL;
}

/**
 * Creates a new Formattable array and copies the values from the specified
 * original.
 * @param array the original array
 * @param count the original array count
 * @return the new Formattable array.
 */
static Formattable* createArrayCopy(const Formattable* array, int32_t count) {
    Formattable *result = new Formattable[count];
    if (result != NULL) {
        for (int32_t i=0; i<count; ++i)
            result[i] = array[i]; // Don't memcpy!
    }
    return result;
}

//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.

/**
 * Set 'ec' to 'err' only if 'ec' is not already set to a failing UErrorCode.
 */
static void setError(UErrorCode& ec, UErrorCode err) {
    if (U_SUCCESS(ec)) {
        ec = err;
    }
}

//
//  Common initialization code, shared by constructors.
//  Put everything into a known state.
//
void  Formattable::init() {
    fValue.fInt64 = 0;
    fType = kLong;
    fDecimalStr = NULL;
    fDecimalQuantity = NULL;
    fBogus.setToBogus(); 
}

// -------------------------------------
// default constructor.
// Creates a formattable object with a long value 0.

Formattable::Formattable() {
    init();
}

// -------------------------------------
// Creates a formattable object with a Date instance.

Formattable::Formattable(UDate date, ISDATE /*isDate*/)
{
    init();
    fType = kDate;
    fValue.fDate = date;
}

// -------------------------------------
// Creates a formattable object with a double value.

Formattable::Formattable(double value)
{
    init();
    fType = kDouble;
    fValue.fDouble = value;
}

// -------------------------------------
// Creates a formattable object with an int32_t value.

Formattable::Formattable(int32_t value)
{
    init();
    fValue.fInt64 = value;
}

// -------------------------------------
// Creates a formattable object with an int64_t value.

Formattable::Formattable(int64_t value)
{
    init();
    fType = kInt64;
    fValue.fInt64 = value;
}

// -------------------------------------
// Creates a formattable object with a decimal number value from a string.

Formattable::Formattable(StringPiece number, UErrorCode &status) {
    init();
    setDecimalNumber(number, status);
}


// -------------------------------------
// Creates a formattable object with a UnicodeString instance.

Formattable::Formattable(const UnicodeString& stringToCopy)
{
    init();
    fType = kString;
    fValue.fString = new UnicodeString(stringToCopy);
}

// -------------------------------------
// Creates a formattable object with a UnicodeString* value.
// (adopting semantics)

Formattable::Formattable(UnicodeString* stringToAdopt)
{
    init();
    fType = kString;
    fValue.fString = stringToAdopt;
}

Formattable::Formattable(UObject* objectToAdopt)
{
    init();
    fType = kObject;
    fValue.fObject = objectToAdopt;
}

// -------------------------------------

Formattable::Formattable(const Formattable* arrayToCopy, int32_t count)
    :   UObject(), fType(kArray)
{
    init();
    fType = kArray;
    fValue.fArrayAndCount.fArray = createArrayCopy(arrayToCopy, count);
    fValue.fArrayAndCount.fCount = count;
}

// -------------------------------------
// copy constructor


Formattable::Formattable(const Formattable &source)
     :  UObject(*this)
{
    init();
    *this = source;
}

// -------------------------------------
// assignment operator

Formattable&
Formattable::operator=(const Formattable& source)
{
    if (this != &source)
    {
        // Disposes the current formattable value/setting.
        dispose();

        // Sets the correct data type for this value.
        fType = source.fType;
        switch (fType)
        {
        case kArray:
            // Sets each element in the array one by one and records the array count.
            fValue.fArrayAndCount.fCount = source.fValue.fArrayAndCount.fCount;
            fValue.fArrayAndCount.fArray = createArrayCopy(source.fValue.fArrayAndCount.fArray,
                                                           source.fValue.fArrayAndCount.fCount);
            break;
        case kString:
            // Sets the string value.
            fValue.fString = new UnicodeString(*source.fValue.fString);
            break;
        case kDouble:
            // Sets the double value.
            fValue.fDouble = source.fValue.fDouble;
            break;
        case kLong:
        case kInt64:
            // Sets the long value.
            fValue.fInt64 = source.fValue.fInt64;
            break;
        case kDate:
            // Sets the Date value.
            fValue.fDate = source.fValue.fDate;
            break;
        case kObject:
            fValue.fObject = objectClone(source.fValue.fObject);
            break;
        }

        UErrorCode status = U_ZERO_ERROR;
        if (source.fDecimalQuantity != NULL) {
          fDecimalQuantity = new DecimalQuantity(*source.fDecimalQuantity);
        }
        if (source.fDecimalStr != NULL) {
            fDecimalStr = new CharString(*source.fDecimalStr, status);
            if (U_FAILURE(status)) {
                delete fDecimalStr;
                fDecimalStr = NULL;
            }
        }
    }
    return *this;
}

// -------------------------------------

bool
Formattable::operator==(const Formattable& that) const
{
    int32_t i;

    if (this == &that) return true;

    // Returns false if the data types are different.
    if (fType != that.fType) return false;

    // Compares the actual data values.
    bool equal = true;
    switch (fType) {
    case kDate:
        equal = (fValue.fDate == that.fValue.fDate);
        break;
    case kDouble:
        equal = (fValue.fDouble == that.fValue.fDouble);
        break;
    case kLong:
    case kInt64:
        equal = (fValue.fInt64 == that.fValue.fInt64);
        break;
    case kString:
        equal = (*(fValue.fString) == *(that.fValue.fString));
        break;
    case kArray:
        if (fValue.fArrayAndCount.fCount != that.fValue.fArrayAndCount.fCount) {
            equal = false;
            break;
        }
        // Checks each element for equality.
        for (i=0; i<fValue.fArrayAndCount.fCount; ++i) {
            if (fValue.fArrayAndCount.fArray[i] != that.fValue.fArrayAndCount.fArray[i]) {
                equal = false;
                break;
            }
        }
        break;
    case kObject:
        if (fValue.fObject == NULL || that.fValue.fObject == NULL) {
            equal = false;
        } else {
            equal = objectEquals(fValue.fObject, that.fValue.fObject);
        }
        break;
    }

    // TODO:  compare digit lists if numeric.
    return equal;
}

// -------------------------------------

Formattable::~Formattable()
{
    dispose();
}

// -------------------------------------

void Formattable::dispose()
{
    // Deletes the data value if necessary.
    switch (fType) {
    case kString:
        delete fValue.fString;
        break;
    case kArray:
        delete[] fValue.fArrayAndCount.fArray;
        break;
    case kObject:
        delete fValue.fObject;
        break;
    default:
        break;
    }

    fType = kLong;
    fValue.fInt64 = 0;

    delete fDecimalStr;
    fDecimalStr = NULL;

    delete fDecimalQuantity;
    fDecimalQuantity = NULL;
}

Formattable *
Formattable::clone() const {
    return new Formattable(*this);
}

// -------------------------------------
// Gets the data type of this Formattable object. 
Formattable::Type
Formattable::getType() const
{
    return fType;
}

UBool
Formattable::isNumeric() const {
    switch (fType) {
    case kDouble:
    case kLong:
    case kInt64:
        return TRUE;
    default:
        return FALSE;
    }
}

// -------------------------------------
int32_t
//Formattable::getLong(UErrorCode* status) const
Formattable::getLong(UErrorCode& status) const
{
    if (U_FAILURE(status)) {
        return 0;
    }
        
    switch (fType) {
    case Formattable::kLong: 
        return (int32_t)fValue.fInt64;
    case Formattable::kInt64:
        if (fValue.fInt64 > INT32_MAX) {
            status = U_INVALID_FORMAT_ERROR;
            return INT32_MAX;
        } else if (fValue.fInt64 < INT32_MIN) {
            status = U_INVALID_FORMAT_ERROR;
            return INT32_MIN;
        } else {
            return (int32_t)fValue.fInt64;
        }
    case Formattable::kDouble:
        if (fValue.fDouble > INT32_MAX) {
            status = U_INVALID_FORMAT_ERROR;
            return INT32_MAX;
        } else if (fValue.fDouble < INT32_MIN) {
            status = U_INVALID_FORMAT_ERROR;
            return INT32_MIN;
        } else {
            return (int32_t)fValue.fDouble; // loses fraction
        }
    case Formattable::kObject:
        if (fValue.fObject == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }
        // TODO Later replace this with instanceof call
        if (instanceOfMeasure(fValue.fObject)) {
            return ((const Measure*) fValue.fObject)->
                getNumber().getLong(status);
        }
        U_FALLTHROUGH;
    default:
        status = U_INVALID_FORMAT_ERROR;
        return 0;
    }
}

// -------------------------------------
// Maximum int that can be represented exactly in a double.  (53 bits)
//    Larger ints may be rounded to a near-by value as not all are representable.
// TODO:  move this constant elsewhere, possibly configure it for different
//        floating point formats, if any non-standard ones are still in use.
static const int64_t U_DOUBLE_MAX_EXACT_INT = 9007199254740992LL;

int64_t
Formattable::getInt64(UErrorCode& status) const
{
    if (U_FAILURE(status)) {
        return 0;
    }
        
    switch (fType) {
    case Formattable::kLong: 
    case Formattable::kInt64: 
        return fValue.fInt64;
    case Formattable::kDouble:
        if (fValue.fDouble > (double)U_INT64_MAX) {
            status = U_INVALID_FORMAT_ERROR;
            return U_INT64_MAX;
        } else if (fValue.fDouble < (double)U_INT64_MIN) {
            status = U_INVALID_FORMAT_ERROR;
            return U_INT64_MIN;
        } else if (fabs(fValue.fDouble) > U_DOUBLE_MAX_EXACT_INT && fDecimalQuantity != NULL) {
            if (fDecimalQuantity->fitsInLong(true)) {
                return fDecimalQuantity->toLong();
            } else {
                // Unexpected
                status = U_INVALID_FORMAT_ERROR;
                return fDecimalQuantity->isNegative() ? U_INT64_MIN : U_INT64_MAX;
            }
        } else {
            return (int64_t)fValue.fDouble;
        } 
    case Formattable::kObject:
        if (fValue.fObject == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }
        if (instanceOfMeasure(fValue.fObject)) {
            return ((const Measure*) fValue.fObject)->
                getNumber().getInt64(status);
        }
        U_FALLTHROUGH;
    default:
        status = U_INVALID_FORMAT_ERROR;
        return 0;
    }
}

// -------------------------------------
double
Formattable::getDouble(UErrorCode& status) const
{
    if (U_FAILURE(status)) {
        return 0;
    }
        
    switch (fType) {
    case Formattable::kLong: 
    case Formattable::kInt64: // loses precision
        return (double)fValue.fInt64;
    case Formattable::kDouble:
        return fValue.fDouble;
    case Formattable::kObject:
        if (fValue.fObject == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }
        // TODO Later replace this with instanceof call
        if (instanceOfMeasure(fValue.fObject)) {
            return ((const Measure*) fValue.fObject)->
                getNumber().getDouble(status);
        }
        U_FALLTHROUGH;
    default:
        status = U_INVALID_FORMAT_ERROR;
        return 0;
    }
}

const UObject*
Formattable::getObject() const {
    return (fType == kObject) ? fValue.fObject : NULL;
}

// -------------------------------------
// Sets the value to a double value d.

void
Formattable::setDouble(double d)
{
    dispose();
    fType = kDouble;
    fValue.fDouble = d;
}

// -------------------------------------
// Sets the value to a long value l.

void
Formattable::setLong(int32_t l)
{
    dispose();
    fType = kLong;
    fValue.fInt64 = l;
}

// -------------------------------------
// Sets the value to an int64 value ll.

void
Formattable::setInt64(int64_t ll)
{
    dispose();
    fType = kInt64;
    fValue.fInt64 = ll;
}

// -------------------------------------
// Sets the value to a Date instance d.

void
Formattable::setDate(UDate d)
{
    dispose();
    fType = kDate;
    fValue.fDate = d;
}

// -------------------------------------
// Sets the value to a string value stringToCopy.

void
Formattable::setString(const UnicodeString& stringToCopy)
{
    dispose();
    fType = kString;
    fValue.fString = new UnicodeString(stringToCopy);
}

// -------------------------------------
// Sets the value to an array of Formattable objects.

void
Formattable::setArray(const Formattable* array, int32_t count)
{
    dispose();
    fType = kArray;
    fValue.fArrayAndCount.fArray = createArrayCopy(array, count);
    fValue.fArrayAndCount.fCount = count;
}

// -------------------------------------
// Adopts the stringToAdopt value.

void
Formattable::adoptString(UnicodeString* stringToAdopt)
{
    dispose();
    fType = kString;
    fValue.fString = stringToAdopt;
}

// -------------------------------------
// Adopts the array value and its count.

void
Formattable::adoptArray(Formattable* array, int32_t count)
{
    dispose();
    fType = kArray;
    fValue.fArrayAndCount.fArray = array;
    fValue.fArrayAndCount.fCount = count;
}

void
Formattable::adoptObject(UObject* objectToAdopt) {
    dispose();
    fType = kObject;
    fValue.fObject = objectToAdopt;
}

// -------------------------------------
UnicodeString& 
Formattable::getString(UnicodeString& result, UErrorCode& status) const 
{
    if (fType != kString) {
        setError(status, U_INVALID_FORMAT_ERROR);
        result.setToBogus();
    } else {
        if (fValue.fString == NULL) {
            setError(status, U_MEMORY_ALLOCATION_ERROR);
        } else {
            result = *fValue.fString;
        }
    }
    return result;
}

// -------------------------------------
const UnicodeString& 
Formattable::getString(UErrorCode& status) const 
{
    if (fType != kString) {
        setError(status, U_INVALID_FORMAT_ERROR);
        return *getBogus();
    }
    if (fValue.fString == NULL) {
        setError(status, U_MEMORY_ALLOCATION_ERROR);
        return *getBogus();
    }
    return *fValue.fString;
}

// -------------------------------------
UnicodeString& 
Formattable::getString(UErrorCode& status) 
{
    if (fType != kString) {
        setError(status, U_INVALID_FORMAT_ERROR);
        return *getBogus();
    }
    if (fValue.fString == NULL) {
    	setError(status, U_MEMORY_ALLOCATION_ERROR);
    	return *getBogus();
    }
    return *fValue.fString;
}

// -------------------------------------
const Formattable* 
Formattable::getArray(int32_t& count, UErrorCode& status) const 
{
    if (fType != kArray) {
        setError(status, U_INVALID_FORMAT_ERROR);
        count = 0;
        return NULL;
    }
    count = fValue.fArrayAndCount.fCount; 
    return fValue.fArrayAndCount.fArray;
}

// -------------------------------------
// Gets the bogus string, ensures mondo bogosity.

UnicodeString*
Formattable::getBogus() const 
{
    return (UnicodeString*)&fBogus; /* cast away const :-( */
}


// --------------------------------------
StringPiece Formattable::getDecimalNumber(UErrorCode &status) {
    if (U_FAILURE(status)) {
        return "";
    }
    if (fDecimalStr != NULL) {
      return fDecimalStr->toStringPiece();
    }

    CharString *decimalStr = internalGetCharString(status);
    if(decimalStr == NULL) {
      return ""; // getDecimalNumber returns "" for error cases
    } else {
      return decimalStr->toStringPiece();
    }
}

CharString *Formattable::internalGetCharString(UErrorCode &status) {
    if(fDecimalStr == NULL) {
      if (fDecimalQuantity == NULL) {
        // No decimal number for the formattable yet.  Which means the value was
        // set directly by the user as an int, int64 or double.  If the value came
        // from parsing, or from the user setting a decimal number, fDecimalNum
        // would already be set.
        //
        LocalPointer<DecimalQuantity> dq(new DecimalQuantity(), status);
        if (U_FAILURE(status)) { return nullptr; }
        populateDecimalQuantity(*dq, status);
        if (U_FAILURE(status)) { return nullptr; }
        fDecimalQuantity = dq.orphan();
      }

      fDecimalStr = new CharString();
      if (fDecimalStr == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
      }
      // Older ICUs called uprv_decNumberToString here, which is not exactly the same as
      // DecimalQuantity::toScientificString(). The biggest difference is that uprv_decNumberToString does
      // not print scientific notation for magnitudes greater than -5 and smaller than some amount (+5?).
      if (fDecimalQuantity->isInfinite()) {
        fDecimalStr->append("Infinity", status);
      } else if (fDecimalQuantity->isNaN()) {
        fDecimalStr->append("NaN", status);
      } else if (fDecimalQuantity->isZeroish()) {
        fDecimalStr->append("0", -1, status);
      } else if (fType==kLong || fType==kInt64 || // use toPlainString for integer types
                  (fDecimalQuantity->getMagnitude() != INT32_MIN && std::abs(fDecimalQuantity->getMagnitude()) < 5)) {
        fDecimalStr->appendInvariantChars(fDecimalQuantity->toPlainString(), status);
      } else {
        fDecimalStr->appendInvariantChars(fDecimalQuantity->toScientificString(), status);
      }
    }
    return fDecimalStr;
}

void
Formattable::populateDecimalQuantity(number::impl::DecimalQuantity& output, UErrorCode& status) const {
    if (fDecimalQuantity != nullptr) {
        output = *fDecimalQuantity;
        return;
    }

    switch (fType) {
        case kDouble:
            output.setToDouble(this->getDouble());
            output.roundToInfinity();
            break;
        case kLong:
            output.setToInt(this->getLong());
            break;
        case kInt64:
            output.setToLong(this->getInt64());
            break;
        default:
            // The formattable's value is not a numeric type.
            status = U_INVALID_STATE_ERROR;
    }
}

// ---------------------------------------
void
Formattable::adoptDecimalQuantity(DecimalQuantity *dq) {
    if (fDecimalQuantity != NULL) {
        delete fDecimalQuantity;
    }
    fDecimalQuantity = dq;
    if (dq == NULL) { // allow adoptDigitList(NULL) to clear
        return;
    }

    // Set the value into the Union of simple type values.
    // Cannot use the set() functions because they would delete the fDecimalNum value.
    if (fDecimalQuantity->fitsInLong()) {
        fValue.fInt64 = fDecimalQuantity->toLong();
        if (fValue.fInt64 <= INT32_MAX && fValue.fInt64 >= INT32_MIN) {
            fType = kLong;
        } else {
            fType = kInt64;
        }
    } else {
        fType = kDouble;
        fValue.fDouble = fDecimalQuantity->toDouble();
    }
}


// ---------------------------------------
void
Formattable::setDecimalNumber(StringPiece numberString, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return;
    }
    dispose();

    auto* dq = new DecimalQuantity();
    dq->setToDecNumber(numberString, status);
    adoptDecimalQuantity(dq);

    // Note that we do not hang on to the caller's input string.
    // If we are asked for the string, we will regenerate one from fDecimalQuantity.
}

#if 0
//----------------------------------------------------
// console I/O
//----------------------------------------------------
#ifdef _DEBUG

#include <iostream>
using namespace std;

#include "unicode/datefmt.h"
#include "unistrm.h"

class FormattableStreamer /* not : public UObject because all methods are static */ {
public:
    static void streamOut(ostream& stream, const Formattable& obj);

private:
    FormattableStreamer() {} // private - forbid instantiation
};

// This is for debugging purposes only.  This will send a displayable
// form of the Formattable object to the output stream.

void
FormattableStreamer::streamOut(ostream& stream, const Formattable& obj)
{
    static DateFormat *defDateFormat = 0;

    UnicodeString buffer;
    switch(obj.getType()) {
        case Formattable::kDate : 
            // Creates a DateFormat instance for formatting the
            // Date instance.
            if (defDateFormat == 0) {
                defDateFormat = DateFormat::createInstance();
            }
            defDateFormat->format(obj.getDate(), buffer);
            stream << buffer;
            break;
        case Formattable::kDouble :
            // Output the double as is.
            stream << obj.getDouble() << 'D';
            break;
        case Formattable::kLong :
            // Output the double as is.
            stream << obj.getLong() << 'L';
            break;
        case Formattable::kString:
            // Output the double as is.  Please see UnicodeString console
            // I/O routine for more details.
            stream << '"' << obj.getString(buffer) << '"';
            break;
        case Formattable::kArray:
            int32_t i, count;
            const Formattable* array;
            array = obj.getArray(count);
            stream << '[';
            // Recursively calling the console I/O routine for each element in the array.
            for (i=0; i<count; ++i) {
                FormattableStreamer::streamOut(stream, array[i]);
                stream << ( (i==(count-1)) ? "" : ", " );
            }
            stream << ']';
            break;
        default:
            // Not a recognizable Formattable object.
            stream << "INVALID_Formattable";
    }
    stream.flush();
}
#endif

#endif

U_NAMESPACE_END

/* ---- UFormattable implementation ---- */

U_NAMESPACE_USE

U_CAPI UFormattable* U_EXPORT2
ufmt_open(UErrorCode *status) {
  if( U_FAILURE(*status) ) {
    return NULL;
  }
  UFormattable *fmt = (new Formattable())->toUFormattable();

  if( fmt == NULL ) {
    *status = U_MEMORY_ALLOCATION_ERROR;
  }
  return fmt;
}

U_CAPI void U_EXPORT2
ufmt_close(UFormattable *fmt) {
  Formattable *obj = Formattable::fromUFormattable(fmt);

  delete obj;
}

U_CAPI UFormattableType U_EXPORT2
ufmt_getType(const UFormattable *fmt, UErrorCode *status) {
  if(U_FAILURE(*status)) {
    return (UFormattableType)UFMT_COUNT;
  }
  const Formattable *obj = Formattable::fromUFormattable(fmt);
  return (UFormattableType)obj->getType();
}


U_CAPI UBool U_EXPORT2
ufmt_isNumeric(const UFormattable *fmt) {
  const Formattable *obj = Formattable::fromUFormattable(fmt);
  return obj->isNumeric();
}

U_CAPI UDate U_EXPORT2
ufmt_getDate(const UFormattable *fmt, UErrorCode *status) {
  const Formattable *obj = Formattable::fromUFormattable(fmt);

  return obj->getDate(*status);
}

U_CAPI double U_EXPORT2
ufmt_getDouble(UFormattable *fmt, UErrorCode *status) {
  Formattable *obj = Formattable::fromUFormattable(fmt);

  return obj->getDouble(*status);
}

U_CAPI int32_t U_EXPORT2
ufmt_getLong(UFormattable *fmt, UErrorCode *status) {
  Formattable *obj = Formattable::fromUFormattable(fmt);

  return obj->getLong(*status);
}


U_CAPI const void *U_EXPORT2
ufmt_getObject(const UFormattable *fmt, UErrorCode *status) {
  const Formattable *obj = Formattable::fromUFormattable(fmt);

  const void *ret = obj->getObject();
  if( ret==NULL &&
      (obj->getType() != Formattable::kObject) &&
      U_SUCCESS( *status )) {
    *status = U_INVALID_FORMAT_ERROR;
  }
  return ret;
}

U_CAPI const UChar* U_EXPORT2
ufmt_getUChars(UFormattable *fmt, int32_t *len, UErrorCode *status) {
  Formattable *obj = Formattable::fromUFormattable(fmt);

  // avoid bogosity by checking the type first.
  if( obj->getType() != Formattable::kString ) {
    if( U_SUCCESS(*status) ){
      *status = U_INVALID_FORMAT_ERROR;
    }
    return NULL;
  }

  // This should return a valid string
  UnicodeString &str = obj->getString(*status);
  if( U_SUCCESS(*status) && len != NULL ) {
    *len = str.length();
  }
  return str.getTerminatedBuffer();
}

U_CAPI int32_t U_EXPORT2
ufmt_getArrayLength(const UFormattable* fmt, UErrorCode *status) {
  const Formattable *obj = Formattable::fromUFormattable(fmt);

  int32_t count;
  (void)obj->getArray(count, *status);
  return count;
}

U_CAPI UFormattable * U_EXPORT2
ufmt_getArrayItemByIndex(UFormattable* fmt, int32_t n, UErrorCode *status) {
  Formattable *obj = Formattable::fromUFormattable(fmt);
  int32_t count;
  (void)obj->getArray(count, *status);
  if(U_FAILURE(*status)) {
    return NULL;
  } else if(n<0 || n>=count) {
    setError(*status, U_INDEX_OUTOFBOUNDS_ERROR);
    return NULL;
  } else {
    return (*obj)[n].toUFormattable(); // returns non-const Formattable
  }
}

U_CAPI const char * U_EXPORT2
ufmt_getDecNumChars(UFormattable *fmt, int32_t *len, UErrorCode *status) {
  if(U_FAILURE(*status)) {
    return "";
  }
  Formattable *obj = Formattable::fromUFormattable(fmt);
  CharString *charString = obj->internalGetCharString(*status);
  if(U_FAILURE(*status)) {
    return "";
  }
  if(charString == NULL) {
    *status = U_MEMORY_ALLOCATION_ERROR;
    return "";
  } else {
    if(len!=NULL) {
      *len = charString->length();
    }
    return charString->data();
  }
}

U_CAPI int64_t U_EXPORT2
ufmt_getInt64(UFormattable *fmt, UErrorCode *status) {
  Formattable *obj = Formattable::fromUFormattable(fmt);
  return obj->getInt64(*status);
}

#endif /* #if !UCONFIG_NO_FORMATTING */

//eof
