diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2022-09-21 20:17:38 +0300 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2022-09-21 20:17:38 +0300 |
commit | e6c9b17192c56494adba359d5e132c431b241191 (patch) | |
tree | 6f2449871a118a0e8919ce842b1174e06cb470ef /contrib/restricted/boost/libs/locale/src/win32/collate.cpp | |
parent | 285021ab1aac39e84b269d9bacd4deee69cf63fc (diff) | |
download | ydb-e6c9b17192c56494adba359d5e132c431b241191.tar.gz |
Ydb stable 22-4-2122.4.21
x-stable-origin-commit: e89099581237299a132feafb5b58af59ebd0468a
Diffstat (limited to 'contrib/restricted/boost/libs/locale/src/win32/collate.cpp')
-rw-r--r-- | contrib/restricted/boost/libs/locale/src/win32/collate.cpp | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/contrib/restricted/boost/libs/locale/src/win32/collate.cpp b/contrib/restricted/boost/libs/locale/src/win32/collate.cpp new file mode 100644 index 0000000000..40e8c3d217 --- /dev/null +++ b/contrib/restricted/boost/libs/locale/src/win32/collate.cpp @@ -0,0 +1,127 @@ +// +// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +#define BOOST_LOCALE_SOURCE +#include <locale> +#include <string> +#include <ios> +#include <boost/locale/encoding.hpp> +#include <boost/locale/generator.hpp> +#include "api.hpp" +#include "../shared/mo_hash.hpp" + +namespace boost { +namespace locale { +namespace impl_win { + +class utf8_collator : public collator<char> { +public: + utf8_collator(winlocale lc,size_t refs = 0) : + collator<char>(refs), + lc_(lc) + { + } + virtual int do_compare(collator_base::level_type level,char const *lb,char const *le,char const *rb,char const *re) const + { + std::wstring l=conv::to_utf<wchar_t>(lb,le,"UTF-8"); + std::wstring r=conv::to_utf<wchar_t>(rb,re,"UTF-8"); + return wcscoll_l(level,l.c_str(),l.c_str()+l.size(),r.c_str(),r.c_str()+r.size(),lc_); + } + virtual long do_hash(collator_base::level_type level,char const *b,char const *e) const + { + std::string key = do_transform(level,b,e); + return gnu_gettext::pj_winberger_hash_function(key.c_str(),key.c_str() + key.size()); + } + virtual std::string do_transform(collator_base::level_type level,char const *b,char const *e) const + { + std::wstring tmp=conv::to_utf<wchar_t>(b,e,"UTF-8"); + std::wstring wkey = wcsxfrm_l(level,tmp.c_str(),tmp.c_str()+tmp.size(),lc_); + std::string key; + if(sizeof(wchar_t)==2) + key.reserve(wkey.size()*2); + else + key.reserve(wkey.size()*3); + for(unsigned i=0;i<wkey.size();i++) { + if(sizeof(wchar_t)==2) { + uint16_t tv = static_cast<uint16_t>(wkey[i]); + key += char(tv >> 8); + key += char(tv & 0xFF); + } + else { // 4 + uint32_t tv = static_cast<uint32_t>(wkey[i]); + // 21 bit + key += char((tv >> 16) & 0xFF); + key += char((tv >> 8) & 0xFF); + key += char(tv & 0xFF); + } + } + return key; + } +private: + winlocale lc_; +}; + + +class utf16_collator : public collator<wchar_t> { +public: + typedef std::collate<wchar_t> wfacet; + utf16_collator(winlocale lc,size_t refs = 0) : + collator<wchar_t>(refs), + lc_(lc) + { + } + virtual int do_compare(collator_base::level_type level,wchar_t const *lb,wchar_t const *le,wchar_t const *rb,wchar_t const *re) const + { + return wcscoll_l(level,lb,le,rb,re,lc_); + } + virtual long do_hash(collator_base::level_type level,wchar_t const *b,wchar_t const *e) const + { + std::wstring key = do_transform(level,b,e); + char const *begin = reinterpret_cast<char const *>(key.c_str()); + char const *end = begin + key.size()*sizeof(wchar_t); + return gnu_gettext::pj_winberger_hash_function(begin,end); + } + virtual std::wstring do_transform(collator_base::level_type level,wchar_t const *b,wchar_t const *e) const + { + return wcsxfrm_l(level,b,e,lc_); + } +private: + winlocale lc_; +}; + + +std::locale create_collate( std::locale const &in, + winlocale const &lc, + character_facet_type type) +{ + if(lc.is_c()) { + switch(type) { + case char_facet: + return std::locale(in,new std::collate_byname<char>("C")); + case wchar_t_facet: + return std::locale(in,new std::collate_byname<wchar_t>("C")); + } + } + else { + switch(type) { + case char_facet: + return std::locale(in,new utf8_collator(lc)); + case wchar_t_facet: + return std::locale(in,new utf16_collator(lc)); + } + } + return in; +} + + +} // impl_std +} // locale +} //boost + + + +// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 |