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->pData, 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