From 953fdb8435f0957ba61cf9f0154ed0dc67d53981 Mon Sep 17 00:00:00 2001 From: johan Date: Sun, 16 Feb 2003 18:55:31 +0000 Subject: [PATCH] added exception classes --- src/Makefile.am | 4 +- src/gdcm.h | 16 ++++-- src/gdcmException.cxx | 86 ++++++++++++++++++++++++++++ src/gdcmException.h | 130 ++++++++++++++++++++++++++++++++++++++++++ src/gdcmHeader.cxx | 26 ++++++--- 5 files changed, 247 insertions(+), 15 deletions(-) create mode 100644 src/gdcmException.cxx create mode 100644 src/gdcmException.h diff --git a/src/Makefile.am b/src/Makefile.am index cf5612db..ae54fef0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/gdcm.h b/src/gdcm.h index 9d159fb9..aea4edc5 100644 --- a/src/gdcm.h +++ b/src/gdcm.h @@ -17,16 +17,19 @@ // 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 -#ifdef _MSC_VER -using namespace std; // string type lives in the std namespace on VC++ -#endif +using namespace std; #include #include // For size_t #include // FIXME For FILE on GCC only #include #include +#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 index 00000000..bc84810a --- /dev/null +++ b/src/gdcmException.cxx @@ -0,0 +1,86 @@ +#include "gdcmException.h" + +#include +#include + + +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 index 00000000..0938733b --- /dev/null +++ b/src/gdcmException.h @@ -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 +#include +#include +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 diff --git a/src/gdcmHeader.cxx b/src/gdcmHeader.cxx index afe3ed32..a79be6e6 100644 --- a/src/gdcmHeader.cxx +++ b/src/gdcmHeader.cxx @@ -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); -- 2.45.2