ErrorCode.h

// ErrorCode.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2017

#pragma once
#ifndef Ceda_cxUtils_ErrorCode_H
#define Ceda_cxUtils_ErrorCode_H

#include "cxUtils.h"
#include <system_error>

/*
An error code is a platform independent type which is cheap to copy, but allows for OS and library 
specific error codes.
*/

namespace ceda
{
class xostream;

///////////////////////////////////////////////////////////////////////////////////////////////////
// ECedaErrorCode

enum class ECedaErrorCode
{
    Success = 0,
    ConnectionClosed,
    BadCommand,
    BadLength,
    ProtocolNotSupported,
    InvalidData,
    BadFormat,

    WriteTemporarilyStopped,         // todo: remove
    WriteShutdown,                   // todo: remove
    
    // While reading from the socket met the end-of-stream indicator.  This means the sender 
    // must have shutdown their side of the connection to indicate no more data would be sent.
    // The end-of-stream indicator is deemed to be invalid if it was encountered in the middle
    // of reading a message.
    ReadValidEndOfStream,
    ReadInvalidEndOfStream,
    
    // The message size specified in the header was negative or else exceeded the maximum allowed
    // message size.
    ReadInvalidMessageSize,
    
    // IMessageReader::ReadMessage() returned false to indicate that the message was unreadable
    ReadBadMessage
};

cxUtils_API const std::error_category& GetCedaErrorCategory() noexcept;

// make_error_code overload to generate custom conditions:
inline std::error_code MakeCedaErrorCode(ECedaErrorCode e) 
{
    return std::error_code(static_cast<int>(e), GetCedaErrorCategory());
}

#ifdef _WIN32
inline std::error_code MakeWindowsErrorCode(int windowsErrorCode)
{
    return std::error_code(windowsErrorCode, std::system_category());
}
#endif

cxUtils_API xostream& operator<<(xostream& os, std::error_code ec);

} // namespace ceda

namespace std 
{
    template<>
    struct is_error_condition_enum<ceda::ECedaErrorCode> : public true_type {};
}

#endif // include guard