• 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 
10 #include <boost/config.hpp>
11 #ifdef BOOST_MSVC
12 #  pragma warning(disable : 4996)
13 #endif
14 
15 #include <locale>
16 #include <stdexcept>
17 #include <boost/locale/generator.hpp>
18 #include <boost/locale/conversion.hpp>
19 #include <boost/locale/encoding.hpp>
20 #include <vector>
21 
22 
23 
24 #include "all_generator.hpp"
25 
26 namespace boost {
27 namespace locale {
28 namespace impl_std {
29 
30 
31 template<typename CharType>
32 class std_converter : public converter<CharType>
33 {
34 public:
35     typedef CharType char_type;
36     typedef std::basic_string<char_type> string_type;
37     typedef std::ctype<char_type> ctype_type;
std_converter(std::locale const & base,size_t refs=0)38     std_converter(std::locale const &base,size_t refs = 0) :
39         converter<CharType>(refs),
40         base_(base)
41     {
42     }
convert(converter_base::conversion_type how,char_type const * begin,char_type const * end,int=0) const43     virtual string_type convert(converter_base::conversion_type how,char_type const *begin,char_type const *end,int /*flags*/ = 0) const
44     {
45         switch(how) {
46         case converter_base::upper_case:
47         case converter_base::lower_case:
48         case converter_base::case_folding:
49             {
50                 ctype_type const &ct=std::use_facet<ctype_type>(base_);
51                 size_t len = end - begin;
52                 std::vector<char_type> res(len+1,0);
53                 char_type *lbegin = &res[0];
54                 std::copy(begin,end,lbegin);
55                 if(how == converter_base::upper_case)
56                     ct.toupper(lbegin,lbegin+len);
57                 else
58                     ct.tolower(lbegin,lbegin+len);
59                 return string_type(lbegin,len);
60             }
61         default:
62             return string_type(begin,end-begin);
63         }
64     }
65 private:
66     std::locale base_;
67 };
68 
69 class utf8_converter : public converter<char> {
70 public:
71     typedef std::ctype<char> ctype_type;
72     typedef std::ctype<wchar_t> wctype_type;
utf8_converter(std::locale const & base,size_t refs=0)73     utf8_converter(std::locale const &base,size_t refs = 0) :
74         converter<char>(refs),
75         base_(base)
76     {
77     }
convert(converter_base::conversion_type how,char const * begin,char const * end,int=0) const78     virtual std::string convert(converter_base::conversion_type how,char const *begin,char const *end,int /*flags*/ = 0) const
79     {
80         switch(how) {
81         case upper_case:
82         case lower_case:
83         case case_folding:
84             {
85                 std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8");
86                 wctype_type const &ct=std::use_facet<wctype_type>(base_);
87                 size_t len = tmp.size();
88                 std::vector<wchar_t> res(len+1,0);
89                 wchar_t *lbegin = &res[0];
90                 std::copy(tmp.c_str(),tmp.c_str()+len,lbegin);
91                 if(how == upper_case)
92                     ct.toupper(lbegin,lbegin+len);
93                 else
94                     ct.tolower(lbegin,lbegin+len);
95                 return conv::from_utf<wchar_t>(lbegin,lbegin+len,"UTF-8");
96             }
97         default:
98             return std::string(begin,end-begin);
99         }
100     }
101 private:
102     std::locale base_;
103 };
104 
create_convert(std::locale const & in,std::string const & locale_name,character_facet_type type,utf8_support utf)105 std::locale create_convert( std::locale const &in,
106                             std::string const &locale_name,
107                             character_facet_type type,
108                             utf8_support utf)
109 {
110         switch(type) {
111         case char_facet:
112             {
113                 if(utf == utf8_native_with_wide || utf == utf8_from_wide) {
114                     std::locale base(std::locale::classic(),new std::ctype_byname<wchar_t>(locale_name.c_str()));
115                     return std::locale(in,new utf8_converter(base));
116                 }
117                 std::locale base(std::locale::classic(),new std::ctype_byname<char>(locale_name.c_str()));
118                 return std::locale(in,new std_converter<char>(base));
119             }
120         case wchar_t_facet:
121             {
122                 std::locale base(std::locale::classic(),new std::ctype_byname<wchar_t>(locale_name.c_str()));
123                 return std::locale(in,new std_converter<wchar_t>(base));
124             }
125         #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
126         case char16_t_facet:
127             {
128                 std::locale base(std::locale::classic(),new std::ctype_byname<char16_t>(locale_name.c_str()));
129                 return std::locale(in,new std_converter<char16_t>(base));
130             }
131         #endif
132         #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
133         case char32_t_facet:
134             {
135                 std::locale base(std::locale::classic(),new std::ctype_byname<char32_t>(locale_name.c_str()));
136                 return std::locale(in,new std_converter<char32_t>(base));
137             }
138         #endif
139         default:
140             return in;
141         }
142 }
143 
144 
145 } // namespace impl_std
146 } // locale
147 } // boost
148 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
149