libsex  3.1.0
simple exception library (C++)
/home/ptr/dev/dev-libs/libsex/libsex/Exception.cxx
Go to the documentation of this file.
00001 /**
00002  * @file
00003  *
00004  * Definition of @ref libsex::Exception.
00005  */
00006 
00007 #include <libsex/Exception.hxx>
00008 #include <cstring> // strncpy()
00009 
00010 libsex::Exception::Exception(const char* const message)
00011 throw()
00012 : _previous(0)
00013 {
00014         _initMessage(message);
00015 }
00016 
00017 libsex::Exception::Exception(
00018         const char* const message,
00019         const Exception& previous)
00020 throw()
00021 : _previous(0)
00022 {
00023         _initMessage(message);
00024         try {
00025                 _previous = previous.clone();
00026         } catch (std::bad_alloc& e) {
00027                 // We need to know the amount of characters
00028                 // that can be put into _message.
00029 
00030                 // Size to begin with:
00031                 unsigned int length = Exception::LENGTH;
00032                 // Substract characters written so far:
00033                 length -= strlen(_message);
00034                 // Substract nullbyte appended by strcat().
00035                 // Prevent underflow.
00036                 if (length > 0) --length;
00037 
00038                 // Add notice to our original message:
00039                 strncat(_message, "\n"
00040                         "std::bad_alloc while cloning Exception!",
00041                         length);
00042         }
00043 }
00044 
00045 libsex::Exception::~Exception()
00046 throw()
00047 {
00048         if (_previous) delete _previous;
00049 }
00050 
00051 void libsex::Exception::write(std::ostream& out) const
00052 throw(std::ios_base::failure)
00053 {
00054         out << what();
00055 }
00056 
00057 void libsex::Exception::backtrace(std::ostream& out) const
00058 throw(std::ios_base::failure)
00059 {
00060         write(out);
00061         if (_previous != 0) {
00062                 out << "\n";
00063                 _previous->backtrace(out);
00064         }
00065 }
00066 
00067 const libsex::Exception* libsex::Exception::clone() const
00068 throw(std::bad_alloc)
00069 {
00070         if (_previous) {
00071                 return new Exception(_message, *_previous);
00072         } else {
00073                 return new Exception(_message);
00074         }
00075 }
00076 
00077 const char* libsex::Exception::what() const
00078 throw()
00079 {
00080         return _message;
00081 }
00082 
00083 void libsex::Exception::_initMessage(const char* const message)
00084 {
00085         strncpy(_message, message, Exception::LENGTH);
00086         // if |message| < |_message|
00087         //      strncpy() will pad with 0
00088         // else
00089         //      strncpy() will NOT add a trailing 0!
00090         _message[Exception::LENGTH] = 0;
00091 }
 All Classes Files Functions Variables Defines