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