Browse Source

Added a ctkException class.

Sascha Zelzer 13 years ago
parent
commit
08b6480b4e
3 changed files with 310 additions and 0 deletions
  1. 2 0
      Libs/Core/CMakeLists.txt
  2. 125 0
      Libs/Core/ctkException.cpp
  3. 183 0
      Libs/Core/ctkException.h

+ 2 - 0
Libs/Core/CMakeLists.txt

@@ -49,6 +49,8 @@ set(KIT_SRCS
   ctkErrorLogQtMessageHandler.h
   ctkErrorLogStreamMessageHandler.cpp
   ctkErrorLogStreamMessageHandler.h
+  ctkException.cpp
+  ctkException.h
   ctkLogger.cpp
   ctkLogger.h
   ctkHistogram.cpp

+ 125 - 0
Libs/Core/ctkException.cpp

@@ -0,0 +1,125 @@
+/*=============================================================================
+  
+  Library: CTK
+  
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+    
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  
+=============================================================================*/
+
+
+#include "ctkException.h"
+
+#include <typeinfo>
+
+#include <QDebug>
+
+// --------------------------------------------------------------------------
+ctkException::ctkException(const QString& msg)
+  : msg(msg), nestedException(0)
+{
+}
+
+// --------------------------------------------------------------------------
+ctkException::ctkException(const QString& msg, const ctkException& cause)
+  : msg(msg), nestedException(cause.clone())
+{
+}
+
+// --------------------------------------------------------------------------
+ctkException::ctkException(const ctkException& exc)
+  : std::exception(exc), msg(exc.msg)
+{
+  nestedException = exc.nestedException ? exc.nestedException->clone() : 0;
+}
+
+// --------------------------------------------------------------------------
+ctkException::~ctkException() throw()
+{
+  delete nestedException;
+}
+
+// --------------------------------------------------------------------------
+ctkException& ctkException::operator=(const ctkException& exc)
+{
+  if (&exc != this)
+  {
+    delete nestedException;
+    msg = exc.msg;
+    nestedException = exc.nestedException ? exc.nestedException->clone() : 0;
+  }
+  return *this;
+}
+
+// --------------------------------------------------------------------------
+const ctkException* ctkException::cause() const throw()
+{
+  return nestedException;
+}
+
+// --------------------------------------------------------------------------
+void ctkException::setCause(const ctkException& cause)
+{
+  delete nestedException;
+  nestedException = cause.clone();
+}
+
+// --------------------------------------------------------------------------
+const char *ctkException::name() const throw()
+{
+  return "ctkException";
+}
+
+// --------------------------------------------------------------------------
+const char* ctkException::className() const throw()
+{
+  return typeid(*this).name();
+}
+
+// --------------------------------------------------------------------------
+const char* ctkException::what() const throw()
+{
+  static std::string txt;
+  txt = std::string(name());
+  if (!msg.isEmpty())
+  {
+    txt += ": ";
+    txt += msg.toStdString();
+  }
+  if (nestedException)
+  {
+    txt +=  std::string("\n  Caused by: ") + nestedException->what();
+  }
+  return txt.c_str();
+}
+
+// --------------------------------------------------------------------------
+ctkException* ctkException::clone() const
+{
+  return new ctkException(*this);
+}
+
+// --------------------------------------------------------------------------
+void ctkException::rethrow() const
+{
+  throw *this;
+}
+
+//----------------------------------------------------------------------------
+QDebug operator<<(QDebug dbg, const ctkException& exc)
+{
+  dbg << exc.what();
+  return dbg.maybeSpace();
+}

+ 183 - 0
Libs/Core/ctkException.h

@@ -0,0 +1,183 @@
+/*=============================================================================
+  
+  Library: CTK
+  
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+    
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  
+=============================================================================*/
+
+
+#ifndef CTKEXCEPTION_H
+#define CTKEXCEPTION_H
+
+// Qt includes
+#include <QString>
+
+// CTK includes
+#include <ctkCoreExport.h>
+
+//---------------------------------------------------------------------------
+/**
+ * \ingroup Core
+ *
+ * \brief The base class for all exceptions defined in CTK.
+ *
+ * This exception class takes a QString object as the message text and can
+ * optionally store another ctkException instance which caused this exception.
+ *
+ * ctkException classes can be copied, saved, and rethrown.
+ */
+class CTK_CORE_EXPORT ctkException : public std::exception
+{
+public:
+
+  /**
+   * @brief Create a new ctkException.
+   * @param msg The exception message.
+   */
+  ctkException(const QString& msg);
+
+  /**
+   * @brief Create a new ctkException containing another exception as the cause.
+   * @param msg The exception message.
+   * @param cause The nested exception causing this exception.
+   */
+  ctkException(const QString& msg, const ctkException& cause);
+
+  /**
+   * @brief Copy constructor.
+   * @param o The exception to copy.
+   */
+  ctkException(const ctkException& o);
+
+  /**
+   * @brief Assignment operator.
+   * @param o The exception to assign to this exception.
+   * @return
+   */
+  ctkException& operator=(const ctkException& o);
+
+  ~ctkException() throw();
+
+  /**
+   * @brief Gets the nested exception which caused this exception.
+   * @return The nested exception, or <code>NULL</code> if there is none.
+   */
+  const ctkException* cause() const throw();
+
+  /**
+   * @brief Sets the cause for this exception.
+   * @param cause The exception causing this exception.
+   */
+  void setCause(const ctkException& cause);
+
+  /**
+   * @brief Returns the name for this exception.
+   * @return The exception name.
+   */
+  virtual const char* name() const throw();
+
+  /**
+   * @brief Returns the class name for this exception.
+   * @return The exception class name.
+   */
+  virtual const char* className() const throw();
+
+  /**
+   * @brief Returns a static string describing this exception.
+   * @return The exception description.
+   */
+  virtual const char* what() const throw();
+
+  /**
+   * @brief Creates a copy of this exception. Use rethrow() to throw the
+   * copy again.
+   * @return A copy of this exception.
+   */
+  virtual ctkException* clone() const;
+
+  /**
+   * @brief (Re)Throws this exception.
+   */
+  void rethrow() const;
+
+private:
+
+  QString msg;
+  ctkException* nestedException;
+};
+
+//---------------------------------------------------------------------------
+/**
+ * \ingroup Core
+ */
+CTK_CORE_EXPORT QDebug operator<<(QDebug dbg, const ctkException& exc);
+
+//---------------------------------------------------------------------------
+/**
+ * \ingroup Core
+ *
+ * \brief Quickly declare a ctkException sub-class.
+ * \param API The export macro.
+ * \param CLS The class name for the ctkException sub-class.
+ * \param BASE The class name of the actual super class.
+ */
+#define CTK_DECLARE_EXCEPTION(API, CLS, BASE)         \
+  class API CLS : public BASE                         \
+  {                                                   \
+  public:                                             \
+    CLS(const QString& msg);                          \
+    CLS(const QString& msg, const ctkException& exc); \
+    CLS(const CLS& exc);                              \
+    ~CLS() throw();                                   \
+    CLS& operator = (const CLS& exc);                 \
+    const char* name() const throw();                 \
+    CLS* clone() const;                               \
+  };
+
+//---------------------------------------------------------------------------
+/**
+ * \ingroup Core
+ *
+ * \brief Quickly implement a ctkException sub-class
+ * \param CLS The class name for the ctkException sub-class.
+ * \param BASE The class name of the actual super class.
+ * \param NAME A human-readable name for this exception class.
+ */
+#define CTK_IMPLEMENT_EXCEPTION(CLS, BASE, NAME)                         \
+  CLS::CLS(const QString& msg) : BASE(msg)                               \
+  { }                                                                    \
+  CLS::CLS(const QString& msg, const ctkException& exc) : BASE(msg, exc) \
+  { }                                                                    \
+  CLS::CLS(const CLS& exc) : BASE(exc)                                   \
+  { }                                                                    \
+  CLS::~CLS() throw()                                                    \
+  { }                                                                    \
+  CLS& CLS::operator = (const CLS& exc)                                  \
+  {                                                                      \
+    BASE::operator = (exc);                                              \
+    return *this;                                                        \
+  }                                                                      \
+  const char* CLS::name() const throw()                                  \
+  {                                                                      \
+    return NAME;                                                         \
+  }                                                                      \
+  ctkException* CLS::clone() const                                       \
+  {                                                                      \
+    return new CLS(*this);                                               \
+  }
+
+#endif // CTKEXCEPTION_H