You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

287 lines
7.8 KiB

/*
* Copyright 2019 by its authors. See AUTHORS.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _EINA_ERROR_HH
#define _EINA_ERROR_HH
#include <Eina.h>
#include <eina_throw.hh>
#include <system_error>
/**
* @addtogroup Eina_Cxx_Tools_Group
*
* @{
*/
namespace efl { namespace eina {
/**
* @defgroup Eina_Cxx_Error_Group Error Handling
* @ingroup Eina_Cxx_Tools_Group
*
* @brief Functions for handling Eina errors.
*
* Integrates the Eina errors with the standard error representation
* defined in the @c system_error library.
*
* @{
*/
/** <tt>std::errc</tt> for Eina errors. */
using std::errc;
/** <tt>std::system_error</tt> for Eina errors. */
using std::system_error;
/** <tt>std::error_code</tt> for Eina errors. */
using std::error_code;
/** <tt>std::error_condition</tt> for Eina errors. */
using std::error_condition;
/** <tt>std::error_category</tt> for Eina errors. */
typedef std::error_category system_error_category;
/**
* @brief Return a @c Eina_Error for an unknown error.
* @return @c Eina_Error indicating a unknown/external error condition.
*
* This function returns an @c Eina_Error indicating a unknown/external
* error condition. When first called, this function will register the
* said error within the other Eina errors, together with a error
* message.
*/
inline Eina_Error unknown_error()
{
static Eina_Error error = eina_error_msg_static_register("Error from C++ from another value category error");
return error;
}
/**
* @brief Gets a <tt>std::generic_category</tt> instance as a <tt>eina::system_error_category</tt>.
* @return a <tt>std::generic_category</tt> instance as a <tt>eina::system_error_category</tt>.
*/
inline system_error_category const& get_generic_category()
{
return ::std::generic_category();
}
/**
* @brief Gets a <tt>std::system_category</tt> instance as a <tt>eina::system_error_category</tt>.
* @return <tt>std::system_category</tt> instance as a <tt>eina::system_error_category</tt>.
*/
inline system_error_category const& get_system_category()
{
return ::std::system_category();
}
/**
* @brief Typesafe representation of an @c Eina_Error.
*
* Used for improved compatibility with @e system_error library.
*/
enum error_type {};
/**
* @brief Specialized error category for Eina errors.
*/
struct error_category : system_error_category
{
/**
* @brief Name of the error category.
* @return String containing the word "eina"
*/
const char* name() const throw()
{
return "eina";
}
/**
* @brief Check if the given error code is equivalent to the given error condition.
* @param code Integer representing the error code.
* @param condition <tt>eina::error_condition</tt> object.
* @return @c true if @c code is equivalent to @c condition.
*/
bool equivalent(int code, eina::error_condition const& condition) const throw()
{
return code == condition.value();
}
/**
* @brief Check if the given error code is equivalent to the given error condition.
* @param code <tt>eina::error_code</tt> object.
* @param condition Integer representing the error condition.
* @return @c true if @c code is equivalent to @c condition.
*/
bool equivalent(eina::error_code const& code, int condition) const throw()
{
return code.value() == condition;
}
/**
* @brief Get the message related with the given error condition.
* @param condition Eina error condition.
* @return String containing the message related with the given error condition.
*
* This member function returns the error message related with the
* given error condition code.
*
* @note When the given condition code is not registered within the
* Eina errors it will return a string indicating that an error
* message is not available.
*/
std::string message(int condition) const
{
const char* e = ::eina_error_msg_get(condition);
return e? e : "::eina_error_msg_get returned NULL. No error message available";
}
};
/**
* @brief Get a default <tt>eina::error_category</tt> object.
* @return Reference to a static instance of an <tt>eina::error_category</tt>.
*/
inline eina::system_error_category& eina_error_category()
{
static error_category _error_category;
return _error_category;
}
/**
* @brief Gets the error code for the last Eina error.
* @return <tt>eina::error_code</tt> for the last Eina error.
*
* This function gets the error code for the last Eina error and
* consumes it. The category of the returned <tt>eina::error_code</tt>
* is @c eina_error_category.
*
* @note If no errors have been occurred or if this functions have
* already been called after the last error occurrence a call to this
* function will return a default <tt>eina::error_code</tt> to indicates
* that there is no unconsumed error.
*/
inline eina::error_code get_error_code()
{
Eina_Error error = eina_error_get();
if(error)
{
eina_error_set(0);
return eina::error_code(error, eina_error_category());
}
else
return eina::error_code();
}
/**
* @brief Sets an error code in the Eina library.
* @param e Error code. Should be an @c eina_error_category error.
*
* This function sets an error code in the Eina library. If the category
* of the given error code is not @c eina_error_category it will
* register an unknown error instead.
*/
inline void set_error_code(eina::error_code const& e)
{
if(e.category() == eina_error_category())
eina_error_set(e.value());
else
eina_error_set(unknown_error());
}
/**
* @brief Gets the error condition for the last Eina error.
* @return <tt>eina::error_condition</tt> for the last Eina error.
*
* This function works exactly like @ref get_error_code but returns an
* <tt>eina::error_condition</tt> object instead.
*/
inline eina::error_condition get_error_condition()
{
Eina_Error error = eina_error_get();
if(error)
{
eina_error_set(0);
return eina::error_condition(error, eina_error_category());
}
else
return eina::error_condition();
}
/**
* @brief Gets the enum value of the last Eina error.
* @return Value of the last Eina error as an @c error_type.
*
* This function returns the error code for the last Eina error.
*
* Differently from @ref get_error_code and @ref get_error_condition,
* this function does not consume the last error.
*/
inline error_type get_error_code_enum()
{
return static_cast<error_type>( ::eina_error_get() );
}
/**
* @brief Throw an exception if there is a error set in Eina library.
* @throw <tt>eina::system_error</tt> containing the error identifier.
*
* This function is meant to be used after executing a operation that
* may set an Eina error. If an error code has been set this function
* will throw an exception.
*
* The thrown exception holds an <tt>eina::error_code</tt> equivalent to
* the one returned by @ref get_error_code.
*
* Like the @ref get_error_code function, this one consumes the last
* error code.
*/
inline void throw_on_error()
{
eina::error_code ec = get_error_code();
if(ec)
{
EFL_CXX_THROW(eina::system_error(ec, "EFL Eina Error"));
}
}
/**
* @}
*/
} }
/**
* @internal
* Template specialization for interoperability with the @e system_error
* standard library.
* @{
*/
namespace std {
template <> struct is_error_condition_enum< ::efl::eina::error_type> : true_type {};
template <> struct is_error_code_enum< ::efl::eina::error_type> : true_type {};
}
/**
* @}
*/
/**
* @}
*/
#endif