1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2009 Oracle.  All rights reserved.
5 *
6 * $Id$
7 */
8
9#ifndef _DB_STL_EXCEPTION_H
10#define _DB_STL_EXCEPTION_H
11
12#include <cstring>
13#include <cstdlib>
14#include <cstdio>
15
16#include <iostream>
17#include <exception>
18
19#include "dbstl_common.h"
20
21START_NS(dbstl)
22
23using std::cerr;
24
25// Internally used only.
26void _exported throw_bdb_exception(const char *caller, int err_ret);
27#define COPY_CONSTRUCTOR(type) type(const type& t) : DbstlException(t){}
28
29/** \defgroup Exception_classes_group dbstl exception classes
30dbstl throws several types of exceptions on several kinds of errors, the
31exception classes form a class hiarachy. First, there is the DbstlException,
32which is the base class for all types of dbstl specific concrete exception
33classes.
34DbstlException inherits from the class DbException of Berkeley DB C++ API. Since
35DbException class inherits from C++ STL exception base class std::exception,
36you can make use of all Berkeley DB C++ and dbstl API exceptions in the same
37way you use the C++ std::exception class.
38
39Besides exceptions of DbstlException and its subclasses, dbstl may also
40throw exceptions of DbException and its subclasses, which happens when a
41Berkeley DB call failed. So you should use the same way you catch Berkeley DB
42C++ API exceptions when you want to catch exceptions throw by Berkeley DB
43operations.
44
45When an exception occurs, dbstl initialize an local exception object on the
46stack and throws the exception object, so you should catch an exception like
47this:
48
49try {
50	// dbstl operations
51}
52catch(DbstlException ex){
53	// Exception handling
54	throw ex; // Optionally throw ex again
55}
56
57@{
58*/
59
60/// Base class of all dbstl exception classes. It is derived from Berkeley
61/// DB C++ API DbException class to maintain consistency with all
62/// Berkeley DB exceptions.
63///
64class _exported DbstlException : public DbException
65{
66public:
67	explicit DbstlException(const char *msg) : DbException(msg) {}
68	DbstlException(const char *msg, int err) : DbException(msg, err) {}
69	DbstlException(const DbstlException&ex) : DbException(ex) {}
70	explicit DbstlException(int err) : DbException(err) {}
71	DbstlException(const char *prefix, const char *msg, int err) :
72	    DbException(prefix, msg, err) {}
73
74	const DbstlException& operator=(const DbstlException&exobj)
75	{
76		ASSIGNMENT_PREDCOND(exobj)
77		DbException::operator =
78		    (dynamic_cast<const DbException&>(exobj));
79		return exobj;
80	}
81
82	virtual ~DbstlException() throw(){}
83};
84
85/// Failed to allocate memory because memory is not enough.
86class _exported NotEnoughMemoryException : public DbstlException
87{
88	size_t failed_size; // The size of the failed allocation.
89public:
90	NotEnoughMemoryException(const char *msg, size_t sz)
91	    : DbstlException(msg)
92	{
93		failed_size = sz;
94	}
95
96
97	NotEnoughMemoryException(const NotEnoughMemoryException &ex)
98	    : DbstlException(ex)
99	{
100		this->failed_size = ex.failed_size;
101	}
102};
103
104/// The iterator has inconsistent status, it is unable to be used any more.
105class _exported InvalidIteratorException : public DbstlException
106{
107public:
108	InvalidIteratorException() : DbstlException("Invalid Iterator")
109	{
110	}
111
112	explicit InvalidIteratorException(int error_code) :
113	    DbstlException("Invalid Iterator", error_code)
114	{
115	}
116	COPY_CONSTRUCTOR(InvalidIteratorException)
117};
118
119/// The cursor has inconsistent status, it is unable to be used any more.
120class _exported InvalidCursorException : public DbstlException
121{
122public:
123	InvalidCursorException() : DbstlException("Invalid cursor")
124	{
125	}
126
127	explicit InvalidCursorException(int error_code) :
128	    DbstlException("Invalid cursor", error_code)
129	{
130	}
131	COPY_CONSTRUCTOR(InvalidCursorException)
132};
133
134/// The Dbt object has inconsistent status or has no valid data, it is unable
135/// to be used any more.
136class _exported InvalidDbtException : public DbstlException
137{
138public:
139	InvalidDbtException() : DbstlException("Invalid Dbt object")
140	{
141	}
142
143	explicit InvalidDbtException(int error_code) :
144	    DbstlException("Invalid Dbt object", error_code)
145	{
146	}
147	COPY_CONSTRUCTOR(InvalidDbtException)
148};
149
150/// The assertions inside dbstl failed. The code file name and line number
151/// will be passed to the exception object of this class.
152class _exported FailedAssertionException : public DbstlException
153{
154private:
155	char *err_msg_;
156public:
157	virtual const char *what() const throw()
158	{
159		return err_msg_;
160	}
161
162	FailedAssertionException(const char *fname, size_t lineno,
163	    const char *msg) : DbstlException(0)
164	{
165		u_int32_t sz;
166		char *str;
167
168		str = (char *)DbstlMalloc(sz = (u_int32_t)(strlen(msg) +
169		    strlen(fname) + 128));
170		_snprintf(str, sz,
171		    "In file %s at line %u, %s expression failed",
172		    fname, (unsigned int)lineno, msg);
173		err_msg_ = str;
174#ifdef DEBUG
175		fprintf(stderr, "%s", str);
176#endif
177	}
178
179	FailedAssertionException(const FailedAssertionException&ex) :
180	    DbstlException(ex)
181	{
182		err_msg_ = (char *)DbstlMalloc((u_int32_t)
183		    strlen(ex.err_msg_) + 1);
184		strcpy(err_msg_, ex.err_msg_);
185	}
186	virtual ~FailedAssertionException() throw()
187	{
188		free(err_msg_);
189	}
190};
191
192/// There is no such key in the database. The key can't not be passed into
193/// the exception instance because this class has to be a class template for
194/// that to work.
195class _exported NoSuchKeyException : public DbstlException
196{
197public:
198	NoSuchKeyException()
199	    : DbstlException("\nNo such key in the container.")
200	{
201	}
202
203	COPY_CONSTRUCTOR(NoSuchKeyException)
204};
205
206/// Some argument of a function is invalid.
207class _exported InvalidArgumentException : public DbstlException
208{
209public:
210	explicit InvalidArgumentException(const char *errmsg) :
211	    DbstlException(errmsg)
212	{
213#ifdef DEBUG
214		cerr<<errmsg;
215#endif
216	}
217
218	InvalidArgumentException(const char *argtype, const char *arg) :
219	    DbstlException(argtype, arg, 0)
220	{
221#ifdef DEBUG
222		cerr<<"\nInvalid argument exception: "<<argtype<<"\t"<<arg;
223#endif
224	}
225
226	COPY_CONSTRUCTOR(InvalidArgumentException)
227};
228
229/// The function called is not supported in this class.
230class _exported NotSupportedException : public DbstlException
231{
232public:
233	explicit NotSupportedException(const char *str) : DbstlException(str)
234	{
235	}
236
237	COPY_CONSTRUCTOR(NotSupportedException)
238};
239
240/// The function can not be called in this context or in current configurations.
241class _exported InvalidFunctionCall : public DbstlException
242{
243public:
244	explicit InvalidFunctionCall(const char *str) : DbstlException(str)
245	{
246#ifdef DEBUG
247		cerr<<"\nInvalid function call: "<<str;
248#endif
249	}
250
251	COPY_CONSTRUCTOR(InvalidFunctionCall)
252};
253/** @}*/
254#undef COPY_CONSTRUCTOR
255END_NS
256
257#endif //_DB_STL_EXCEPTION_H
258