1 /***************************************************************************
2 $RCSfile$
3 -------------------
4 cvs : $Id$
5 begin : Sun Jan 25 2004
6 copyright : (C) 2004 by Martin Preuss
7 email : martin@libchipcard.de
8
9 ***************************************************************************
10 * *
11 * This library is free software; you can redistribute it and/or *
12 * modify it under the terms of the GNU Lesser General Public *
13 * License as published by the Free Software Foundation; either *
14 * version 2.1 of the License, or (at your option) any later version. *
15 * *
16 * This library is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
19 * Lesser General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU Lesser General Public *
22 * License along with this library; if not, write to the Free Software *
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
24 * MA 02111-1307 USA *
25 * *
26 ***************************************************************************/
27
28
29 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif
32
33 #include "refptr_p.h"
34 #include <gwenhywfar/misc.h>
35 #include <gwenhywfar/debug.h>
36 #include <stdlib.h>
37
38
39
GWEN_RefPtrObject_new(void * dp,GWEN_REFPTR_INFO * rpi)40 GWEN_REFPTR_POBJECT *GWEN_RefPtrObject_new(void *dp, GWEN_REFPTR_INFO *rpi)
41 {
42 GWEN_REFPTR_POBJECT *rpo;
43
44 GWEN_NEW_OBJECT(GWEN_REFPTR_POBJECT, rpo);
45 rpo->refCount=1;
46 rpo->ptr=dp;
47 rpo->infoPtr=rpi;
48 if (rpi)
49 GWEN_RefPtrInfo_Attach(rpi);
50 return rpo;
51 }
52
53
54
GWEN_RefPtrObject_free(GWEN_REFPTR_POBJECT * rpo)55 void GWEN_RefPtrObject_free(GWEN_REFPTR_POBJECT *rpo)
56 {
57 if (rpo) {
58 assert(rpo->refCount);
59 if (--(rpo->refCount)==0) {
60 DBG_VERBOUS(GWEN_LOGDOMAIN, "Freeing GWEN_RefPtrObject");
61 if ((rpo->flags & GWEN_REFPTR_FLAGS_AUTODELETE) &&
62 rpo->infoPtr &&
63 rpo->ptr) {
64 if (rpo->infoPtr->freeFn)
65 rpo->infoPtr->freeFn(rpo->ptr);
66 }
67 GWEN_FREE_OBJECT(rpo);
68 }
69 }
70 }
71
72
73
GWEN_RefPtrObject_Attach(GWEN_REFPTR_POBJECT * rpo)74 void GWEN_RefPtrObject_Attach(GWEN_REFPTR_POBJECT *rpo)
75 {
76 assert(rpo);
77 assert(rpo->refCount);
78 rpo->refCount++;
79 }
80
81
82
GWEN_RefPtrInfo_GetFlags(const GWEN_REFPTR_INFO * rpi)83 uint32_t GWEN_RefPtrInfo_GetFlags(const GWEN_REFPTR_INFO *rpi)
84 {
85 assert(rpi);
86 return rpi->flags;
87 }
88
89
90
GWEN_RefPtrInfo_SetFlags(GWEN_REFPTR_INFO * rpi,uint32_t fl)91 void GWEN_RefPtrInfo_SetFlags(GWEN_REFPTR_INFO *rpi, uint32_t fl)
92 {
93 assert(rpi);
94 rpi->flags=fl;
95 }
96
97
98
GWEN_RefPtrInfo_AddFlags(GWEN_REFPTR_INFO * rpi,uint32_t fl)99 void GWEN_RefPtrInfo_AddFlags(GWEN_REFPTR_INFO *rpi, uint32_t fl)
100 {
101 assert(rpi);
102 rpi->flags|=fl;
103 }
104
105
106
GWEN_RefPtrInfo_DelFlags(GWEN_REFPTR_INFO * rpi,uint32_t fl)107 void GWEN_RefPtrInfo_DelFlags(GWEN_REFPTR_INFO *rpi, uint32_t fl)
108 {
109 assert(rpi);
110 rpi->flags&=~fl;
111 }
112
113
114
115
116
117
118
119
120
121
GWEN_RefPtrInfo_new(void)122 GWEN_REFPTR_INFO *GWEN_RefPtrInfo_new(void)
123 {
124 GWEN_REFPTR_INFO *rpi;
125
126 GWEN_NEW_OBJECT(GWEN_REFPTR_INFO, rpi);
127 rpi->refCount=1;
128
129 return rpi;
130 }
131
132
133
GWEN_RefPtrInfo_free(GWEN_REFPTR_INFO * rpi)134 void GWEN_RefPtrInfo_free(GWEN_REFPTR_INFO *rpi)
135 {
136 if (rpi) {
137 assert(rpi->refCount);
138 if (--(rpi->refCount)==0) {
139 DBG_VERBOUS(GWEN_LOGDOMAIN, "Freeing GWEN_RefPtrInfo");
140 GWEN_FREE_OBJECT(rpi);
141 }
142 }
143 }
144
145
146
GWEN_RefPtrInfo_Attach(GWEN_REFPTR_INFO * rpi)147 void GWEN_RefPtrInfo_Attach(GWEN_REFPTR_INFO *rpi)
148 {
149 assert(rpi);
150 assert(rpi->refCount);
151 rpi->refCount++;
152 }
153
154
155
GWEN_RefPtrInfo_SetFreeFn(GWEN_REFPTR_INFO * rpi,GWEN_REFPTR_INFO_FREE_FN f)156 void GWEN_RefPtrInfo_SetFreeFn(GWEN_REFPTR_INFO *rpi,
157 GWEN_REFPTR_INFO_FREE_FN f)
158 {
159 assert(rpi);
160 rpi->freeFn=f;
161 }
162
163
164
GWEN_RefPtrInfo_SetDupFn(GWEN_REFPTR_INFO * rpi,GWEN_REFPTR_INFO_DUP_FN f)165 void GWEN_RefPtrInfo_SetDupFn(GWEN_REFPTR_INFO *rpi,
166 GWEN_REFPTR_INFO_DUP_FN f)
167 {
168 assert(rpi);
169 rpi->dupFn=f;
170 }
171
172
173
174
175
176
177
178
179
180
181
182
183
GWEN_RefPtr_new(void * dp,GWEN_REFPTR_INFO * rpi)184 GWEN_REFPTR *GWEN_RefPtr_new(void *dp, GWEN_REFPTR_INFO *rpi)
185 {
186 GWEN_REFPTR *rp;
187
188 GWEN_NEW_OBJECT(GWEN_REFPTR, rp);
189 rp->objectPtr=GWEN_RefPtrObject_new(dp, rpi);
190 if (rpi)
191 rp->objectPtr->flags=rpi->flags;
192 return rp;
193 }
194
195
196
GWEN_RefPtr_free(GWEN_REFPTR * rp)197 void GWEN_RefPtr_free(GWEN_REFPTR *rp)
198 {
199 if (rp) {
200 DBG_VERBOUS(GWEN_LOGDOMAIN, "Freeing GWEN_RefPtr");
201 GWEN_RefPtrObject_free(rp->objectPtr);
202 GWEN_FREE_OBJECT(rp);
203 }
204 }
205
206
207
GWEN_RefPtr_dup(const GWEN_REFPTR * rp)208 GWEN_REFPTR *GWEN_RefPtr_dup(const GWEN_REFPTR *rp)
209 {
210 GWEN_REFPTR *nrp;
211
212 assert(rp);
213 GWEN_NEW_OBJECT(GWEN_REFPTR, nrp);
214 nrp->objectPtr=rp->objectPtr;
215 GWEN_RefPtrObject_Attach(nrp->objectPtr);
216 return nrp;
217 }
218
219
220
GWEN_RefPtr_copy(const GWEN_REFPTR * rp)221 GWEN_REFPTR *GWEN_RefPtr_copy(const GWEN_REFPTR *rp)
222 {
223 GWEN_REFPTR *nrp;
224
225 assert(rp);
226 if (rp->objectPtr) {
227 if (rp->objectPtr->ptr) {
228 if (rp->objectPtr->infoPtr) {
229 if (rp->objectPtr->infoPtr->dupFn) {
230 void *p;
231
232 p=rp->objectPtr->infoPtr->dupFn(rp->objectPtr->ptr);
233 nrp=GWEN_RefPtr_new(p, rp->objectPtr->infoPtr);
234 return nrp;
235 }
236 }
237 }
238 }
239 return 0;
240 }
241
242
243
GWEN_RefPtr_GetData(const GWEN_REFPTR * rp)244 void *GWEN_RefPtr_GetData(const GWEN_REFPTR *rp)
245 {
246 if (!rp)
247 return 0;
248 if (rp->objectPtr) {
249 return rp->objectPtr->ptr;
250 }
251 return 0;
252 }
253
254
255
GWEN_RefPtr_SetData(GWEN_REFPTR * rp,void * dp,GWEN_REFPTR_INFO * rpi)256 void GWEN_RefPtr_SetData(GWEN_REFPTR *rp, void *dp, GWEN_REFPTR_INFO *rpi)
257 {
258 assert(rp);
259
260 if (rp->objectPtr) {
261 GWEN_RefPtrObject_free(rp->objectPtr);
262 }
263 rp->objectPtr=GWEN_RefPtrObject_new(dp, rpi);
264 }
265
266
267
GWEN_RefPtr_GetFlags(const GWEN_REFPTR * rp)268 uint32_t GWEN_RefPtr_GetFlags(const GWEN_REFPTR *rp)
269 {
270 assert(rp);
271 if (rp->objectPtr)
272 return rp->objectPtr->flags;
273 DBG_INFO(GWEN_LOGDOMAIN, "No object in RefPtr");
274 return 0;
275 }
276
277
278
GWEN_RefPtr_SetFlags(GWEN_REFPTR * rp,uint32_t fl)279 void GWEN_RefPtr_SetFlags(GWEN_REFPTR *rp, uint32_t fl)
280 {
281 assert(rp);
282 if (rp->objectPtr)
283 rp->objectPtr->flags=fl;
284 else {
285 DBG_INFO(GWEN_LOGDOMAIN, "No object in RefPtr");
286 }
287 }
288
289
290
GWEN_RefPtr_AddFlags(GWEN_REFPTR * rp,uint32_t fl)291 void GWEN_RefPtr_AddFlags(GWEN_REFPTR *rp, uint32_t fl)
292 {
293 assert(rp);
294 if (rp->objectPtr)
295 rp->objectPtr->flags|=fl;
296 else {
297 DBG_INFO(GWEN_LOGDOMAIN, "No object in RefPtr");
298 }
299 }
300
301
302
GWEN_RefPtr_DelFlags(GWEN_REFPTR * rp,uint32_t fl)303 void GWEN_RefPtr_DelFlags(GWEN_REFPTR *rp, uint32_t fl)
304 {
305 assert(rp);
306 if (rp->objectPtr)
307 rp->objectPtr->flags&=~fl;
308 else {
309 DBG_INFO(GWEN_LOGDOMAIN, "No object in RefPtr");
310 }
311 }
312
313
314
315
316
317
318
319
320
321