blocxx
Exception.hpp
Go to the documentation of this file.
1/*******************************************************************************
2* Copyright (C) 2005, Vintela, Inc. All rights reserved.
3* Copyright (C) 2006, Novell, Inc. All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7*
8* * Redistributions of source code must retain the above copyright notice,
9* this list of conditions and the following disclaimer.
10* * Redistributions in binary form must reproduce the above copyright
11* notice, this list of conditions and the following disclaimer in the
12* documentation and/or other materials provided with the distribution.
13* * Neither the name of
14* Vintela, Inc.,
15* nor Novell, Inc.,
16* nor the names of its contributors or employees may be used to
17* endorse or promote products derived from this software without
18* specific prior written permission.
19*
20* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30* POSSIBILITY OF SUCH DAMAGE.
31*******************************************************************************/
32
33
38
39#ifndef BLOCXX_EXCEPTION_HPP_INCLUDE_GUARD_
40#define BLOCXX_EXCEPTION_HPP_INCLUDE_GUARD_
41#include "blocxx/BLOCXX_config.h"
42#include "blocxx/AutoPtr.hpp"
43#if defined(BLOCXX_NON_THREAD_SAFE_EXCEPTION_HANDLING)
44#include "blocxx/CommonFwd.hpp" // for Mutex
45#endif
46#include <iosfwd>
47#include <exception>
48#include <new>
49
50#include <cerrno>
51
52namespace BLOCXX_NAMESPACE
53{
54
65class BLOCXX_COMMON_API Exception : public std::exception
66{
67protected:
71 Exception(const char* file, int line, const char* msg) BLOCXX_DEPRECATED; // in 3.1.0
88 Exception(const char* file, int line, const char* msg, int errorCode, const Exception* otherException = 0, int subClassId = UNKNOWN_SUBCLASS_ID);
89
90 Exception(int subClassId, const char* file, int line, const char* msg, int errorCode,
91 const Exception* otherException = 0) BLOCXX_DEPRECATED; // in 3.1.0 -
92 // Had to change the order of the parameters so the subClassId could be
93 // defaulted and the subclasses' signature could match the base class signature.
94
95#ifdef BLOCXX_WIN32
96 // Can't seem to catch exceptions by reference if copy CTOR is
97 // protected on Windoz
98public:
99#endif
100 Exception(const Exception& e);
101 Exception& operator= (const Exception& rhs);
102#ifdef BLOCXX_WIN32
103protected:
104#endif
105 void swap(Exception& x);
106 void setSubClassId(int subClassId);
107 void setErrorCode(int errorCode);
108
109public:
110 virtual ~Exception() throw();
111
112 static const int UNKNOWN_SUBCLASS_ID = -1;
113 static const int UNKNOWN_ERROR_CODE = -1;
114
119 virtual const char* type() const;
124 virtual const char* getMessage() const;
128 const char* getFile() const;
129 int getLine() const;
130 int getSubClassId() const;
134 const Exception* getSubException() const;
140 int getErrorCode() const;
141
145 virtual const char* what() const throw();
146
158 virtual Exception* clone() const;
159
164 virtual void rethrow() const;
165
172 char* dupString(const char* str);
173
174private:
175 char* m_file;
177 char* m_msg;
181
182#if defined(BLOCXX_NON_THREAD_SAFE_EXCEPTION_HANDLING)
183 static Mutex* m_mutex;
184#endif
185
186};
187
188
189namespace ExceptionDetail
190{
191
192 // Reconciles GNU strerror_r and POSIX strerror_r.
193 //
194 BLOCXX_COMMON_API void portable_strerror_r(int errnum, char * buf, unsigned n);
195
196 struct BLOCXX_COMMON_API FormatMsgImpl;
197
198 class BLOCXX_COMMON_API FormatMsg
199 {
200
201#ifdef BLOCXX_WIN32
202#pragma warning (push)
203#pragma warning (disable: 4251)
204#endif
205
207
208#ifdef BLOCXX_WIN32
209#pragma warning (pop)
210#endif
211
212 public:
213 FormatMsg(char const * msg, int errnum);
214 ~FormatMsg();
215 char const * get() const;
216 private:
219 };
220
221 unsigned const BUFSZ = 1024;
222
223 template <typename exType>
224 struct Errno
225 {
226 static exType simple(char const * file, int line, int errnum)
227 {
228 char buf[BUFSZ];
229 portable_strerror_r(errnum, buf, BUFSZ);
230 return exType(file, line, buf, errnum);
231 }
232
233 template <typename Mtype>
234 static exType format(char const * file, int line,
235 Mtype const & msg, int errnum)
236 {
237 return format(file, line, msg.c_str(), errnum);
238 }
239
240 static exType format(char const * file, int line,
241 char const * msg, int errnum)
242 {
243 FormatMsg fm(msg, errnum);
244 return exType(file, line, fm.get(), errnum);
245 }
246 }; // struct Errno
247
248} // namespace ExceptionDetail
249
254BLOCXX_COMMON_API std::ostream& operator<< (std::ostream& os, const Exception& e);
255
263#define BLOCXX_THROW(exType, msg) throw exType(__FILE__, __LINE__, (msg))
264
268#define BLOCXX_THROWL(exType, line, msg) throw exType(__FILE__, (line), (msg))
269
277#define BLOCXX_THROW_SUBEX(exType, msg, subex) \
278throw exType(__FILE__, __LINE__, (msg), \
279 ::BLOCXX_NAMESPACE::Exception::UNKNOWN_ERROR_CODE, &(subex))
280
287#define BLOCXX_THROW_ERR(exType, msg, err) \
288throw exType(__FILE__, __LINE__, (msg), (err))
289
295#define BLOCXX_THROW_ERRNO(exType) BLOCXX_THROW_ERRNO1(exType, errno)
296
303#define BLOCXX_THROW_ERRNO1(exType, errnum) \
304throw ::BLOCXX_NAMESPACE::ExceptionDetail::Errno< exType >::simple(__FILE__, __LINE__, (errnum))
305
312#define BLOCXX_THROW_ERRNO_MSG(exType, msg) \
313BLOCXX_THROW_ERRNO_MSG1(exType, (msg), errno)
314
322#define BLOCXX_THROW_ERRNO_MSG1(exType, msg, errnum) \
323throw ::BLOCXX_NAMESPACE::ExceptionDetail::Errno< exType >:: \
324 format(__FILE__, __LINE__, (msg), (errnum))
325
334#define BLOCXX_THROW_ERR_SUBEX(exType, msg, err, subex) \
335throw exType(__FILE__, __LINE__, (msg), (err), &(subex))
336
344#define BLOCXX_DECLARE_EXCEPTION2(NAME, BASE) \
345class NAME##Exception : public BASE \
346{ \
347public: \
348 NAME##Exception(const char* file, int line, const char* msg, int errorCode = ::BLOCXX_NAMESPACE::Exception::UNKNOWN_ERROR_CODE, const Exception* otherException = 0, int subClassId = ::BLOCXX_NAMESPACE::Exception::UNKNOWN_SUBCLASS_ID); \
349 virtual ~NAME##Exception() throw(); \
350 virtual const char* type() const; \
351 virtual NAME##Exception* clone() const; \
352 virtual void rethrow() const; \
353};
354
366#define BLOCXX_DECLARE_APIEXCEPTION2(NAME, BASE, LINKAGE_SPEC) \
367class LINKAGE_SPEC NAME##Exception : public BASE \
368{ \
369public: \
370 NAME##Exception(const char* file, int line, const char* msg, int errorCode = ::BLOCXX_NAMESPACE::Exception::UNKNOWN_ERROR_CODE, const Exception* otherException = 0, int subClassId = ::BLOCXX_NAMESPACE::Exception::UNKNOWN_SUBCLASS_ID); \
371 virtual ~NAME##Exception() throw(); \
372 virtual const char* type() const; \
373 virtual NAME##Exception* clone() const; \
374 virtual void rethrow() const; \
375};
376
377
378
379
386#define BLOCXX_DECLARE_EXCEPTION(NAME) BLOCXX_DECLARE_EXCEPTION2(NAME, ::BLOCXX_NAMESPACE::Exception)
387
396#define BLOCXX_DECLARE_APIEXCEPTION(NAME, LINKAGE_SPEC) BLOCXX_DECLARE_APIEXCEPTION2(NAME, ::BLOCXX_NAMESPACE::Exception, LINKAGE_SPEC)
397
406#define BLOCXX_DEFINE_EXCEPTION2(NAME, BASE) \
407NAME##Exception::NAME##Exception(const char* file, int line, const char* msg, int errorCode, const ::BLOCXX_NAMESPACE::Exception* otherException, int subClassId) \
408 : BASE(file, line, msg, errorCode, otherException, subClassId) {} \
409NAME##Exception::~NAME##Exception() throw() { } \
410NAME##Exception* NAME##Exception::clone() const { return new(std::nothrow) NAME##Exception(*this); } \
411const char* NAME##Exception::type() const { return #NAME "Exception"; }\
412void NAME##Exception::rethrow() const { throw *this; }
413
423#define BLOCXX_DEFINE_EXCEPTION_WITH_BASE_AND_ID_AUX(NAME, BASE, SUB_CLASS_ID) \
424NAME##Exception::NAME##Exception(const char* file, int line, const char* msg, int errorCode, const ::BLOCXX_NAMESPACE::Exception* otherException, int subClassId) \
425 : BASE(file, line, msg, errorCode, otherException, subClassId == ::BLOCXX_NAMESPACE::Exception::UNKNOWN_SUBCLASS_ID ? (SUB_CLASS_ID) : subClassId) {} \
426NAME##Exception::~NAME##Exception() throw() { } \
427NAME##Exception* NAME##Exception::clone() const { return new(std::nothrow) NAME##Exception(*this); } \
428const char* NAME##Exception::type() const { return #NAME "Exception"; } \
429void NAME##Exception::rethrow() const { throw *this; }
430
439#define BLOCXX_DEFINE_EXCEPTION(NAME) BLOCXX_DEFINE_EXCEPTION_WITH_BASE_AND_ID_AUX(NAME, ::BLOCXX_NAMESPACE::Exception, ::BLOCXX_NAMESPACE::Exception::UNKNOWN_SUBCLASS_ID)
440
449#define BLOCXX_DEFINE_EXCEPTION_WITH_ID(NAME) BLOCXX_DEFINE_EXCEPTION_WITH_BASE_AND_ID_AUX(NAME, ::BLOCXX_NAMESPACE::Exception, ::BLOCXX_NAMESPACE::ExceptionIds::NAME##ExceptionId)
450
460#define BLOCXX_DEFINE_EXCEPTION_WITH_BASE_AND_ID(NAME, BASE) BLOCXX_DEFINE_EXCEPTION_WITH_BASE_AND_ID_AUX(NAME, BASE, ::BLOCXX_NAMESPACE::ExceptionIds::NAME##ExceptionId)
461
462} // end namespace BLOCXX_NAMESPACE
463
464#endif
The AutoPtr class provides a simple class for smart pointers to single objects (for multiple,...
Definition AutoPtr.hpp:63
FormatMsg & operator=(const FormatMsg &)
FormatMsg(char const *msg, int errnum)
static const int UNKNOWN_SUBCLASS_ID
virtual const char * what() const
Returns getMessage()
int getErrorCode() const
Returns the error code representing the error which occurred.
void setSubClassId(int subClassId)
virtual const char * getMessage() const
Returns the message.
const Exception * m_subException
Exception(const char *file, int line, const char *msg) BLOCXX_DEPRECATED
This constructor is deprecated.
Definition Exception.cpp:86
const char * getFile() const
Returns the file.
void setErrorCode(int errorCode)
virtual void rethrow() const
Re-throws the exception.
const Exception * getSubException() const
Returns the sub exception if available, otherwise 0.
virtual const char * type() const
Returns a string representing the concrete type.
static const int UNKNOWN_ERROR_CODE
void swap(Exception &x)
char * dupString(const char *str)
Utility function to copy a string.
Definition Exception.cpp:71
virtual Exception * clone() const
Make a copy of this exception object.
void portable_strerror_r(int errnum, char *buf, unsigned n)
Taken from RFC 1321.
ostream & operator<<(ostream &ostrm, const Bool &arg)
Definition Bool.cpp:77
static exType format(char const *file, int line, Mtype const &msg, int errnum)
static exType format(char const *file, int line, char const *msg, int errnum)
static exType simple(char const *file, int line, int errnum)