blob: 61d484de4951630e6433fe6311ea3c1ffdf5dd47 [file] [log] [blame]
//
// 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)
//
#define BOOST_LOCALE_SOURCE
#include <boost/locale/generator.hpp>
#include <boost/locale/encoding.hpp>
#include <boost/locale/localization_backend.hpp>
#include <map>
#include <vector>
#include <algorithm>
#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>
namespace boost {
namespace locale {
struct generator::data {
data(localization_backend_manager const &mgr) :
cats(all_categories),
chars(all_characters),
caching_enabled(false),
use_ansi_encoding(false),
backend_manager(mgr)
{
}
typedef std::map<std::string,std::locale> cached_type;
mutable cached_type cached;
mutable boost::mutex cached_lock;
locale_category_type cats;
character_facet_type chars;
bool caching_enabled;
bool use_ansi_encoding;
std::vector<std::string> paths;
std::vector<std::string> domains;
std::map<std::string,std::vector<std::string> > options;
localization_backend_manager backend_manager;
};
generator::generator(localization_backend_manager const &mgr) :
d(new generator::data(mgr))
{
}
generator::generator() :
d(new generator::data(localization_backend_manager::global()))
{
}
generator::~generator()
{
}
locale_category_type generator::categories() const
{
return d->cats;
}
void generator::categories(locale_category_type t)
{
d->cats=t;
}
void generator::characters(character_facet_type t)
{
d->chars=t;
}
character_facet_type generator::characters() const
{
return d->chars;
}
void generator::add_messages_domain(std::string const &domain)
{
if(std::find(d->domains.begin(),d->domains.end(),domain) == d->domains.end())
d->domains.push_back(domain);
}
void generator::set_default_messages_domain(std::string const &domain)
{
std::vector<std::string>::iterator p;
if((p=std::find(d->domains.begin(),d->domains.end(),domain)) == d->domains.end()) {
d->domains.erase(p);
}
d->domains.insert(d->domains.begin(),domain);
}
void generator::clear_domains()
{
d->domains.clear();
}
void generator::add_messages_path(std::string const &path)
{
d->paths.push_back(path);
}
void generator::clear_paths()
{
d->paths.clear();
}
void generator::clear_cache()
{
d->cached.clear();
}
std::locale generator::generate(std::string const &id) const
{
std::locale base=std::locale::classic();
return generate(base,id);
}
std::locale generator::generate(std::locale const &base,std::string const &id) const
{
if(d->caching_enabled) {
boost::unique_lock<boost::mutex> guard(d->cached_lock);
data::cached_type::const_iterator p = d->cached.find(id);
if(p!=d->cached.end()) {
return p->second;
}
}
shared_ptr<localization_backend> backend(d->backend_manager.get());
set_all_options(backend,id);
std::locale result = base;
locale_category_type facets = d->cats;
character_facet_type chars = d->chars;
for(locale_category_type facet = per_character_facet_first; facet <= per_character_facet_last && facet!=0; facet <<=1) {
if(!(facets & facet))
continue;
for(character_facet_type ch = character_first_facet ; ch<=character_last_facet;ch <<=1) {
if(!(ch & chars))
continue;
result = backend->install(result,facet,ch);
}
}
for(locale_category_type facet = non_character_facet_first; facet <= non_character_facet_last && facet!=0; facet <<=1) {
if(!(facets & facet))
continue;
result = backend->install(result,facet);
}
if(d->caching_enabled) {
boost::unique_lock<boost::mutex> guard(d->cached_lock);
data::cached_type::const_iterator p = d->cached.find(id);
if(p==d->cached.end()) {
d->cached[id] = result;
}
}
return result;
}
bool generator::use_ansi_encoding() const
{
return d->use_ansi_encoding;
}
void generator::use_ansi_encoding(bool v)
{
d->use_ansi_encoding = v;
}
bool generator::locale_cache_enabled() const
{
return d->caching_enabled;
}
void generator::locale_cache_enabled(bool enabled)
{
d->caching_enabled = enabled;
}
void generator::set_all_options(shared_ptr<localization_backend> backend,std::string const &id) const
{
backend->set_option("locale",id);
if(d->use_ansi_encoding)
backend->set_option("use_ansi_encoding","true");
for(size_t i=0;i<d->domains.size();i++)
backend->set_option("message_application",d->domains[i]);
for(size_t i=0;i<d->paths.size();i++)
backend->set_option("message_path",d->paths[i]);
}
} // locale
} // boost
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4