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/info.hpp>
12 #include "all_generator.hpp"
13 #include "win_backend.hpp"
14 #include <boost/locale/util.hpp>
15 #include "../util/gregorian.hpp"
16 #include "../util/locale_data.hpp"
17 #include "api.hpp"
18 #include <algorithm>
19 #include <iterator>
20 
21 namespace boost {
22 namespace locale {
23 namespace impl_win {
24 
25     class winapi_localization_backend : public localization_backend {
26     public:
winapi_localization_backend()27         winapi_localization_backend() :
28             invalid_(true)
29         {
30         }
winapi_localization_backend(winapi_localization_backend const & other)31         winapi_localization_backend(winapi_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         {
38         }
clone() const39         virtual winapi_localization_backend *clone() const
40         {
41             return new winapi_localization_backend(*this);
42         }
43 
set_option(std::string const & name,std::string const & value)44         void set_option(std::string const &name,std::string const &value)
45         {
46             invalid_ = true;
47             if(name=="locale")
48                 locale_id_ = value;
49             else if(name=="message_path")
50                 paths_.push_back(value);
51             else if(name=="message_application")
52                 domains_.push_back(value);
53 
54         }
clear_options()55         void clear_options()
56         {
57             invalid_ = true;
58             locale_id_.clear();
59             paths_.clear();
60             domains_.clear();
61         }
62 
prepare_data()63         void prepare_data()
64         {
65             if(!invalid_)
66                 return;
67             invalid_ = false;
68             if(locale_id_.empty()) {
69                 real_id_ = util::get_system_locale(true); // always UTF-8
70                 lc_ = winlocale(real_id_);
71             }
72             else {
73                 lc_=winlocale(locale_id_);
74                 real_id_ = locale_id_;
75             }
76             util::locale_data d;
77             d.parse(real_id_);
78             if(!d.utf8) {
79                 lc_ = winlocale();
80                 // Make it C as non-UTF8 locales are not supported
81             }
82         }
83 
install(std::locale const & base,locale_category_type category,character_facet_type type=nochar_facet)84         virtual std::locale install(std::locale const &base,
85                                     locale_category_type category,
86                                     character_facet_type type = nochar_facet)
87         {
88             prepare_data();
89 
90             switch(category) {
91             case convert_facet:
92                 return create_convert(base,lc_,type);
93             case collation_facet:
94                 return create_collate(base,lc_,type);
95             case formatting_facet:
96                 return create_formatting(base,lc_,type);
97             case parsing_facet:
98                 return create_parsing(base,lc_,type);
99             case calendar_facet:
100                 {
101                     util::locale_data inf;
102                     inf.parse(real_id_);
103                     return util::install_gregorian_calendar(base,inf.country);
104                 }
105             case message_facet:
106                 {
107                     gnu_gettext::messages_info minf;
108                     std::locale tmp=util::create_info(std::locale::classic(),real_id_);
109                     boost::locale::info const &inf=std::use_facet<boost::locale::info>(tmp);
110                     minf.language = inf.language();
111                     minf.country = inf.country();
112                     minf.variant = inf.variant();
113                     minf.encoding = inf.encoding();
114                     std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains));
115                     minf.paths = paths_;
116                     switch(type) {
117                     case char_facet:
118                         return std::locale(base,gnu_gettext::create_messages_facet<char>(minf));
119                     case wchar_t_facet:
120                         return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf));
121                     default:
122                         return base;
123                     }
124                 }
125             case information_facet:
126                 return util::create_info(base,real_id_);
127             case codepage_facet:
128                 return util::create_codecvt(base,util::create_utf8_converter(),type);
129             default:
130                 return base;
131             }
132         }
133 
134     private:
135 
136         std::vector<std::string> paths_;
137         std::vector<std::string> domains_;
138         std::string locale_id_;
139         std::string real_id_;
140 
141         bool invalid_;
142         winlocale lc_;
143     };
144 
create_localization_backend()145     localization_backend *create_localization_backend()
146     {
147         return new winapi_localization_backend();
148     }
149 
150 }  // impl win
151 }  // locale
152 }  // boost
153 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
154