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