diff --git a/Makefile b/Makefile index 55b6a17..64c3342 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ OBJS =\ base58\ base64\ hash/sha256\ + Exception TOOLS = ${LIB} @@ -23,6 +24,7 @@ TESTS =\ test-base58\ test-base64\ hash/test-sha256\ + test-Exception ifeq (${origin CC}, default) CC = g++ diff --git a/include/basen.hpp b/include/basen.hpp index a1dd335..2f3da77 100644 --- a/include/basen.hpp +++ b/include/basen.hpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include diff --git a/include/basen/Exception.hpp b/include/basen/Exception.hpp new file mode 100644 index 0000000..1344db7 --- /dev/null +++ b/include/basen/Exception.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace basen +{ + class Exception : public std::exception + { + public: + enum class Code + { + BASE, + PADDING, + CHECKSUM, + OVERFLOW, + LENGTH, + OUT_OF_ALPH, + ALPH_COLLISION + }; + static const std::unordered_map messages; + + Exception(Code code, const std::source_location &location = std::source_location::current()); + const char *what() const noexcept override + { + return _what.c_str(); + } + inline const char *message() const noexcept + { + return messages.at(_code).c_str(); + } + inline Code code() const noexcept + { + return _code; + } + + private: + Code _code; + std::string _what; + }; +} \ No newline at end of file diff --git a/src/Exception.cpp b/src/Exception.cpp new file mode 100644 index 0000000..46baf89 --- /dev/null +++ b/src/Exception.cpp @@ -0,0 +1,29 @@ +#include + +#include + +namespace basen +{ + const std::unordered_map Exception::messages = { + {Code::BASE, "incorrect base"}, + {Code::PADDING, "incorrect padding"}, + {Code::CHECKSUM, "incorrect checksum"}, + {Code::OVERFLOW, "overflow"}, + {Code::LENGTH, "not enough allocated length"}, + {Code::OUT_OF_ALPH, "out of alphabet"}, + {Code::ALPH_COLLISION, "alphabet contains same chars"}, + }; + Exception::Exception(Code code, const std::source_location &location) + { + _code = code; + std::ostringstream oss; + oss << "\033[34m" + << location.function_name() + << ':' + << location.line() + << ": \033[31mbasen::Exception:\n\t\033[0m" + << message() + << "\n"; + _what = oss.str(); + } +} \ No newline at end of file diff --git a/test/test-Exception.cpp b/test/test-Exception.cpp new file mode 100644 index 0000000..c70221c --- /dev/null +++ b/test/test-Exception.cpp @@ -0,0 +1,35 @@ +#include +#include + +TEST(Exception, Exception) +{ + EXPECT_ANY_THROW(throw basen::Exception(basen::Exception::Code::BASE)); +} +TEST(Exception, message) +{ + try + { + throw basen::Exception(basen::Exception::Code::BASE); + } + catch (const basen::Exception &e) + { + EXPECT_STREQ(e.message(), "incorrect base"); + } +} +TEST(Exception, code) +{ + try + { + throw basen::Exception(basen::Exception::Code::BASE); + } + catch (const basen::Exception &e) + { + EXPECT_EQ(uint32_t(e.code()), uint32_t(basen::Exception::Code::BASE)); + } +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file