Some time ago I mentioned here that system_category() doesn't have a name() method that translates the error-code according to the current thread's locale under Win32. I also wrote that in the Microsoft developer forum and they said that they will fix this except for WinRT apps.
So I wrote my own class xsystem_category but I'm not sure if I did everything correctly. Maybe someone here more experienced with the innards of exception-hanling in C++ will check that:
#include <Windows.h>
#include <iostream>
#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;
};
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() );
}
inline bool xsystem_category::equivalent( int code, std::error_condition const &condition ) const noexcept
{
return default_error_condition( code ) == condition;
}
inline 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
{
using namespace std;
LCID lcid = GetThreadLocale();
string errStr( 64, '\0' );
while( !FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, 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(), "FormatMessage() failed" );
errStr.resize( strlen( errStr.data() ) );
return errStr;
}
Aucun commentaire:
Enregistrer un commentaire