Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the encoding used by boost-asio error messages?

I am using boost-asio and I want to process correctly the error message.

In this example, I made a typo (1278 instead of 127):

boost::system::error_code ec;
auto address=boost::asio::ip::address::from_string("1278.0.0.1",ec);
if(ec)
{
    auto text=ec.message();
    //Do Something with text but what is its encoding ?
}

I get an error message and it seems to be encoded in Windows 1252 (I am using Windows 7). So it seems that the encoding is the OS encoding.

However, I was unable to find any documentation that states this fact.

Are error message in boost asio encoded with the OS character set ?

like image 799
Arnaud Avatar asked Aug 28 '13 13:08

Arnaud


1 Answers

After digging into boost on my system, I found that the included hpp files include an ipp file which in turn calls the OS functions. If there is an error, only the code of the error is known at this stage.

The real error message is formed when the message() function is called.

The implementation on windows calls FormatMessageA or FormatMessageW depending if BOOST_NO_ANSI_APIS is defined:

  std::string system_error_category::message( int ev ) const
  {
# ifndef BOOST_NO_ANSI_APIS  
    LPVOID lpMsgBuf = 0;
    DWORD retval = ::FormatMessageA( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM | 
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        ev,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPSTR) &lpMsgBuf,
        0,
        NULL 
    );
    detail::local_free_on_destruction lfod(lpMsgBuf);
    if (retval == 0)
        return std::string("Unknown error");

    std::string str( static_cast<LPCSTR>(lpMsgBuf) );
# else  // WinCE workaround
    LPVOID lpMsgBuf = 0;
    DWORD retval = ::FormatMessageW( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM | 
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        ev,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPWSTR) &lpMsgBuf,
        0,
        NULL 
    );
    detail::local_free_on_destruction lfod(lpMsgBuf);
    if (retval == 0)
        return std::string("Unknown error");

    int num_chars = (wcslen( static_cast<LPCWSTR>(lpMsgBuf) ) + 1) * 2;
    LPSTR narrow_buffer = (LPSTR)_alloca( num_chars );
    if (::WideCharToMultiByte(CP_ACP, 0, static_cast<LPCWSTR>(lpMsgBuf), -1, narrow_buffer, num_chars, NULL, NULL) == 0)
        return std::string("Unknown error");

    std::string str( narrow_buffer );
# endif
    while ( str.size()
      && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
        str.erase( str.size()-1 );
    if ( str.size() && str[str.size()-1] == '.' ) 
      { str.erase( str.size()-1 ); }
    return str;
  }

If message calls FormatMessageW, the string is narrowed back to the system default Windows ANSI code page (CP_ACP)

In all cases on Windows the result is the default ANSI Codepage.

like image 131
Arnaud Avatar answered Oct 03 '22 12:10

Arnaud