Bonita Montero
unread,Aug 29, 2022, 10:48:28 AM8/29/22You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to
If you throw a system_error with system_category and a platform-specific
error code as an integer the error-code is translated by the runtime to
a platform-specific error string. I think under Windows FormatMessage()
is used and under Unix strerror() is used(). This translation is done
by the error_cateogy-subclass you supply while throwing the error.
Unfortunately under Windows this error string isn't localized. So I
wrote my own error_cagegory subclass for Win32 and Unix:
// xsystem_category.h
#pragma once
#include <system_error>
struct xsystem_category : public std::error_category
{
xsystem_category() = default;
xsystem_category( xsystem_category const & ) = delete;
virtual ~xsystem_category() override = default;
void operator =( xsystem_category const & ) = delete;
virtual char const *name() const noexcept override;
virtual std::error_condition default_error_condition( int code ) const
noexcept override;
virtual bool equivalent( int code, std::error_condition const
&condition ) const noexcept override;
virtual bool equivalent( std::error_code const &code, int condition )
const noexcept override;
virtual std::string message( int condition ) const override;
};
// xsystem_category.cpp
#if defined(_WIN32)
#include <Windows.h>
#elif defined(__unix__)
#include <string.h>
#include <locale.h>
#endif
#include "xsystem_category.h"
char const *xsystem_category::name() const noexcept
{
return "xsystem_category";
}
std::error_condition xsystem_category::default_error_condition( int code
) const noexcept
{
return std::error_condition( code, xsystem_category() );
}
bool xsystem_category::equivalent( int code, std::error_condition const
&condition ) const noexcept
{
return default_error_condition( code ) == condition;
}
bool xsystem_category::equivalent( std::error_code const &code, int
condition ) const noexcept
{
return *this == code.category() && code.value() == condition;
}
std::string xsystem_category::message( int condition ) const
{
#if defined(_WIN32)
using namespace std;
LCID lcid = GetThreadLocale();
string errStr( 64, '\0' );
while( !FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
condition, lcid, errStr.data(), (DWORD)errStr.size(), nullptr ) )
if( DWORD dwFmErr = GetLastError(); dwFmErr == ERROR_INSUFFICIENT_BUFFER )
errStr.resize( 2 * errStr.size(), '\0' );
else
throw system_error( (int)dwFmErr, system_category(), "localized
FormatMessage() for xsystem_category::message() failed" );
errStr.resize( strlen( errStr.data() ) );
return errStr;
#elif defined(__unix__)
return std::string( strerror_l( condition, uselocale( (locale_t)0 ) ) );
#endif
}