xref: /trunk/main/cppu/source/uno/destr.hxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #ifndef DESTR_HXX
28 #define DESTR_HXX
29 
30 #include "prim.hxx"
31 
32 
33 namespace cppu
34 {
35 
36 //##################################################################################################
37 //#### destruction #################################################################################
38 //##################################################################################################
39 
40 //--------------------------------------------------------------------------------------------------
41 inline void _destructUnion(
42     void * pValue,
43     typelib_TypeDescription * pTypeDescr,
44     uno_ReleaseFunc release )
45     SAL_THROW( () )
46 {
47     typelib_TypeDescriptionReference * pType = _unionGetSetType( pValue, pTypeDescr );
48     ::uno_type_destructData(
49         (char *)pValue + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
50         pType, release );
51     ::typelib_typedescriptionreference_release( pType );
52 }
53 //==================================================================================================
54 void destructStruct(
55     void * pValue,
56     typelib_CompoundTypeDescription * pTypeDescr,
57     uno_ReleaseFunc release )
58     SAL_THROW( () );
59 //--------------------------------------------------------------------------------------------------
60 inline void _destructStruct(
61     void * pValue,
62     typelib_CompoundTypeDescription * pTypeDescr,
63     uno_ReleaseFunc release )
64     SAL_THROW( () )
65 {
66     if (pTypeDescr->pBaseTypeDescription)
67     {
68         destructStruct( pValue, pTypeDescr->pBaseTypeDescription, release );
69     }
70 
71     typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
72     sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
73     sal_Int32 nDescr = pTypeDescr->nMembers;
74     while (nDescr--)
75     {
76         ::uno_type_destructData(
77             (char *)pValue + pMemberOffsets[nDescr],
78             ppTypeRefs[nDescr], release );
79     }
80 }
81 
82 //--------------------------------------------------------------------------------------------------
83 inline void _destructArray(
84     void * pValue,
85     typelib_ArrayTypeDescription * pTypeDescr,
86     uno_ReleaseFunc release )
87     throw ()
88 {
89     typelib_TypeDescription * pElementType = NULL;
90     TYPELIB_DANGER_GET( &pElementType, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );
91     sal_Int32 nElementSize = pElementType->nSize;
92     TYPELIB_DANGER_RELEASE( pElementType );
93 
94     sal_Int32 nTotalElements = pTypeDescr->nTotalElements;
95     for(sal_Int32 i=0; i < nTotalElements; i++)
96     {
97         ::uno_type_destructData(
98             (sal_Char *)pValue + i * nElementSize,
99             ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, release );
100     }
101 
102     typelib_typedescriptionreference_release(((typelib_IndirectTypeDescription *)pTypeDescr)->pType);
103 }
104 
105 //==============================================================================
106 void destructSequence(
107     uno_Sequence * pSequence,
108     typelib_TypeDescriptionReference * pType,
109     typelib_TypeDescription * pTypeDescr,
110     uno_ReleaseFunc release );
111 
112 //--------------------------------------------------------------------------------------------------
113 inline void _destructAny(
114     uno_Any * pAny,
115     uno_ReleaseFunc release )
116     SAL_THROW( () )
117 {
118     typelib_TypeDescriptionReference * pType = pAny->pType;
119 
120     switch (pType->eTypeClass)
121     {
122     case typelib_TypeClass_HYPER:
123     case typelib_TypeClass_UNSIGNED_HYPER:
124         if (sizeof(void *) < sizeof(sal_Int64))
125         {
126             ::rtl_freeMemory( pAny->pData );
127         }
128         break;
129     case typelib_TypeClass_FLOAT:
130         if (sizeof(void *) < sizeof(float))
131         {
132             ::rtl_freeMemory( pAny->pData );
133         }
134         break;
135     case typelib_TypeClass_DOUBLE:
136         if (sizeof(void *) < sizeof(double))
137         {
138             ::rtl_freeMemory( pAny->pData );
139         }
140         break;
141     case typelib_TypeClass_STRING:
142         ::rtl_uString_release( (rtl_uString *)pAny->pReserved );
143         break;
144     case typelib_TypeClass_TYPE:
145         ::typelib_typedescriptionreference_release(
146             (typelib_TypeDescriptionReference *)pAny->pReserved );
147         break;
148     case typelib_TypeClass_ANY:
149         OSL_ENSURE( sal_False, "### unexpected nested any!" );
150         ::uno_any_destruct( (uno_Any *)pAny->pData, release );
151         ::rtl_freeMemory( pAny->pData );
152         break;
153     case typelib_TypeClass_TYPEDEF:
154         OSL_ENSURE( 0, "### unexpected typedef!" );
155         break;
156     case typelib_TypeClass_STRUCT:
157     case typelib_TypeClass_EXCEPTION:
158     {
159         typelib_TypeDescription * pTypeDescr = 0;
160         TYPELIB_DANGER_GET( &pTypeDescr, pType );
161         _destructStruct( pAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr, release );
162         TYPELIB_DANGER_RELEASE( pTypeDescr );
163         ::rtl_freeMemory( pAny->pData );
164         break;
165     }
166     case typelib_TypeClass_UNION:
167     {
168         typelib_TypeDescription * pTypeDescr = 0;
169         TYPELIB_DANGER_GET( &pTypeDescr, pType );
170         _destructUnion( pAny->pData, pTypeDescr, release );
171         TYPELIB_DANGER_RELEASE( pTypeDescr );
172         ::rtl_freeMemory( pAny->pData );
173         break;
174     }
175     case typelib_TypeClass_SEQUENCE:
176     {
177         destructSequence(
178             *(uno_Sequence **) &pAny->pReserved, pType, 0, release );
179         break;
180     }
181     case typelib_TypeClass_INTERFACE:
182         _release( pAny->pReserved, release );
183         break;
184     default:
185         break;
186     }
187 #if OSL_DEBUG_LEVEL > 0
188     pAny->pData = (void *)0xdeadbeef;
189 #endif
190 
191     ::typelib_typedescriptionreference_release( pType );
192 }
193 //--------------------------------------------------------------------------------------------------
194 inline sal_Int32 idestructElements(
195     void * pElements, typelib_TypeDescriptionReference * pElementType,
196     sal_Int32 nStartIndex, sal_Int32 nStopIndex,
197     uno_ReleaseFunc release )
198     SAL_THROW( () )
199 {
200     switch (pElementType->eTypeClass)
201     {
202     case typelib_TypeClass_CHAR:
203         return (sal_Int32)(sizeof(sal_Unicode));
204     case typelib_TypeClass_BOOLEAN:
205         return (sal_Int32)(sizeof(sal_Bool));
206     case typelib_TypeClass_BYTE:
207         return (sal_Int32)(sizeof(sal_Int8));
208     case typelib_TypeClass_SHORT:
209     case typelib_TypeClass_UNSIGNED_SHORT:
210         return (sal_Int32)(sizeof(sal_Int16));
211     case typelib_TypeClass_LONG:
212     case typelib_TypeClass_UNSIGNED_LONG:
213         return (sal_Int32)(sizeof(sal_Int32));
214     case typelib_TypeClass_HYPER:
215     case typelib_TypeClass_UNSIGNED_HYPER:
216         return (sal_Int32)(sizeof(sal_Int64));
217     case typelib_TypeClass_FLOAT:
218         return (sal_Int32)(sizeof(float));
219     case typelib_TypeClass_DOUBLE:
220         return (sal_Int32)(sizeof(double));
221 
222     case typelib_TypeClass_STRING:
223     {
224         rtl_uString ** pDest = (rtl_uString **)pElements;
225         for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
226         {
227             ::rtl_uString_release( pDest[nPos] );
228         }
229         return (sal_Int32)(sizeof(rtl_uString *));
230     }
231     case typelib_TypeClass_TYPE:
232     {
233         typelib_TypeDescriptionReference ** pDest = (typelib_TypeDescriptionReference **)pElements;
234         for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
235         {
236             ::typelib_typedescriptionreference_release( pDest[nPos] );
237         }
238         return (sal_Int32)(sizeof(typelib_TypeDescriptionReference *));
239     }
240     case typelib_TypeClass_ANY:
241     {
242         uno_Any * pDest = (uno_Any *)pElements;
243         for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
244         {
245             _destructAny( &pDest[nPos], release );
246         }
247         return (sal_Int32)(sizeof(uno_Any));
248     }
249     case typelib_TypeClass_ENUM:
250         return (sal_Int32)(sizeof(sal_Int32));
251     case typelib_TypeClass_STRUCT:
252     case typelib_TypeClass_EXCEPTION:
253     {
254         typelib_TypeDescription * pElementTypeDescr = 0;
255         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
256         sal_Int32 nElementSize = pElementTypeDescr->nSize;
257         for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
258         {
259             _destructStruct(
260                 (char *)pElements + (nElementSize * nPos),
261                 (typelib_CompoundTypeDescription *)pElementTypeDescr,
262                 release );
263         }
264         sal_Int32 nSize = pElementTypeDescr->nSize;
265         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
266         return nSize;
267     }
268     case typelib_TypeClass_UNION:
269     {
270         typelib_TypeDescription * pElementTypeDescr = 0;
271         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
272         sal_Int32 nElementSize = pElementTypeDescr->nSize;
273         for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
274         {
275             _destructUnion(
276                 (char *)pElements + (nElementSize * nPos),
277                 pElementTypeDescr,
278                 release );
279         }
280         sal_Int32 nSize = pElementTypeDescr->nSize;
281         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
282         return nSize;
283     }
284     case typelib_TypeClass_SEQUENCE:
285     {
286         typelib_TypeDescription * pElementTypeDescr = 0;
287         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
288         uno_Sequence ** pDest = (uno_Sequence **)pElements;
289         for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
290         {
291             destructSequence(
292                 pDest[nPos],
293                 pElementTypeDescr->pWeakRef, pElementTypeDescr,
294                 release );
295         }
296         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
297         return (sal_Int32)(sizeof(uno_Sequence *));
298     }
299     case typelib_TypeClass_INTERFACE:
300     {
301         if (release)
302         {
303             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
304             {
305                 void * p = ((void **)pElements)[nPos];
306                 if (p)
307                 {
308                     (*release)( p );
309                 }
310             }
311         }
312         else
313         {
314             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
315             {
316                 uno_Interface * p = ((uno_Interface **)pElements)[nPos];
317                 if (p)
318                 {
319                     (*p->release)( p );
320                 }
321             }
322         }
323         return (sal_Int32)(sizeof(void *));
324     }
325     default:
326         OSL_ASSERT(false);
327         return 0;
328     }
329 }
330 
331 //------------------------------------------------------------------------------
332 inline void idestructSequence(
333     uno_Sequence * pSeq,
334     typelib_TypeDescriptionReference * pType,
335     typelib_TypeDescription * pTypeDescr,
336     uno_ReleaseFunc release )
337 {
338     if (::osl_decrementInterlockedCount( &pSeq->nRefCount ) == 0)
339     {
340         if (pSeq->nElements > 0)
341         {
342             if (pTypeDescr)
343             {
344                 idestructElements(
345                     pSeq->elements,
346                     ((typelib_IndirectTypeDescription *) pTypeDescr)->pType, 0,
347                     pSeq->nElements, release );
348             }
349             else
350             {
351                 TYPELIB_DANGER_GET( &pTypeDescr, pType );
352                 idestructElements(
353                     pSeq->elements,
354                     ((typelib_IndirectTypeDescription *) pTypeDescr)->pType, 0,
355                     pSeq->nElements, release );
356                 TYPELIB_DANGER_RELEASE( pTypeDescr );
357             }
358         }
359         ::rtl_freeMemory( pSeq );
360     }
361 }
362 
363 //--------------------------------------------------------------------------------------------------
364 inline void _destructData(
365     void * pValue,
366     typelib_TypeDescriptionReference * pType,
367     typelib_TypeDescription * pTypeDescr,
368     uno_ReleaseFunc release )
369     SAL_THROW( () )
370 {
371     switch (pType->eTypeClass)
372     {
373     case typelib_TypeClass_STRING:
374         ::rtl_uString_release( *(rtl_uString **)pValue );
375         break;
376     case typelib_TypeClass_TYPE:
377         ::typelib_typedescriptionreference_release( *(typelib_TypeDescriptionReference **)pValue );
378         break;
379     case typelib_TypeClass_ANY:
380         _destructAny( (uno_Any *)pValue, release );
381         break;
382     case typelib_TypeClass_TYPEDEF:
383         OSL_ENSURE( 0, "### unexpected typedef!" );
384         break;
385     case typelib_TypeClass_STRUCT:
386     case typelib_TypeClass_EXCEPTION:
387         if (pTypeDescr)
388         {
389             _destructStruct( pValue, (typelib_CompoundTypeDescription *)pTypeDescr, release );
390         }
391         else
392         {
393             TYPELIB_DANGER_GET( &pTypeDescr, pType );
394             _destructStruct( pValue, (typelib_CompoundTypeDescription *)pTypeDescr, release );
395             TYPELIB_DANGER_RELEASE( pTypeDescr );
396         }
397         break;
398     case typelib_TypeClass_ARRAY:
399         if (pTypeDescr)
400         {
401             _destructArray( pValue, (typelib_ArrayTypeDescription *)pTypeDescr, release );
402         }
403         else
404         {
405             TYPELIB_DANGER_GET( &pTypeDescr, pType );
406             _destructArray( pValue, (typelib_ArrayTypeDescription *)pTypeDescr, release );
407             TYPELIB_DANGER_RELEASE( pTypeDescr );
408         }
409         break;
410     case typelib_TypeClass_UNION:
411         if (pTypeDescr)
412         {
413             _destructUnion( pValue, pTypeDescr, release );
414         }
415         else
416         {
417             TYPELIB_DANGER_GET( &pTypeDescr, pType );
418             _destructUnion( pValue, pTypeDescr, release );
419             TYPELIB_DANGER_RELEASE( pTypeDescr );
420         }
421         break;
422     case typelib_TypeClass_SEQUENCE:
423     {
424         idestructSequence(
425             *(uno_Sequence **)pValue, pType, pTypeDescr, release );
426         break;
427     }
428     case typelib_TypeClass_INTERFACE:
429         _release( *(void **)pValue, release );
430         break;
431     default:
432         break;
433     }
434 }
435 
436 }
437 
438 #endif
439