]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/system/detail/system_category_message_win32.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / system / detail / system_category_message_win32.hpp
1 #ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_WIN32_HPP_INCLUDED
2 #define BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_WIN32_HPP_INCLUDED
3
4 // Copyright Beman Dawes 2002, 2006
5 // Copyright (c) Microsoft Corporation 2014
6 // Copyright 2018, 2020 Peter Dimov
7 //
8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10 //
11 // See library home page at http://www.boost.org/libs/system
12
13 #include <boost/winapi/error_handling.hpp>
14 #include <boost/winapi/character_code_conversion.hpp>
15 #include <boost/winapi/local_memory.hpp>
16 #include <boost/config.hpp>
17 #include <cstdio>
18
19 //
20
21 namespace boost
22 {
23
24 namespace system
25 {
26
27 namespace detail
28 {
29
30 #if ( defined(_MSC_VER) && _MSC_VER < 1900 ) || ( defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) )
31
32 inline char const * unknown_message_win32( int ev, char * buffer, std::size_t len )
33 {
34 # if defined( BOOST_MSVC )
35 # pragma warning( push )
36 # pragma warning( disable: 4996 )
37 # endif
38
39 _snprintf( buffer, len - 1, "Unknown error (%d)", ev );
40
41 buffer[ len - 1 ] = 0;
42 return buffer;
43
44 # if defined( BOOST_MSVC )
45 # pragma warning( pop )
46 # endif
47 }
48
49 #else
50
51 inline char const * unknown_message_win32( int ev, char * buffer, std::size_t len )
52 {
53 std::snprintf( buffer, len, "Unknown error (%d)", ev );
54 return buffer;
55 }
56
57 #endif
58
59 inline boost::winapi::UINT_ message_cp_win32()
60 {
61 #if defined(BOOST_SYSTEM_USE_UTF8)
62
63 return boost::winapi::CP_UTF8_;
64
65 #else
66
67 return boost::winapi::CP_ACP_;
68
69 #endif
70 }
71
72 inline char const * system_category_message_win32( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
73 {
74 if( len == 0 )
75 {
76 return buffer;
77 }
78
79 if( len == 1 )
80 {
81 buffer[0] = 0;
82 return buffer;
83 }
84
85 boost::winapi::UINT_ const code_page = message_cp_win32();
86
87 int r = 0;
88
89 #if !defined(BOOST_NO_ANSI_APIS)
90
91 if( code_page == boost::winapi::CP_ACP_ )
92 {
93 using namespace boost::winapi;
94
95 DWORD_ retval = boost::winapi::FormatMessageA(
96 FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
97 NULL,
98 ev,
99 MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language
100 buffer,
101 static_cast<DWORD_>( len ),
102 NULL
103 );
104
105 r = static_cast<int>( retval );
106 }
107 else
108
109 #endif
110
111 {
112 using namespace boost::winapi;
113
114 wchar_t * lpMsgBuf = 0;
115
116 DWORD_ retval = boost::winapi::FormatMessageW(
117 FORMAT_MESSAGE_ALLOCATE_BUFFER_ | FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
118 NULL,
119 ev,
120 MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language
121 (LPWSTR_) &lpMsgBuf,
122 0,
123 NULL
124 );
125
126 if( retval != 0 )
127 {
128 r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, buffer, static_cast<int>( len ), NULL, NULL );
129 boost::winapi::LocalFree( lpMsgBuf );
130 if ( r != 0 ) --r; // exclude null terminator
131 }
132 }
133
134 if( r == 0 )
135 {
136 return unknown_message_win32( ev, buffer, len );
137 }
138
139 while( r > 0 && ( buffer[ r-1 ] == '\n' || buffer[ r-1 ] == '\r' ) )
140 {
141 buffer[ --r ] = 0;
142 }
143
144 if( r > 0 && buffer[ r-1 ] == '.' )
145 {
146 buffer[ --r ] = 0;
147 }
148
149 return buffer;
150 }
151
152 struct local_free
153 {
154 void * p_;
155
156 ~local_free()
157 {
158 boost::winapi::LocalFree( p_ );
159 }
160 };
161
162 inline std::string unknown_message_win32( int ev )
163 {
164 char buffer[ 38 ];
165 return unknown_message_win32( ev, buffer, sizeof( buffer ) );
166 }
167
168 inline std::string system_category_message_win32( int ev )
169 {
170 using namespace boost::winapi;
171
172 wchar_t * lpMsgBuf = 0;
173
174 DWORD_ retval = boost::winapi::FormatMessageW(
175 FORMAT_MESSAGE_ALLOCATE_BUFFER_ | FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
176 NULL,
177 ev,
178 MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language
179 (LPWSTR_) &lpMsgBuf,
180 0,
181 NULL
182 );
183
184 if( retval == 0 )
185 {
186 return unknown_message_win32( ev );
187 }
188
189 local_free lf_ = { lpMsgBuf };
190 (void)lf_;
191
192 UINT_ const code_page = message_cp_win32();
193
194 int r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, 0, 0, NULL, NULL );
195
196 if( r == 0 )
197 {
198 return unknown_message_win32( ev );
199 }
200
201 std::string buffer( r, char() );
202
203 r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, &buffer[0], r, NULL, NULL );
204
205 if( r == 0 )
206 {
207 return unknown_message_win32( ev );
208 }
209
210 --r; // exclude null terminator
211
212 while( r > 0 && ( buffer[ r-1 ] == '\n' || buffer[ r-1 ] == '\r' ) )
213 {
214 --r;
215 }
216
217 if( r > 0 && buffer[ r-1 ] == '.' )
218 {
219 --r;
220 }
221
222 buffer.resize( r );
223
224 return buffer;
225 }
226
227 } // namespace detail
228
229 } // namespace system
230
231 } // namespace boost
232
233 #endif // #ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_WIN32_HPP_INCLUDED