• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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