123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- #ifndef KAITAI_EXCEPTIONS_H
- #define KAITAI_EXCEPTIONS_H
- #include <kaitai/kaitaistream.h>
- #include <string>
- #include <stdexcept>
- // We need to use "noexcept" in virtual destructor of our exceptions
- // subclasses. Different compilers have different ideas on how to
- // achieve that: C++98 compilers prefer `throw()`, C++11 and later
- // use `noexcept`. We define KS_NOEXCEPT macro for that.
- #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
- #define KS_NOEXCEPT noexcept
- #else
- #define KS_NOEXCEPT throw()
- #endif
- namespace kaitai {
- /**
- * Common ancestor for all error originating from Kaitai Struct usage.
- * Stores KSY source path, pointing to an element supposedly guilty of
- * an error.
- */
- class kstruct_error: public std::runtime_error {
- public:
- kstruct_error(const std::string what, const std::string src_path):
- std::runtime_error(src_path + ": " + what),
- m_src_path(src_path)
- {
- }
- virtual ~kstruct_error() KS_NOEXCEPT {};
- protected:
- const std::string m_src_path;
- };
- /**
- * Error that occurs when default endianness should be decided with
- * a switch, but nothing matches (although using endianness expression
- * implies that there should be some positive result).
- */
- class undecided_endianness_error: public kstruct_error {
- public:
- undecided_endianness_error(const std::string src_path):
- kstruct_error("unable to decide on endianness for a type", src_path)
- {
- }
- virtual ~undecided_endianness_error() KS_NOEXCEPT {};
- };
- /**
- * Common ancestor for all validation failures. Stores pointer to
- * KaitaiStream IO object which was involved in an error.
- */
- class validation_failed_error: public kstruct_error {
- public:
- validation_failed_error(const std::string what, kstream* io, const std::string src_path):
- kstruct_error("at pos " + kstream::to_string(static_cast<int>(io->pos())) + ": validation failed: " + what, src_path),
- m_io(io)
- {
- }
- // "at pos #{io.pos}: validation failed: #{msg}"
- virtual ~validation_failed_error() KS_NOEXCEPT {};
- protected:
- kstream* m_io;
- };
- /**
- * Signals validation failure: we required "actual" value to be equal to
- * "expected", but it turned out that it's not.
- */
- template<typename T>
- class validation_not_equal_error: public validation_failed_error {
- public:
- validation_not_equal_error<T>(const T& expected, const T& actual, kstream* io, const std::string src_path):
- validation_failed_error("not equal", io, src_path),
- m_expected(expected),
- m_actual(actual)
- {
- }
- // "not equal, expected #{expected.inspect}, but got #{actual.inspect}"
- virtual ~validation_not_equal_error<T>() KS_NOEXCEPT {};
- protected:
- const T& m_expected;
- const T& m_actual;
- };
- /**
- * Signals validation failure: we required "actual" value to be greater
- * than or equal to "min", but it turned out that it's not.
- */
- template<typename T>
- class validation_less_than_error: public validation_failed_error {
- public:
- validation_less_than_error<T>(const T& min, const T& actual, kstream* io, const std::string src_path):
- validation_failed_error("not in range", io, src_path),
- m_min(min),
- m_actual(actual)
- {
- }
- // "not in range, min #{min.inspect}, but got #{actual.inspect}"
- virtual ~validation_less_than_error<T>() KS_NOEXCEPT {};
- protected:
- const T& m_min;
- const T& m_actual;
- };
- /**
- * Signals validation failure: we required "actual" value to be less
- * than or equal to "max", but it turned out that it's not.
- */
- template<typename T>
- class validation_greater_than_error: public validation_failed_error {
- public:
- validation_greater_than_error<T>(const T& max, const T& actual, kstream* io, const std::string src_path):
- validation_failed_error("not in range", io, src_path),
- m_max(max),
- m_actual(actual)
- {
- }
- // "not in range, max #{max.inspect}, but got #{actual.inspect}"
- virtual ~validation_greater_than_error<T>() KS_NOEXCEPT {};
- protected:
- const T& m_max;
- const T& m_actual;
- };
- /**
- * Signals validation failure: we required "actual" value to be from
- * the list, but it turned out that it's not.
- */
- template<typename T>
- class validation_not_any_of_error: public validation_failed_error {
- public:
- validation_not_any_of_error<T>(const T& actual, kstream* io, const std::string src_path):
- validation_failed_error("not any of the list", io, src_path),
- m_actual(actual)
- {
- }
- // "not any of the list, got #{actual.inspect}"
- virtual ~validation_not_any_of_error<T>() KS_NOEXCEPT {};
- protected:
- const T& m_actual;
- };
- /**
- * Signals validation failure: we required "actual" value to match
- * the expression, but it turned out that it doesn't.
- */
- template<typename T>
- class validation_expr_error: public validation_failed_error {
- public:
- validation_expr_error<T>(const T& actual, kstream* io, const std::string src_path):
- validation_failed_error("not matching the expression", io, src_path),
- m_actual(actual)
- {
- }
- // "not matching the expression, got #{actual.inspect}"
- virtual ~validation_expr_error<T>() KS_NOEXCEPT {};
- protected:
- const T& m_actual;
- };
- }
- #endif
|