libsex
3.1.0
simple exception library (C++)
|
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 }