diff --git a/headers/os/LocaleKit.h b/headers/os/LocaleKit.h index 6dfc95823b..110113e437 100644 --- a/headers/os/LocaleKit.h +++ b/headers/os/LocaleKit.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/headers/os/locale/GenericNumberFormat.h b/headers/os/locale/GenericNumberFormat.h deleted file mode 100644 index 7f5e4b9ec1..0000000000 --- a/headers/os/locale/GenericNumberFormat.h +++ /dev/null @@ -1,157 +0,0 @@ -#ifndef _B_GENERIC_NUMBER_FORMAT_H_ -#define _B_GENERIC_NUMBER_FORMAT_H_ - -#include - -class BString; -struct format_field_position; - -class BGenericNumberFormat { -public: - BGenericNumberFormat(); - ~BGenericNumberFormat(); - - status_t FormatInteger(const BIntegerFormatParameters *parameters, - int64 number, BString *buffer, - format_field_position *positions = NULL, - int32 positionCount = 1, - int32 *fieldCount = NULL, - bool allFieldPositions = false) const; - - status_t FormatInteger(const BIntegerFormatParameters *parameters, - int64 number, char *buffer, size_t bufferSize, - format_field_position *positions = NULL, - int32 positionCount = 1, - int32 *fieldCount = NULL, - bool allFieldPositions = false) const; - - status_t FormatInteger(const BIntegerFormatParameters *parameters, - uint64 number, BString *buffer, - format_field_position *positions = NULL, - int32 positionCount = 1, - int32 *fieldCount = NULL, - bool allFieldPositions = false) const; - - status_t FormatInteger(const BIntegerFormatParameters *parameters, - uint64 number, char *buffer, size_t bufferSize, - format_field_position *positions = NULL, - int32 positionCount = 1, - int32 *fieldCount = NULL, - bool allFieldPositions = false) const; - - // default number format parameters - - status_t SetDefaultIntegerFormatParameters( - const BIntegerFormatParameters *parameters); - BIntegerFormatParameters *DefaultIntegerFormatParameters(); - const BIntegerFormatParameters *DefaultIntegerFormatParameters() const; - - // other parameters configuring the formatter - - status_t SetDigitSymbols(const char **digits); - status_t SetFractionSeparator(const char *decimalSeparator); - status_t SetGroupingInfo(const char **groupingSeparators, - size_t separatorCount, size_t *groupSizes, size_t sizeCount); - status_t SetExponentSymbol(const char *exponentSymbol, - const char *upperCaseExponentSymbol = NULL); - status_t SetSpecialNumberSymbols(const char *nan, - const char *infinity, const char *negativeInfinity = NULL, - const char *upperCaseNaN = NULL, - const char *upperCaseInfinity = NULL, - const char *upperCaseNegativeInfinity = NULL); - status_t SetSignSymbols(const char *plusPrefix, - const char *minusPrefix, const char *padPlusPrefix, - const char *noForcePlusPrefix = NULL, const char *plusSuffix = NULL, - const char *minusSuffix = NULL, const char *padPlusSuffix = NULL, - const char *noForcePlusSuffix = NULL); - status_t SetMantissaSignSymbols(const char *plusPrefix, - const char *minusPrefix, const char *padPlusPrefix, - const char *noForcePlusPrefix = NULL, const char *plusSuffix = NULL, - const char *minusSuffix = NULL, const char *padPlusSuffix = NULL, - const char *noForcePlusSuffix = NULL); - status_t SetExponentSignSymbols(const char *plusPrefix, - const char *minusPrefix, const char *plusSuffix = NULL, - const char *minusSuffix = NULL); -// TODO: Support engineering representation of scientific format (exponent -// is a multiple of 3), i.e. allow setting the number of which the exponent -// must be a multiple of. - -private: - class BufferWriter; - class Float; - class GroupingInfo; - class Integer; - class SignSymbols; - struct SpecialNumberSymbols; - - struct Symbol { - char *symbol; - int length; - int char_count; - - Symbol(const char *symbol = NULL); - ~Symbol(); - - status_t SetTo(const char *symbol); - void Unset() { SetTo(NULL); } - }; - - static const Symbol kDefaultDigitSymbols[]; - static const Symbol kDefaultFractionSeparator; - static const Symbol kDefaultExponentSymbol; - static const Symbol kDefaultUpperCaseExponentSymbol; - static const Symbol kDefaultNaNSymbol; - static const Symbol kDefaultUpperCaseNaNSymbol; - static const Symbol kDefaultInfinitySymbol; - static const Symbol kDefaultUpperCaseInfinitySymbol; - static const Symbol kDefaultNegativeInfinitySymbol; - static const Symbol kDefaultUpperCaseNegativeInfinitySymbol; - - static const GroupingInfo kDefaultGroupingInfo; - static const GroupingInfo kNoGroupingInfo; - - static const SignSymbols kDefaultSignSymbols; - static const SignSymbols kDefaultMantissaSignSymbols; - static const SignSymbols kDefaultExponentSignSymbols; - - status_t FormatInteger(const BIntegerFormatParameters *parameters, - const Integer &integer, char *buffer, - size_t bufferSize, - format_field_position *positions = NULL, - int32 positionCount = 1, - int32 *fieldCount = NULL, - bool allFieldPositions = false) const; - - const Symbol *DigitSymbols() const; - const Symbol *FractionSeparator() const; - const GroupingInfo *GetGroupingInfo() const; - const Symbol *ExponentSymbol(bool upperCase = false) const; - const Symbol *NaNSymbol(bool upperCase = false) const; - const Symbol *InfinitySymbol(bool upperCase = false) const; - const Symbol *NegativeInfinitySymbol(bool upperCase = false) const; - void GetSpecialNumberSymbols(bool upperCase, - SpecialNumberSymbols *symbols) const; - const SignSymbols *GetSignSymbols() const; - const SignSymbols *MantissaSignSymbols() const; - const SignSymbols *ExponentSignSymbols() const; - - static status_t _SetSymbol(Symbol **symbol, const char *str); - - BIntegerFormatParameters fIntegerParameters; - Symbol *fDigitSymbols; - Symbol *fFractionSeparator; - GroupingInfo *fGroupingInfo; - Symbol *fExponentSymbol; - Symbol *fUpperCaseExponentSymbol; - Symbol *fNaNSymbol; - Symbol *fUpperCaseNaNSymbol; - Symbol *fInfinitySymbol; - Symbol *fUpperCaseInfinitySymbol; - Symbol *fNegativeInfinitySymbol; - Symbol *fUpperCaseNegativeInfinitySymbol; - SignSymbols *fSignSymbols; - SignSymbols *fMantissaSignSymbols; - SignSymbols *fExponentSignSymbols; -}; - -#endif // _B_GENERIC_NUMBER_FORMAT_H_ diff --git a/src/kits/locale/GenericNumberFormat.cpp b/src/kits/locale/GenericNumberFormat.cpp deleted file mode 100644 index d1e63ec073..0000000000 --- a/src/kits/locale/GenericNumberFormat.cpp +++ /dev/null @@ -1,1550 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include - -#if __GNUC__ > 2 -using std::max; -using std::min; -using std::nothrow; -#endif - -// constants (more below the helper classes) - -static const int kMaxIntDigitCount = 20; // int64: 19 + sign, uint64: 20 -static const int kMaxFloatDigitCount = DBL_DIG + 2; - // double: mantissa precision + 2 - - -// Symbol - -// constructor -BGenericNumberFormat::Symbol::Symbol(const char *symbol) - : symbol(NULL), - length(0), - char_count(0) -{ - SetTo(symbol); -} - -// destructor -BGenericNumberFormat::Symbol::~Symbol() -{ - Unset(); -} - -// SetTo -status_t -BGenericNumberFormat::Symbol::SetTo(const char *symbol) -{ - // unset old - if (this->symbol) { - free(this->symbol); - length = 0; - char_count = 0; - } - // set new - if (symbol) { - this->symbol = strdup(symbol); - if (!this->symbol) - return B_NO_MEMORY; - length = strlen(this->symbol); - char_count = BUnicodeChar::UTF8StringLength(this->symbol); - } - return B_OK; -} - - -// SpecialNumberSymbols -struct BGenericNumberFormat::SpecialNumberSymbols { - const Symbol *nan; - const Symbol *infinity; - const Symbol *negative_infinity; -}; - - -// GroupingInfo -class BGenericNumberFormat::GroupingInfo { - public: - GroupingInfo() - : fSeparators(NULL), - fSeparatorCount(0), - fSizes(NULL), - fSizeCount(0), - fSumSizes(NULL), - fSumSeparators(NULL) - { - } - - GroupingInfo(const char **separators, int32 separatorCount, - const size_t *sizes, int32 sizeCount) - : fSeparators(NULL), - fSeparatorCount(0), - fSizes(NULL), - fSizeCount(0), - fSumSizes(NULL), - fSumSeparators(NULL) - { - SetTo(separators, separatorCount, sizes, sizeCount); - } - - ~GroupingInfo() - { - Unset(); - } - - status_t SetTo(const char **separators, int32 separatorCount, - const size_t *sizes, int32 sizeCount) - { - // unset old - Unset(); - // set new - if ((!separators && separatorCount <= 0) - || (!sizes && sizeCount <= 0)) - return B_OK; - // allocate arrays - fSeparators = new(nothrow) Symbol[separatorCount]; - fSizes = new(nothrow) int32[sizeCount]; - fSumSizes = new(nothrow) int32[sizeCount]; - fSumSeparators = new(nothrow) Symbol*[separatorCount]; - if (!fSeparators || !fSizes || !fSumSizes || !fSumSeparators) { - Unset(); - return B_NO_MEMORY; - } - fSeparatorCount = separatorCount; - fSizeCount = sizeCount; - // separators - for (int i = 0; i < separatorCount; i++) { - status_t error = fSeparators[i].SetTo(separators[i]); - if (error != B_OK) { - Unset(); - return error; - } - } - // sizes and sum arrays - int32 sumSize = -1; - for (int32 i = 0; i < sizeCount; i++) { - fSizes[i] = (int32)sizes[i]; - sumSize += fSizes[i]; - fSumSizes[i] = sumSize; - fSumSeparators[i] = &fSeparators[min(i, fSeparatorCount)]; - } - return B_OK; - } - - void Unset() - { - if (fSeparators) { - delete[] fSeparators; - fSeparators = NULL; - } - fSeparatorCount = 0; - if (fSizes) { - delete[] fSizes; - fSizes = NULL; - } - fSizeCount = 0; - if (fSumSizes) { - delete[] fSumSizes; - fSumSizes = NULL; - } - if (fSumSeparators) { - delete[] fSumSeparators; - fSumSeparators = NULL; - } - } - - const Symbol *SeparatorForDigit(int32 position) const - { - for (int i = fSizeCount - 1; i >= 0; i--) { - if (fSumSizes[i] <= position) { - if (fSumSizes[i] == position - || (i == fSizeCount - 1 - && (position - fSumSizes[i]) % fSizes[i] == 0)) { - return fSumSeparators[i]; - } - return NULL; - } - } - return NULL; - } - - private: - Symbol *fSeparators; - int32 fSeparatorCount; - int32 *fSizes; - int32 fSizeCount; - int32 *fSumSizes; - Symbol **fSumSeparators; -}; - - -// SignSymbols -class BGenericNumberFormat::SignSymbols { - public: - SignSymbols() - : fPlusPrefix(), - fMinusPrefix(), - fPadPlusPrefix(), - fNoForcePlusPrefix(), - fPlusSuffix(), - fMinusSuffix(), - fPadPlusSuffix(), - fNoForcePlusSuffix() - { - } - - SignSymbols(const char *plusPrefix, const char *minusPrefix, - const char *padPlusPrefix, const char *noForcePlusPrefix, - const char *plusSuffix, const char *minusSuffix, - const char *padPlusSuffix, const char *noForcePlusSuffix) - : fPlusPrefix(plusPrefix), - fMinusPrefix(minusPrefix), - fPadPlusPrefix(padPlusPrefix), - fNoForcePlusPrefix(noForcePlusPrefix), - fPlusSuffix(plusSuffix), - fMinusSuffix(minusSuffix), - fPadPlusSuffix(padPlusSuffix), - fNoForcePlusSuffix(noForcePlusSuffix) - { - } - - ~SignSymbols() - { - } - - status_t SetTo(const char *plusPrefix, const char *minusPrefix, - const char *padPlusPrefix, const char *noForcePlusPrefix, - const char *plusSuffix, const char *minusSuffix, - const char *padPlusSuffix, const char *noForcePlusSuffix) - { - status_t error = B_OK; - if (error == B_OK) - error = fPlusPrefix.SetTo(plusPrefix); - if (error == B_OK) - error = fMinusPrefix.SetTo(minusPrefix); - if (error == B_OK) - error = fPadPlusPrefix.SetTo(noForcePlusPrefix); - if (error == B_OK) - error = fNoForcePlusPrefix.SetTo(noForcePlusPrefix); - if (error == B_OK) - error = fPlusSuffix.SetTo(plusSuffix); - if (error == B_OK) - error = fMinusSuffix.SetTo(minusSuffix); - if (error == B_OK) - error = fPadPlusSuffix.SetTo(noForcePlusSuffix); - if (error == B_OK) - error = fNoForcePlusSuffix.SetTo(noForcePlusSuffix); - if (error != B_OK) - Unset(); - return error; - } - - void Unset() - { - fPlusPrefix.Unset(); - fMinusPrefix.Unset(); - fNoForcePlusPrefix.Unset(); - fPadPlusPrefix.Unset(); - fPlusSuffix.Unset(); - fMinusSuffix.Unset(); - fNoForcePlusSuffix.Unset(); - fPadPlusSuffix.Unset(); - } - - const Symbol *PlusPrefix() const - { - return &fPlusPrefix; - } - - const Symbol *MinusPrefix() const - { - return &fMinusPrefix; - } - - const Symbol *PadPlusPrefix() const - { - return &fPadPlusPrefix; - } - - const Symbol *NoForcePlusPrefix() const - { - return &fNoForcePlusPrefix; - } - - const Symbol *PlusSuffix() const - { - return &fPlusSuffix; - } - - const Symbol *MinusSuffix() const - { - return &fMinusSuffix; - } - - const Symbol *PadPlusSuffix() const - { - return &fPadPlusSuffix; - } - - const Symbol *NoForcePlusSuffix() const - { - return &fNoForcePlusSuffix; - } - - private: - Symbol fPlusPrefix; - Symbol fMinusPrefix; - Symbol fPadPlusPrefix; - Symbol fNoForcePlusPrefix; - Symbol fPlusSuffix; - Symbol fMinusSuffix; - Symbol fPadPlusSuffix; - Symbol fNoForcePlusSuffix; -}; - - -// BufferWriter -class BGenericNumberFormat::BufferWriter { - public: - BufferWriter(char *buffer = NULL, int32 bufferSize = 0) - { - SetTo(buffer, bufferSize); - } - - void SetTo(char *buffer = NULL, int32 bufferSize = 0) - { - fBuffer = buffer; - fBufferSize = bufferSize; - fPosition = 0; - fCharCount = 0; - fDryRun = (!fBuffer || (fBufferSize == 0)); - if (!fDryRun) - fBuffer[0] = '\0'; - } - - int32 StringLength() const - { - return fPosition; - } - - int32 CharCount() const - { - return fCharCount; - } - - bool IsOverflow() const - { - return (fPosition >= fBufferSize); - } - - void Append(const char *bytes, size_t length, size_t charCount) - { - int32 newPosition = fPosition + length; - fDryRun |= (newPosition >= fBufferSize); - if (!fDryRun && length > 0) { - memcpy(fBuffer + fPosition, bytes, length); - fBuffer[newPosition] = '\0'; - } - fPosition = newPosition; - fCharCount += charCount; - } - - void Append(const Symbol &symbol) - { - Append(symbol.symbol, symbol.length, symbol.char_count); - } - - void Append(const Symbol *symbol) - { - if (symbol) - Append(*symbol); - } - - void Append(char c, int32 count) // ASCII 128 chars only! - { - if (count <= 0) - return; - int32 newPosition = fPosition + count; - fDryRun |= (newPosition >= fBufferSize); - if (!fDryRun && count > 0) { - memset(fBuffer + fPosition, c, count); - fBuffer[newPosition] = '\0'; - } - fPosition = newPosition; - fCharCount += count; - } - - void Append(const Symbol &symbol, int32 count) - { - if (count <= 0) - return; - int32 bytes = count * symbol.length; - int32 newPosition = fPosition + bytes; - fDryRun |= (newPosition >= fBufferSize); - if (!fDryRun && count > 0) { - for (int i = 0; i < count * symbol.length; i++) - fBuffer[i] = symbol.symbol[i % symbol.length]; - fBuffer[newPosition] = '\0'; - } - fPosition = newPosition; - fCharCount += count * symbol.char_count; - } - - void Append(const Symbol *symbol, int32 count) - { - if (symbol) - Append(*symbol, count); - } - - private: - char *fBuffer; - int32 fBufferSize; - int32 fPosition; - int32 fCharCount; - bool fDryRun; -}; - - -// constants - -// digit symbols -const BGenericNumberFormat::Symbol - BGenericNumberFormat::kDefaultDigitSymbols[] = { - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" - }; - -// decimal separator symbol -const BGenericNumberFormat::Symbol - BGenericNumberFormat::kDefaultFractionSeparator = "."; - -// grouping separator symbols -static const char *kDefaultGroupingSeparators[] = { "," }; -static const int32 kDefaultGroupingSeparatorCount - = sizeof(kDefaultGroupingSeparators) / sizeof(const char*); -static const char *kNoGroupingSeparators[] = { NULL }; // to please mwcc -static const int32 kNoGroupingSeparatorCount = 0; - -// grouping sizes -static const size_t kDefaultGroupingSizes[] = { 3 }; -static const int32 kDefaultGroupingSizeCount - = sizeof(kDefaultGroupingSizes) / sizeof(size_t); -static const size_t kNoGroupingSizes[] = { 0 }; // to please mwcc -static const int32 kNoGroupingSizeCount = 0; - -// grouping info -const BGenericNumberFormat::GroupingInfo - BGenericNumberFormat::kDefaultGroupingInfo( - kDefaultGroupingSeparators, kDefaultGroupingSeparatorCount, - kDefaultGroupingSizes, kDefaultGroupingSizeCount - ); -const BGenericNumberFormat::GroupingInfo - BGenericNumberFormat::kNoGroupingInfo( - kNoGroupingSeparators, kNoGroupingSeparatorCount, - kNoGroupingSizes, kNoGroupingSizeCount - ); - -// exponent symbol -const BGenericNumberFormat::Symbol - BGenericNumberFormat::kDefaultExponentSymbol = "e"; -const BGenericNumberFormat::Symbol - BGenericNumberFormat::kDefaultUpperCaseExponentSymbol = "E"; - -// NaN symbol -const BGenericNumberFormat::Symbol - BGenericNumberFormat::kDefaultNaNSymbol = "NaN"; -const BGenericNumberFormat::Symbol - BGenericNumberFormat::kDefaultUpperCaseNaNSymbol = "NaN"; - -// infinity symbol -const BGenericNumberFormat::Symbol - BGenericNumberFormat::kDefaultInfinitySymbol = "infinity"; -const BGenericNumberFormat::Symbol - BGenericNumberFormat::kDefaultUpperCaseInfinitySymbol = "INFINITY"; - -// negative infinity symbol -const BGenericNumberFormat::Symbol - BGenericNumberFormat::kDefaultNegativeInfinitySymbol = "-infinity"; -const BGenericNumberFormat::Symbol - BGenericNumberFormat::kDefaultUpperCaseNegativeInfinitySymbol = "-INFINITY"; - -// sign symbols -const BGenericNumberFormat::SignSymbols - BGenericNumberFormat::kDefaultSignSymbols( - "+", "-", " ", "", // prefixes - "", "", "", "" // suffixes - ); - -// mantissa sign symbols -const BGenericNumberFormat::SignSymbols - BGenericNumberFormat::kDefaultMantissaSignSymbols( - "", "", "", "", // prefixes - "", "", "", "" // suffixes - ); - -// exponent sign symbols -const BGenericNumberFormat::SignSymbols - BGenericNumberFormat::kDefaultExponentSignSymbols( - "+", "-", " ", "", // prefixes - "", "", "", "" // suffixes - ); - - -// Integer -class BGenericNumberFormat::Integer { - public: - Integer(int64 number) - : fDigitCount(0), - fNegative(number < 0) - { - if (fNegative) - Init(0ULL - (uint64)number); - else - Init(number); - } - - Integer(uint64 number) - : fDigitCount(0), - fNegative(false) - { - Init(number); - } - - int DigitCount() const - { - return fDigitCount; - } - - bool IsNegative() const - { - return fNegative; - } - - char *ToString(char *str) const - { - if (fDigitCount == 0) { - str[0] = '0'; - str[1] = '\0'; - } else if (fNegative) { - str[0] = '-'; - for (int i = 0; i < fDigitCount; i++) - str[i + 1] = '0' + fDigits[fDigitCount - i - 1]; - str[fDigitCount + 1] = '\0'; - } else { - for (int i = 0; i < fDigitCount; i++) - str[i] = '0' + fDigits[fDigitCount - i - 1]; - str[fDigitCount] = '\0'; - } - return str; - } - - void Format(BufferWriter &writer, const Symbol *digitSymbols, - const SignSymbols *signSymbols, - number_format_sign_policy signPolicy, - const GroupingInfo *groupingInfo, int32 minDigits) const - { - const Symbol *suffix = NULL; - // write sign prefix - if (fNegative) { - writer.Append(signSymbols->MinusPrefix()); - suffix = signSymbols->MinusSuffix(); - } else { - switch (signPolicy) { - case B_USE_NEGATIVE_SIGN_ONLY: - writer.Append(signSymbols->NoForcePlusPrefix()); - suffix = signSymbols->NoForcePlusSuffix(); - break; - case B_USE_SPACE_FOR_POSITIVE_SIGN: - writer.Append(signSymbols->PadPlusPrefix()); - suffix = signSymbols->PadPlusSuffix(); - break; - case B_USE_POSITIVE_SIGN: - writer.Append(signSymbols->PlusPrefix()); - suffix = signSymbols->PlusSuffix(); - break; - } - } - // the digits - if (fDigitCount == 0 && minDigits < 1) { - // special case for zero and less the one minimal digit - writer.Append(digitSymbols[0]); - } else { - // not zero or at least one minimal digit - if (groupingInfo) { - // use grouping - // pad with zeros up to minDigits - int32 digitCount = max(fDigitCount, minDigits); - for (int i = minDigits - 1; i >= fDigitCount; i--) { - if (i != digitCount - 1) - writer.Append(groupingInfo->SeparatorForDigit(i)); - writer.Append(digitSymbols[0]); - } - // write digits - for (int i = fDigitCount - 1; i >= 0; i--) { - if (i != digitCount - 1) - writer.Append(groupingInfo->SeparatorForDigit(i)); - writer.Append(digitSymbols[fDigits[i]]); - } - } else { - // no grouping - // pad with zeros up to minDigits - if (fDigitCount < minDigits) - writer.Append(digitSymbols, minDigits - fDigitCount); - // write digits - for (int i = fDigitCount - 1; i >= 0; i--) - writer.Append(digitSymbols[fDigits[i]]); - } - } - // append suffix - writer.Append(suffix); - } - - private: - void Init(uint64 number) - { - fDigitCount = 0; - while (number) { - fDigits[fDigitCount] = number % 10; - number /= 10; - fDigitCount++; - } - } - - private: - uchar fDigits[kMaxIntDigitCount]; - int32 fDigitCount; - bool fNegative; -}; - - -// Float -class BGenericNumberFormat::Float { - public: - Float(double number) - : fNegative(signbit(number)), - fClass(fpclassify(number)), - fExponent(0), - fDigitCount(0) - { - // filter special cases - switch (fClass) { - case FP_NAN: - case FP_INFINITE: - return; - case FP_ZERO: - fDigits[0] = 0; - fDigitCount = 1; - return; - case FP_NORMAL: - case FP_SUBNORMAL: - break; - } - if (fNegative) - number = -number; - // We start with an exponent great enough to make - // number / 10^fExponent < 10. It may even be < 1 or 0.1. - // We simply cut those digits later. - fExponent = (int)ceil(log10(number)); - int shiftBy = kMaxFloatDigitCount - fExponent - 1; - // We don't multiply with 10^shiftBy not in one go, since for - // subnormal numbers 10^shiftBy will not be representable. Maybe - // also for normal numbers close to the limit -- so don't risk - // anything, for the time being. TODO: Optimize later. - double mantissa = number * pow(10, shiftBy / 2); - mantissa *= pow(10, shiftBy - shiftBy / 2); - // get the mantissa's digits -- we drop trailing zeros - int32 firstNonNull = -1; - for (int i = 0; i < kMaxFloatDigitCount; i++) { - char digit = (char)fmod(mantissa, 10); - if (firstNonNull < 0 && digit > 0) - firstNonNull = i; - if (firstNonNull >= 0) - fDigits[i - firstNonNull] = digit; - mantissa /= 10; - } - if (firstNonNull >= 0) - fDigitCount = kMaxFloatDigitCount - firstNonNull; - else - fDigitCount = 0; - // drop leading zeros - while (fDigitCount > 0 && fDigits[fDigitCount - 1] == 0) { - fDigitCount--; - fExponent--; - } - // due to rounding effects we may end up with zero: switch to its - // canaonical representation then - if (fDigitCount == 0) { - fExponent = 0; - fDigits[0] = 0; - fDigitCount = 1; - } - } - - void Format(BufferWriter &writer, const Symbol *digitSymbols, - const SpecialNumberSymbols *specialNumbers, - const Symbol *fractionSeparator, - const Symbol *exponentSymbol, - const SignSymbols *signSymbols, - const SignSymbols *mantissaSignSymbols, - const SignSymbols *exponentSignSymbols, - float_format_type formatType, - number_format_sign_policy signPolicy, - const GroupingInfo *groupingInfo, - int32 minIntegerDigits, int32 minFractionDigits, - int32 maxFractionDigits, bool forceFractionSeparator, - bool keepTrailingFractionZeros) const - { - // deal with special numbers - switch (fClass) { - case FP_NAN: - writer.Append(specialNumbers->nan); - return; - case FP_INFINITE: - if (fNegative) - writer.Append(specialNumbers->negative_infinity); - else - writer.Append(specialNumbers->infinity); - return; - case FP_ZERO: - case FP_NORMAL: - case FP_SUBNORMAL: - break; - } - // format according to the specified format type - bool scientific = false; - switch (formatType) { - case B_FIXED_POINT_FLOAT_FORMAT: - break; - case B_SCIENTIFIC_FLOAT_FORMAT: - scientific = true; - break; - case B_AUTO_FLOAT_FORMAT: - // the criterion printf() uses: - scientific = (fExponent >= maxFractionDigits - || fExponent < -4); - break; - } - // finally invoke the respective method that does the formatting - if (scientific) { - FormatScientific(writer, digitSymbols, fractionSeparator, - exponentSymbol, signSymbols, mantissaSignSymbols, - exponentSignSymbols, signPolicy, minIntegerDigits, - minFractionDigits, maxFractionDigits, - forceFractionSeparator, keepTrailingFractionZeros); - } else { - FormatFixedPoint(writer, digitSymbols, fractionSeparator, - signSymbols, mantissaSignSymbols, signPolicy, groupingInfo, - minIntegerDigits, minFractionDigits, maxFractionDigits, - forceFractionSeparator, keepTrailingFractionZeros); - } - } - - void FormatScientific(BufferWriter &writer, const Symbol *digitSymbols, - const Symbol *fractionSeparator, - const Symbol *exponentSymbol, - const SignSymbols *signSymbols, - const SignSymbols *mantissaSignSymbols, - const SignSymbols *exponentSignSymbols, - number_format_sign_policy signPolicy, - int32 minIntegerDigits, int32 minFractionDigits, - int32 maxFractionDigits, bool forceFractionSeparator, - bool keepTrailingFractionZeros) const - { - const Symbol *suffix = NULL; - const Symbol *mantissaSuffix = NULL; - // write sign prefix - if (fNegative) { - writer.Append(signSymbols->MinusPrefix()); - writer.Append(mantissaSignSymbols->MinusPrefix()); - suffix = signSymbols->MinusSuffix(); - mantissaSuffix = mantissaSignSymbols->MinusSuffix(); - } else { - switch (signPolicy) { - case B_USE_NEGATIVE_SIGN_ONLY: - writer.Append(signSymbols->NoForcePlusPrefix()); - writer.Append(mantissaSignSymbols->NoForcePlusPrefix()); - suffix = signSymbols->NoForcePlusSuffix(); - mantissaSuffix - = mantissaSignSymbols->NoForcePlusSuffix(); - break; - case B_USE_SPACE_FOR_POSITIVE_SIGN: - writer.Append(signSymbols->PadPlusPrefix()); - writer.Append(mantissaSignSymbols->PadPlusPrefix()); - suffix = signSymbols->PadPlusSuffix(); - mantissaSuffix = mantissaSignSymbols->PadPlusSuffix(); - break; - case B_USE_POSITIVE_SIGN: - writer.Append(signSymbols->PlusPrefix()); - writer.Append(mantissaSignSymbols->PlusPrefix()); - suffix = signSymbols->PlusSuffix(); - mantissaSuffix = mantissaSignSymbols->PlusSuffix(); - break; - } - } - // round - int32 exponent = fExponent; - char digits[kMaxFloatDigitCount]; - int32 integerDigits = max(minIntegerDigits, 1L); - int32 fractionDigits - = max(fDigitCount - integerDigits, minFractionDigits); - fractionDigits = min(fractionDigits, maxFractionDigits); - int32 digitCount - = _Round(digits, integerDigits + fractionDigits, exponent); - fractionDigits = digitCount - integerDigits; - if (keepTrailingFractionZeros) - fractionDigits = max(fractionDigits, minFractionDigits); - fractionDigits = min(fractionDigits, maxFractionDigits); - // the mantissa - // integer part - int32 existingIntegerDigits = min(integerDigits, digitCount); - for (int i = 0; i < existingIntegerDigits; i++) - writer.Append(digitSymbols[(int)digits[digitCount - i - 1]]); - // pad with zeros to get the desired number of integer digits - if (existingIntegerDigits < integerDigits) { - writer.Append(digitSymbols, - integerDigits - existingIntegerDigits); - } - // unless the number is 0, adjust the exponent - if (!_IsZero(digits, digitCount)) - exponent -= integerDigits - 1; - // fraction part - if (fractionDigits > 0 || forceFractionSeparator) - writer.Append(fractionSeparator); - int32 existingFractionDigits - = min(digitCount - integerDigits, fractionDigits); - for (int i = existingFractionDigits - 1; i >= 0; i--) - writer.Append(digitSymbols[(int)digits[i]]); - // pad with zeros to get the desired number of fraction digits - if (fractionDigits > existingFractionDigits) { - writer.Append(digitSymbols, - fractionDigits - existingFractionDigits); - } - writer.Append(mantissaSuffix); - // the exponent - writer.Append(exponentSymbol); - - Integer(static_cast(exponent)).Format(writer, digitSymbols, - exponentSignSymbols, B_USE_POSITIVE_SIGN, &kNoGroupingInfo, 2); - // sign suffix - writer.Append(suffix); - } - - void FormatFixedPoint(BufferWriter &writer, const Symbol *digitSymbols, - const Symbol *fractionSeparator, - const SignSymbols *signSymbols, - const SignSymbols *mantissaSignSymbols, - number_format_sign_policy signPolicy, - const GroupingInfo *groupingInfo, - int32 minIntegerDigits, int32 minFractionDigits, - int32 maxFractionDigits, bool forceFractionSeparator, - bool keepTrailingFractionZeros) const - { - const Symbol *suffix = NULL; - const Symbol *mantissaSuffix = NULL; - // write sign prefix - if (fNegative) { - writer.Append(signSymbols->MinusPrefix()); - writer.Append(mantissaSignSymbols->MinusPrefix()); - suffix = signSymbols->MinusSuffix(); - mantissaSuffix = mantissaSignSymbols->MinusSuffix(); - } else { - switch (signPolicy) { - case B_USE_NEGATIVE_SIGN_ONLY: - writer.Append(signSymbols->NoForcePlusPrefix()); - writer.Append(mantissaSignSymbols->NoForcePlusPrefix()); - suffix = signSymbols->NoForcePlusSuffix(); - mantissaSuffix - = mantissaSignSymbols->NoForcePlusSuffix(); - break; - case B_USE_SPACE_FOR_POSITIVE_SIGN: - writer.Append(signSymbols->PadPlusPrefix()); - writer.Append(mantissaSignSymbols->PadPlusPrefix()); - suffix = signSymbols->PadPlusSuffix(); - mantissaSuffix = mantissaSignSymbols->PadPlusSuffix(); - break; - case B_USE_POSITIVE_SIGN: - writer.Append(signSymbols->PlusPrefix()); - writer.Append(mantissaSignSymbols->PlusPrefix()); - suffix = signSymbols->PlusSuffix(); - mantissaSuffix = mantissaSignSymbols->PlusSuffix(); - break; - } - } - // round - int32 exponent = fExponent; - char digits[kMaxFloatDigitCount]; - int32 integerDigits = max(minIntegerDigits, exponent + 1L); - int32 fractionDigits - = max(fDigitCount - integerDigits, minFractionDigits); - fractionDigits = min(fractionDigits, maxFractionDigits); - int32 digitCount - = _Round(digits, integerDigits + fractionDigits, exponent); - fractionDigits = digitCount - integerDigits; - if (keepTrailingFractionZeros) - fractionDigits = max(fractionDigits, minFractionDigits); - fractionDigits = min(fractionDigits, maxFractionDigits); - // integer part - int32 existingIntegerDigits = min(integerDigits, exponent + 1); - existingIntegerDigits = max(existingIntegerDigits, 0L); - if (groupingInfo) { - // use grouping - // pad with zeros up to minDigits - for (int i = integerDigits - 1; - i >= existingIntegerDigits; - i--) { - if (i != integerDigits - 1) - writer.Append(groupingInfo->SeparatorForDigit(i)); - writer.Append(digitSymbols[0]); - } - // write digits - for (int i = existingIntegerDigits - 1; i >= 0; i--) { - if (i != integerDigits - 1) - writer.Append(groupingInfo->SeparatorForDigit(i)); - writer.Append(digitSymbols[(int)digits[ - digitCount - existingIntegerDigits + i]]); - } - } else { - // no grouping - // pad with zeros to get the desired number of integer digits - if (existingIntegerDigits < integerDigits) { - writer.Append(digitSymbols[0], - integerDigits - existingIntegerDigits); - } - // write digits - for (int i = 0; i < existingIntegerDigits; i++) { - writer.Append( - digitSymbols[(int)digits[digitCount - i - 1]]); - } - } - // fraction part - if (fractionDigits > 0 || forceFractionSeparator) - writer.Append(fractionSeparator); - int32 existingFractionDigits - = min(digitCount - existingIntegerDigits, fractionDigits); - for (int i = existingFractionDigits - 1; i >= 0; i--) - writer.Append(digitSymbols[(int)digits[i]]); - // pad with zeros to get the desired number of fraction digits - if (fractionDigits > existingFractionDigits) { - writer.Append(digitSymbols, - fractionDigits - existingFractionDigits); - } - // sign suffixes - writer.Append(mantissaSuffix); - writer.Append(suffix); - } - - private: - int32 _Round(char *digits, int32 count, int32 &exponent) const - { - if (count > fDigitCount) - count = fDigitCount; - int firstNonNull = -1; -// TODO: Non-hardcoded base-independent rounding. - bool carry = false; - if (count < fDigitCount) - carry = (fDigits[fDigitCount - count - 1] >= 5); - for (int i = 0; i < count; i++) { - char digit = fDigits[fDigitCount - count + i]; - if (carry) { - digit++; - if (digit == 10) // == base - digit = 0; - else - carry = false; - } - if (firstNonNull < 0 && digit > 0) - firstNonNull = i; - if (firstNonNull >= 0) - digits[i - firstNonNull] = digit; - } - if (firstNonNull < 0) { - if (carry) { - // 9.999999... -> 10 - digits[0] = 1; - exponent++; - } else { - // 0.0000...1 -> 0 - exponent = 0; - digits[0] = 0; - } - count = 1; - } else - count -= firstNonNull; - return count; - } - - static bool _IsZero(const char *digits, int32 digitCount) - { - return (digitCount == 1 && digits[0] == 0); - } - - private: - bool fNegative; - int fClass; - int32 fExponent; - char fDigits[kMaxFloatDigitCount]; - int32 fDigitCount; -}; - - -// constructor -BGenericNumberFormat::BGenericNumberFormat() - : fIntegerParameters(), - fFloatParameters(), - fDigitSymbols(NULL), - fFractionSeparator(NULL), - fGroupingInfo(NULL), - fExponentSymbol(NULL), - fUpperCaseExponentSymbol(NULL), - fNaNSymbol(NULL), - fUpperCaseNaNSymbol(NULL), - fInfinitySymbol(NULL), - fUpperCaseInfinitySymbol(NULL), - fNegativeInfinitySymbol(NULL), - fUpperCaseNegativeInfinitySymbol(NULL), - fSignSymbols(NULL), - fMantissaSignSymbols(NULL), - fExponentSignSymbols(NULL) -{ -} - -// destructor -BGenericNumberFormat::~BGenericNumberFormat() -{ - delete fSignSymbols; - delete fMantissaSignSymbols; - delete fExponentSignSymbols; -} - -// FormatInteger -status_t -BGenericNumberFormat::FormatInteger( - const BIntegerFormatParameters *parameters, int64 number, BString *buffer, - format_field_position *positions, int32 positionCount, int32 *fieldCount, - bool allFieldPositions) const -{ - if (!buffer) - return B_BAD_VALUE; - char localBuffer[1024]; - status_t error = FormatInteger(parameters, number, localBuffer, - sizeof(localBuffer), positions, positionCount, fieldCount, - allFieldPositions); - if (error == B_OK) { - buffer->Append(localBuffer); - // TODO: Check, if the allocation succeeded. - } - return error; -} - -// FormatInteger -status_t -BGenericNumberFormat::FormatInteger( - const BIntegerFormatParameters *parameters, uint64 number, BString *buffer, - format_field_position *positions, int32 positionCount, int32 *fieldCount, - bool allFieldPositions) const -{ - if (!buffer) - return B_BAD_VALUE; - char localBuffer[1024]; - status_t error = FormatInteger(parameters, number, localBuffer, - sizeof(localBuffer), positions, positionCount, fieldCount, - allFieldPositions); - if (error == B_OK) { - buffer->Append(localBuffer); - // TODO: Check, if the allocation succeeded. - } - return error; -} - -// FormatInteger -status_t -BGenericNumberFormat::FormatInteger( - const BIntegerFormatParameters *parameters, int64 number, char *buffer, - size_t bufferSize, format_field_position *positions, int32 positionCount, - int32 *fieldCount, bool allFieldPositions) const -{ - Integer integer(number); - return FormatInteger(parameters, integer, buffer, bufferSize, positions, - positionCount, fieldCount, allFieldPositions); -} - -// FormatInteger -status_t -BGenericNumberFormat::FormatInteger( - const BIntegerFormatParameters *parameters, uint64 number, char *buffer, - size_t bufferSize, format_field_position *positions, int32 positionCount, - int32 *fieldCount, bool allFieldPositions) const -{ - Integer integer(number); - return FormatInteger(parameters, integer, buffer, bufferSize, positions, - positionCount, fieldCount, allFieldPositions); -} - -// FormatFloat -status_t -BGenericNumberFormat::FormatFloat(const BFloatFormatParameters *parameters, - double number, BString *buffer, format_field_position *positions, - int32 positionCount, int32 *fieldCount, bool allFieldPositions) const -{ - if (!buffer) - return B_BAD_VALUE; - // TODO: How to ensure that this is enough? - char localBuffer[1024]; - status_t error = FormatFloat(parameters, number, localBuffer, - sizeof(localBuffer), positions, positionCount, fieldCount, - allFieldPositions); - if (error == B_OK) { - buffer->Append(localBuffer); - // TODO: Check, if the allocation succeeded. - } - return error; -} - -// FormatFloat -status_t -BGenericNumberFormat::FormatFloat(const BFloatFormatParameters *parameters, - double number, char *buffer, size_t bufferSize, - format_field_position *positions, int32 positionCount, int32 *fieldCount, - bool allFieldPositions) const -{ - // TODO: Check parameters. - if (!parameters) - parameters = DefaultFloatFormatParameters(); - if (bufferSize <= parameters->FormatWidth()) - return EOVERFLOW; - Float floatNumber(number); - // prepare some parameters - const GroupingInfo *groupingInfo = NULL; - if (parameters->UseGrouping()) - groupingInfo = GetGroupingInfo(); - bool upperCase = parameters->UseUpperCase(); - SpecialNumberSymbols specialSymbols; - GetSpecialNumberSymbols(upperCase, &specialSymbols); - // compute the length of the formatted string - BufferWriter writer; - floatNumber.Format(writer, DigitSymbols(), &specialSymbols, - FractionSeparator(), ExponentSymbol(), GetSignSymbols(), - MantissaSignSymbols(), ExponentSignSymbols(), - parameters->FloatFormatType(), parameters->SignPolicy(), groupingInfo, - parameters->MinimalIntegerDigits(), parameters->MinimalFractionDigits(), - parameters->MaximalFractionDigits(), - parameters->AlwaysUseFractionSeparator(), - parameters->KeepTrailingFractionZeros()); - int32 stringLength = writer.StringLength(); - int32 charCount = writer.CharCount(); - // consider alignment and check the available space in the buffer - int32 padding = max(0L, (int32)parameters->FormatWidth() - charCount); -// TODO: Padding with zeros. - if ((int32)bufferSize <= stringLength + padding) - return EOVERFLOW; - // prepare for writing - writer.SetTo(buffer, bufferSize); - // write padding for right field alignment - if (parameters->Alignment() == B_ALIGN_FORMAT_RIGHT && padding > 0) - writer.Append(' ', padding); - // write the number - floatNumber.Format(writer, DigitSymbols(), &specialSymbols, - FractionSeparator(), ExponentSymbol(), GetSignSymbols(), - MantissaSignSymbols(), ExponentSignSymbols(), - parameters->FloatFormatType(), parameters->SignPolicy(), groupingInfo, - parameters->MinimalIntegerDigits(), parameters->MinimalFractionDigits(), - parameters->MaximalFractionDigits(), - parameters->AlwaysUseFractionSeparator(), - parameters->KeepTrailingFractionZeros()); - // write padding for left field alignment - if (parameters->Alignment() == B_ALIGN_FORMAT_LEFT && padding > 0) - writer.Append(' ', padding); - return B_OK; -} - -// SetDefaultIntegerFormatParameters -status_t -BGenericNumberFormat::SetDefaultIntegerFormatParameters( - const BIntegerFormatParameters *parameters) -{ - if (!parameters) - return B_BAD_VALUE; - fIntegerParameters = *parameters; - return B_OK; -} - -// DefaultIntegerFormatParameters -BIntegerFormatParameters * -BGenericNumberFormat::DefaultIntegerFormatParameters() -{ - return &fIntegerParameters; -} - -// DefaultIntegerFormatParameters -const BIntegerFormatParameters * -BGenericNumberFormat::DefaultIntegerFormatParameters() const -{ - return &fIntegerParameters; -} - -// SetDefaultFloatFormatParameters -status_t -BGenericNumberFormat::SetDefaultFloatFormatParameters( - const BFloatFormatParameters *parameters) -{ - if (!parameters) - return B_BAD_VALUE; - fFloatParameters = *parameters; - return B_OK; -} - -// DefaultFloatFormatParameters -BFloatFormatParameters * -BGenericNumberFormat::DefaultFloatFormatParameters() -{ - return &fFloatParameters; -} - -// DefaultFloatFormatParameters -const BFloatFormatParameters * -BGenericNumberFormat::DefaultFloatFormatParameters() const -{ - return &fFloatParameters; -} - -// SetDigitSymbols -status_t -BGenericNumberFormat::SetDigitSymbols(const char **digits) -{ - // check parameters - if (digits) { - for (int i = 0; i < 10; i++) { - if (!digits[i]) - return B_BAD_VALUE; - } - } - // unset old - if (fDigitSymbols) { - delete[] fDigitSymbols; - fDigitSymbols = NULL; - } - // set new - if (digits) { - fDigitSymbols = new(nothrow) Symbol[10]; - if (!fDigitSymbols) - return B_NO_MEMORY; - for (int i = 0; i < 10; i++) { - status_t error = fDigitSymbols[i].SetTo(digits[i]); - if (error != B_OK) { - SetDigitSymbols(NULL); - return error; - } - } - } - return B_OK; -} - -// SetFractionSeparator -status_t -BGenericNumberFormat::SetFractionSeparator(const char *decimalSeparator) -{ - return _SetSymbol(&fFractionSeparator, decimalSeparator); -} - -// SetGroupingInfo -status_t -BGenericNumberFormat::SetGroupingInfo(const char **groupingSeparators, - size_t separatorCount, size_t *groupingSizes, size_t sizeCount) -{ - // check parameters - if (groupingSeparators && separatorCount > 0 && groupingSizes - && sizeCount) { - for (int i = 0; i < (int)separatorCount; i++) { - if (!groupingSeparators[i]) - return B_BAD_VALUE; - } - } - // unset old - if (fGroupingInfo) { - delete fGroupingInfo; - fGroupingInfo = NULL; - } - // set new - if (groupingSeparators && separatorCount > 0 && groupingSizes - && sizeCount) { - fGroupingInfo = new GroupingInfo; - if (!fGroupingInfo) - return B_NO_MEMORY; - status_t error = fGroupingInfo->SetTo(groupingSeparators, - separatorCount, groupingSizes, sizeCount); - if (error != B_OK) { - delete fGroupingInfo; - fGroupingInfo = NULL; - return error; - } - } - return B_OK; -} - -// SetExponentSymbol -status_t -BGenericNumberFormat::SetExponentSymbol(const char *exponentSymbol, - const char *upperCaseExponentSymbol) -{ - status_t error = _SetSymbol(&fExponentSymbol, exponentSymbol); - if (error == B_OK) - error = _SetSymbol(&fUpperCaseExponentSymbol, upperCaseExponentSymbol); - if (error != B_OK) - SetExponentSymbol(NULL, NULL); - return error; -} - -// SetSpecialNumberSymbols -status_t -BGenericNumberFormat::SetSpecialNumberSymbols(const char *nan, - const char *infinity, const char *negativeInfinity, - const char *upperCaseNaN, const char *upperCaseInfinity, - const char *upperCaseNegativeInfinity) -{ - status_t error = _SetSymbol(&fNaNSymbol, nan); - if (error == B_OK) - error = _SetSymbol(&fInfinitySymbol, infinity); - if (error == B_OK) - error = _SetSymbol(&fNegativeInfinitySymbol, negativeInfinity); - if (error == B_OK) - error = _SetSymbol(&fUpperCaseNaNSymbol, upperCaseNaN); - if (error == B_OK) - error = _SetSymbol(&fUpperCaseInfinitySymbol, upperCaseInfinity); - if (error == B_OK) { - error = _SetSymbol(&fUpperCaseNegativeInfinitySymbol, - upperCaseNegativeInfinity); - } - if (error != B_OK) - SetSpecialNumberSymbols(NULL, NULL, NULL, NULL, NULL, NULL); - return error; -} - -// SetSignSymbols -status_t -BGenericNumberFormat::SetSignSymbols(const char *plusPrefix, - const char *minusPrefix, const char *padPlusPrefix, - const char *noForcePlusPrefix, const char *plusSuffix, - const char *minusSuffix, const char *padPlusSuffix, - const char *noForcePlusSuffix) -{ - if (!fSignSymbols) { - fSignSymbols = new(nothrow) SignSymbols; - if (!fSignSymbols) - return B_NO_MEMORY; - } - return fSignSymbols->SetTo(plusPrefix, minusPrefix, padPlusPrefix, - noForcePlusPrefix, plusSuffix, minusSuffix, padPlusSuffix, - noForcePlusSuffix); -} - -// SetMantissaSignSymbols -status_t -BGenericNumberFormat::SetMantissaSignSymbols(const char *plusPrefix, - const char *minusPrefix, const char *padPlusPrefix, - const char *noForcePlusPrefix, const char *plusSuffix, - const char *minusSuffix, const char *padPlusSuffix, - const char *noForcePlusSuffix) -{ - if (!fMantissaSignSymbols) { - fMantissaSignSymbols = new(nothrow) SignSymbols; - if (!fMantissaSignSymbols) - return B_NO_MEMORY; - } - return fMantissaSignSymbols->SetTo(plusPrefix, minusPrefix, padPlusPrefix, - noForcePlusPrefix, plusSuffix, minusSuffix, padPlusSuffix, - noForcePlusSuffix); -} - -// SetExponentSignSymbols -status_t -BGenericNumberFormat::SetExponentSignSymbols(const char *plusPrefix, - const char *minusPrefix, const char *plusSuffix, const char *minusSuffix) -{ - if (!fExponentSignSymbols) { - fExponentSignSymbols = new(nothrow) SignSymbols; - if (!fExponentSignSymbols) - return B_NO_MEMORY; - } - return fExponentSignSymbols->SetTo(plusPrefix, minusPrefix, plusPrefix, - plusPrefix, plusSuffix, minusSuffix, plusSuffix, plusSuffix); -} - -// FormatInteger -status_t -BGenericNumberFormat::FormatInteger( - const BIntegerFormatParameters *parameters, const Integer &integer, - char *buffer, size_t bufferSize, format_field_position *positions, - int32 positionCount, int32 *fieldCount, bool allFieldPositions) const -{ - // TODO: Check parameters. - if (!parameters) - parameters = DefaultIntegerFormatParameters(); - if (bufferSize <= parameters->FormatWidth()) - return EOVERFLOW; - // prepare some parameters - const GroupingInfo *groupingInfo = NULL; - if (parameters->UseGrouping()) - groupingInfo = GetGroupingInfo(); - // compute the length of the formatted string - BufferWriter writer; - integer.Format(writer, DigitSymbols(), - GetSignSymbols(), parameters->SignPolicy(), groupingInfo, - parameters->MinimalIntegerDigits()); - int32 stringLength = writer.StringLength(); - int32 charCount = writer.CharCount(); - // consider alignment and check the available space in the buffer - int32 padding = max(0L, (int32)parameters->FormatWidth() - charCount); -// TODO: Padding with zeros. - if ((int32)bufferSize <= stringLength + padding) - return EOVERFLOW; - // prepare for writing - writer.SetTo(buffer, bufferSize); - // write padding for right field alignment - if (parameters->Alignment() == B_ALIGN_FORMAT_RIGHT && padding > 0) - writer.Append(' ', padding); - // write the number - integer.Format(writer, DigitSymbols(), - GetSignSymbols(), parameters->SignPolicy(), groupingInfo, - parameters->MinimalIntegerDigits()); - // write padding for left field alignment - if (parameters->Alignment() == B_ALIGN_FORMAT_LEFT && padding > 0) - writer.Append(' ', padding); - return B_OK; -} - -// DigitSymbols -const BGenericNumberFormat::Symbol * -BGenericNumberFormat::DigitSymbols() const -{ - return (fDigitSymbols ? fDigitSymbols : kDefaultDigitSymbols); -} - -// FractionSeparator -const BGenericNumberFormat::Symbol * -BGenericNumberFormat::FractionSeparator() const -{ - return (fFractionSeparator ? fFractionSeparator - : &kDefaultFractionSeparator); -} - -// GetGroupingInfo -const BGenericNumberFormat::GroupingInfo * -BGenericNumberFormat::GetGroupingInfo() const -{ - return (fGroupingInfo ? fGroupingInfo : &kDefaultGroupingInfo); -} - -// ExponentSymbol -const BGenericNumberFormat::Symbol * -BGenericNumberFormat::ExponentSymbol(bool upperCase) const -{ - if (fExponentSymbol) { - return (upperCase && fUpperCaseExponentSymbol ? fUpperCaseExponentSymbol - : fExponentSymbol); - } - return (upperCase ? &kDefaultUpperCaseExponentSymbol - : &kDefaultExponentSymbol); -} - -// NaNSymbol -const BGenericNumberFormat::Symbol * -BGenericNumberFormat::NaNSymbol(bool upperCase) const -{ - if (fNaNSymbol) { - return (upperCase && fUpperCaseNaNSymbol ? fUpperCaseNaNSymbol - : fNaNSymbol); - } - return (upperCase ? &kDefaultUpperCaseNaNSymbol - : &kDefaultNaNSymbol); -} - -// InfinitySymbol -const BGenericNumberFormat::Symbol * -BGenericNumberFormat::InfinitySymbol(bool upperCase) const -{ - if (fInfinitySymbol) { - return (upperCase && fUpperCaseInfinitySymbol ? fUpperCaseInfinitySymbol - : fInfinitySymbol); - } - return (upperCase ? &kDefaultUpperCaseInfinitySymbol - : &kDefaultInfinitySymbol); -} - -// NegativeInfinitySymbol -const BGenericNumberFormat::Symbol * -BGenericNumberFormat::NegativeInfinitySymbol(bool upperCase) const -{ - if (fNegativeInfinitySymbol) { - return (upperCase && fUpperCaseNegativeInfinitySymbol - ? fUpperCaseNegativeInfinitySymbol : fNegativeInfinitySymbol); - } - return (upperCase ? &kDefaultUpperCaseNegativeInfinitySymbol - : &kDefaultNegativeInfinitySymbol); -} - -// GetSpecialNumberSymbols -void -BGenericNumberFormat::GetSpecialNumberSymbols(bool upperCase, - SpecialNumberSymbols *symbols) const -{ - symbols->nan = NaNSymbol(upperCase); - symbols->infinity = InfinitySymbol(upperCase); - symbols->negative_infinity = NegativeInfinitySymbol(upperCase); -} - -// GetSignSymbols -const BGenericNumberFormat::SignSymbols * -BGenericNumberFormat::GetSignSymbols() const -{ - return (fSignSymbols ? fSignSymbols : &kDefaultSignSymbols); -} - -// MantissaSignSymbols -const BGenericNumberFormat::SignSymbols * -BGenericNumberFormat::MantissaSignSymbols() const -{ - return (fMantissaSignSymbols ? fMantissaSignSymbols - : &kDefaultMantissaSignSymbols); -} - -// ExponentSignSymbols -const BGenericNumberFormat::SignSymbols * -BGenericNumberFormat::ExponentSignSymbols() const -{ - return (fExponentSignSymbols ? fExponentSignSymbols - : &kDefaultExponentSignSymbols); -} - -// _SetSymbol -status_t -BGenericNumberFormat::_SetSymbol(Symbol **symbol, const char *str) -{ - if (!str) { - // no symbol -- unset old - if (*symbol) { - delete *symbol; - symbol = NULL; - } - } else { - // allocate if not existing - if (!*symbol) { - *symbol = new(nothrow) Symbol; - if (!*symbol) - return B_NO_MEMORY; - } - // set symbol - status_t error = (*symbol)->SetTo(str); - if (error != B_OK) { - delete *symbol; - *symbol = NULL; - return B_NO_MEMORY; - } - } - return B_OK; -} - diff --git a/src/kits/locale/Jamfile b/src/kits/locale/Jamfile index 94130b9158..9fabd30115 100644 --- a/src/kits/locale/Jamfile +++ b/src/kits/locale/Jamfile @@ -38,7 +38,6 @@ local sources = # old, needs investigation # FormatImpl.cpp # FormatParameters.cpp - # GenericNumberFormat.cpp # NumberFormatParameters.cpp ; diff --git a/src/tests/kits/locale/Jamfile b/src/tests/kits/locale/Jamfile index 2fd68b621f..2184393d9c 100644 --- a/src/tests/kits/locale/Jamfile +++ b/src/tests/kits/locale/Jamfile @@ -14,7 +14,6 @@ Depends LocaleKitTests collatorSpeed collatorTest ICUTest -# libNumberFormatTests.so localekittest.so ; @@ -30,7 +29,6 @@ LocaleTest catalogSpeed.cpp ; LocaleTest catalogTest.cpp ; LocaleTest collatorSpeed.cpp ; LocaleTest collatorTest.cpp ; -LocaleTest genericNumberFormatTest.cpp ; Includes [ FGristFiles ICUTest.cpp ] : [ BuildFeatureAttribute icu : headers ] ; # Dependency needed to trigger downloading/unzipping the package before diff --git a/src/tests/kits/locale/genericNumberFormatTest.cpp b/src/tests/kits/locale/genericNumberFormatTest.cpp deleted file mode 100644 index 179ec292ef..0000000000 --- a/src/tests/kits/locale/genericNumberFormatTest.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* -** Copyright 2004, Ingo Weinhold, bonefish@cs.tu-berlin.de. All rights reserved. -** Distributed under the terms of the MIT License. -*/ - -#include -#include - -#include -#include - -void -format_integer(const char *test, const BGenericNumberFormat &format, - const BIntegerFormatParameters *parameters, int64 number) -{ - const int bufferSize = 1024; - char buffer[bufferSize]; - status_t error = format.FormatInteger(parameters, number, buffer, - bufferSize); - if (error == B_OK) - printf("%-20s `%s'\n", test, buffer); - else - printf("%-20s Failed to format number: %s\n", test, strerror(error)); -} - -void -format_integer(BGenericNumberFormat &format, int64 number) -{ - printf("number: %lld\n", number); - BIntegerFormatParameters parameters( - format.DefaultIntegerFormatParameters()); - format_integer(" default:", format, ¶meters, number); - parameters.SetFormatWidth(25); - format_integer(" right aligned:", format, ¶meters, number); - parameters.SetAlignment(B_ALIGN_FORMAT_LEFT); - format_integer(" left aligned:", format, ¶meters, number); - parameters.SetFormatWidth(1); - parameters.SetAlignment(B_ALIGN_FORMAT_RIGHT); - parameters.SetSignPolicy(B_USE_POSITIVE_SIGN); - format_integer(" use plus:", format, ¶meters, number); - parameters.SetSignPolicy(B_USE_SPACE_FOR_POSITIVE_SIGN); - format_integer(" space for plus:", format, ¶meters, number); - parameters.SetSignPolicy(B_USE_NEGATIVE_SIGN_ONLY); - parameters.SetMinimalIntegerDigits(0); - format_integer(" min digits 0:", format, ¶meters, number); - parameters.SetMinimalIntegerDigits(5); - format_integer(" min digits 5:", format, ¶meters, number); - parameters.SetMinimalIntegerDigits(20); - format_integer(" min digits 20:", format, ¶meters, number); - parameters.SetMinimalIntegerDigits(30); - format_integer(" min digits 30:", format, ¶meters, number); -} - -void -format_float(const char *test, const BGenericNumberFormat &format, - const BFloatFormatParameters *parameters, double number) -{ - const int bufferSize = 1024; - char buffer[bufferSize]; - status_t error = format.FormatFloat(parameters, number, buffer, bufferSize); - if (error == B_OK) - printf("%-20s `%s'\n", test, buffer); - else - printf("%-20s Failed to format number: %s\n", test, strerror(error)); -} - -void -format_float(BGenericNumberFormat &format, double number) -{ - printf("number: %g\n", number); - BFloatFormatParameters parameters( format.DefaultFloatFormatParameters()); - format_float(" default:", format, ¶meters, number); -} - -int -main() -{ - BGenericNumberFormat format; - printf("Integer\n"); - printf("=======\n\n"); - format_integer(format, 0); - format_integer(format, 1234567890LL); - format_integer(format, -1234567890LL); - format.DefaultIntegerFormatParameters()->SetUseGrouping(true); - format_integer(format, 0); - format_integer(format, 1234567890LL); - format_integer(format, -1234567890LL); - - printf("\n\nFloat\n"); - printf("=====\n\n"); - format_float(format, 0.0); - format_float(format, -0.0); - format_float(format, 1234567890.0); - format_float(format, -1234567890.0); - format_float(format, 1234.56789); - format_float(format, -1234.56789); - format.DefaultFloatFormatParameters()->SetUseGrouping(true); - format_float(format, 0.0); - format_float(format, -0.0); - format_float(format, 1234567890.0); - format_float(format, -1234567890.0); - format_float(format, 1234.56789); - format_float(format, -1234.56789); - return 0; -} - diff --git a/src/tests/kits/locale/number_format/Jamfile b/src/tests/kits/locale/number_format/Jamfile deleted file mode 100644 index c003e8fe51..0000000000 --- a/src/tests/kits/locale/number_format/Jamfile +++ /dev/null @@ -1,15 +0,0 @@ -SubDir HAIKU_TOP src tests kits locale number_format ; - -UsePublicHeaders locale ; - -SEARCH_SOURCE += [ FDirName $(SUBDIR) generic_number_format ] ; - -UnitTestLib libNumberFormatTests.so - : NumberFormatTestAddOn.cpp - - # BGenericNumberFormat - GenericNumberFormatTests.cpp - GenericNumberFormatConstructorTest.cpp - - : be [ TargetLibstdc++ ] -; diff --git a/src/tests/kits/locale/number_format/NumberFormatTestAddOn.cpp b/src/tests/kits/locale/number_format/NumberFormatTestAddOn.cpp deleted file mode 100644 index 6c3fbf5742..0000000000 --- a/src/tests/kits/locale/number_format/NumberFormatTestAddOn.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include - -#include "generic_number_format/GenericNumberFormatTests.h" - -// getTestSuite -BTestSuite* -getTestSuite() -{ - BTestSuite *suite = new BTestSuite("NumberFormat"); - - suite->addTest("BGenericNumberFormat", GenericNumberFormatTestSuite()); - - return suite; -} diff --git a/src/tests/kits/locale/number_format/generic_number_format/GenericNumberFormatConstructorTest.cpp b/src/tests/kits/locale/number_format/generic_number_format/GenericNumberFormatConstructorTest.cpp deleted file mode 100644 index 7f2b86e81d..0000000000 --- a/src/tests/kits/locale/number_format/generic_number_format/GenericNumberFormatConstructorTest.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include - -#include - -#include -#include -#include -#include -#include - -#include "GenericNumberFormatConstructorTest.h" - -using namespace CppUnit; - -// Suite -Test * -GenericNumberFormatConstructorTest::Suite() -{ - CppUnit::TestSuite *suite = new CppUnit::TestSuite(); - typedef CppUnit::TestCaller TC; - - suite->addTest(new TC("BGenericNumberFormat::Constructor Test1", - &GenericNumberFormatConstructorTest::ConstructorTest1)); - - return suite; -} - -// ConstructorTest1 -void GenericNumberFormatConstructorTest::ConstructorTest1() -{ - BGenericNumberFormat format; -} - diff --git a/src/tests/kits/locale/number_format/generic_number_format/GenericNumberFormatConstructorTest.h b/src/tests/kits/locale/number_format/generic_number_format/GenericNumberFormatConstructorTest.h deleted file mode 100644 index 7adb7d07ca..0000000000 --- a/src/tests/kits/locale/number_format/generic_number_format/GenericNumberFormatConstructorTest.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _GENERIC_NUMBER_FORMAT_CONSTRUCTOR_TEST_ -#define _GENERIC_NUMBER_FORMAT_CONSTRUCTOR_TEST_ - -#include - -class GenericNumberFormatConstructorTest : public CppUnit::TestCase { - public: - GenericNumberFormatConstructorTest() {} - GenericNumberFormatConstructorTest(string name) - : TestCase(name) {} - - void ConstructorTest1(); - - static Test* Suite(); -}; - -#endif // _GENERIC_NUMBER_FORMAT_CONSTRUCTOR_TEST_ diff --git a/src/tests/kits/locale/number_format/generic_number_format/GenericNumberFormatTests.cpp b/src/tests/kits/locale/number_format/generic_number_format/GenericNumberFormatTests.cpp deleted file mode 100644 index c5b28a3abe..0000000000 --- a/src/tests/kits/locale/number_format/generic_number_format/GenericNumberFormatTests.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include - -#include "GenericNumberFormatTests.h" - -#include "GenericNumberFormatConstructorTest.h" - -// getTestSuite -CppUnit::Test* -GenericNumberFormatTestSuite() -{ - CppUnit::TestSuite *testSuite = new CppUnit::TestSuite(); - - testSuite->addTest(GenericNumberFormatConstructorTest::Suite()); - - return testSuite; -} diff --git a/src/tests/kits/locale/number_format/generic_number_format/GenericNumberFormatTests.h b/src/tests/kits/locale/number_format/generic_number_format/GenericNumberFormatTests.h deleted file mode 100644 index 5205915925..0000000000 --- a/src/tests/kits/locale/number_format/generic_number_format/GenericNumberFormatTests.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _GENERIC_NUMBER_FORMAT_TESTS_H -#define _GENERIC_NUMBER_FORMAT_TESTS_H - -namespace CppUnit { - class Test; -} - -CppUnit::Test *GenericNumberFormatTestSuite(); - -#endif // _GENERIC_NUMBER_FORMAT_TESTS_H