• 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 #include <locale>
10 #include <string>
11 #include <ios>
12 #include <boost/locale/encoding.hpp>
13 #include "all_generator.hpp"
14 
15 namespace boost {
16 namespace locale {
17 namespace impl_std {
18 
19 class utf8_collator_from_wide : public std::collate<char> {
20 public:
21     typedef std::collate<wchar_t> wfacet;
utf8_collator_from_wide(std::locale const & base,size_t refs=0)22     utf8_collator_from_wide(std::locale const &base,size_t refs = 0) :
23         std::collate<char>(refs),
24         base_(base)
25     {
26     }
do_compare(char const * lb,char const * le,char const * rb,char const * re) const27     virtual int do_compare(char const *lb,char const *le,char const *rb,char const *re) const
28     {
29         std::wstring l=conv::to_utf<wchar_t>(lb,le,"UTF-8");
30         std::wstring r=conv::to_utf<wchar_t>(rb,re,"UTF-8");
31         return std::use_facet<wfacet>(base_).compare(   l.c_str(),l.c_str()+l.size(),
32                                                         r.c_str(),r.c_str()+r.size());
33     }
do_hash(char const * b,char const * e) const34     virtual long do_hash(char const *b,char const *e) const
35     {
36         std::wstring tmp=conv::to_utf<wchar_t>(b,e,"UTF-8");
37         return std::use_facet<wfacet>(base_).hash(tmp.c_str(),tmp.c_str()+tmp.size());
38     }
do_transform(char const * b,char const * e) const39     virtual std::string do_transform(char const *b,char const *e) const
40     {
41         std::wstring tmp=conv::to_utf<wchar_t>(b,e,"UTF-8");
42         std::wstring wkey =
43             std::use_facet<wfacet>(base_).transform(tmp.c_str(),tmp.c_str()+tmp.size());
44         std::string key;
45         if(sizeof(wchar_t)==2)
46             key.reserve(wkey.size()*2);
47         else
48             key.reserve(wkey.size()*3);
49         for(unsigned i=0;i<wkey.size();i++) {
50             if(sizeof(wchar_t)==2) {
51                 uint16_t tv = static_cast<uint16_t>(wkey[i]);
52                 key += char(tv >> 8);
53                 key += char(tv & 0xFF);
54             }
55             else { // 4
56                 uint32_t tv = static_cast<uint32_t>(wkey[i]);
57                 // 21 bit
58                 key += char((tv >> 16) & 0xFF);
59                 key += char((tv >> 8) & 0xFF);
60                 key += char(tv & 0xFF);
61             }
62         }
63         return key;
64     }
65 private:
66     std::locale base_;
67 };
68 
create_collate(std::locale const & in,std::string const & locale_name,character_facet_type type,utf8_support utf)69 std::locale create_collate( std::locale const &in,
70                             std::string const &locale_name,
71                             character_facet_type type,
72                             utf8_support utf)
73 {
74     switch(type) {
75     case char_facet:
76         {
77             if(utf == utf8_from_wide) {
78                 std::locale base=
79                     std::locale(std::locale::classic(),
80                                 new std::collate_byname<wchar_t>(locale_name.c_str()));
81                 return std::locale(in,new utf8_collator_from_wide(base));
82             }
83             else
84             {
85                 return std::locale(in,new std::collate_byname<char>(locale_name.c_str()));
86             }
87         }
88 
89     case wchar_t_facet:
90         return std::locale(in,new std::collate_byname<wchar_t>(locale_name.c_str()));
91 
92     #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
93     case char16_t_facet:
94         return std::locale(in,new std::collate_byname<char16_t>(locale_name.c_str()));
95     #endif
96 
97     #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
98     case char32_t_facet:
99         return std::locale(in,new std::collate_byname<char32_t>(locale_name.c_str()));
100     #endif
101     default:
102         return in;
103     }
104 }
105 
106 
107 } // impl_std
108 } // locale
109 } //boost
110 
111 
112 
113 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
114