[ create a new paste ] login | about

Link: http://codepad.org/pEi4Jzf7    [ raw code | fork ]

C++, pasted on Sep 6:
#pragma once
// Copyright (c) 2011, Alf P. Steinbach


//-------------------------------------------------- Dependencies:

#include <progrock/compiler_specific/fixups.h>      // CPPX_NOEXCEPT

#include <progrock/cppx/error_handling.h>           // cppx::throwX etc.
#include <progrock/cppx/string_building.h>          // S
#include <progrock/winapi/wrapper/windows_h.h>

#include <system_error>



//-------------------------------------------------- Interface:

#ifndef     CPPX_NOEXCEPT
#   define  CPPX_NOEXCEPT   noexcept
#endif

namespace progrock{ namespace winapi{
    using std::string;

    typedef DWORD               ErrorCode;
    typedef cppx::narrow::S     NarrowS;

    namespace errorMessage {
        inline string fromApi( ErrorCode const code )
        {
            struct RawMessage
            {
                char const* p;
                RawMessage(): p(0) {}
                ~RawMessage() { ::LocalFree( const_cast<char*>( p ) ); }
            };

            RawMessage  message;
            int const stringLength    = FormatMessageA(
                0   | FORMAT_MESSAGE_ALLOCATE_BUFFER
                    | FORMAT_MESSAGE_FROM_SYSTEM
                    | FORMAT_MESSAGE_IGNORE_INSERTS,
                0,              // lpSource
                code,
                MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
                reinterpret_cast<char*>( &message.p ),
                0,              // nSize
                0
                );

            // Just in case message.p isn't set:
            if( stringLength == 0 ) { return ""; }

            // Remove trailing control chars:
            char const* pEnd    = message.p + stringLength;
            for( ;; )
            {
                if( pEnd == message.p ) { break; }
                if( *(pEnd - 1) >= ' ' ) { break; }
                --pEnd;
            }
            return string( message.p, pEnd );
        }

        inline string withCode( ErrorCode code, string const& text )
        {
            return NarrowS() << text << " (code " << code << ")";
        }

        inline string forUnknown( ErrorCode const code )
        {
            return withCode( code, "Unknown error" );
        }

        inline string explaining( ErrorCode const code )
        {
            if( code == 0 )
            {
                // ERROR_SUCCESS.
                // Instead of "The operation completed successfully.":
                return forUnknown( code );
            }
    
            string const    rawMessage  = fromApi( code );
            if( rawMessage.length() == 0 )
            {
                return forUnknown( code );
            }

            return withCode( code, rawMessage );
        }
    }    // namespace errorMessage

    class WinApiErrorCategory
        : public std::error_category
    {
    public:
        virtual const char* name() const CPPX_NOEXCEPT
        {
            return "WindowsApiError";
        }
    
        virtual std::error_condition default_error_condition( int code ) const CPPX_NOEXCEPT
        {
            return std::error_condition( code, *this );
        }

        virtual string message( int code ) const
        {
            return errorMessage::explaining( code );
        }
    };

    inline std::error_category const& winApiErrorCategory()
    {
        static WinApiErrorCategory const    theInstance;
        return theInstance;
    }

    class WinApiError
        : public std::system_error
    {
    private:
        mutable std::string fullDescription_;

    public:
        char const* what() const CPPX_NOEXCEPT
        {
            if( fullDescription_.length() == 0 )
            {
                fullDescription_ = NarrowS()
                    << std::system_error::what() << ": " << code().message()
                    << NarrowS::toString;
            }
            return fullDescription_.c_str();
        }

        WinApiError( int code, std::string const& description )
            : std::system_error(
                std::error_code( code, winApiErrorCategory() ),
                description
                )
        {}
    
        virtual ~WinApiError() CPPX_NOEXCEPT {}
    };

    bool throwX( ErrorCode errorCode, string const& s )
    {
        throw WinApiError( errorCode, s );
    }

} }  // namespace progrock::winapi


Create a new paste based on this one


Comments: