1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1997,2008 Oracle.  All rights reserved.
5 *
6 * $Id: cxx_except.cpp,v 12.14 2008/01/08 20:58:09 bostic Exp $
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12
13#include "db_cxx.h"
14#include "dbinc/cxx_int.h"
15
16static const int MAX_DESCRIPTION_LENGTH = 1024;
17
18// Note: would not be needed if we can inherit from exception
19// It does not appear to be possible to inherit from exception
20// with the current Microsoft library (VC5.0).
21//
22static char *dupString(const char *s)
23{
24	char *r = new char[strlen(s)+1];
25	strcpy(r, s);
26	return (r);
27}
28
29////////////////////////////////////////////////////////////////////////
30//                                                                    //
31//                            DbException                             //
32//                                                                    //
33////////////////////////////////////////////////////////////////////////
34
35DbException::~DbException() throw()
36{
37	delete [] what_;
38}
39
40DbException::DbException(int err)
41:	err_(err)
42,	dbenv_(0)
43{
44	describe(0, 0);
45}
46
47DbException::DbException(const char *description)
48:	err_(0)
49,	dbenv_(0)
50{
51	describe(0, description);
52}
53
54DbException::DbException(const char *description, int err)
55:	err_(err)
56,	dbenv_(0)
57{
58	describe(0, description);
59}
60
61DbException::DbException(const char *prefix, const char *description, int err)
62:	err_(err)
63,	dbenv_(0)
64{
65	describe(prefix, description);
66}
67
68DbException::DbException(const DbException &that)
69:	__DB_STD(exception)()
70,	what_(dupString(that.what_))
71,	err_(that.err_)
72,	dbenv_(0)
73{
74}
75
76DbException &DbException::operator = (const DbException &that)
77{
78	if (this != &that) {
79		err_ = that.err_;
80		delete [] what_;
81		what_ = dupString(that.what_);
82	}
83	return (*this);
84}
85
86void DbException::describe(const char *prefix, const char *description)
87{
88	char *msgbuf, *p, *end;
89
90	msgbuf = new char[MAX_DESCRIPTION_LENGTH];
91	p = msgbuf;
92	end = msgbuf + MAX_DESCRIPTION_LENGTH - 1;
93
94	if (prefix != NULL) {
95		strncpy(p, prefix, (p < end) ? end - p: 0);
96		p += strlen(prefix);
97		strncpy(p, ": ", (p < end) ? end - p: 0);
98		p += 2;
99	}
100	if (description != NULL) {
101		strncpy(p, description, (p < end) ? end - p: 0);
102		p += strlen(description);
103		if (err_ != 0) {
104			strncpy(p, ": ", (p < end) ? end - p: 0);
105			p += 2;
106		}
107	}
108	if (err_ != 0) {
109		strncpy(p, db_strerror(err_), (p < end) ? end - p: 0);
110		p += strlen(db_strerror(err_));
111	}
112
113	/*
114	 * If the result was too long, the buffer will not be null-terminated,
115	 * so we need to fix that here before duplicating it.
116	 */
117	if (p >= end)
118		*end = '\0';
119
120	what_ = dupString(msgbuf);
121	delete [] msgbuf;
122}
123
124int DbException::get_errno() const
125{
126	return (err_);
127}
128
129const char *DbException::what() const throw()
130{
131	return (what_);
132}
133
134DbEnv *DbException::get_env() const
135{
136	return dbenv_;
137}
138
139void DbException::set_env(DbEnv *dbenv)
140{
141	dbenv_= dbenv;
142}
143
144////////////////////////////////////////////////////////////////////////
145//                                                                    //
146//                            DbMemoryException                       //
147//                                                                    //
148////////////////////////////////////////////////////////////////////////
149
150static const char *memory_err_desc = "Dbt not large enough for available data";
151DbMemoryException::~DbMemoryException() throw()
152{
153}
154
155DbMemoryException::DbMemoryException(Dbt *dbt)
156:	DbException(memory_err_desc, DB_BUFFER_SMALL)
157,	dbt_(dbt)
158{
159}
160
161DbMemoryException::DbMemoryException(const char *prefix, Dbt *dbt)
162:	DbException(prefix, memory_err_desc, DB_BUFFER_SMALL)
163,	dbt_(dbt)
164{
165}
166
167DbMemoryException::DbMemoryException(const DbMemoryException &that)
168:	DbException(that)
169,	dbt_(that.dbt_)
170{
171}
172
173DbMemoryException
174&DbMemoryException::operator =(const DbMemoryException &that)
175{
176	if (this != &that) {
177		DbException::operator=(that);
178		dbt_ = that.dbt_;
179	}
180	return (*this);
181}
182
183Dbt *DbMemoryException::get_dbt() const
184{
185	return (dbt_);
186}
187
188////////////////////////////////////////////////////////////////////////
189//                                                                    //
190//                            DbDeadlockException                     //
191//                                                                    //
192////////////////////////////////////////////////////////////////////////
193
194DbDeadlockException::~DbDeadlockException() throw()
195{
196}
197
198DbDeadlockException::DbDeadlockException(const char *description)
199:	DbException(description, DB_LOCK_DEADLOCK)
200{
201}
202
203DbDeadlockException::DbDeadlockException(const DbDeadlockException &that)
204:	DbException(that)
205{
206}
207
208DbDeadlockException
209&DbDeadlockException::operator =(const DbDeadlockException &that)
210{
211	if (this != &that)
212		DbException::operator=(that);
213	return (*this);
214}
215
216////////////////////////////////////////////////////////////////////////
217//                                                                    //
218//                            DbLockNotGrantedException               //
219//                                                                    //
220////////////////////////////////////////////////////////////////////////
221
222DbLockNotGrantedException::~DbLockNotGrantedException() throw()
223{
224	delete lock_;
225}
226
227DbLockNotGrantedException::DbLockNotGrantedException(const char *prefix,
228    db_lockop_t op, db_lockmode_t mode, const Dbt *obj, const DbLock lock,
229    int index)
230:	DbException(prefix, DbEnv::strerror(DB_LOCK_NOTGRANTED),
231		    DB_LOCK_NOTGRANTED)
232,	op_(op)
233,	mode_(mode)
234,	obj_(obj)
235,	lock_(new DbLock(lock))
236,	index_(index)
237{
238}
239
240DbLockNotGrantedException::DbLockNotGrantedException(const char *description)
241:	DbException(description, DB_LOCK_NOTGRANTED)
242,	op_(DB_LOCK_GET)
243,	mode_(DB_LOCK_NG)
244,	obj_(NULL)
245,	lock_(NULL)
246,	index_(0)
247{
248}
249
250DbLockNotGrantedException::DbLockNotGrantedException
251    (const DbLockNotGrantedException &that)
252:	DbException(that)
253{
254	op_ = that.op_;
255	mode_ = that.mode_;
256	obj_ = that.obj_;
257	lock_ = (that.lock_ != NULL) ? new DbLock(*that.lock_) : NULL;
258	index_ = that.index_;
259}
260
261DbLockNotGrantedException
262&DbLockNotGrantedException::operator =(const DbLockNotGrantedException &that)
263{
264	if (this != &that) {
265		DbException::operator=(that);
266		op_ = that.op_;
267		mode_ = that.mode_;
268		obj_ = that.obj_;
269		lock_ = (that.lock_ != NULL) ? new DbLock(*that.lock_) : NULL;
270		index_ = that.index_;
271	}
272	return (*this);
273}
274
275db_lockop_t DbLockNotGrantedException::get_op() const
276{
277	return op_;
278}
279
280db_lockmode_t DbLockNotGrantedException::get_mode() const
281{
282	return mode_;
283}
284
285const Dbt* DbLockNotGrantedException::get_obj() const
286{
287	return obj_;
288}
289
290DbLock* DbLockNotGrantedException::get_lock() const
291{
292	return lock_;
293}
294
295int DbLockNotGrantedException::get_index() const
296{
297	return index_;
298}
299
300////////////////////////////////////////////////////////////////////////
301//                                                                    //
302//                            DbRepHandleDeadException                //
303//                                                                    //
304////////////////////////////////////////////////////////////////////////
305
306DbRepHandleDeadException::~DbRepHandleDeadException() throw()
307{
308}
309
310DbRepHandleDeadException::DbRepHandleDeadException(const char *description)
311:	DbException(description, DB_REP_HANDLE_DEAD)
312{
313}
314
315DbRepHandleDeadException::DbRepHandleDeadException
316    (const DbRepHandleDeadException &that)
317:	DbException(that)
318{
319}
320
321DbRepHandleDeadException
322&DbRepHandleDeadException::operator =(const DbRepHandleDeadException &that)
323{
324	if (this != &that)
325		DbException::operator=(that);
326	return (*this);
327}
328
329////////////////////////////////////////////////////////////////////////
330//                                                                    //
331//                            DbRunRecoveryException                  //
332//                                                                    //
333////////////////////////////////////////////////////////////////////////
334
335DbRunRecoveryException::~DbRunRecoveryException() throw()
336{
337}
338
339DbRunRecoveryException::DbRunRecoveryException(const char *description)
340:	DbException(description, DB_RUNRECOVERY)
341{
342}
343
344DbRunRecoveryException::DbRunRecoveryException
345    (const DbRunRecoveryException &that)
346:	DbException(that)
347{
348}
349
350DbRunRecoveryException
351&DbRunRecoveryException::operator =(const DbRunRecoveryException &that)
352{
353	if (this != &that)
354		DbException::operator=(that);
355	return (*this);
356}
357