00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #ifndef OW_EXCEPTION_HPP_INCLUDE_GUARD_
00037 #define OW_EXCEPTION_HPP_INCLUDE_GUARD_
00038 #include "OW_config.h"
00039 #include "OW_AutoPtr.hpp"
00040 #if defined(OW_NON_THREAD_SAFE_EXCEPTION_HANDLING)
00041 #include "OW_CommonFwd.hpp"
00042 #endif
00043 #include <iosfwd>
00044 #include <exception>
00045 #include <new>
00046
00047 #include <cerrno>
00048
00049 namespace OW_NAMESPACE
00050 {
00051
00062 class OW_COMMON_API Exception : public std::exception
00063 {
00064 protected:
00068 Exception(const char* file, int line, const char* msg) OW_DEPRECATED;
00085 Exception(const char* file, int line, const char* msg, int errorCode, const Exception* otherException = 0, int subClassId = UNKNOWN_SUBCLASS_ID);
00086
00087 Exception(int subClassId, const char* file, int line, const char* msg, int errorCode,
00088 const Exception* otherException = 0) OW_DEPRECATED;
00089
00090
00091
00092 #ifdef OW_WIN32
00093
00094
00095 public:
00096 #endif
00097 Exception(const Exception& e);
00098 Exception& operator= (const Exception& rhs);
00099 #ifdef OW_WIN32
00100 protected:
00101 #endif
00102 void swap(Exception& x);
00103 virtual ~Exception() throw();
00104 void setSubClassId(int subClassId);
00105 void setErrorCode(int errorCode);
00106
00107 public:
00108
00109 static const int UNKNOWN_SUBCLASS_ID = -1;
00110 static const int UNKNOWN_ERROR_CODE = -1;
00111
00116 virtual const char* type() const;
00121 virtual const char* getMessage() const;
00125 const char* getFile() const;
00126 int getLine() const;
00127 int getSubClassId() const;
00131 const Exception* getSubException() const;
00137 int getErrorCode() const;
00138
00142 virtual const char* what() const throw();
00143
00155 virtual Exception* clone() const;
00156
00163 char* dupString(const char* str);
00164
00165 private:
00166 char* m_file;
00167 int m_line;
00168 char* m_msg;
00169 int m_subClassId;
00170 const Exception* m_subException;
00171 int m_errorCode;
00172
00173 #if defined(OW_NON_THREAD_SAFE_EXCEPTION_HANDLING)
00174 static Mutex* m_mutex;
00175 #endif
00176
00177 };
00178
00179
00180 namespace ExceptionDetail
00181 {
00182
00183
00184
00185 OW_COMMON_API void portable_strerror_r(int errnum, char * buf, unsigned n);
00186
00187 struct OW_COMMON_API FormatMsgImpl;
00188
00189 class OW_COMMON_API FormatMsg
00190 {
00191
00192 #ifdef OW_WIN32
00193 #pragma warning (push)
00194 #pragma warning (disable: 4251)
00195 #endif
00196
00197 AutoPtr<FormatMsgImpl> pImpl;
00198
00199 #ifdef OW_WIN32
00200 #pragma warning (pop)
00201 #endif
00202
00203 public:
00204 FormatMsg(char const * msg, int errnum);
00205 ~FormatMsg();
00206 char const * get() const;
00207 private:
00208 FormatMsg(const FormatMsg&);
00209 FormatMsg& operator=(const FormatMsg&);
00210 };
00211
00212 unsigned const BUFSZ = 1024;
00213
00214 template <typename exType>
00215 struct Errno
00216 {
00217 static exType simple(char const * file, int line, int errnum)
00218 {
00219 char buf[BUFSZ];
00220 portable_strerror_r(errnum, buf, BUFSZ);
00221 return exType(file, line, buf, errnum);
00222 }
00223
00224 template <typename Mtype>
00225 static exType format(char const * file, int line,
00226 Mtype const & msg, int errnum)
00227 {
00228 return format(file, line, msg.c_str(), errnum);
00229 }
00230
00231 static exType format(char const * file, int line,
00232 char const * msg, int errnum)
00233 {
00234 FormatMsg fm(msg, errnum);
00235 return exType(file, line, fm.get(), errnum);
00236 }
00237 };
00238
00239 }
00240
00245 OW_COMMON_API std::ostream& operator<< (std::ostream& os, const Exception& e);
00246
00254 #define OW_THROW(exType, msg) throw exType(__FILE__, __LINE__, (msg))
00255
00259 #define OW_THROWL(exType, line, msg) throw exType(__FILE__, (line), (msg))
00260
00268 #define OW_THROW_SUBEX(exType, msg, subex) \
00269 throw exType(__FILE__, __LINE__, (msg), \
00270 ::OW_NAMESPACE::Exception::UNKNOWN_ERROR_CODE, &(subex))
00271
00278 #define OW_THROW_ERR(exType, msg, err) \
00279 throw exType(__FILE__, __LINE__, (msg), (err))
00280
00286 #define OW_THROW_ERRNO(exType) OW_THROW_ERRNO1(exType, errno)
00287
00293 #define OW_THROW_ERRNO1(exType, errnum) \
00294 throw ExceptionDetail::Errno< exType >::simple(__FILE__, __LINE__, (errnum))
00295
00301 #define OW_THROW_ERRNO_MSG(exType, msg) \
00302 OW_THROW_ERRNO_MSG1(exType, (msg), errno)
00303
00309 #define OW_THROW_ERRNO_MSG1(exType, msg, errnum) \
00310 throw ExceptionDetail::Errno< exType >:: \
00311 format(__FILE__, __LINE__, (msg), (errnum))
00312
00321 #define OW_THROW_ERR_SUBEX(exType, msg, err, subex) \
00322 throw exType(__FILE__, __LINE__, (msg), (err), &(subex))
00323
00331 #define OW_DECLARE_EXCEPTION2(NAME, BASE) \
00332 class NAME##Exception : public BASE \
00333 { \
00334 public: \
00335 NAME##Exception(const char* file, int line, const char* msg, int errorCode = ::OW_NAMESPACE::Exception::UNKNOWN_ERROR_CODE, const Exception* otherException = 0, int subClassId = ::OW_NAMESPACE::Exception::UNKNOWN_SUBCLASS_ID); \
00336 virtual ~NAME##Exception() throw(); \
00337 virtual const char* type() const; \
00338 virtual NAME##Exception* clone() const; \
00339 };
00340
00352 #define OW_DECLARE_APIEXCEPTION2(NAME, BASE, LINKAGE_SPEC) \
00353 class LINKAGE_SPEC NAME##Exception : public BASE \
00354 { \
00355 public: \
00356 NAME##Exception(const char* file, int line, const char* msg, int errorCode = ::OW_NAMESPACE::Exception::UNKNOWN_ERROR_CODE, const Exception* otherException = 0, int subClassId = ::OW_NAMESPACE::Exception::UNKNOWN_SUBCLASS_ID); \
00357 virtual ~NAME##Exception() throw(); \
00358 virtual const char* type() const; \
00359 virtual NAME##Exception* clone() const; \
00360 };
00361
00362
00363
00364
00371 #define OW_DECLARE_EXCEPTION(NAME) OW_DECLARE_EXCEPTION2(NAME, ::OW_NAMESPACE::Exception)
00372
00381 #define OW_DECLARE_APIEXCEPTION(NAME, LINKAGE_SPEC) OW_DECLARE_APIEXCEPTION2(NAME, ::OW_NAMESPACE::Exception, LINKAGE_SPEC)
00382
00391 #define OW_DEFINE_EXCEPTION2(NAME, BASE) \
00392 NAME##Exception::NAME##Exception(const char* file, int line, const char* msg, int errorCode, const ::OW_NAMESPACE::Exception* otherException, int subClassId) \
00393 : BASE(file, line, msg, errorCode, otherException, subClassId) {} \
00394 NAME##Exception::~NAME##Exception() throw() { } \
00395 NAME##Exception* NAME##Exception::clone() const { return new(std::nothrow) NAME##Exception(*this); } \
00396 const char* NAME##Exception::type() const { return #NAME "Exception"; }
00397
00407 #define OW_DEFINE_EXCEPTION_WITH_BASE_AND_ID_AUX(NAME, BASE, SUB_CLASS_ID) \
00408 NAME##Exception::NAME##Exception(const char* file, int line, const char* msg, int errorCode, const ::OW_NAMESPACE::Exception* otherException, int subClassId) \
00409 : BASE(file, line, msg, errorCode, otherException, subClassId == ::OW_NAMESPACE::Exception::UNKNOWN_SUBCLASS_ID ? (SUB_CLASS_ID) : subClassId) {} \
00410 NAME##Exception::~NAME##Exception() throw() { } \
00411 NAME##Exception* NAME##Exception::clone() const { return new(std::nothrow) NAME##Exception(*this); } \
00412 const char* NAME##Exception::type() const { return #NAME "Exception"; }
00413
00422 #define OW_DEFINE_EXCEPTION(NAME) OW_DEFINE_EXCEPTION_WITH_BASE_AND_ID_AUX(NAME, ::OW_NAMESPACE::Exception, ::OW_NAMESPACE::Exception::UNKNOWN_SUBCLASS_ID)
00423
00432 #define OW_DEFINE_EXCEPTION_WITH_ID(NAME) OW_DEFINE_EXCEPTION_WITH_BASE_AND_ID_AUX(NAME, ::OW_NAMESPACE::Exception, ::OW_NAMESPACE::ExceptionIds::NAME##ExceptionId)
00433
00443 #define OW_DEFINE_EXCEPTION_WITH_BASE_AND_ID(NAME, BASE) OW_DEFINE_EXCEPTION_WITH_BASE_AND_ID_AUX(NAME, BASE, ::OW_NAMESPACE::ExceptionIds::NAME##ExceptionId)
00444
00445 }
00446
00447 #endif