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/config.hpp>
10 
11 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
12 #define BOOST_LOCALE_WITH_WCONV
13 #endif
14 
15 #ifdef BOOST_LOCALE_WITH_ICONV
16 #include "iconv_codepage.ipp"
17 #endif
18 #ifdef BOOST_LOCALE_WITH_ICU
19 #include "uconv_codepage.ipp"
20 #endif
21 #ifdef BOOST_LOCALE_WITH_WCONV
22 #include "wconv_codepage.ipp"
23 #endif
24 
25 #include <boost/locale/encoding.hpp>
26 #include <boost/locale/hold_ptr.hpp>
27 
28 #include <string>
29 #include <cstring>
30 #include <memory>
31 
32 namespace boost {
33     namespace locale {
34         namespace conv {
35             namespace impl {
36 
convert_between(char const * begin,char const * end,char const * to_charset,char const * from_charset,method_type how)37                 std::string convert_between(char const *begin,
38                                             char const *end,
39                                             char const *to_charset,
40                                             char const *from_charset,
41                                             method_type how)
42                 {
43                     hold_ptr<converter_between> cvt;
44                     #ifdef BOOST_LOCALE_WITH_ICONV
45                     cvt.reset(new iconv_between());
46                     if(cvt->open(to_charset,from_charset,how))
47                         return cvt->convert(begin,end);
48                     #endif
49                     #ifdef BOOST_LOCALE_WITH_ICU
50                     cvt.reset(new uconv_between());
51                     if(cvt->open(to_charset,from_charset,how))
52                         return cvt->convert(begin,end);
53                     #endif
54                     #ifdef BOOST_LOCALE_WITH_WCONV
55                     cvt.reset(new wconv_between());
56                     if(cvt->open(to_charset,from_charset,how))
57                         return cvt->convert(begin,end);
58                     #endif
59                     throw invalid_charset_error(std::string(to_charset) + " or " + from_charset);
60                 }
61 
62                 template<typename CharType>
convert_to(char const * begin,char const * end,char const * charset,method_type how)63                 std::basic_string<CharType> convert_to(
64                                         char const *begin,
65                                         char const *end,
66                                         char const *charset,
67                                         method_type how)
68                 {
69                     hold_ptr<converter_to_utf<CharType> > cvt;
70                     #ifdef BOOST_LOCALE_WITH_ICONV
71                     cvt.reset(new iconv_to_utf<CharType>());
72                     if(cvt->open(charset,how))
73                         return cvt->convert(begin,end);
74                     #endif
75                     #ifdef BOOST_LOCALE_WITH_ICU
76                     cvt.reset(new uconv_to_utf<CharType>());
77                     if(cvt->open(charset,how))
78                         return cvt->convert(begin,end);
79                     #endif
80                     #ifdef BOOST_LOCALE_WITH_WCONV
81                     cvt.reset(new wconv_to_utf<CharType>());
82                     if(cvt->open(charset,how))
83                         return cvt->convert(begin,end);
84                     #endif
85                     throw invalid_charset_error(charset);
86                 }
87 
88                 template<typename CharType>
convert_from(CharType const * begin,CharType const * end,char const * charset,method_type how)89                 std::string convert_from(
90                                         CharType const *begin,
91                                         CharType const *end,
92                                         char const *charset,
93                                         method_type how)
94                 {
95                     hold_ptr<converter_from_utf<CharType> > cvt;
96                     #ifdef BOOST_LOCALE_WITH_ICONV
97                     cvt.reset(new iconv_from_utf<CharType>());
98                     if(cvt->open(charset,how))
99                         return cvt->convert(begin,end);
100                     #endif
101                     #ifdef BOOST_LOCALE_WITH_ICU
102                     cvt.reset(new uconv_from_utf<CharType>());
103                     if(cvt->open(charset,how))
104                         return cvt->convert(begin,end);
105                     #endif
106                     #ifdef BOOST_LOCALE_WITH_WCONV
107                     cvt.reset(new wconv_from_utf<CharType>());
108                     if(cvt->open(charset,how))
109                         return cvt->convert(begin,end);
110                     #endif
111                     throw invalid_charset_error(charset);
112                 }
113 
normalize_encoding(char const * ccharset)114                 std::string normalize_encoding(char const *ccharset)
115                 {
116                     std::string charset;
117                     charset.reserve(std::strlen(ccharset));
118                     while(*ccharset!=0) {
119                         char c=*ccharset++;
120                         if('0' <= c && c<= '9')
121                             charset+=c;
122                         else if('a' <=c && c <='z')
123                             charset+=c;
124                         else if('A' <=c && c <='Z')
125                             charset+=char(c-'A'+'a');
126                     }
127                     return charset;
128                 }
129 
130 
131             } // impl
132 
133             using namespace impl;
134 
between(char const * begin,char const * end,std::string const & to_charset,std::string const & from_charset,method_type how)135             std::string between(char const *begin,char const *end,
136                                 std::string const &to_charset,std::string const &from_charset,method_type how)
137             {
138                 return convert_between(begin,end,to_charset.c_str(),from_charset.c_str(),how);
139             }
140 
141             template<>
to_utf(char const * begin,char const * end,std::string const & charset,method_type how)142             std::basic_string<char> to_utf(char const *begin,char const *end,std::string const &charset,method_type how)
143             {
144                 return convert_to<char>(begin,end,charset.c_str(),how);
145             }
146 
147             template<>
from_utf(char const * begin,char const * end,std::string const & charset,method_type how)148             std::string from_utf(char const *begin,char const *end,std::string const &charset,method_type how)
149             {
150                 return convert_from<char>(begin,end,charset.c_str(),how);
151             }
152 
153             template<>
to_utf(char const * begin,char const * end,std::string const & charset,method_type how)154             std::basic_string<wchar_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how)
155             {
156                 return convert_to<wchar_t>(begin,end,charset.c_str(),how);
157             }
158 
159             template<>
from_utf(wchar_t const * begin,wchar_t const * end,std::string const & charset,method_type how)160             std::string from_utf(wchar_t const *begin,wchar_t const *end,std::string const &charset,method_type how)
161             {
162                 return convert_from<wchar_t>(begin,end,charset.c_str(),how);
163             }
164 
165             #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
166             template<>
to_utf(char const * begin,char const * end,std::string const & charset,method_type how)167             std::basic_string<char16_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how)
168             {
169                 return convert_to<char16_t>(begin,end,charset.c_str(),how);
170             }
171 
172             template<>
from_utf(char16_t const * begin,char16_t const * end,std::string const & charset,method_type how)173             std::string from_utf(char16_t const *begin,char16_t const *end,std::string const &charset,method_type how)
174             {
175                 return convert_from<char16_t>(begin,end,charset.c_str(),how);
176             }
177             #endif
178 
179             #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
180             template<>
to_utf(char const * begin,char const * end,std::string const & charset,method_type how)181             std::basic_string<char32_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how)
182             {
183                 return convert_to<char32_t>(begin,end,charset.c_str(),how);
184             }
185 
186             template<>
from_utf(char32_t const * begin,char32_t const * end,std::string const & charset,method_type how)187             std::string from_utf(char32_t const *begin,char32_t const *end,std::string const &charset,method_type how)
188             {
189                 return convert_from<char32_t>(begin,end,charset.c_str(),how);
190             }
191             #endif
192 
193 
194         }
195     }
196 }
197 
198 
199 
200 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
201 
202