forked from boostorg/system
Add a noexcept overload of message() taking a buffer
This commit is contained in:
1 parent
a4e700ecf4
commit
ec93d058fe
6 files changed
+310
-83
No files matched your search
@@ -20,45 +20,71 @@ namespace detail
|
||||
|
||||
#if defined(__GLIBC__)
|
||||
|
||||
// std::strerror is not thread-safe on glibc (for no reason)
|
||||
// glibc also has two incompatible strerror_r definitions (for no reason)
|
||||
// glibc has two incompatible strerror_r definitions
|
||||
|
||||
inline char const * strerror_r_helper( char const * r, char const * )
|
||||
inline char const * strerror_r_helper( char const * r, char const * ) BOOST_NOEXCEPT
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
inline char const * strerror_r_helper( int r, char const * buffer )
|
||||
inline char const * strerror_r_helper( int r, char const * buffer ) BOOST_NOEXCEPT
|
||||
{
|
||||
return r == 0? buffer: "Unknown error";
|
||||
}
|
||||
|
||||
inline char const * generic_error_category_message( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
|
||||
{
|
||||
return strerror_r_helper( strerror_r( ev, buffer, len ), buffer );
|
||||
}
|
||||
|
||||
inline std::string generic_error_category_message( int ev )
|
||||
{
|
||||
char buffer[ 128 ];
|
||||
return strerror_r_helper( strerror_r( ev, buffer, sizeof( buffer ) ), buffer );
|
||||
return generic_error_category_message( ev, buffer, sizeof( buffer ) );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// std::strerror is thread-safe on everything else, incl. Windows
|
||||
|
||||
inline std::string generic_error_category_message( int ev )
|
||||
{
|
||||
# if defined( BOOST_MSVC )
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable: 4996 )
|
||||
# endif
|
||||
|
||||
inline std::string generic_error_category_message( int ev )
|
||||
{
|
||||
char const * m = std::strerror( ev );
|
||||
return m? m: "Unknown error";
|
||||
}
|
||||
|
||||
inline char const * generic_error_category_message( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
|
||||
{
|
||||
if( len == 0 )
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
if( len == 1 )
|
||||
{
|
||||
buffer[0] = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char const * m = std::strerror( ev );
|
||||
|
||||
if( m == 0 ) return "Unknown error";
|
||||
|
||||
std::strncpy( buffer, m, len - 1 );
|
||||
buffer[ len-1 ] = 0;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
# if defined( BOOST_MSVC )
|
||||
# pragma warning( pop )
|
||||
# endif
|
||||
|
||||
return m? m: "Unknown error";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -24,66 +24,72 @@ namespace system
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline std::string system_category_message_win32( int ev )
|
||||
inline char const * system_category_message_win32( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
|
||||
{
|
||||
using namespace boost::winapi;
|
||||
|
||||
std::wstring buf( 128, wchar_t() );
|
||||
|
||||
for( ;; )
|
||||
if( len == 0 )
|
||||
{
|
||||
DWORD_ retval = boost::winapi::FormatMessageW(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
|
||||
NULL,
|
||||
ev,
|
||||
MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language
|
||||
&buf[0],
|
||||
static_cast<DWORD_>( buf.size() ),
|
||||
NULL
|
||||
);
|
||||
|
||||
if( retval > 0 )
|
||||
{
|
||||
buf.resize(retval);
|
||||
break;
|
||||
}
|
||||
else if( boost::winapi::GetLastError() != ERROR_INSUFFICIENT_BUFFER_ )
|
||||
{
|
||||
return "Unknown error";
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.resize( buf.size() + buf.size() / 2 );
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int num_chars = static_cast<int>( buf.size() + 1 ) * 2;
|
||||
if( len == 1 )
|
||||
{
|
||||
buffer[0] = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
boost::winapi::LPSTR_ narrow_buffer =
|
||||
#if defined(__GNUC__)
|
||||
(boost::winapi::LPSTR_)__builtin_alloca( num_chars );
|
||||
# define BOOST_SYSTEM_ALLOCA __builtin_alloca
|
||||
#else
|
||||
(boost::winapi::LPSTR_)_alloca( num_chars );
|
||||
# define BOOST_SYSTEM_ALLOCA _alloca
|
||||
#endif
|
||||
|
||||
if( boost::winapi::WideCharToMultiByte( CP_ACP_, 0, buf.c_str(), -1, narrow_buffer, num_chars, NULL, NULL ) == 0 )
|
||||
wchar_t * wbuffer = static_cast<wchar_t*>( BOOST_SYSTEM_ALLOCA( len * sizeof( wchar_t ) ) );
|
||||
|
||||
#undef BOOST_SYSTEM_ALLOCA
|
||||
|
||||
using namespace boost::winapi;
|
||||
|
||||
DWORD_ retval = boost::winapi::FormatMessageW(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
|
||||
NULL,
|
||||
ev,
|
||||
MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language
|
||||
wbuffer,
|
||||
static_cast<DWORD_>( len ),
|
||||
NULL
|
||||
);
|
||||
|
||||
if( retval == 0 )
|
||||
{
|
||||
return "Unknown error";
|
||||
}
|
||||
|
||||
std::string str( narrow_buffer );
|
||||
int r = boost::winapi::WideCharToMultiByte( CP_ACP_, 0, wbuffer, -1, buffer, static_cast<int>( len ), NULL, NULL );
|
||||
|
||||
while( !str.empty() && ( str[ str.size() - 1 ] == '\n' || str[ str.size() - 1 ] == '\r' ) )
|
||||
if( r == 0 )
|
||||
{
|
||||
str.erase( str.size() - 1 );
|
||||
return "Unknown error";
|
||||
}
|
||||
|
||||
if( str.size() && str[ str.size() - 1 ] == '.' )
|
||||
--r; // exclude null terminator
|
||||
|
||||
while( r > 0 && ( buffer[ r-1 ] == '\n' || buffer[ r-1 ] == '\r' ) )
|
||||
{
|
||||
str.erase( str.size() - 1 );
|
||||
buffer[ --r ] = 0;
|
||||
}
|
||||
|
||||
return str;
|
||||
if( r > 0 && buffer[ r-1 ] == '.' )
|
||||
{
|
||||
buffer[ --r ] = 0;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
inline std::string system_category_message_win32( int ev )
|
||||
{
|
||||
char buffer[ 256 ];
|
||||
return system_category_message_win32( ev, buffer, sizeof( buffer ) );
|
||||
}
|
||||
|
||||
inline error_condition system_category_default_error_condition_win32( int ev ) BOOST_NOEXCEPT
|
||||
|
||||
Reference in new issue
Block a user