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/generator.hpp> 10 #include <boost/locale/encoding.hpp> 11 #include <boost/locale/localization_backend.hpp> 12 #include <map> 13 #include <vector> 14 #include <algorithm> 15 #include <boost/shared_ptr.hpp> 16 #include <boost/thread/locks.hpp> 17 #include <boost/thread/mutex.hpp> 18 19 namespace boost { 20 namespace locale { 21 struct generator::data { databoost::locale::generator::data22 data(localization_backend_manager const &mgr) : 23 cats(all_categories), 24 chars(all_characters), 25 caching_enabled(false), 26 use_ansi_encoding(false), 27 backend_manager(mgr) 28 { 29 } 30 31 typedef std::map<std::string,std::locale> cached_type; 32 mutable cached_type cached; 33 mutable boost::mutex cached_lock; 34 35 locale_category_type cats; 36 character_facet_type chars; 37 38 bool caching_enabled; 39 bool use_ansi_encoding; 40 41 std::vector<std::string> paths; 42 std::vector<std::string> domains; 43 44 std::map<std::string,std::vector<std::string> > options; 45 46 localization_backend_manager backend_manager; 47 48 }; 49 generator(localization_backend_manager const & mgr)50 generator::generator(localization_backend_manager const &mgr) : 51 d(new generator::data(mgr)) 52 { 53 } generator()54 generator::generator() : 55 d(new generator::data(localization_backend_manager::global())) 56 { 57 } ~generator()58 generator::~generator() 59 { 60 } 61 categories() const62 locale_category_type generator::categories() const 63 { 64 return d->cats; 65 } categories(locale_category_type t)66 void generator::categories(locale_category_type t) 67 { 68 d->cats=t; 69 } 70 characters(character_facet_type t)71 void generator::characters(character_facet_type t) 72 { 73 d->chars=t; 74 } 75 characters() const76 character_facet_type generator::characters() const 77 { 78 return d->chars; 79 } 80 add_messages_domain(std::string const & domain)81 void generator::add_messages_domain(std::string const &domain) 82 { 83 if(std::find(d->domains.begin(),d->domains.end(),domain) == d->domains.end()) 84 d->domains.push_back(domain); 85 } 86 set_default_messages_domain(std::string const & domain)87 void generator::set_default_messages_domain(std::string const &domain) 88 { 89 std::vector<std::string>::iterator p; 90 if((p=std::find(d->domains.begin(),d->domains.end(),domain)) != d->domains.end()) { 91 d->domains.erase(p); 92 } 93 d->domains.insert(d->domains.begin(),domain); 94 } 95 clear_domains()96 void generator::clear_domains() 97 { 98 d->domains.clear(); 99 } add_messages_path(std::string const & path)100 void generator::add_messages_path(std::string const &path) 101 { 102 d->paths.push_back(path); 103 } clear_paths()104 void generator::clear_paths() 105 { 106 d->paths.clear(); 107 } clear_cache()108 void generator::clear_cache() 109 { 110 d->cached.clear(); 111 } 112 generate(std::string const & id) const113 std::locale generator::generate(std::string const &id) const 114 { 115 std::locale base=std::locale::classic(); 116 117 return generate(base,id); 118 } 119 generate(std::locale const & base,std::string const & id) const120 std::locale generator::generate(std::locale const &base,std::string const &id) const 121 { 122 if(d->caching_enabled) { 123 boost::unique_lock<boost::mutex> guard(d->cached_lock); 124 data::cached_type::const_iterator p = d->cached.find(id); 125 if(p!=d->cached.end()) { 126 return p->second; 127 } 128 } 129 shared_ptr<localization_backend> backend(d->backend_manager.create()); 130 set_all_options(backend,id); 131 132 std::locale result = base; 133 locale_category_type facets = d->cats; 134 character_facet_type chars = d->chars; 135 136 for(locale_category_type facet = per_character_facet_first; facet <= per_character_facet_last && facet!=0; facet <<=1) { 137 if(!(facets & facet)) 138 continue; 139 for(character_facet_type ch = character_first_facet ; ch<=character_last_facet;ch <<=1) { 140 if(!(ch & chars)) 141 continue; 142 result = backend->install(result,facet,ch); 143 } 144 } 145 for(locale_category_type facet = non_character_facet_first; facet <= non_character_facet_last && facet!=0; facet <<=1) { 146 if(!(facets & facet)) 147 continue; 148 result = backend->install(result,facet); 149 } 150 if(d->caching_enabled) { 151 boost::unique_lock<boost::mutex> guard(d->cached_lock); 152 data::cached_type::const_iterator p = d->cached.find(id); 153 if(p==d->cached.end()) { 154 d->cached[id] = result; 155 } 156 } 157 return result; 158 } 159 use_ansi_encoding() const160 bool generator::use_ansi_encoding() const 161 { 162 return d->use_ansi_encoding; 163 } 164 use_ansi_encoding(bool v)165 void generator::use_ansi_encoding(bool v) 166 { 167 d->use_ansi_encoding = v; 168 } 169 locale_cache_enabled() const170 bool generator::locale_cache_enabled() const 171 { 172 return d->caching_enabled; 173 } locale_cache_enabled(bool enabled)174 void generator::locale_cache_enabled(bool enabled) 175 { 176 d->caching_enabled = enabled; 177 } 178 set_all_options(shared_ptr<localization_backend> backend,std::string const & id) const179 void generator::set_all_options(shared_ptr<localization_backend> backend,std::string const &id) const 180 { 181 backend->set_option("locale",id); 182 if(d->use_ansi_encoding) 183 backend->set_option("use_ansi_encoding","true"); 184 for(size_t i=0;i<d->domains.size();i++) 185 backend->set_option("message_application",d->domains[i]); 186 for(size_t i=0;i<d->paths.size();i++) 187 backend->set_option("message_path",d->paths[i]); 188 } 189 190 } // locale 191 } // boost 192 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 193