]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/filesystem/src/path_traits.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / filesystem / src / path_traits.cpp
CommitLineData
7c673cae
FG
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
20effc67 12#include "platform_config.hpp"
7c673cae 13
1e59de90 14#include <boost/filesystem/config.hpp>
7c673cae
FG
15#include <boost/filesystem/path_traits.hpp>
16#include <boost/system/system_error.hpp>
1e59de90
TL
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>
7c673cae
FG
24
25namespace pt = boost::filesystem::path_traits;
26namespace fs = boost::filesystem;
27namespace bs = boost::system;
28
29//--------------------------------------------------------------------------------------//
30// configuration //
31//--------------------------------------------------------------------------------------//
32
33#ifndef BOOST_FILESYSTEM_CODECVT_BUF_SIZE
1e59de90 34#define BOOST_FILESYSTEM_CODECVT_BUF_SIZE 256
7c673cae
FG
35#endif
36
37namespace {
38
1e59de90 39BOOST_CONSTEXPR_OR_CONST std::size_t default_codecvt_buf_size = BOOST_FILESYSTEM_CODECVT_BUF_SIZE;
7c673cae
FG
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
1e59de90
TL
52void 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{
7c673cae
FG
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
1e59de90 66 std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
7c673cae
FG
67 const char* from_next;
68 wchar_t* to_next;
69
70 std::codecvt_base::result res;
71
1e59de90 72 if ((res = cvt.in(state, from, from_end, from_next, to, to_end, to_next)) != std::codecvt_base::ok)
7c673cae 73 {
1e59de90
TL
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"));
7c673cae 76 }
92f5a8d4 77 target.append(to, to_next);
1e59de90 78}
7c673cae
FG
79
80//--------------------------------------------------------------------------------------//
81// convert_aux const wchar_t* to string //
82//--------------------------------------------------------------------------------------//
83
1e59de90
TL
84void 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{
7c673cae
FG
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
1e59de90 98 std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
7c673cae
FG
99 const wchar_t* from_next;
100 char* to_next;
101
102 std::codecvt_base::result res;
103
1e59de90 104 if ((res = cvt.out(state, from, from_end, from_next, to, to_end, to_next)) != std::codecvt_base::ok)
7c673cae 105 {
1e59de90
TL
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"));
7c673cae 108 }
92f5a8d4 109 target.append(to, to_next);
1e59de90 110}
92f5a8d4 111
1e59de90 112} // unnamed namespace
7c673cae
FG
113
114//--------------------------------------------------------------------------------------//
115// path_traits //
116//--------------------------------------------------------------------------------------//
117
1e59de90
TL
118namespace boost {
119namespace filesystem {
120namespace path_traits {
7c673cae
FG
121
122//--------------------------------------------------------------------------------------//
123// convert const char* to wstring //
124//--------------------------------------------------------------------------------------//
125
1e59de90
TL
126BOOST_FILESYSTEM_DECL
127void convert(const char* from,
128 const char* from_end, // 0 for null terminated MBCS
129 std::wstring& to, codecvt_type const& cvt)
130{
7c673cae
FG
131 BOOST_ASSERT(from);
132
1e59de90 133 if (!from_end) // null terminated
7c673cae 134 {
1e59de90 135 from_end = from + std::strlen(from);
7c673cae
FG
136 }
137
1e59de90
TL
138 if (from == from_end)
139 return;
7c673cae 140
1e59de90 141 std::size_t buf_size = (from_end - from) * 3; // perhaps too large, but that's OK
7c673cae
FG
142
143 // dynamically allocate a buffer only if source is unusually large
144 if (buf_size > default_codecvt_buf_size)
145 {
1e59de90
TL
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);
7c673cae
FG
148 }
149 else
150 {
1e59de90
TL
151 wchar_t buf[default_codecvt_buf_size];
152 convert_aux(from, from_end, buf, buf + default_codecvt_buf_size, to, cvt);
7c673cae 153 }
1e59de90 154}
7c673cae
FG
155
156//--------------------------------------------------------------------------------------//
157// convert const wchar_t* to string //
158//--------------------------------------------------------------------------------------//
159
1e59de90
TL
160BOOST_FILESYSTEM_DECL
161void 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{
7c673cae
FG
165 BOOST_ASSERT(from);
166
1e59de90 167 if (!from_end) // null terminated
7c673cae 168 {
1e59de90 169 from_end = from + std::wcslen(from);
7c673cae
FG
170 }
171
1e59de90
TL
172 if (from == from_end)
173 return;
7c673cae
FG
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.
1e59de90
TL
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
7c673cae
FG
181
182 // dynamically allocate a buffer only if source is unusually large
183 if (buf_size > default_codecvt_buf_size)
184 {
1e59de90
TL
185 boost::scoped_array< char > buf(new char[buf_size]);
186 convert_aux(from, from_end, buf.get(), buf.get() + buf_size, to, cvt);
7c673cae
FG
187 }
188 else
189 {
1e59de90
TL
190 char buf[default_codecvt_buf_size];
191 convert_aux(from, from_end, buf, buf + default_codecvt_buf_size, to, cvt);
7c673cae 192 }
1e59de90
TL
193}
194
195} // namespace path_traits
196} // namespace filesystem
197} // namespace boost