/
zOMGdev
/
cppcms
Обзор
Документация
Войти
/
zOMGdev
/
cppcms
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
booster/lib/locale/src/icu/codecvt.cpp
158 строк
4 KB
Artyom Beilis
Switch from booster::shared_ptr/weak_ptr to std::ones
11 авг 2020, 22:57
11 авг 2020, 22:57
dfc88bd
Код
Авторство
О чём код?
// // 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 #include <booster/locale/encoding.h> #include <booster/locale/encoding_errors.h> #include "../encoding/conv.h" #include "all_generator.h" #include "uconv.h" #include <unicode/ucnv.h> #include <unicode/ucnv_err.h> #include <booster/locale/util.h> #include "codecvt.h" #ifdef BOOSTER_MSVC # pragma warning(disable : 4244) // loose data #endif #include "icu_util.h" #include <vector> namespace booster { namespace locale { namespace impl_icu { class uconv_converter : public util::base_converter { public: uconv_converter(std::string const &encoding) : encoding_(encoding) { UErrorCode err=U_ZERO_ERROR; // No need to check err each time, this // is how ICU works. cvt_ = ucnv_open(encoding.c_str(),&err); ucnv_setFromUCallBack(cvt_,UCNV_FROM_U_CALLBACK_STOP,0,0,0,&err); ucnv_setToUCallBack(cvt_,UCNV_TO_U_CALLBACK_STOP,0,0,0,&err); if(!cvt_ || U_FAILURE(err)) { if(cvt_) ucnv_close(cvt_); throw conv::invalid_charset_error(encoding); } max_len_ = ucnv_getMaxCharSize(cvt_); } virtual ~uconv_converter() { ucnv_close(cvt_); } virtual bool is_thread_safe() const { return false; } virtual uconv_converter *clone() const { return new uconv_converter(encoding_); } uint32_t to_unicode(char const *&begin,char const *end) { UErrorCode err=U_ZERO_ERROR; char const *tmp = begin; UChar32 c=ucnv_getNextUChar(cvt_,&tmp,end,&err); ucnv_reset(cvt_); if(err == U_TRUNCATED_CHAR_FOUND) { return incomplete; } if(U_FAILURE(err)) { return illegal; } begin = tmp; return c; } uint32_t from_unicode(uint32_t u,char *begin,char const *end) { UChar code_point[2]={0}; int len; if(u<=0xFFFF) { if(0xD800 <=u && u<= 0xDFFF) // No surragates return illegal; code_point[0]=u; len=1; } else { u-=0x10000; code_point[0]=0xD800 | (u>>10); code_point[1]=0xDC00 | (u & 0x3FF); len=2; } UErrorCode err=U_ZERO_ERROR; int olen = ucnv_fromUChars(cvt_,begin,end-begin,code_point,len,&err); ucnv_reset(cvt_); if(err == U_BUFFER_OVERFLOW_ERROR) return incomplete; if(U_FAILURE(err)) return illegal; return olen; } virtual int max_len() const { return max_len_; } private: std::string encoding_; UConverter *cvt_; int max_len_; }; std::unique_ptr<util::base_converter> create_uconv_converter(std::string const &encoding) { std::unique_ptr<util::base_converter> cvt; try { cvt.reset(new uconv_converter(encoding)); } catch(std::exception const &/*e*/) { // no encoding so we return empty pointer } return cvt; } std::locale create_codecvt(std::locale const &in,std::string const &encoding,character_facet_type type) { if(conv::impl::normalize_encoding(encoding.c_str())=="utf8") return util::create_utf8_codecvt(in,type); try { return util::create_simple_codecvt(in,encoding,type); } catch(booster::locale::conv::invalid_charset_error const &) { std::unique_ptr<util::base_converter> cvt; try { cvt = create_uconv_converter(encoding); } catch(std::exception const &/*e*/) { cvt.reset(new util::base_converter()); } return util::create_codecvt(in,std::move(cvt),type); } } } // impl_icu } // locale } // boost // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4