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