]> Creatis software - gdcm.git/commitdiff
added exception classes
authorjohan <johan>
Sun, 16 Feb 2003 18:55:31 +0000 (18:55 +0000)
committerjohan <johan>
Sun, 16 Feb 2003 18:55:31 +0000 (18:55 +0000)
src/Makefile.am
src/gdcm.h
src/gdcmException.cxx [new file with mode: 0644]
src/gdcmException.h [new file with mode: 0644]
src/gdcmHeader.cxx

index cf5612dbf05dccd48b0d6ad1011ae150c96f77cb..ae54fef0bf5a795d27f15a5114ff52a9f68b99a0 100644 (file)
@@ -15,7 +15,8 @@ LTVERSION = 0:1:0
 lib_LTLIBRARIES = libgdcm.la
 
 libgdcm_la_SOURCES=            \
-       gdcmUtil.cxx    \
+       gdcmException.cxx       \
+       gdcmUtil.cxx            \
        gdcmHeader.cxx    \
        gdcmElValue.cxx   \
        gdcmDictEntry.cxx \
@@ -29,5 +30,6 @@ libgdcmincludedir = $(includedir)
 libgdcminclude_HEADERS =       \
        config.h        \
        gdcm.h          \
+       gdcmException.h \
        gdcmIdo.h       \
        gdcmUtil.h
index 9d159fb9bd96df58b8ac78ecdeeaa195c923e195..aea4edc5c3a450ef9a9d4570a0b5af1ee7b45e92 100644 (file)
 // problems appears at loading of _gdcm.[so/dll]). So, simply uncomment
 // the declaration once you provided the definition of the method...
 
+#ifndef GDCM_H
+#define GDCM_H
+
 #include <string>
-#ifdef _MSC_VER
-using namespace std;  // string type lives in the std namespace on VC++
-#endif
+using namespace std;
 
 #include <iostream>
 #include <stddef.h>   // For size_t
 #include <stdio.h>    // FIXME For FILE on GCC only
 #include <list>
 #include <map>
+#include "gdcmException.h"
+
 
                      // The requirement for the hash table (or map) that
                       // we shall use:
@@ -368,8 +371,10 @@ protected:
        int anonymize(ostream&);  // FIXME : anonymize should be a friend ?
 public:
        void LoadElements(void);
-       virtual void ParseHeader(void);
-       gdcmHeader(const char* filename);
+       virtual void ParseHeader(bool exception_on_error = false)
+         throw(gdcmFormatError);
+       gdcmHeader(const char *filename, bool exception_on_error = false)
+         throw(gdcmFileError);
        virtual ~gdcmHeader();
        
        size_t GetPixelOffset(void);
@@ -544,3 +549,4 @@ public:
 //class gdcmMultiFrame : gdcmFile;
 
 
