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