1 | /* |
2 | * PROGRAM: Firebird exceptions classes |
3 | * MODULE: StatusHolder.h |
4 | * DESCRIPTION: Firebird's exception classes |
5 | * |
6 | * The contents of this file are subject to the Initial |
7 | * Developer's Public License Version 1.0 (the "License"); |
8 | * you may not use this file except in compliance with the |
9 | * License. You may obtain a copy of the License at |
10 | * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. |
11 | * |
12 | * Software distributed under the License is distributed AS IS, |
13 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. |
14 | * See the License for the specific language governing rights |
15 | * and limitations under the License. |
16 | * |
17 | * The Original Code was created by Vlad Khorsun |
18 | * for the Firebird Open Source RDBMS project. |
19 | * |
20 | * Copyright (c) 2007 Vlad Khorsun <hvlad at users.sourceforge.net> |
21 | * and all contributors signed below. |
22 | * |
23 | * All Rights Reserved. |
24 | * Contributor(s): ______________________________________. |
25 | * |
26 | * |
27 | */ |
28 | |
29 | #ifndef FB_STATUS_HOLDER |
30 | #define FB_STATUS_HOLDER |
31 | |
32 | #include "firebird/Provider.h" |
33 | #include "../common/utils_proto.h" |
34 | #include "../common/classes/ImplementHelper.h" |
35 | #include "../common/classes/array.h" |
36 | |
37 | namespace Firebird { |
38 | |
39 | class BaseStatus : public IStatus |
40 | { |
41 | public: |
42 | // IStatus implementation |
43 | virtual void FB_CARG set(const ISC_STATUS* value) |
44 | { |
45 | set(fb_utils::statusLength(value), value); |
46 | } |
47 | |
48 | virtual void FB_CARG set(unsigned int length, const ISC_STATUS* value) |
49 | { |
50 | fb_utils::copyStatus(vector, FB_NELEM(vector), value, length); |
51 | } |
52 | |
53 | virtual void FB_CARG init() |
54 | { |
55 | fb_utils::init_status(vector); |
56 | } |
57 | |
58 | virtual const ISC_STATUS* FB_CARG get() const |
59 | { |
60 | return vector; |
61 | } |
62 | |
63 | virtual int FB_CARG isSuccess() const |
64 | { |
65 | return vector[1] == 0; |
66 | } |
67 | |
68 | public: |
69 | BaseStatus() |
70 | { |
71 | init(); |
72 | } |
73 | |
74 | void check() |
75 | { |
76 | if (!isSuccess()) |
77 | status_exception::raise(get()); |
78 | } |
79 | |
80 | private: |
81 | ISC_STATUS vector[40]; // FixMe - may be a kind of dynamic storage will be better? |
82 | }; |
83 | |
84 | class LocalStatus : public AutoIface<BaseStatus, FB_STATUS_VERSION> |
85 | { |
86 | public: |
87 | virtual void FB_CARG dispose() |
88 | { } |
89 | }; |
90 | |
91 | |
92 | // This trivial container is used when we need to grow vector element by element w/o any conversions |
93 | typedef HalfStaticArray<ISC_STATUS, ISC_STATUS_LENGTH> SimpleStatusVector; |
94 | |
95 | |
96 | // DynamicStatusVector owns strings, contained in it |
97 | class DynamicStatusVector |
98 | { |
99 | public: |
100 | explicit DynamicStatusVector(const ISC_STATUS* status = NULL) |
101 | : m_status_vector(*getDefaultMemoryPool()) |
102 | { |
103 | ISC_STATUS* s = m_status_vector.getBuffer(ISC_STATUS_LENGTH); |
104 | fb_utils::init_status(s); |
105 | |
106 | if (status) |
107 | { |
108 | save(status); |
109 | } |
110 | } |
111 | |
112 | ~DynamicStatusVector() |
113 | { |
114 | clear(); |
115 | } |
116 | |
117 | ISC_STATUS save(const ISC_STATUS* status); |
118 | void clear(); |
119 | |
120 | ISC_STATUS getError() const |
121 | { |
122 | return value()[1]; |
123 | } |
124 | |
125 | const ISC_STATUS* value() const |
126 | { |
127 | return m_status_vector.begin(); |
128 | } |
129 | |
130 | bool isSuccess() const |
131 | { |
132 | return getError() == 0; |
133 | } |
134 | |
135 | ISC_STATUS& operator[](unsigned int index) |
136 | { |
137 | return m_status_vector[index]; |
138 | } |
139 | |
140 | private: |
141 | SimpleStatusVector m_status_vector; |
142 | }; |
143 | |
144 | |
145 | class StatusHolder |
146 | { |
147 | public: |
148 | explicit StatusHolder(const ISC_STATUS* status = NULL) |
149 | : m_status_vector(status), m_raised(false) |
150 | { } |
151 | |
152 | ISC_STATUS save(const ISC_STATUS* status); |
153 | void clear(); |
154 | void raise(); |
155 | |
156 | ISC_STATUS getError() |
157 | { |
158 | return value()[1]; |
159 | } |
160 | |
161 | const ISC_STATUS* value() |
162 | { |
163 | if (m_raised) { |
164 | clear(); |
165 | } |
166 | return m_status_vector.value(); |
167 | } |
168 | |
169 | bool isSuccess() |
170 | { |
171 | return getError() == 0; |
172 | } |
173 | |
174 | private: |
175 | DynamicStatusVector m_status_vector; |
176 | bool m_raised; |
177 | }; |
178 | |
179 | |
180 | } // namespace Firebird |
181 | |
182 | |
183 | #endif // FB_STATUS_HOLDER |
184 | |