1 // 2 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See 5 // accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 // 8 #define BOOST_LOCALE_SOURCE 9 #include <boost/locale/localization_backend.hpp> 10 #include <boost/locale/gnu_gettext.hpp> 11 #include <boost/locale/util.hpp> 12 #include "all_generator.hpp" 13 #include "cdata.hpp" 14 #include "icu_backend.hpp" 15 #include "../util/locale_data.hpp" 16 #include <algorithm> 17 #include <iterator> 18 19 #include <unicode/ucnv.h> 20 21 namespace boost { 22 namespace locale { 23 namespace impl_icu { 24 class icu_localization_backend : public localization_backend { 25 public: icu_localization_backend()26 icu_localization_backend() : 27 invalid_(true), 28 use_ansi_encoding_(false) 29 { 30 } icu_localization_backend(icu_localization_backend const & other)31 icu_localization_backend(icu_localization_backend const &other) : 32 localization_backend(), 33 paths_(other.paths_), 34 domains_(other.domains_), 35 locale_id_(other.locale_id_), 36 invalid_(true), 37 use_ansi_encoding_(other.use_ansi_encoding_) 38 { 39 } clone() const40 virtual icu_localization_backend *clone() const 41 { 42 return new icu_localization_backend(*this); 43 } 44 set_option(std::string const & name,std::string const & value)45 void set_option(std::string const &name,std::string const &value) 46 { 47 invalid_ = true; 48 if(name=="locale") 49 locale_id_ = value; 50 else if(name=="message_path") 51 paths_.push_back(value); 52 else if(name=="message_application") 53 domains_.push_back(value); 54 else if(name=="use_ansi_encoding") 55 use_ansi_encoding_ = value == "true"; 56 57 } clear_options()58 void clear_options() 59 { 60 invalid_ = true; 61 use_ansi_encoding_ = false; 62 locale_id_.clear(); 63 paths_.clear(); 64 domains_.clear(); 65 } 66 prepare_data()67 void prepare_data() 68 { 69 if(!invalid_) 70 return; 71 invalid_ = false; 72 real_id_ = locale_id_; 73 if(real_id_.empty()) { 74 bool utf8 = ! use_ansi_encoding_; 75 real_id_ = util::get_system_locale(utf8); 76 } 77 78 util::locale_data d; 79 d.parse(real_id_); 80 81 data_.locale = icu::Locale::createCanonical(real_id_.c_str()); 82 data_.encoding = d.encoding; 83 data_.utf8 = d.utf8; 84 language_ = d.language; 85 country_ = d.country; 86 variant_ = d.variant; 87 } 88 install(std::locale const & base,locale_category_type category,character_facet_type type=nochar_facet)89 virtual std::locale install(std::locale const &base, 90 locale_category_type category, 91 character_facet_type type = nochar_facet) 92 { 93 prepare_data(); 94 95 switch(category) { 96 case convert_facet: 97 return create_convert(base,data_,type); 98 case collation_facet: 99 return create_collate(base,data_,type); 100 case formatting_facet: 101 return create_formatting(base,data_,type); 102 case parsing_facet: 103 return create_parsing(base,data_,type); 104 case codepage_facet: 105 return create_codecvt(base,data_.encoding,type); 106 case message_facet: 107 { 108 gnu_gettext::messages_info minf; 109 minf.language = language_; 110 minf.country = country_; 111 minf.variant = variant_; 112 minf.encoding = data_.encoding; 113 std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains)); 114 minf.paths = paths_; 115 switch(type) { 116 case char_facet: 117 return std::locale(base,gnu_gettext::create_messages_facet<char>(minf)); 118 case wchar_t_facet: 119 return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf)); 120 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T 121 case char16_t_facet: 122 return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf)); 123 #endif 124 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T 125 case char32_t_facet: 126 return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf)); 127 #endif 128 default: 129 return base; 130 } 131 } 132 case boundary_facet: 133 return create_boundary(base,data_,type); 134 case calendar_facet: 135 return create_calendar(base,data_); 136 case information_facet: 137 return util::create_info(base,real_id_); 138 default: 139 return base; 140 } 141 } 142 143 private: 144 145 std::vector<std::string> paths_; 146 std::vector<std::string> domains_; 147 std::string locale_id_; 148 149 cdata data_; 150 std::string language_; 151 std::string country_; 152 std::string variant_; 153 std::string real_id_; 154 bool invalid_; 155 bool use_ansi_encoding_; 156 }; 157 create_localization_backend()158 localization_backend *create_localization_backend() 159 { 160 return new icu_localization_backend(); 161 } 162 163 } // impl icu 164 } // locale 165 } // boost 166 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 167