aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/icu/i18n/fmtable.cpp
diff options
context:
space:
mode:
authorneksard <neksard@yandex-team.ru>2022-02-10 16:45:33 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:33 +0300
commit1d9c550e7c38e051d7961f576013a482003a70d9 (patch)
treeb2cc84ee7850122e7ccf51d0ea21e4fa7e7a5685 /contrib/libs/icu/i18n/fmtable.cpp
parent8f7cf138264e0caa318144bf8a2c950e0b0a8593 (diff)
downloadydb-1d9c550e7c38e051d7961f576013a482003a70d9.tar.gz
Restoring authorship annotation for <neksard@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/icu/i18n/fmtable.cpp')
-rw-r--r--contrib/libs/icu/i18n/fmtable.cpp1922
1 files changed, 961 insertions, 961 deletions
diff --git a/contrib/libs/icu/i18n/fmtable.cpp b/contrib/libs/icu/i18n/fmtable.cpp
index 9a5e064cad..dbfd3c26ba 100644
--- a/contrib/libs/icu/i18n/fmtable.cpp
+++ b/contrib/libs/icu/i18n/fmtable.cpp
@@ -1,734 +1,734 @@
// © 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
-
+// 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 <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)
-
+
+// *****************************************************************************
+// 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;
+
+
+//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
+
+// 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 symantics)
-
-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;
+ 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 symantics)
+
+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;
-}
-
-// -------------------------------------
-
-UBool
-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.
- UBool 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;
+ }
+ if (source.fDecimalStr != NULL) {
+ fDecimalStr = new CharString(*source.fDecimalStr, status);
+ if (U_FAILURE(status)) {
+ delete fDecimalStr;
+ fDecimalStr = NULL;
+ }
+ }
+ }
+ return *this;
+}
+
+// -------------------------------------
+
+UBool
+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.
+ UBool 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;
+}
+
+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:
- 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;
+ 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 {
+ } else {
// Unexpected
- status = U_INVALID_FORMAT_ERROR;
+ 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;
+ }
+ } else {
+ return (int64_t)fValue.fDouble;
}
- }
- 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) {
+ 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.
- //
+ // 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;
- }
+ 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?).
@@ -744,17 +744,17 @@ CharString *Formattable::internalGetCharString(UErrorCode &status) {
} else {
fDecimalStr->appendInvariantChars(fDecimalQuantity->toScientificString(), status);
}
- }
- return fDecimalStr;
-}
-
+ }
+ 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());
@@ -770,10 +770,10 @@ Formattable::populateDecimalQuantity(number::impl::DecimalQuantity& output, UErr
// The formattable's value is not a numeric type.
status = U_INVALID_STATE_ERROR;
}
-}
-
-// ---------------------------------------
-void
+}
+
+// ---------------------------------------
+void
Formattable::adoptDecimalQuantity(DecimalQuantity *dq) {
if (fDecimalQuantity != NULL) {
delete fDecimalQuantity;
@@ -782,8 +782,8 @@ Formattable::adoptDecimalQuantity(DecimalQuantity *dq) {
if (dq == NULL) { // allow adoptDigitList(NULL) to clear
return;
}
-
- // Set the value into the Union of simple type values.
+
+ // 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();
@@ -792,251 +792,251 @@ Formattable::adoptDecimalQuantity(DecimalQuantity *dq) {
} else {
fType = kInt64;
}
- } else {
- fType = kDouble;
+ } else {
+ fType = kDouble;
fValue.fDouble = fDecimalQuantity->toDouble();
- }
-}
-
-
-// ---------------------------------------
-void
-Formattable::setDecimalNumber(StringPiece numberString, UErrorCode &status) {
- if (U_FAILURE(status)) {
- return;
- }
- dispose();
-
+ }
+}
+
+
+// ---------------------------------------
+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.
+
+ // 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_DRAFT 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_DRAFT void U_EXPORT2
-ufmt_close(UFormattable *fmt) {
- Formattable *obj = Formattable::fromUFormattable(fmt);
-
- delete obj;
-}
-
-U_INTERNAL 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_INTERNAL UBool U_EXPORT2
-ufmt_isNumeric(const UFormattable *fmt) {
- const Formattable *obj = Formattable::fromUFormattable(fmt);
- return obj->isNumeric();
-}
-
-U_DRAFT UDate U_EXPORT2
-ufmt_getDate(const UFormattable *fmt, UErrorCode *status) {
- const Formattable *obj = Formattable::fromUFormattable(fmt);
-
- return obj->getDate(*status);
-}
-
-U_DRAFT double U_EXPORT2
-ufmt_getDouble(UFormattable *fmt, UErrorCode *status) {
- Formattable *obj = Formattable::fromUFormattable(fmt);
-
- return obj->getDouble(*status);
-}
-
-U_DRAFT int32_t U_EXPORT2
-ufmt_getLong(UFormattable *fmt, UErrorCode *status) {
- Formattable *obj = Formattable::fromUFormattable(fmt);
-
- return obj->getLong(*status);
-}
-
-
-U_DRAFT 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_DRAFT 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_DRAFT 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_DRAFT 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_DRAFT 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_DRAFT 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
+}
+
+#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_DRAFT 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_DRAFT void U_EXPORT2
+ufmt_close(UFormattable *fmt) {
+ Formattable *obj = Formattable::fromUFormattable(fmt);
+
+ delete obj;
+}
+
+U_INTERNAL 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_INTERNAL UBool U_EXPORT2
+ufmt_isNumeric(const UFormattable *fmt) {
+ const Formattable *obj = Formattable::fromUFormattable(fmt);
+ return obj->isNumeric();
+}
+
+U_DRAFT UDate U_EXPORT2
+ufmt_getDate(const UFormattable *fmt, UErrorCode *status) {
+ const Formattable *obj = Formattable::fromUFormattable(fmt);
+
+ return obj->getDate(*status);
+}
+
+U_DRAFT double U_EXPORT2
+ufmt_getDouble(UFormattable *fmt, UErrorCode *status) {
+ Formattable *obj = Formattable::fromUFormattable(fmt);
+
+ return obj->getDouble(*status);
+}
+
+U_DRAFT int32_t U_EXPORT2
+ufmt_getLong(UFormattable *fmt, UErrorCode *status) {
+ Formattable *obj = Formattable::fromUFormattable(fmt);
+
+ return obj->getLong(*status);
+}
+
+
+U_DRAFT 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_DRAFT 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_DRAFT 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_DRAFT 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_DRAFT 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_DRAFT 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