/
zOMGdev
/
cppcms
Обзор
Документация
Войти
/
zOMGdev
/
cppcms
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
booster/lib/locale/src/posix/converter.cpp
165 строк
5 KB
Artyom Beilis
Merge of FreeBSD fixes from Boost.Locale
05 ноя 2015, 11:41
05 ноя 2015, 11:41
8e9a29d
Код
Авторство
О чём код?
// // 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 BOOSTER_SOURCE #if defined(__FreeBSD__) #include <xlocale.h> #endif #include <locale> #include <booster/backtrace.h> #include <booster/locale/generator.h> #include <booster/locale/conversion.h> #include <booster/locale/encoding.h> #include <booster/shared_ptr.h> #include <vector> #include <string.h> #include <wctype.h> #include <ctype.h> #include <langinfo.h> #include "all_generator.h" namespace booster { namespace locale { namespace impl_posix { template<typename CharType> struct case_traits; template<> struct case_traits<char> { static char lower(char c,locale_t lc) { return tolower_l(c,lc); } static char upper(char c,locale_t lc) { return toupper_l(c,lc); } }; template<> struct case_traits<wchar_t> { static wchar_t lower(wchar_t c,locale_t lc) { return towlower_l(c,lc); } static wchar_t upper(wchar_t c,locale_t lc) { return towupper_l(c,lc); } }; template<typename CharType> class std_converter : public converter<CharType> { public: typedef CharType char_type; typedef std::basic_string<char_type> string_type; typedef std::ctype<char_type> ctype_type; std_converter(booster::shared_ptr<locale_t> lc,size_t refs = 0) : converter<CharType>(refs), lc_(lc) { } virtual string_type convert(converter_base::conversion_type how,char_type const *begin,char_type const *end,int /*flags*/ = 0) const { switch(how) { case converter_base::upper_case: { string_type res; res.reserve(end-begin); while(begin!=end) { res+=case_traits<char_type>::upper(*begin++,*lc_); } return res; } case converter_base::lower_case: case converter_base::case_folding: { string_type res; res.reserve(end-begin); while(begin!=end) { res+=case_traits<char_type>::lower(*begin++,*lc_); } return res; } default: return string_type(begin,end-begin); } } private: booster::shared_ptr<locale_t> lc_; }; class utf8_converter : public converter<char> { public: utf8_converter(booster::shared_ptr<locale_t> lc,size_t refs = 0) : converter<char>(refs), lc_(lc) { } virtual std::string convert(converter_base::conversion_type how,char const *begin,char const *end,int /*flags*/ = 0) const { switch(how) { case upper_case: { std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8"); std::wstring wres; wres.reserve(tmp.size()); for(unsigned i=0;i<tmp.size();i++) wres+=towupper_l(tmp[i],*lc_); return conv::from_utf<wchar_t>(wres,"UTF-8"); } case lower_case: case case_folding: { std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8"); std::wstring wres; wres.reserve(tmp.size()); for(unsigned i=0;i<tmp.size();i++) wres+=towlower_l(tmp[i],*lc_); return conv::from_utf<wchar_t>(wres,"UTF-8"); } default: return std::string(begin,end-begin); } } private: booster::shared_ptr<locale_t> lc_; }; std::locale create_convert( std::locale const &in, booster::shared_ptr<locale_t> lc, character_facet_type type) { switch(type) { case char_facet: { std::string encoding = nl_langinfo_l(CODESET,*lc); for(unsigned i=0;i<encoding.size();i++) if('A'<=encoding[i] && encoding[i]<='Z') encoding[i]=encoding[i]-'A'+'a'; if(encoding=="utf-8" || encoding=="utf8" || encoding=="utf_8") { return std::locale(in,new utf8_converter(lc)); } return std::locale(in,new std_converter<char>(lc)); } case wchar_t_facet: return std::locale(in,new std_converter<wchar_t>(lc)); default: return in; } } } // namespace impl_std } // locale } // boost // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4