xref: /aoo42x/main/cppu/source/uno/destr.hxx (revision c6ed87c9)
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 //--------------------------------------------------------------------------------------------------
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 //--------------------------------------------------------------------------------------------------
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 //--------------------------------------------------------------------------------------------------
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 //--------------------------------------------------------------------------------------------------
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 //--------------------------------------------------------------------------------------------------
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 //------------------------------------------------------------------------------
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 //--------------------------------------------------------------------------------------------------
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