00001 #ifndef _DHT_EXCEPTION_H_ 00002 #define _DHT_EXCEPTION_H_ 00003 00014 #include <exception> 00015 #include <stdarg.h> 00016 00017 #include "common.h" 00018 00019 namespace dht { 00039 class exception : public std::exception { 00040 private: 00041 const char *_str; 00042 public: 00043 exception(const char *reason) : 00044 _str(reason) { 00045 ACE_ERROR((LM_ERROR, "dht::exception: %s\n", reason)); 00046 } 00047 virtual ~exception() throw(); 00048 00052 virtual const char *what() const throw() { return _str; } 00053 }; 00054 00055 00056 class exceptionf : public dht::exception { 00057 private: 00058 char _str_store[256]; 00059 protected: 00060 inline void _initv(const char *format, va_list a) { 00061 vsnprintf(_str_store, sizeof(_str_store)/sizeof(_str_store[0]), 00062 format, a); 00063 } 00064 struct initv_ctor {}; 00065 exceptionf(const char *format, initv_ctor) 00066 : exception(format) {} 00067 public: 00068 exceptionf(const char *format, ...) 00069 : exception(format) { 00070 va_list a; 00071 va_start(a, format); 00072 _initv(format, a); 00073 va_end(a); 00074 } 00075 virtual ~exceptionf() throw(); 00076 virtual const char *what() const throw() { return _str_store; } 00077 }; 00078 00079 template <typename ParentType = exception> 00080 class exception_class : public ParentType { 00081 public: 00082 exception_class(const char *reason) : ParentType(reason) {} 00083 }; 00084 00085 template <typename ParentType = exceptionf> 00086 class exception_classf : public ParentType { 00087 public: 00088 exception_classf(const char *format, ...) 00089 : ParentType(format, typename ParentType::initv_ctor()) { 00090 va_list a; 00091 va_start(a, format); 00092 ParentType::_initv(format, a); 00093 va_end(a); 00094 } 00095 }; 00096 00097 #define _DHT_EXCEPTION_CLASS(name) \ 00098 typedef exception_class<> name;\ 00099 typedef exception_classf<> name##f; 00100 00101 #define _DHT_EXCEPTION_SUBCLASS(name, parent) \ 00102 typedef exception_class<parent> name;\ 00103 typedef exception_classf<parent##f> name##f; 00104 00105 _DHT_EXCEPTION_CLASS(call_error) 00106 _DHT_EXCEPTION_CLASS(operation_error) 00107 _DHT_EXCEPTION_CLASS(io_error) 00108 _DHT_EXCEPTION_CLASS(unexpected_error) 00109 00110 } 00111 00112 #endif //_DHT_EXCEPTION_H_