Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A localized system_category

11 views
Skip to first unread message

Bonita Montero

unread,
Aug 29, 2022, 10:48:28 AM8/29/22
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
}

0 new messages