1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
//
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#ifndef BOOST_LOCALE_IMPL_UCONV_CODEPAGE_HPP
#define BOOST_LOCALE_IMPL_UCONV_CODEPAGE_HPP
#include <boost/locale/encoding.hpp>
#include <boost/locale/hold_ptr.hpp>
#include "../icu/icu_util.hpp"
#include "../icu/uconv.hpp"
#include <unicode/ucnv.h>
#include <unicode/ucnv_err.h>
namespace boost { namespace locale { namespace conv { namespace impl {
template<typename CharType>
class uconv_to_utf final : public detail::utf_encoder<CharType> {
public:
bool open(const std::string& charset, method_type how)
{
try {
using impl_icu::cpcvt_type;
cvt_from_.reset(new from_type(charset, how == skip ? cpcvt_type::skip : cpcvt_type::stop));
cvt_to_.reset(new to_type("UTF-8", how == skip ? cpcvt_type::skip : cpcvt_type::stop));
} catch(const std::exception& /*e*/) {
cvt_from_.reset();
cvt_to_.reset();
return false;
}
return true;
}
std::basic_string<CharType> convert(const char* begin, const char* end) override
{
try {
return cvt_to_->std(cvt_from_->icu_checked(begin, end));
} catch(const std::exception& /*e*/) {
throw conversion_error();
}
}
private:
typedef impl_icu::icu_std_converter<char> from_type;
typedef impl_icu::icu_std_converter<CharType> to_type;
hold_ptr<from_type> cvt_from_;
hold_ptr<to_type> cvt_to_;
};
template<typename CharType>
class uconv_from_utf final : public detail::utf_decoder<CharType> {
public:
bool open(const std::string& charset, method_type how)
{
try {
using impl_icu::cpcvt_type;
cvt_from_.reset(new from_type("UTF-8", how == skip ? cpcvt_type::skip : cpcvt_type::stop));
cvt_to_.reset(new to_type(charset, how == skip ? cpcvt_type::skip : cpcvt_type::stop));
} catch(const std::exception& /*e*/) {
cvt_from_.reset();
cvt_to_.reset();
return false;
}
return true;
}
std::string convert(const CharType* begin, const CharType* end) override
{
try {
return cvt_to_->std(cvt_from_->icu_checked(begin, end));
} catch(const std::exception& /*e*/) {
throw conversion_error();
}
}
private:
typedef impl_icu::icu_std_converter<CharType> from_type;
typedef impl_icu::icu_std_converter<char> to_type;
hold_ptr<from_type> cvt_from_;
hold_ptr<to_type> cvt_to_;
};
class uconv_between final : public detail::narrow_converter {
public:
bool open(const std::string& to_charset, const std::string& from_charset, method_type how)
{
try {
using impl_icu::cpcvt_type;
cvt_from_.reset(new from_type(from_charset, how == skip ? cpcvt_type::skip : cpcvt_type::stop));
cvt_to_.reset(new to_type(to_charset, how == skip ? cpcvt_type::skip : cpcvt_type::stop));
} catch(const std::exception& /*e*/) {
cvt_from_.reset();
cvt_to_.reset();
return false;
}
return true;
}
std::string convert(const char* begin, const char* end) override
{
try {
return cvt_to_->std(cvt_from_->icu(begin, end));
} catch(const std::exception& /*e*/) {
throw conversion_error();
}
}
private:
typedef impl_icu::icu_std_converter<char> from_type;
typedef impl_icu::icu_std_converter<char> to_type;
hold_ptr<from_type> cvt_from_;
hold_ptr<to_type> cvt_to_;
};
}}}} // namespace boost::locale::conv::impl
#endif
|