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