|
- //
- // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef BOOSTER_LOCALE_PREDEFINED_FORMATTERS_H_INCLUDED
- #define BOOSTER_LOCALE_PREDEFINED_FORMATTERS_H_INCLUDED
-
- #include <string>
- #include <booster/auto_ptr_inc.h>
- #include <booster/cstdint.h>
- #include <booster/thread.h>
- #include <booster/config.h>
-
- #include <unicode/locid.h>
- #include <unicode/numfmt.h>
- #include <unicode/rbnf.h>
- #include <unicode/datefmt.h>
- #include <unicode/smpdtfmt.h>
- #include <unicode/decimfmt.h>
-
- namespace booster {
- namespace locale {
- namespace impl_icu {
-
- class icu_formatters_cache : public std::locale::facet {
- public:
-
- static std::locale::id id;
-
- icu_formatters_cache(icu::Locale const &locale) :
- locale_(locale)
- {
-
- static const icu::DateFormat::EStyle styles[4] = {
- icu::DateFormat::kShort,
- icu::DateFormat::kMedium,
- icu::DateFormat::kLong,
- icu::DateFormat::kFull
- };
-
-
- for(int i=0;i<4;i++) {
- std::auto_ptr<icu::DateFormat> fmt(icu::DateFormat::createDateInstance(styles[i],locale));
- icu::SimpleDateFormat *sfmt = dynamic_cast<icu::SimpleDateFormat*>(fmt.get());
- if(sfmt) {
- sfmt->toPattern(date_format_[i]);
- }
- }
-
- for(int i=0;i<4;i++) {
- std::auto_ptr<icu::DateFormat> fmt(icu::DateFormat::createTimeInstance(styles[i],locale));
- icu::SimpleDateFormat *sfmt = dynamic_cast<icu::SimpleDateFormat*>(fmt.get());
- if(sfmt) {
- sfmt->toPattern(time_format_[i]);
- }
- }
-
- for(int i=0;i<4;i++) {
- for(int j=0;j<4;j++) {
- std::auto_ptr<icu::DateFormat> fmt(
- icu::DateFormat::createDateTimeInstance(styles[i],styles[j],locale));
- icu::SimpleDateFormat *sfmt = dynamic_cast<icu::SimpleDateFormat*>(fmt.get());
- if(sfmt) {
- sfmt->toPattern(date_time_format_[i][j]);
- }
- }
- }
-
-
- }
-
- typedef enum {
- fmt_number,
- fmt_sci,
- fmt_curr_nat,
- fmt_curr_iso,
- fmt_per,
- fmt_spell,
- fmt_ord,
- fmt_count
- } fmt_type;
-
- icu::NumberFormat *number_format(fmt_type type) const
- {
- icu::NumberFormat *ptr = number_format_[type].get();
- if(ptr)
- return ptr;
- UErrorCode err=U_ZERO_ERROR;
- std::auto_ptr<icu::NumberFormat> ap;
-
- switch(type) {
- case fmt_number:
- ap.reset(icu::NumberFormat::createInstance(locale_,err));
- break;
- case fmt_sci:
- ap.reset(icu::NumberFormat::createScientificInstance(locale_,err));
- break;
- #if U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM >= 402
- #if U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM >= 408
- case fmt_curr_nat:
- ap.reset(icu::NumberFormat::createInstance(locale_,UNUM_CURRENCY,err));
- break;
- case fmt_curr_iso:
- ap.reset(icu::NumberFormat::createInstance(locale_,UNUM_CURRENCY_ISO,err));
- break;
- #else
- case fmt_curr_nat:
- ap.reset(icu::NumberFormat::createInstance(locale_,icu::NumberFormat::kCurrencyStyle,err));
- break;
- case fmt_curr_iso:
- ap.reset(icu::NumberFormat::createInstance(locale_,icu::NumberFormat::kIsoCurrencyStyle,err));
- break;
- #endif
- #else
- case fmt_curr_nat:
- case fmt_curr_iso:
- ap.reset(icu::NumberFormat::createCurrencyInstance(locale_,err));
- break;
- #endif
- case fmt_per:
- ap.reset(icu::NumberFormat::createPercentInstance(locale_,err));
- break;
- case fmt_spell:
- ap.reset(new icu::RuleBasedNumberFormat(icu::URBNF_SPELLOUT,locale_,err));
- break;
- case fmt_ord:
- ap.reset(new icu::RuleBasedNumberFormat(icu::URBNF_ORDINAL,locale_,err));
- break;
- default:
- throw booster::runtime_error("locale::internal error should not get there");
- }
-
- test(err);
- ptr = ap.get();
- number_format_[type].reset(ap.release());
- return ptr;
- }
-
- void test(UErrorCode err) const
- {
- if(U_FAILURE(err))
- throw booster::runtime_error("Failed to create a formatter");
- }
-
- icu::UnicodeString date_format_[4];
- icu::UnicodeString time_format_[4];
- icu::UnicodeString date_time_format_[4][4];
-
- icu::SimpleDateFormat *date_formatter() const
- {
- icu::SimpleDateFormat *p=date_formatter_.get();
- if(p)
- return p;
-
- std::auto_ptr<icu::DateFormat> fmt(icu::DateFormat::createDateTimeInstance(
- icu::DateFormat::kMedium,
- icu::DateFormat::kMedium,
- locale_));
-
- if(dynamic_cast<icu::SimpleDateFormat *>(fmt.get())) {
- p = static_cast<icu::SimpleDateFormat *>(fmt.release());
- date_formatter_.reset(p);
- }
- return p;
- }
-
- private:
-
- mutable booster::thread_specific_ptr<icu::NumberFormat> number_format_[fmt_count];
- mutable booster::thread_specific_ptr<icu::SimpleDateFormat> date_formatter_;
- icu::Locale locale_;
- };
-
-
-
- } // namespace impl_icu
- } // namespace locale
- } // namespace boost
-
-
-
- #endif
- // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|