]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/filesystem/src/path_traits.cpp
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / boost / libs / filesystem / src / path_traits.cpp
1 // filesystem path_traits.cpp --------------------------------------------------------//
2
3 // Copyright Beman Dawes 2008, 2009
4
5 // Distributed under the Boost Software License, Version 1.0.
6 // See http://www.boost.org/LICENSE_1_0.txt
7
8 // Library home page: http://www.boost.org/libs/filesystem
9
10 //--------------------------------------------------------------------------------------//
11
12 #include "platform_config.hpp"
13
14 #include <boost/filesystem/config.hpp>
15 #include <boost/filesystem/path_traits.hpp>
16 #include <boost/system/system_error.hpp>
17 #include <boost/smart_ptr/scoped_array.hpp>
18 #include <boost/assert.hpp>
19 #include <string>
20 #include <locale> // for codecvt_base::result
21 #include <cstring> // for strlen
22 #include <cwchar> // for wcslen
23 #include <cstddef>
24
25 namespace pt = boost::filesystem::path_traits;
26 namespace fs = boost::filesystem;
27 namespace bs = boost::system;
28
29 //--------------------------------------------------------------------------------------//
30 // configuration //
31 //--------------------------------------------------------------------------------------//
32
33 #ifndef BOOST_FILESYSTEM_CODECVT_BUF_SIZE
34 #define BOOST_FILESYSTEM_CODECVT_BUF_SIZE 256
35 #endif
36
37 namespace {
38
39 BOOST_CONSTEXPR_OR_CONST std::size_t default_codecvt_buf_size = BOOST_FILESYSTEM_CODECVT_BUF_SIZE;
40
41 //--------------------------------------------------------------------------------------//
42 // //
43 // The public convert() functions do buffer management, and then forward to the //
44 // convert_aux() functions for the actual call to the codecvt facet. //
45 // //
46 //--------------------------------------------------------------------------------------//
47
48 //--------------------------------------------------------------------------------------//
49 // convert_aux const char* to wstring //
50 //--------------------------------------------------------------------------------------//
51
52 void convert_aux(
53 const char* from,
54 const char* from_end,
55 wchar_t* to, wchar_t* to_end,
56 std::wstring& target,
57 pt::codecvt_type const& cvt)
58 {
59 //std::cout << std::hex
60 // << " from=" << std::size_t(from)
61 // << " from_end=" << std::size_t(from_end)
62 // << " to=" << std::size_t(to)
63 // << " to_end=" << std::size_t(to_end)
64 // << std::endl;
65
66 std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
67 const char* from_next;
68 wchar_t* to_next;
69
70 std::codecvt_base::result res;
71
72 if ((res = cvt.in(state, from, from_end, from_next, to, to_end, to_next)) != std::codecvt_base::ok)
73 {
74 //std::cout << " result is " << static_cast<int>(res) << std::endl;
75 BOOST_FILESYSTEM_THROW(bs::system_error(res, fs::codecvt_error_category(), "boost::filesystem::path codecvt to wstring"));
76 }
77 target.append(to, to_next);
78 }
79
80 //--------------------------------------------------------------------------------------//
81 // convert_aux const wchar_t* to string //
82 //--------------------------------------------------------------------------------------//
83
84 void convert_aux(
85 const wchar_t* from,
86 const wchar_t* from_end,
87 char* to, char* to_end,
88 std::string& target,
89 pt::codecvt_type const& cvt)
90 {
91 //std::cout << std::hex
92 // << " from=" << std::size_t(from)
93 // << " from_end=" << std::size_t(from_end)
94 // << " to=" << std::size_t(to)
95 // << " to_end=" << std::size_t(to_end)
96 // << std::endl;
97
98 std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
99 const wchar_t* from_next;
100 char* to_next;
101
102 std::codecvt_base::result res;
103
104 if ((res = cvt.out(state, from, from_end, from_next, to, to_end, to_next)) != std::codecvt_base::ok)
105 {
106 //std::cout << " result is " << static_cast<int>(res) << std::endl;
107 BOOST_FILESYSTEM_THROW(bs::system_error(res, fs::codecvt_error_category(), "boost::filesystem::path codecvt to string"));
108 }
109 target.append(to, to_next);
110 }
111
112 } // unnamed namespace
113
114 //--------------------------------------------------------------------------------------//
115 // path_traits //
116 //--------------------------------------------------------------------------------------//
117
118 namespace boost {
119 namespace filesystem {
120 namespace path_traits {
121
122 //--------------------------------------------------------------------------------------//
123 // convert const char* to wstring //
124 //--------------------------------------------------------------------------------------//
125
126 BOOST_FILESYSTEM_DECL
127 void convert(const char* from,
128 const char* from_end, // 0 for null terminated MBCS
129 std::wstring& to, codecvt_type const& cvt)
130 {
131 BOOST_ASSERT(from);
132
133 if (!from_end) // null terminated
134 {
135 from_end = from + std::strlen(from);
136 }
137
138 if (from == from_end)
139 return;
140
141 std::size_t buf_size = (from_end - from) * 3; // perhaps too large, but that's OK
142
143 // dynamically allocate a buffer only if source is unusually large
144 if (buf_size > default_codecvt_buf_size)
145 {
146 boost::scoped_array< wchar_t > buf(new wchar_t[buf_size]);
147 convert_aux(from, from_end, buf.get(), buf.get() + buf_size, to, cvt);
148 }
149 else
150 {
151 wchar_t buf[default_codecvt_buf_size];
152 convert_aux(from, from_end, buf, buf + default_codecvt_buf_size, to, cvt);
153 }
154 }
155
156 //--------------------------------------------------------------------------------------//
157 // convert const wchar_t* to string //
158 //--------------------------------------------------------------------------------------//
159
160 BOOST_FILESYSTEM_DECL
161 void convert(const wchar_t* from,
162 const wchar_t* from_end, // 0 for null terminated MBCS
163 std::string& to, codecvt_type const& cvt)
164 {
165 BOOST_ASSERT(from);
166
167 if (!from_end) // null terminated
168 {
169 from_end = from + std::wcslen(from);
170 }
171
172 if (from == from_end)
173 return;
174
175 // The codecvt length functions may not be implemented, and I don't really
176 // understand them either. Thus this code is just a guess; if it turns
177 // out the buffer is too small then an error will be reported and the code
178 // will have to be fixed.
179 std::size_t buf_size = (from_end - from) * 4; // perhaps too large, but that's OK
180 buf_size += 4; // encodings like shift-JIS need some prefix space
181
182 // dynamically allocate a buffer only if source is unusually large
183 if (buf_size > default_codecvt_buf_size)
184 {
185 boost::scoped_array< char > buf(new char[buf_size]);
186 convert_aux(from, from_end, buf.get(), buf.get() + buf_size, to, cvt);
187 }
188 else
189 {
190 char buf[default_codecvt_buf_size];
191 convert_aux(from, from_end, buf, buf + default_codecvt_buf_size, to, cvt);
192 }
193 }
194
195 } // namespace path_traits
196 } // namespace filesystem
197 } // namespace boost