diff options
Diffstat (limited to 'include/ricochet/net/sys/exception.hh')
| -rw-r--r-- | include/ricochet/net/sys/exception.hh | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/include/ricochet/net/sys/exception.hh b/include/ricochet/net/sys/exception.hh new file mode 100644 index 0000000..9587e5c --- /dev/null +++ b/include/ricochet/net/sys/exception.hh @@ -0,0 +1,80 @@ +/** + * --------------------------------------------------------------------------- + * @notice This file was adapted from the Minnow networking framework, + * originally developed for Stanford University's CS144 course. + * It has been incorporated into the Ricochet project as foundational + * system utility code. + * --------------------------------------------------------------------------- + */ + +#pragma once + +#include <cxxabi.h> +#include <memory> +#include <string> +#include <string_view> +#include <system_error> + +class tagged_error : public std::system_error +{ +private: + std::string attempt_and_error_; + int error_code_; + +public: + tagged_error( const std::error_category& category, const std::string_view s_attempt, const int error_code ) + : system_error( error_code, category ) + , attempt_and_error_( std::string( s_attempt ) + ": " + std::system_error::what() ) + , error_code_( error_code ) + {} + + const char* what() const noexcept override { return attempt_and_error_.c_str(); } + + int error_code() const { return error_code_; } +}; + +class unix_error : public tagged_error +{ +public: + explicit unix_error( const std::string_view s_attempt, const int s_errno = errno ) + : tagged_error( std::system_category(), s_attempt, s_errno ) + {} +}; + +inline int CheckSystemCall( const std::string_view s_attempt, const int return_value ) +{ + if ( return_value >= 0 ) { + return return_value; + } + + throw unix_error { s_attempt }; +} + +template<typename T> +inline T* notnull( const std::string_view context, T* const x ) +{ + return x ? x : throw std::runtime_error( std::string( context ) + ": returned null pointer" ); +} + +template<typename T> +inline std::unique_ptr<T> notnull( const std::string_view context, std::unique_ptr<T> x ) +{ + return x ? x : throw std::runtime_error( std::string( context ) + ": returned null pointer" ); +} + +template<typename T> +inline std::shared_ptr<T> notnull( const std::string_view context, std::shared_ptr<T>&& x ) +{ + return x ? std::move( x ) : throw std::runtime_error( std::string( context ) + ": returned null pointer" ); +} + +inline std::string demangle( const char* name ) +{ + int status {}; + const std::unique_ptr<char, decltype( &free )> res { abi::__cxa_demangle( name, nullptr, nullptr, &status ), + free }; + if ( status ) { + throw std::runtime_error( "cxa_demangle" ); + } + return res.get(); +} |
