]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/filesystem/src/path_traits.cpp
import new upstream nautilus stable release 14.2.8
[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 #ifndef BOOST_SYSTEM_NO_DEPRECATED
13 # define BOOST_SYSTEM_NO_DEPRECATED
14 #endif
15
16 #include <boost/filesystem/config.hpp>
17 #include <boost/filesystem/path_traits.hpp>
18 #include <boost/system/system_error.hpp>
19 #include <boost/scoped_array.hpp>
20 #include <locale> // for codecvt_base::result
21 #include <cstring> // for strlen
22 #include <cwchar> // for wcslen
23
24 namespace pt = boost::filesystem::path_traits;
25 namespace fs = boost::filesystem;
26 namespace bs = boost::system;
27
28 //--------------------------------------------------------------------------------------//
29 // configuration //
30 //--------------------------------------------------------------------------------------//
31
32 #ifndef BOOST_FILESYSTEM_CODECVT_BUF_SIZE
33 # define BOOST_FILESYSTEM_CODECVT_BUF_SIZE 256
34 #endif
35
36 namespace {
37
38 const std::size_t default_codecvt_buf_size = BOOST_FILESYSTEM_CODECVT_BUF_SIZE;
39
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 const pt::codecvt_type & 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,
73 to, to_end, to_next)) != std::codecvt_base::ok)
74 {
75 //std::cout << " result is " << static_cast<int>(res) << std::endl;
76 BOOST_FILESYSTEM_THROW(bs::system_error(res, fs::codecvt_error_category(),
77 "boost::filesystem::path codecvt to wstring"));
78 }
79 target.append(to, to_next);
80 }
81
82 //--------------------------------------------------------------------------------------//
83 // convert_aux const wchar_t* to string //
84 //--------------------------------------------------------------------------------------//
85
86 void convert_aux(
87 const wchar_t* from,
88 const wchar_t* from_end,
89 char* to, char* to_end,
90 std::string & target,
91 const pt::codecvt_type & cvt)
92 {
93 //std::cout << std::hex
94 // << " from=" << std::size_t(from)
95 // << " from_end=" << std::size_t(from_end)
96 // << " to=" << std::size_t(to)
97 // << " to_end=" << std::size_t(to_end)
98 // << std::endl;
99
100 std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
101 const wchar_t* from_next;
102 char* to_next;
103
104 std::codecvt_base::result res;
105
106 if ((res=cvt.out(state, from, from_end, from_next,
107 to, to_end, to_next)) != std::codecvt_base::ok)
108 {
109 //std::cout << " result is " << static_cast<int>(res) << std::endl;
110 BOOST_FILESYSTEM_THROW(bs::system_error(res, fs::codecvt_error_category(),
111 "boost::filesystem::path codecvt to string"));
112 }
113 target.append(to, to_next);
114 }
115
116 } // unnamed namespace
117
118 //--------------------------------------------------------------------------------------//
119 // path_traits //
120 //--------------------------------------------------------------------------------------//
121
122 namespace boost { namespace filesystem { namespace path_traits {
123
124 //--------------------------------------------------------------------------------------//
125 // convert const char* to wstring //
126 //--------------------------------------------------------------------------------------//
127
128 BOOST_FILESYSTEM_DECL
129 void convert(const char* from,
130 const char* from_end, // 0 for null terminated MBCS
131 std::wstring & to,
132 const codecvt_type & cvt)
133 {
134 BOOST_ASSERT(from);
135
136 if (!from_end) // null terminated
137 {
138 from_end = from + std::strlen(from);
139 }
140
141 if (from == from_end) return;
142
143 std::size_t buf_size = (from_end - from) * 3; // perhaps too large, but that's OK
144
145 // dynamically allocate a buffer only if source is unusually large
146 if (buf_size > default_codecvt_buf_size)
147 {
148 boost::scoped_array< wchar_t > buf(new wchar_t [buf_size]);
149 convert_aux(from, from_end, buf.get(), buf.get()+buf_size, to, cvt);
150 }
151 else
152 {
153 wchar_t buf[default_codecvt_buf_size];
154 convert_aux(from, from_end, buf, buf+default_codecvt_buf_size, to, cvt);
155 }
156 }
157
158 //--------------------------------------------------------------------------------------//
159 // convert const wchar_t* to string //
160 //--------------------------------------------------------------------------------------//
161
162 BOOST_FILESYSTEM_DECL
163 void convert(const wchar_t* from,
164 const wchar_t* from_end, // 0 for null terminated MBCS
165 std::string & to,
166 const codecvt_type & cvt)
167 {
168 BOOST_ASSERT(from);
169
170 if (!from_end) // null terminated
171 {
172 from_end = from + std::wcslen(from);
173 }
174
175 if (from == from_end) return;
176
177 // The codecvt length functions may not be implemented, and I don't really
178 // understand them either. Thus this code is just a guess; if it turns
179 // out the buffer is too small then an error will be reported and the code
180 // will have to be fixed.
181 std::size_t buf_size = (from_end - from) * 4; // perhaps too large, but that's OK
182 buf_size += 4; // encodings like shift-JIS need some prefix space
183
184 // dynamically allocate a buffer only if source is unusually large
185 if (buf_size > default_codecvt_buf_size)
186 {
187 boost::scoped_array< char > buf(new char [buf_size]);
188 convert_aux(from, from_end, buf.get(), buf.get()+buf_size, to, cvt);
189 }
190 else
191 {
192 char buf[default_codecvt_buf_size];
193 convert_aux(from, from_end, buf, buf+default_codecvt_buf_size, to, cvt);
194 }
195 }
196 }}} // namespace boost::filesystem::path_traits