• 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 #if defined(__FreeBSD__)
10 #include <xlocale.h>
11 #endif
12 #include <locale>
13 #include <locale.h>
14 #include <string.h>
15 #include <wchar.h>
16 #include <string>
17 #include <stdexcept>
18 #include <ios>
19 #include <vector>
20 #include <boost/locale/generator.hpp>
21 #include "../shared/mo_hash.hpp"
22 
23 #include "all_generator.hpp"
24 
25 namespace boost {
26 namespace locale {
27 namespace impl_posix {
28 
29 template<typename CharType>
30 struct coll_traits;
31 
32 template<>
33 struct coll_traits<char> {
xfrmboost::locale::impl_posix::coll_traits34     static size_t xfrm(char *out,char const *in,size_t n,locale_t l)
35     {
36         return strxfrm_l(out,in,n,l);
37     }
collboost::locale::impl_posix::coll_traits38     static size_t coll(char const *left,char const *right,locale_t l)
39     {
40         return strcoll_l(left,right,l);
41     }
42 };
43 
44 template<>
45 struct coll_traits<wchar_t> {
xfrmboost::locale::impl_posix::coll_traits46     static size_t xfrm(wchar_t *out,wchar_t const *in,size_t n,locale_t l)
47     {
48         return wcsxfrm_l(out,in,n,l);
49     }
collboost::locale::impl_posix::coll_traits50     static size_t coll(wchar_t const *left,wchar_t const *right,locale_t l)
51     {
52         return wcscoll_l(left,right,l);
53     }
54 };
55 
56 template<typename CharType>
57 class collator : public std::collate<CharType> {
58 public:
59     typedef CharType char_type;
60     typedef std::basic_string<char_type> string_type;
collator(boost::shared_ptr<locale_t> l,size_t refs=0)61     collator(boost::shared_ptr<locale_t> l,size_t refs = 0) :
62         std::collate<CharType>(refs),
63         lc_(l)
64     {
65     }
~collator()66     virtual ~collator()
67     {
68     }
do_compare(char_type const * lb,char_type const * le,char_type const * rb,char_type const * re) const69     virtual int do_compare(char_type const *lb,char_type const *le,char_type const *rb,char_type const *re) const
70     {
71         string_type left(lb,le-lb);
72         string_type right(rb,re-rb);
73         int res = coll_traits<char_type>::coll(left.c_str(),right.c_str(),*lc_);
74         if(res < 0)
75             return -1;
76         if(res > 0)
77             return 1;
78         return 0;
79     }
do_hash(char_type const * b,char_type const * e) const80     virtual long do_hash(char_type const *b,char_type const *e) const
81     {
82         string_type s(do_transform(b,e));
83         char const *begin = reinterpret_cast<char const *>(s.c_str());
84         char const *end = begin + s.size() * sizeof(char_type);
85         return gnu_gettext::pj_winberger_hash_function(begin,end);
86     }
do_transform(char_type const * b,char_type const * e) const87     virtual string_type do_transform(char_type const *b,char_type const *e) const
88     {
89         string_type s(b,e-b);
90         std::vector<char_type> buf((e-b)*2+1);
91         size_t n = coll_traits<char_type>::xfrm(&buf.front(),s.c_str(),buf.size(),*lc_);
92         if(n>buf.size()) {
93             buf.resize(n);
94             coll_traits<char_type>::xfrm(&buf.front(),s.c_str(),n,*lc_);
95         }
96         return string_type(&buf.front(),n);
97     }
98 private:
99     boost::shared_ptr<locale_t> lc_;
100 };
101 
102 
create_collate(std::locale const & in,boost::shared_ptr<locale_t> lc,character_facet_type type)103 std::locale create_collate( std::locale const &in,
104                             boost::shared_ptr<locale_t> lc,
105                             character_facet_type type)
106 {
107     switch(type) {
108     case char_facet:
109         return std::locale(in,new collator<char>(lc));
110     case wchar_t_facet:
111         return std::locale(in,new collator<wchar_t>(lc));
112     default:
113         return in;
114     }
115 }
116 
117 
118 } // impl_std
119 } // locale
120 } //boost
121 
122 
123 
124 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
125