Coverage Report

Created: 2026-06-30 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boost/libs/program_options/src/convert.cpp
Line
Count
Source
1
// Copyright Vladimir Prus 2004.
2
// Distributed under the Boost Software License, Version 1.0.
3
// (See accompanying file LICENSE_1_0.txt
4
// or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6
#include <fstream>
7
#include <locale.h>
8
#include <locale>
9
#include <iostream>
10
#include <string>
11
#include <locale>
12
#include <stdexcept>
13
14
#include <boost/config.hpp>
15
16
#ifndef BOOST_PROGRAM_OPTIONS_SOURCE
17
# define BOOST_PROGRAM_OPTIONS_SOURCE
18
#endif
19
#include <boost/program_options/config.hpp>
20
#include <boost/program_options/detail/convert.hpp>
21
#include <boost/program_options/detail/utf8_codecvt_facet.hpp>
22
#include <boost/throw_exception.hpp>
23
24
#include <boost/bind/bind.hpp>
25
26
using namespace std;
27
using namespace boost::placeholders;
28
29
namespace boost { namespace detail {
30
31
    /* Internal function to actually perform conversion.
32
       The logic in from_8_bit and to_8_bit function is exactly
33
       the same, except that one calls 'in' method of codecvt and another
34
       calls the 'out' method, and that syntax difference makes straightforward
35
       template implementation impossible.
36
37
       This functions takes a 'fun' argument, which should have the same 
38
       parameters and return type and the in/out methods. The actual converting
39
       function will pass functional objects created with boost::bind.
40
       Experiments show that the performance loss is less than 10%.
41
    */
42
    template<class ToChar, class FromChar, class Fun>
43
    std::basic_string<ToChar>
44
    convert(const std::basic_string<FromChar>& s, Fun fun)
45
        
46
0
    {
47
0
        std::basic_string<ToChar> result;
48
        
49
0
        std::mbstate_t state = std::mbstate_t();
50
51
0
        const FromChar* from = s.data();
52
0
        const FromChar* from_end = s.data() + s.size();
53
        // The interface of cvt is not really iterator-like, and it's
54
        // not possible the tell the required output size without the conversion.
55
        // All we can is convert data by pieces.
56
0
        while(from != from_end) {
57
            
58
            // std::basic_string does not provide non-const pointers to the data,
59
            // so converting directly into string is not possible.
60
0
            ToChar buffer[32];
61
            
62
0
            ToChar* to_next = buffer;
63
            // Need variable because boost::bind doesn't work with rvalues.
64
0
            ToChar* to_end = buffer + 32;
65
0
            std::codecvt_base::result r = 
66
0
                fun(state, from, from_end, from, buffer, to_end, to_next);
67
            
68
0
            if (r == std::codecvt_base::error)
69
0
                boost::throw_exception(
70
0
                    std::logic_error("character conversion failed"));
71
            // 'partial' is not an error, it just means not all source
72
            // characters were converted. However, we need to check that at
73
            // least one new target character was produced. If not, it means
74
            // the source data is incomplete, and since we don't have extra
75
            // data to add to source, it's error.
76
0
            if (to_next == buffer)
77
0
                boost::throw_exception(
78
0
                    std::logic_error("character conversion failed"));
79
            
80
            // Add converted characters
81
0
            result.append(buffer, to_next);
82
0
        }
83
        
84
0
        return result;        
85
0
    }           
Unexecuted instantiation: std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > boost::detail::convert<wchar_t, char, boost::_bi::bind_t<boost::_bi::unspecified, boost::_mfi::mf<std::__1::codecvt_base::result (std::__1::codecvt<wchar_t, char, __mbstate_t>::*)(__mbstate_t&, char const*, char const*, char const*&, wchar_t*, wchar_t*, wchar_t*&) const, std::__1::codecvt_base::result, std::__1::codecvt<wchar_t, char, __mbstate_t>, __mbstate_t&, char const*, char const*, char const*&, wchar_t*, wchar_t*, wchar_t*&>, boost::_bi::list<boost::_bi::value<std::__1::codecvt<wchar_t, char, __mbstate_t> const*>, boost::arg<1>, boost::arg<2>, boost::arg<3>, boost::arg<4>, boost::arg<5>, boost::arg<6>, boost::arg<7> > > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, boost::_bi::bind_t<boost::_bi::unspecified, boost::_mfi::mf<std::__1::codecvt_base::result (std::__1::codecvt<wchar_t, char, __mbstate_t>::*)(__mbstate_t&, char const*, char const*, char const*&, wchar_t*, wchar_t*, wchar_t*&) const, std::__1::codecvt_base::result, std::__1::codecvt<wchar_t, char, __mbstate_t>, __mbstate_t&, char const*, char const*, char const*&, wchar_t*, wchar_t*, wchar_t*&>, boost::_bi::list<boost::_bi::value<std::__1::codecvt<wchar_t, char, __mbstate_t> const*>, boost::arg<1>, boost::arg<2>, boost::arg<3>, boost::arg<4>, boost::arg<5>, boost::arg<6>, boost::arg<7> > >)
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > boost::detail::convert<char, wchar_t, boost::_bi::bind_t<boost::_bi::unspecified, boost::_mfi::mf<std::__1::codecvt_base::result (std::__1::codecvt<wchar_t, char, __mbstate_t>::*)(__mbstate_t&, wchar_t const*, wchar_t const*, wchar_t const*&, char*, char*, char*&) const, std::__1::codecvt_base::result, std::__1::codecvt<wchar_t, char, __mbstate_t>, __mbstate_t&, wchar_t const*, wchar_t const*, wchar_t const*&, char*, char*, char*&>, boost::_bi::list<boost::_bi::value<std::__1::codecvt<wchar_t, char, __mbstate_t> const*>, boost::arg<1>, boost::arg<2>, boost::arg<3>, boost::arg<4>, boost::arg<5>, boost::arg<6>, boost::arg<7> > > >(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, boost::_bi::bind_t<boost::_bi::unspecified, boost::_mfi::mf<std::__1::codecvt_base::result (std::__1::codecvt<wchar_t, char, __mbstate_t>::*)(__mbstate_t&, wchar_t const*, wchar_t const*, wchar_t const*&, char*, char*, char*&) const, std::__1::codecvt_base::result, std::__1::codecvt<wchar_t, char, __mbstate_t>, __mbstate_t&, wchar_t const*, wchar_t const*, wchar_t const*&, char*, char*, char*&>, boost::_bi::list<boost::_bi::value<std::__1::codecvt<wchar_t, char, __mbstate_t> const*>, boost::arg<1>, boost::arg<2>, boost::arg<3>, boost::arg<4>, boost::arg<5>, boost::arg<6>, boost::arg<7> > >)
86
}}
87
88
namespace boost {
89
90
#ifndef BOOST_NO_STD_WSTRING
91
    BOOST_PROGRAM_OPTIONS_DECL std::wstring 
92
    from_8_bit(const std::string& s, 
93
               const std::codecvt<wchar_t, char, std::mbstate_t>& cvt)
94
0
    {
95
0
        return detail::convert<wchar_t>(
96
0
            s,                 
97
0
            boost::bind(&std::codecvt<wchar_t, char, mbstate_t>::in,
98
0
                        &cvt,
99
0
                        _1, _2, _3, _4, _5, _6, _7));
100
0
    }
101
102
    BOOST_PROGRAM_OPTIONS_DECL std::string 
103
    to_8_bit(const std::wstring& s, 
104
             const std::codecvt<wchar_t, char, std::mbstate_t>& cvt)
105
0
    {
106
0
        return detail::convert<char>(
107
0
            s,                 
108
0
            boost::bind(&codecvt<wchar_t, char, mbstate_t>::out,
109
0
                        &cvt,
110
0
                        _1, _2, _3, _4, _5, _6, _7));
111
0
    }
112
113
114
    namespace {
115
        boost::program_options::detail::utf8_codecvt_facet
116
            utf8_facet;
117
    }
118
    
119
    BOOST_PROGRAM_OPTIONS_DECL std::wstring
120
    from_utf8(const std::string& s)
121
0
    {
122
0
        return from_8_bit(s, utf8_facet);
123
0
    }
124
    
125
    BOOST_PROGRAM_OPTIONS_DECL std::string
126
    to_utf8(const std::wstring& s)
127
0
    {
128
0
        return to_8_bit(s, utf8_facet);
129
0
    }
130
131
    BOOST_PROGRAM_OPTIONS_DECL std::wstring
132
    from_local_8_bit(const std::string& s)
133
0
    {
134
0
        typedef codecvt<wchar_t, char, mbstate_t> facet_type;
135
0
        return from_8_bit(s, 
136
0
                          BOOST_USE_FACET(facet_type, locale()));
137
0
    }
138
139
    BOOST_PROGRAM_OPTIONS_DECL std::string
140
    to_local_8_bit(const std::wstring& s)
141
0
    {
142
0
        typedef codecvt<wchar_t, char, mbstate_t> facet_type;
143
0
        return to_8_bit(s, 
144
0
                        BOOST_USE_FACET(facet_type, locale()));                        
145
0
    }
146
#endif
147
148
    namespace program_options
149
    {
150
        BOOST_PROGRAM_OPTIONS_DECL std::string to_internal(const std::string& s)
151
1.58M
        {
152
1.58M
            return s;
153
1.58M
        }
154
155
#ifndef BOOST_NO_STD_WSTRING
156
        BOOST_PROGRAM_OPTIONS_DECL std::string to_internal(const std::wstring& s)
157
0
        {
158
0
            return to_utf8(s);
159
0
        }
160
#endif
161
    }
162
163
164
}