exceptions.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #ifndef KAITAI_EXCEPTIONS_H
  2. #define KAITAI_EXCEPTIONS_H
  3. #include <kaitai/kaitaistream.h>
  4. #include <string>
  5. #include <stdexcept>
  6. // We need to use "noexcept" in virtual destructor of our exceptions
  7. // subclasses. Different compilers have different ideas on how to
  8. // achieve that: C++98 compilers prefer `throw()`, C++11 and later
  9. // use `noexcept`. We define KS_NOEXCEPT macro for that.
  10. #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
  11. #define KS_NOEXCEPT noexcept
  12. #else
  13. #define KS_NOEXCEPT throw()
  14. #endif
  15. namespace kaitai {
  16. /**
  17. * Common ancestor for all error originating from Kaitai Struct usage.
  18. * Stores KSY source path, pointing to an element supposedly guilty of
  19. * an error.
  20. */
  21. class kstruct_error: public std::runtime_error {
  22. public:
  23. kstruct_error(const std::string what, const std::string src_path):
  24. std::runtime_error(src_path + ": " + what),
  25. m_src_path(src_path)
  26. {
  27. }
  28. virtual ~kstruct_error() KS_NOEXCEPT {};
  29. protected:
  30. const std::string m_src_path;
  31. };
  32. /**
  33. * Error that occurs when default endianness should be decided with
  34. * a switch, but nothing matches (although using endianness expression
  35. * implies that there should be some positive result).
  36. */
  37. class undecided_endianness_error: public kstruct_error {
  38. public:
  39. undecided_endianness_error(const std::string src_path):
  40. kstruct_error("unable to decide on endianness for a type", src_path)
  41. {
  42. }
  43. virtual ~undecided_endianness_error() KS_NOEXCEPT {};
  44. };
  45. /**
  46. * Common ancestor for all validation failures. Stores pointer to
  47. * KaitaiStream IO object which was involved in an error.
  48. */
  49. class validation_failed_error: public kstruct_error {
  50. public:
  51. validation_failed_error(const std::string what, kstream* io, const std::string src_path):
  52. kstruct_error("at pos " + kstream::to_string(static_cast<int>(io->pos())) + ": validation failed: " + what, src_path),
  53. m_io(io)
  54. {
  55. }
  56. // "at pos #{io.pos}: validation failed: #{msg}"
  57. virtual ~validation_failed_error() KS_NOEXCEPT {};
  58. protected:
  59. kstream* m_io;
  60. };
  61. /**
  62. * Signals validation failure: we required "actual" value to be equal to
  63. * "expected", but it turned out that it's not.
  64. */
  65. template<typename T>
  66. class validation_not_equal_error: public validation_failed_error {
  67. public:
  68. validation_not_equal_error<T>(const T& expected, const T& actual, kstream* io, const std::string src_path):
  69. validation_failed_error("not equal", io, src_path),
  70. m_expected(expected),
  71. m_actual(actual)
  72. {
  73. }
  74. // "not equal, expected #{expected.inspect}, but got #{actual.inspect}"
  75. virtual ~validation_not_equal_error<T>() KS_NOEXCEPT {};
  76. protected:
  77. const T& m_expected;
  78. const T& m_actual;
  79. };
  80. /**
  81. * Signals validation failure: we required "actual" value to be greater
  82. * than or equal to "min", but it turned out that it's not.
  83. */
  84. template<typename T>
  85. class validation_less_than_error: public validation_failed_error {
  86. public:
  87. validation_less_than_error<T>(const T& min, const T& actual, kstream* io, const std::string src_path):
  88. validation_failed_error("not in range", io, src_path),
  89. m_min(min),
  90. m_actual(actual)
  91. {
  92. }
  93. // "not in range, min #{min.inspect}, but got #{actual.inspect}"
  94. virtual ~validation_less_than_error<T>() KS_NOEXCEPT {};
  95. protected:
  96. const T& m_min;
  97. const T& m_actual;
  98. };
  99. /**
  100. * Signals validation failure: we required "actual" value to be less
  101. * than or equal to "max", but it turned out that it's not.
  102. */
  103. template<typename T>
  104. class validation_greater_than_error: public validation_failed_error {
  105. public:
  106. validation_greater_than_error<T>(const T& max, const T& actual, kstream* io, const std::string src_path):
  107. validation_failed_error("not in range", io, src_path),
  108. m_max(max),
  109. m_actual(actual)
  110. {
  111. }
  112. // "not in range, max #{max.inspect}, but got #{actual.inspect}"
  113. virtual ~validation_greater_than_error<T>() KS_NOEXCEPT {};
  114. protected:
  115. const T& m_max;
  116. const T& m_actual;
  117. };
  118. /**
  119. * Signals validation failure: we required "actual" value to be from
  120. * the list, but it turned out that it's not.
  121. */
  122. template<typename T>
  123. class validation_not_any_of_error: public validation_failed_error {
  124. public:
  125. validation_not_any_of_error<T>(const T& actual, kstream* io, const std::string src_path):
  126. validation_failed_error("not any of the list", io, src_path),
  127. m_actual(actual)
  128. {
  129. }
  130. // "not any of the list, got #{actual.inspect}"
  131. virtual ~validation_not_any_of_error<T>() KS_NOEXCEPT {};
  132. protected:
  133. const T& m_actual;
  134. };
  135. /**
  136. * Signals validation failure: we required "actual" value to match
  137. * the expression, but it turned out that it doesn't.
  138. */
  139. template<typename T>
  140. class validation_expr_error: public validation_failed_error {
  141. public:
  142. validation_expr_error<T>(const T& actual, kstream* io, const std::string src_path):
  143. validation_failed_error("not matching the expression", io, src_path),
  144. m_actual(actual)
  145. {
  146. }
  147. // "not matching the expression, got #{actual.inspect}"
  148. virtual ~validation_expr_error<T>() KS_NOEXCEPT {};
  149. protected:
  150. const T& m_actual;
  151. };
  152. }
  153. #endif