diff options
Diffstat (limited to 'Build/source/libs/icu-xetex/samples/numfmt/main.cpp')
-rw-r--r-- | Build/source/libs/icu-xetex/samples/numfmt/main.cpp | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/Build/source/libs/icu-xetex/samples/numfmt/main.cpp b/Build/source/libs/icu-xetex/samples/numfmt/main.cpp new file mode 100644 index 00000000000..1ebd4948c37 --- /dev/null +++ b/Build/source/libs/icu-xetex/samples/numfmt/main.cpp @@ -0,0 +1,274 @@ +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 1999-2004, International Business Machines Corporation and + * others. All Rights Reserved. + ********************************************************************/ + +#include "unicode/utypes.h" +#include "unicode/unistr.h" +#include "unicode/numfmt.h" +#include "unicode/dcfmtsym.h" +#include "unicode/decimfmt.h" +#include "unicode/locid.h" +#include "unicode/uclean.h" +#include "util.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) + +extern "C" void capi(); +void cppapi(); + +static void +showCurrencyFormatting(UBool useICU26API); + +int main(int argc, char **argv) { + printf("%s output is in UTF-8\n", argv[0]); + + printf("C++ API\n"); + cppapi(); + + printf("C API\n"); + capi(); + + showCurrencyFormatting(FALSE); + showCurrencyFormatting(TRUE); + + u_cleanup(); // Release any additional storage held by ICU. + + printf("Exiting successfully\n"); + return 0; +} + +/** + * Sample code for the C++ API to NumberFormat. + */ +void cppapi() { + Locale us("en", "US"); + UErrorCode status = U_ZERO_ERROR; + + // Create a number formatter for the US locale + NumberFormat *fmt = NumberFormat::createInstance(us, status); + check(status, "NumberFormat::createInstance"); + + // Parse a string. The string uses the digits '0' through '9' + // and the decimal separator '.', standard in the US locale + UnicodeString str("9876543210.123"); + Formattable result; + fmt->parse(str, result, status); + check(status, "NumberFormat::parse"); + + printf("NumberFormat::parse(\""); // Display the result + uprintf(str); + printf("\") => "); + uprintf(formattableToString(result)); + printf("\n"); + + // Take the number parsed above, and use the formatter to + // format it. + str.remove(); // format() will APPEND to this string + fmt->format(result, str, status); + check(status, "NumberFormat::format"); + + printf("NumberFormat::format("); // Display the result + uprintf(formattableToString(result)); + printf(") => \""); + uprintf(str); + printf("\"\n"); + + delete fmt; // Release the storage used by the formatter + +} + +// currency formatting ----------------------------------------------------- *** + +/* + * Set a currency on a NumberFormat with pre-ICU 2.6 APIs. + * This is a "hack" that will not work properly for all cases because + * only ICU 2.6 introduced a more complete framework and data for this. + * + * @param nf The NumberFormat on which to set the currency; takes effect on + * currency-formatting NumberFormat instances. + * This must actually be a DecimalFormat instance. + * The display style of the output is controlled by nf (its pattern, + * usually from the display locale ID used to create this instance) + * while the currency symbol and number of decimals are set for + * the currency. + * @param currency The 3-letter ISO 4217 currency code, NUL-terminated. + * @param errorCode ICU error code, must pass U_SUCCESS() on input. + */ +static void +setNumberFormatCurrency_2_4(NumberFormat &nf, const char *currency, UErrorCode &errorCode) { + // argument checking + if(U_FAILURE(errorCode)) { + return; + } + if(currency==NULL || strlen(currency)!=3) { + errorCode=U_ILLEGAL_ARGUMENT_ERROR; + return; + } + + // check that the formatter is a DecimalFormat instance + // necessary because we will cast to the DecimalFormat subclass to set + // the currency symbol + if(nf.getDynamicClassID()!=DecimalFormat::getStaticClassID()) { + errorCode=U_ILLEGAL_ARGUMENT_ERROR; + return; + } + + // map the currency code to a locale ID + // only the currencies in this array are supported + // it would be possible to map to a locale ID, instantiate a currency + // formatter for that and copy its values, but that would be slower, + // and we have to hardcode something here anyway + static const struct { + // ISO currency ID + const char *currency; + + // fractionDigits==minimumFractionDigits==maximumFractionDigits + // for these currencies + int32_t fractionDigits; + + /* + * Set the rounding increment to 0 if it is implied with the number of + * fraction digits. Setting an explicit rounding increment makes + * number formatting slower. + * In other words, set it to something other than 0 only for unusual + * cases like "nickel rounding" (0.05) when the increment differs from + * 10^(-maximumFractionDigits). + */ + double roundingIncrement; + + // Unicode string with the desired currency display symbol or name + UChar symbol[16]; + } currencyMap[]={ + { "USD", 2, 0.0, { 0x24, 0 } }, + { "GBP", 2, 0.0, { 0xa3, 0 } }, + { "EUR", 2, 0.0, { 0x20ac, 0 } }, + { "JPY", 0, 0.0, { 0xa5, 0 } } + }; + + int32_t i; + + for(i=0; i<LENGTHOF(currencyMap); ++i) { + if(strcmp(currency, currencyMap[i].currency)==0) { + break; + } + } + if(i==LENGTHOF(currencyMap)) { + // a more specific error code would be useful in a real application + errorCode=U_UNSUPPORTED_ERROR; + return; + } + + // set the currency-related data into the caller's formatter + + nf.setMinimumFractionDigits(currencyMap[i].fractionDigits); + nf.setMaximumFractionDigits(currencyMap[i].fractionDigits); + + DecimalFormat &dnf=(DecimalFormat &)nf; + dnf.setRoundingIncrement(currencyMap[i].roundingIncrement); + + DecimalFormatSymbols symbols(*dnf.getDecimalFormatSymbols()); + symbols.setSymbol(DecimalFormatSymbols::kCurrencySymbol, currencyMap[i].symbol); + dnf.setDecimalFormatSymbols(symbols); // do not adopt symbols: Jitterbug 2889 +} + +/* + * Set a currency on a NumberFormat with ICU 2.6 APIs. + * + * @param nf The NumberFormat on which to set the currency; takes effect on + * currency-formatting NumberFormat instances. + * The display style of the output is controlled by nf (its pattern, + * usually from the display locale ID used to create this instance) + * while the currency symbol and number of decimals are set for + * the currency. + * @param currency The 3-letter ISO 4217 currency code, NUL-terminated. + * @param errorCode ICU error code, must pass U_SUCCESS() on input. + */ +static void +setNumberFormatCurrency_2_6(NumberFormat &nf, const char *currency, UErrorCode &errorCode) { + if(U_FAILURE(errorCode)) { + return; + } + if(currency==NULL || strlen(currency)!=3) { + errorCode=U_ILLEGAL_ARGUMENT_ERROR; + return; + } + + // invariant-character conversion to UChars (see utypes.h and putil.h) + UChar uCurrency[4]; + u_charsToUChars(currency, uCurrency, 4); + + // set the currency + // in ICU 3.0 this API (which was @draft ICU 2.6) gained a UErrorCode& argument +#if (U_ICU_VERSION_MAJOR_NUM < 3) + nf.setCurrency(uCurrency); +#else + nf.setCurrency(uCurrency, errorCode); +#endif +} + +static const char *const +sampleLocaleIDs[]={ + // use locale IDs complete with country code to be sure to + // pick up number/currency format patterns + "en_US", "en_GB", "de_DE", "ja_JP", "fr_FR", "hi_IN" +}; + +static const char *const +sampleCurrencies[]={ + "USD", "GBP", "EUR", "JPY" +}; + +static void +showCurrencyFormatting(UBool useICU26API) { + NumberFormat *nf; + int32_t i, j; + + UnicodeString output; + + UErrorCode errorCode; + + // TODO: Using printf() here assumes that the runtime encoding is ASCII-friendly + // and can therefore be mixed with UTF-8 + + for(i=0; i<LENGTHOF(sampleLocaleIDs); ++i) { + printf("show currency formatting (method for %s) in the locale \"%s\"\n", + useICU26API ? "ICU 2.6" : "before ICU 2.6", + sampleLocaleIDs[i]); + + // get a currency formatter for this locale ID + errorCode=U_ZERO_ERROR; + nf=NumberFormat::createCurrencyInstance(sampleLocaleIDs[i], errorCode); + if(U_FAILURE(errorCode)) { + printf("NumberFormat::createCurrencyInstance(%s) failed - %s\n", + sampleLocaleIDs[i], u_errorName(errorCode)); + continue; + } + + for(j=0; j<LENGTHOF(sampleCurrencies); ++j) { + printf(" - format currency \"%s\": ", sampleCurrencies[j]); + + // set the actual currency to be formatted + if(useICU26API) { + setNumberFormatCurrency_2_6(*nf, sampleCurrencies[j], errorCode); + } else { + setNumberFormatCurrency_2_4(*nf, sampleCurrencies[j], errorCode); + } + if(U_FAILURE(errorCode)) { + printf("setNumberFormatCurrency(%s) failed - %s\n", + sampleCurrencies[j], u_errorName(errorCode)); + continue; + } + + // output=formatted currency value + output.remove(); + nf->format(12345678.93, output); + output+=(UChar)0x0a; // '\n' + uprintf(output); + } + } +} |