GCException.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. //-----------------------------------------------------------------------------
  2. // (c) 2004 by Basler Vision Technologies
  3. // Section: Vision Components
  4. // Project: GenICam
  5. // Author: Fritz Dierks
  6. // $Header$
  7. //
  8. // 01.10.2014 Stemmer, SD
  9. // prepared for remove of std::exception base class
  10. //
  11. // 14.03.2005 Stemmer, RS
  12. // changed minor things like namespace
  13. // added a AccessException
  14. // added a TimeoutException
  15. //
  16. // 21.02.2006 Stemmer, SD
  17. // used _vsnprintf_s function for VS8 and higher (compiler fork)
  18. //
  19. // License: This file is published under the license of the EMVA GenICam Standard Group.
  20. // A text file describing the legal terms is included in your installation as 'GenICam_license.pdf'.
  21. // If for some reason you are missing this file please contact the EMVA or visit the website
  22. // (http://www.genicam.org) for a full copy.
  23. //
  24. // THIS SOFTWARE IS PROVIDED BY THE EMVA GENICAM STANDARD GROUP "AS IS"
  25. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  26. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  27. // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE EMVA GENICAM STANDARD GROUP
  28. // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  29. // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  30. // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  31. // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  32. // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  33. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  34. // POSSIBILITY OF SUCH DAMAGE.
  35. //-----------------------------------------------------------------------------
  36. /*!
  37. \file
  38. Standard GenICam Exceptions
  39. \ingroup Base_PublicUtilities
  40. */
  41. #ifndef GENCAM_EXCEPTION_H_
  42. #define GENCAM_EXCEPTION_H_
  43. #include <cassert>
  44. #include <cstdarg>
  45. #include <exception>
  46. #include <sstream>
  47. #include <stdio.h>
  48. #include <stdarg.h>
  49. #include <Base/GCTypes.h>
  50. #include <Base/GCString.h>
  51. #pragma pack(push, 8)
  52. namespace GENICAM_NAMESPACE
  53. {
  54. /**
  55. \brief GenICam's exception class
  56. \ingroup Base_PublicUtilities
  57. */
  58. class GCBASE_RTTI_CLASS_API GenericException
  59. {
  60. public:
  61. //! Constructor
  62. GenericException(const char* pDescription, const char *pSourceFileName, unsigned int SourceLine);
  63. //! Constructor
  64. GenericException(const char* pDescription, const char *pSourceFileName, unsigned int SourceLine, const char* pExceptionType);
  65. //! Constructor (GenApi specific)
  66. GenericException(const char* pDescription, const char *pSourceFileName, unsigned int SourceLine, const char *pEntryPoint, const char *pErrorNodeName, const char* pExceptionType);
  67. //! Get error description
  68. virtual const char* GetDescription() const throw();
  69. //! Get filename in which the error occurred
  70. virtual const char* GetSourceFileName() const throw();
  71. //! Get line number at which the error occurred
  72. virtual unsigned int GetSourceLine() const throw();
  73. //! Get error description (overwrite from std:exception)
  74. virtual const char *what() const throw();
  75. virtual ~GenericException() throw();
  76. private:
  77. //! Assembles the error message
  78. void AssembleMessage();
  79. //! The full error message
  80. GENICAM_NAMESPACE::gcstring m_What;
  81. //! The full error message
  82. GENICAM_NAMESPACE::gcstring m_ExceptionType;
  83. //! Line number at which the error occurred
  84. unsigned int m_SourceLine;
  85. //! Filename in which the error occurred
  86. GENICAM_NAMESPACE::gcstring m_SourceFileName;
  87. //! Error description
  88. GENICAM_NAMESPACE::gcstring m_Description;
  89. /* the following members are GenApi specific */
  90. //! Node and method where the call stack entered the node map (may be empty)
  91. GENICAM_NAMESPACE::gcstring m_EntryPoint;
  92. //! Node where the error occurred (may be empty)
  93. GENICAM_NAMESPACE::gcstring m_ErrorNodeName;
  94. };
  95. //! Creates an exception with the same functionality as the GenericException but being of different type
  96. //! \ingroup Base_PublicUtilities
  97. #define DECLARE_EXCEPTION( name ) \
  98. class GCBASE_RTTI_CLASS_API name : public GENICAM_NAMESPACE::GenericException \
  99. { \
  100. public: \
  101. name( const char* pDescription, const char *pSourceFileName, int SourceLine ); \
  102. name( const char* pDescription, const char *pSourceFileName, int SourceLine, const char* pExceptionType ); \
  103. name( const char* pDescription, const char *pSourceFileName, int SourceLine, const char *pEntryPoint, const char *pErrorNodeName, const char* pExceptionType ); \
  104. }
  105. //! \addtogroup Base_PublicUtilities
  106. DECLARE_EXCEPTION(BadAllocException);
  107. //! Exception fired if an argument is invalid
  108. DECLARE_EXCEPTION(InvalidArgumentException);
  109. //! Exception fired if an argument is out of range
  110. DECLARE_EXCEPTION(OutOfRangeException);
  111. //! Exception fired if a property access fails
  112. DECLARE_EXCEPTION(PropertyException);
  113. //! Runtime exception
  114. DECLARE_EXCEPTION(RuntimeException);
  115. //! Exception to be thrown to indicate logical errors in program flow
  116. DECLARE_EXCEPTION(LogicalErrorException);
  117. //! Exception to be thrown to indicate an access error
  118. DECLARE_EXCEPTION(AccessException);
  119. //! Exception to be thrown to indicate an timeout error
  120. DECLARE_EXCEPTION(TimeoutException);
  121. //! Exception to be thrown to indicate the result of a dynamic cast was zero
  122. DECLARE_EXCEPTION(DynamicCastException);
  123. //! \}
  124. /*-----------------------------------------------------------------*/
  125. // Utilities
  126. /*-----------------------------------------------------------------*/
  127. /**
  128. \brief printf like creation of exceptions
  129. \ingroup Base_PublicImpl
  130. */
  131. template <typename E>
  132. class ExceptionReporter
  133. {
  134. public:
  135. ExceptionReporter(const char* pSourceFileName, int SourceLine)
  136. : m_SourceFileName(pSourceFileName)
  137. , m_SourceLine(SourceLine)
  138. {
  139. }
  140. ExceptionReporter(const char* pSourceFileName, int SourceLine, const char* pExceptionType)
  141. : m_SourceFileName(pSourceFileName)
  142. , m_SourceLine(SourceLine)
  143. , m_ExceptionType(pExceptionType)
  144. {
  145. }
  146. E Report(const char* pFormat, ...)
  147. {
  148. char pBuffer[256];
  149. va_list vap;
  150. va_start(vap, pFormat);
  151. # if defined (_MSC_VER)
  152. vsnprintf_s(pBuffer, sizeof pBuffer, _TRUNCATE, pFormat, vap);
  153. # else
  154. vsnprintf( pBuffer, sizeof pBuffer, pFormat, vap );
  155. # endif
  156. va_end(vap);
  157. return E(pBuffer, m_SourceFileName.c_str(), m_SourceLine, m_ExceptionType.c_str());
  158. };
  159. E Report()
  160. {
  161. return E("", m_SourceFileName.c_str(), m_SourceLine, m_ExceptionType.c_str());
  162. }
  163. E Report(const std::string &s)
  164. {
  165. return E(s.c_str(), m_SourceFileName.c_str(), m_SourceLine, m_ExceptionType.c_str());
  166. }
  167. E Report(const std::stringstream& str)
  168. {
  169. return E(str.str().c_str(), m_SourceFileName.c_str(), m_SourceLine, m_ExceptionType.c_str());
  170. }
  171. protected:
  172. //! the path to the source file where the exception is thrown
  173. GENICAM_NAMESPACE::gcstring m_SourceFileName;
  174. //! The line within the source file where the exception is thrown
  175. int m_SourceLine;
  176. //! the type of the exception in string
  177. GENICAM_NAMESPACE::gcstring m_ExceptionType;
  178. };
  179. //! \addtogroup Base_PublicImpl
  180. //! \{
  181. //! Fires a generic exception, e.g. throw GENERIC_EXCEPTION("%ld too large", Value);
  182. #define GENERIC_EXCEPTION GENICAM_NAMESPACE::ExceptionReporter<GENICAM_NAMESPACE::GenericException>(__FILE__, __LINE__).Report
  183. //! Fires a bad alloc exception, e.g. throw BAD_ALLOC_EXCEPTION();
  184. #define BAD_ALLOC_EXCEPTION GENICAM_NAMESPACE::ExceptionReporter<GENICAM_NAMESPACE::BadAllocException>(__FILE__, __LINE__, "BadAllocException" ).Report
  185. //! Fires an invalid argument exception, e.g. throw INVALID_ARGUMENT_EXCEPTION("%ld too large", Value);
  186. #define INVALID_ARGUMENT_EXCEPTION GENICAM_NAMESPACE::ExceptionReporter<GENICAM_NAMESPACE::InvalidArgumentException>(__FILE__, __LINE__, "InvalidArgumentException" ).Report
  187. //! Fires an out of range exception, e.g. throw OUT_OF_RANGE_EXCEPTION("%ld too large", Value);
  188. #define OUT_OF_RANGE_EXCEPTION GENICAM_NAMESPACE::ExceptionReporter<GENICAM_NAMESPACE::OutOfRangeException>(__FILE__, __LINE__, "OutOfRangeException" ).Report
  189. //! Fires an property exception, e.g. throw PROPERTY_EXCEPTION("%ld too large", Value);
  190. #define PROPERTY_EXCEPTION GENICAM_NAMESPACE::ExceptionReporter<GENICAM_NAMESPACE::PropertyException>(__FILE__, __LINE__, "PropertyException" ).Report
  191. //! Fires a runtime exception, e.g. throw RUNTIME_EXCEPTION("buh!")
  192. #define RUNTIME_EXCEPTION GENICAM_NAMESPACE::ExceptionReporter<GENICAM_NAMESPACE::RuntimeException>(__FILE__, __LINE__, "RuntimeException" ).Report
  193. //! Fires a logical error exception, e.g. throw LOGICAL_ERROR_EXCEPTION("Should never reach this point")
  194. #define LOGICAL_ERROR_EXCEPTION GENICAM_NAMESPACE::ExceptionReporter<GENICAM_NAMESPACE::LogicalErrorException>(__FILE__, __LINE__, "LogicalErrorException" ).Report
  195. //! Fires a access exception, e.g. throw ACCESS_EXCEPTION("Not everybody")
  196. #define ACCESS_EXCEPTION GENICAM_NAMESPACE::ExceptionReporter<GENICAM_NAMESPACE::AccessException>(__FILE__, __LINE__, "AccessException" ).Report
  197. //! Fires a timeout error exception, e.g. throw TIMEOUT_EXCEPTION("Not everybody")
  198. #define TIMEOUT_EXCEPTION GENICAM_NAMESPACE::ExceptionReporter<GENICAM_NAMESPACE::TimeoutException>(__FILE__, __LINE__,"TimeoutException" ).Report
  199. //! Fires a dynamic cast exception, e.g. throw DYNAMICCAST_EXCEPTION("Not everybody")
  200. #define DYNAMICCAST_EXCEPTION GENICAM_NAMESPACE::ExceptionReporter<GENICAM_NAMESPACE::DynamicCastException>(__FILE__, __LINE__, "DynamicCastException" ).Report
  201. //! Range check for int64
  202. #define CHECK_RANGE_I64(_Value, _Min, _Max, _Inc) \
  203. if((int64_t)(_Value) < (int64_t)(_Min)) \
  204. throw OUT_OF_RANGE_EXCEPTION("Value = %" FMT_I64 "d must be equal or greater than Min = %" FMT_I64 "d", (int64_t)(_Value), (int64_t)(_Min)); \
  205. else if((int64_t)(_Value) > (int64_t)(_Max)) \
  206. throw OUT_OF_RANGE_EXCEPTION("Value = %" FMT_I64 "d must be equal or smaller than Max = %" FMT_I64 "d", (int64_t)(_Value), (int64_t)(_Max)); \
  207. else if ( 0 == _Inc ) \
  208. throw LOGICAL_ERROR_EXCEPTION("Increment must not equal 0!"); \
  209. else if( ((int64_t)(_Value) - (int64_t)(_Min)) % (int64_t)(_Inc) != 0) \
  210. throw OUT_OF_RANGE_EXCEPTION("The difference between Value = %" FMT_I64 "d and Min = %" FMT_I64 "d must be dividable without rest by Inc = %" FMT_I64 "d", (int64_t)(_Value), (int64_t)(_Min), (int64_t)(_Inc));
  211. //! Range check for float
  212. #define CHECK_RANGE_FLT(_Value, _Min, _Max) \
  213. if ((_Value) < (_Min)) \
  214. throw OUT_OF_RANGE_EXCEPTION( "Value %f must be greater than or equal %f", (_Value), (_Min) ); \
  215. else if ((_Value) > (_Max)) \
  216. throw OUT_OF_RANGE_EXCEPTION( "Value %f must be smaller than or equal %f", (_Value), (_Max) );
  217. //! Checks if a dynamic_cast is possible
  218. #define CHECK_DYNAMIC_CAST_POINTER( _Pointer )\
  219. assert( (_Pointer) != NULL ); \
  220. if (NULL == (_Pointer)) throw LOGICAL_ERROR_EXCEPTION( "Unexpected type in dynamic cast" )
  221. //! \}
  222. }
  223. #pragma pack(pop)
  224. #endif // GENCAM_EXCEPTION_H_