1//
2// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
3//
4// Distributed under the Boost Software License, Version 1.0.
5// https://www.boost.org/LICENSE_1_0.txt
6
7#ifndef BOOST_LOCALE_ICONV_FIXER_HPP
8#define BOOST_LOCALE_ICONV_FIXER_HPP
9
10#include <boost/core/exchange.hpp>
11#include <iconv.h>
12
13namespace boost { namespace locale {
14 class iconv_handle {
15 iconv_t h_;
16 void close()
17 {
18 if(*this)
19 iconv_close(cd: h_);
20 }
21
22 public:
23 explicit iconv_handle(iconv_t h = iconv_t(-1)) : h_(h) {}
24
25 iconv_handle(const iconv_handle& rhs) = delete;
26 iconv_handle(iconv_handle&& rhs) noexcept : h_(exchange(t&: rhs.h_, u: iconv_t(-1))) {}
27
28 iconv_handle& operator=(const iconv_handle& rhs) = delete;
29 iconv_handle& operator=(iconv_handle&& rhs) noexcept
30 {
31 h_ = exchange(t&: rhs.h_, u: iconv_t(-1));
32 return *this;
33 }
34 iconv_handle& operator=(iconv_t h)
35 {
36 close();
37 h_ = h;
38 return *this;
39 }
40 ~iconv_handle() { close(); }
41
42 operator iconv_t() const { return h_; }
43 explicit operator bool() const { return h_ != iconv_t(-1); }
44 };
45
46 extern "C" {
47#if defined(__ICONV_F_HIDE_INVALID) && defined(__FreeBSD__)
48# define BOOST_LOCALE_ICONV_FUNC __iconv
49# define BOOST_LOCALE_ICONV_FLAGS , __ICONV_F_HIDE_INVALID, 0
50
51 // GNU variant
52 typedef size_t (*const_iconv_ptr_type)(iconv_t, const char**, size_t*, char**, size_t*, uint32_t, size_t*);
53 // POSIX variant
54 typedef size_t (*nonconst_iconv_ptr_type)(iconv_t, char**, size_t*, char**, size_t*, uint32_t, size_t*);
55#else
56# define BOOST_LOCALE_ICONV_FUNC iconv
57# define BOOST_LOCALE_ICONV_FLAGS
58
59 typedef size_t (*const_iconv_ptr_type)(iconv_t, const char**, size_t*, char**, size_t*);
60 typedef size_t (*nonconst_iconv_ptr_type)(iconv_t, char**, size_t*, char**, size_t*);
61#endif
62 }
63
64 inline size_t
65 call_iconv_impl(const_iconv_ptr_type ptr, iconv_t d, const char** in, size_t* insize, char** out, size_t* outsize)
66 {
67 return ptr(d, in, insize, out, outsize BOOST_LOCALE_ICONV_FLAGS);
68 }
69 inline size_t call_iconv_impl(nonconst_iconv_ptr_type ptr,
70 iconv_t d,
71 const char** in,
72 size_t* insize,
73 char** out,
74 size_t* outsize)
75 {
76 return ptr(d, const_cast<char**>(in), insize, out, outsize BOOST_LOCALE_ICONV_FLAGS);
77 }
78
79 inline size_t call_iconv(iconv_t d, const char** in, size_t* insize, char** out, size_t* outsize)
80 {
81 return call_iconv_impl(BOOST_LOCALE_ICONV_FUNC, d, in, insize, out, outsize);
82 }
83
84 // Convenience overload when the adjusted in/out ptrs are not required
85 inline size_t call_iconv(iconv_t d, const char* in, size_t* insize, char* out, size_t* outsize)
86 {
87 return call_iconv(d, in: &in, insize, out: &out, outsize);
88 }
89 // Disambiguation
90 inline size_t call_iconv(iconv_t d, std::nullptr_t, std::nullptr_t, std::nullptr_t, std::nullptr_t)
91 {
92 return call_iconv_impl(BOOST_LOCALE_ICONV_FUNC, d, in: nullptr, insize: nullptr, out: nullptr, outsize: nullptr);
93 }
94}} // namespace boost::locale
95
96#endif
97

source code of boost/libs/locale/src/boost/locale/util/iconv.hpp