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