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