+#endif // #ifndef GDCM_H
diff --git a/src/gdcmException.cxx b/src/gdcmException.cxx
new file mode 100644 (file)
index 0000000..bc84810
--- /dev/null
@@ -0,0 +1,86 @@
+#include "gdcmException.h"
+
+#include <typeinfo>
+#include <stdio.h>
+
+
+gdcmException::gdcmException(const string &f, const string& msg) throw()
+#ifdef __GNUC__
+  try
+#endif
+  : from(f), error(msg) {
+  }
+#ifdef __GNUC__
+catch(...) {
+  fatal("gdcmException::gdcmException(const std::string&, const std::string&, const std::string&)");
+}
+#endif
+
+
+void gdcmException::fatal(const char *from) throw() {
+  try {
+    cerr << "Fatal: exception received in " << from 
+        << " while handling exception." << endl;
+    exit(-1);
+  }
+  catch(...) {
+    try {
+      cerr << "Fatal: exception received in Exception::fatal while handling exception."
+          << endl;
+      exit(-1);
+    }
+    catch(...) {
+      exit(-1);
+    }
+  }  
+}
+
+
+string gdcmException::getName() const throw() {
+  try {
+#ifdef __GNUC__   // GNU C++ compiler class name demangling
+      unsigned int nested = 1, i, nb, offset;
+      string one;
+
+      string name;
+      string iname = typeid(*this).name();
+      if(iname[0] == 'Q') {
+       nested = iname[1] - '0';
+       iname = string(iname, 2, std::string::npos);
+      }
+      for(i = 0; i < nested; i++) {
+       ::sscanf(iname.c_str(), "%u%n", &nb, &offset);
+       iname = string(iname, offset, std::string::npos);
+       name += string(iname, 0, nb);
+       if(i + 1 < nested) name += "::";
+       iname = string(iname, nb, std::string::npos);
+      }
+      return name;
+#else             // no class name demangling
+      //name = typeid(*this).name();
+      return "Exception";
+#endif
+  }
+  catch(...) {
+    fatal("Exception::getName(string &)");
+    return "";
+  }
+}
+
+
+gdcmException::operator const char *() const throw() {
+  return getName().c_str();
+}
+
+
+ostream& operator<<(ostream &os, const gdcmException &e) {
+  try {  
+    os << "Exception " << e.getName() << " thrown: " << e.error << endl;
+  }
+  catch(...) {
+    gdcmException::fatal("operator<<(ostream &, const gdcmException&)");
+  }
+  return os;
+}
+
+  
diff --git a/src/gdcmException.h b/src/gdcmException.h
new file mode 100644 (file)
index 0000000..0938733
--- /dev/null
@@ -0,0 +1,130 @@
+// gdcm.h
+
+// gdcmlib Intro:  
+// * gdcmlib is a library dedicated to reading and writing dicom files.
+// * LGPL for the license
+// * lightweigth as opposed to CTN or DCMTK which come bundled which try
+//   to implement the full DICOM standard (networking...). gdcmlib concentrates
+//   on reading and writing
+// * Formats: this lib should be able to read ACR-NEMA v1 and v2, Dicom v3 (as
+//   stated in part10). [cf dcmtk/dcmdata/docs/datadict.txt]
+// * Targeted plateforms: Un*xes and Win32/VC++6.0
+//
+//
+
+#ifndef GDCM_EXCEPTION_H
+#define GDCM_EXCEPTION_H
+
+#include <string>
+#include <iostream>
+#include <exception>
+using namespace std;
+
+#ifdef _MSC_VER
+#define GDCM_EXPORT __declspec( dllexport )
+#else
+#define GDCM_EXPORT
+#endif
+
+/**
+ * Any exception thrown in the gdcm library
+ */
+class GDCM_EXPORT gdcmException : public exception {
+ protected:
+  /// error message
+  string from;
+  /// error message
+  string error;
+
+  /// exception caught within exception class: print error message and die
+  static void fatal(const char *from) throw();
+
+  /// try to discover this (dynamic) class name
+  virtual string getName() const throw();
+
+ public:
+  /**
+   * Builds an exception with minimal information: name of the thrower
+   * method and error message
+   *
+   * @param from name of the thrower
+   * @param error error description string
+   */
+  explicit gdcmException(const string &from, const string &error = "")
+    throw();
+  
+
+  /**
+   * virtual descructor makes this class dynamic
+   */
+  virtual ~gdcmException() {
+  }
+  
+  /// returns error message
+  const string &getError(void) const throw() {
+    return error;
+  }
+
+  /// returns exception name string
+  operator const char *() const throw();
+
+  /// returns exception name string (overloads std::exception::what)
+  virtual const char *what() const throw() {
+    return (const char *) *this;
+  }
+
+
+  friend ostream& operator<<(ostream &os, const gdcmException &e);
+  
+};
+
+
+/** prints exception stack on output stream
+ * @param os output stream
+ * @param e exception to print
+ * @returns output stream os
+ */
+ostream& operator<<(ostream &os, const gdcmException &e);
+
+
+/**
+ * File error exception thrown in the gdcm library
+ */
+class GDCM_EXPORT gdcmFileError : public gdcmException {
+ public:
+  /**
+   * Builds an file-related exception with minimal information: name of
+   * the thrower method and error message
+   *
+   * @param from name of the thrower
+   * @param error error description string
+   */
+  explicit gdcmFileError(const string &from,
+                        const string &error = "File error")
+    throw() : gdcmException(from, error) {
+  }
+};
+
+
+
+
+/**
+ * Invalid file format exception
+ */
+class GDCM_EXPORT gdcmFormatError : public gdcmException {
+ public:
+  /**
+   * Builds an file-related exception with minimal information: name of
+   * the thrower method and error message
+   *
+   * @param from name of the thrower
+   * @param error error description string
+   */
+  explicit gdcmFormatError(const string &from,
+                          const string &error = "Invalid file format error")
+    throw() : gdcmException(from, error) {
+  }
+};
+
+
+#endif // GDCM_EXCEPTION_H
index afe3ed329bf5ce308a6f188720a1b6501f4f4afa..a79be6e602c1ae967073a8830c379b703333cefd 100644 (file)
@@ -37,16 +37,24 @@ void gdcmHeader::Initialise(void) {
        RefShaDict = (gdcmDict*)0;
 }
 
-gdcmHeader::gdcmHeader (const char* InFilename) {
-       SetMaxSizeLoadElementValue(_MaxSizeLoadElementValue_);
-       filename = InFilename;
-       Initialise();
-       fp=fopen(InFilename,"rw");
-       dbg.Error(!fp, "gdcmHeader::gdcmHeader cannot open file", InFilename);
-       ParseHeader();
-       AddAndDefaultElements();
+
+gdcmHeader::gdcmHeader(const char *InFilename, bool exception_on_error) 
+  throw(gdcmFileError) {
+  SetMaxSizeLoadElementValue(_MaxSizeLoadElementValue_);
+  filename = InFilename;
+  Initialise();
+  fp=fopen(InFilename,"rw");
+  if(exception_on_error) {
+    if(!fp)
+      throw gdcmFileError("gdcmHeader::gdcmHeader(const char *, bool)");
+  }
+  else
+    dbg.Error(!fp, "gdcmHeader::gdcmHeader cannot open file", InFilename);
+  ParseHeader();
+  AddAndDefaultElements();
 }
 
+
 gdcmHeader::~gdcmHeader (void) {
        fclose(fp);
        return;
@@ -1198,7 +1206,7 @@ int gdcmHeader::SetShaElValByName(string content, string TagName) {
  * \ingroup gdcmHeader
  * \brief   Parses the header of the file but WITHOUT loading element values.
  */
-void gdcmHeader::ParseHeader(void) {
+void gdcmHeader::ParseHeader(bool exception_on_error) throw(gdcmFormatError) {
        ElValue * newElValue = (ElValue *)0;
        
        rewind(fp);