/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include "constr.hxx" #include "copy.hxx" #include "destr.hxx" using namespace cppu; namespace cppu { static uno_Sequence * reallocSeq( uno_Sequence * pReallocate, std::size_t nElementSize, sal_Int32 nElements ) { OSL_ASSERT( nElements >= 0 ); uno_Sequence * pNew = nullptr; sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements ); if (nSize > 0) { if (pReallocate == nullptr) { pNew = static_cast(std::malloc( nSize )); } else { pNew = static_cast(std::realloc( pReallocate, nSize )); } if (pNew != nullptr) { // header init pNew->nRefCount = 1; pNew->nElements = nElements; } } return pNew; } static bool idefaultConstructElements( uno_Sequence ** ppSeq, typelib_TypeDescriptionReference * pElementType, sal_Int32 nStartIndex, sal_Int32 nStopIndex, sal_Int32 nAlloc ) // >= 0 means (re)alloc memory for nAlloc elements { uno_Sequence * pSeq = *ppSeq; switch (pElementType->eTypeClass) { case typelib_TypeClass_CHAR: if (nAlloc >= 0) pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc ); if (pSeq != nullptr) { memset( pSeq->elements + (sizeof(sal_Unicode) * nStartIndex), 0, sizeof(sal_Unicode) * (nStopIndex - nStartIndex) ); } break; case typelib_TypeClass_BOOLEAN: if (nAlloc >= 0) pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc ); if (pSeq != nullptr) { memset( pSeq->elements + (sizeof(sal_Bool) * nStartIndex), 0, sizeof(sal_Bool) * (nStopIndex - nStartIndex) ); } break; case typelib_TypeClass_BYTE: if (nAlloc >= 0) pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc ); if (pSeq != nullptr) { memset( pSeq->elements + (sizeof(sal_Int8) * nStartIndex), 0, sizeof(sal_Int8) * (nStopIndex - nStartIndex) ); } break; case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT: if (nAlloc >= 0) pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc ); if (pSeq != nullptr) { memset( pSeq->elements + (sizeof(sal_Int16) * nStartIndex), 0, sizeof(sal_Int16) * (nStopIndex - nStartIndex) ); } break; case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: if (nAlloc >= 0) pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); if (pSeq != nullptr) { memset( pSeq->elements + (sizeof(sal_Int32) * nStartIndex), 0, sizeof(sal_Int32) * (nStopIndex - nStartIndex) ); } break; case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: if (nAlloc >= 0) pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc ); if (pSeq != nullptr) { memset( pSeq->elements + (sizeof(sal_Int64) * nStartIndex), 0, sizeof(sal_Int64) * (nStopIndex - nStartIndex) ); } break; case typelib_TypeClass_FLOAT: { if (nAlloc >= 0) pSeq = reallocSeq( pSeq, sizeof(float), nAlloc ); if (pSeq != nullptr) { float * pElements = reinterpret_cast(pSeq->elements); for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) { pElements[nPos] = 0.0; } } break; } case typelib_TypeClass_DOUBLE: { if (nAlloc >= 0) pSeq = reallocSeq( pSeq, sizeof(double), nAlloc ); if (pSeq != nullptr) { double * pElements = reinterpret_cast(pSeq->elements); for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) { pElements[nPos] = 0.0; } } break; } case typelib_TypeClass_STRING: { if (nAlloc >= 0) pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc ); if (pSeq != nullptr) { rtl_uString ** pElements = reinterpret_cast(pSeq->elements); for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) { pElements[nPos] = nullptr; rtl_uString_new( &pElements[nPos] ); } } break; } case typelib_TypeClass_TYPE: { if (nAlloc >= 0) { pSeq = reallocSeq( pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc ); } if (pSeq != nullptr) { typelib_TypeDescriptionReference ** pElements = reinterpret_cast(pSeq->elements); for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) { pElements[nPos] = _getVoidType(); } } break; } case typelib_TypeClass_ANY: { if (nAlloc >= 0) pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc ); if (pSeq != nullptr) { uno_Any * pElements = reinterpret_cast(pSeq->elements); for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) { CONSTRUCT_EMPTY_ANY( &pElements[nPos] ); } } break; } case typelib_TypeClass_ENUM: { if (nAlloc >= 0) pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); if (pSeq != nullptr) { typelib_TypeDescription * pElementTypeDescr = nullptr; TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); if (pElementTypeDescr == nullptr) { std::abort(); } sal_Int32 eEnum = reinterpret_cast( pElementTypeDescr)->nDefaultEnumValue; TYPELIB_DANGER_RELEASE( pElementTypeDescr ); sal_Int32 * pElements = reinterpret_cast(pSeq->elements); for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) { pElements[nPos] = eEnum; } } break; } case typelib_TypeClass_STRUCT: case typelib_TypeClass_EXCEPTION: { typelib_TypeDescription * pElementTypeDescr = nullptr; TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); if (pElementTypeDescr == nullptr) { std::abort(); } sal_Int32 nElementSize = pElementTypeDescr->nSize; if (nAlloc >= 0) pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); if (pSeq != nullptr) { char * pElements = pSeq->elements; for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) { _defaultConstructStruct( pElements + (nElementSize * nPos), reinterpret_cast(pElementTypeDescr) ); } } TYPELIB_DANGER_RELEASE( pElementTypeDescr ); break; } case typelib_TypeClass_SEQUENCE: { if (nAlloc >= 0) { // coverity[suspicious_sizeof : FALSE] - sizeof(uno_Sequence*) is correct here pSeq = reallocSeq(pSeq, sizeof(uno_Sequence*), nAlloc); } if (pSeq != nullptr) { uno_Sequence ** pElements = reinterpret_cast(pSeq->elements); for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) { pElements[nPos] = createEmptySequence(); } } break; } case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface if (nAlloc >= 0) pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc ); if (pSeq != nullptr) { memset( pSeq->elements + (sizeof(void *) * nStartIndex), 0, sizeof(void *) * (nStopIndex - nStartIndex) ); } break; default: OSL_FAIL( "### unexpected element type!" ); pSeq = nullptr; break; } if (pSeq == nullptr) { OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure return false; } *ppSeq = pSeq; return true; } // coverity[ -tainted_data_sink : arg-1 ] static bool icopyConstructFromElements( uno_Sequence ** ppSeq, void * pSourceElements, typelib_TypeDescriptionReference * pElementType, sal_Int32 nStopIndex, uno_AcquireFunc acquire, sal_Int32 nAlloc ) { uno_Sequence * pSeq = *ppSeq; switch (pElementType->eTypeClass) { case typelib_TypeClass_CHAR: pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc ); if (pSeq != nullptr) { memcpy( pSeq->elements, pSourceElements, sizeof(sal_Unicode) * nStopIndex ); } break; case typelib_TypeClass_BOOLEAN: pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc ); if (pSeq != nullptr) { memcpy( pSeq->elements, pSourceElements, sizeof(sal_Bool) * nStopIndex ); } break; case typelib_TypeClass_BYTE: pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc ); if (pSeq != nullptr) { memcpy( pSeq->elements, pSourceElements, sizeof(sal_Int8) * nStopIndex ); } break; case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT: pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc ); if (pSeq != nullptr) { memcpy( pSeq->elements, pSourceElements, sizeof(sal_Int16) * nStopIndex ); } break; case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); if (pSeq != nullptr) { memcpy( pSeq->elements, pSourceElements, sizeof(sal_Int32) * nStopIndex ); } break; case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc ); if (pSeq != nullptr) { memcpy( pSeq->elements, pSourceElements, sizeof(sal_Int64) * nStopIndex ); } break; case typelib_TypeClass_FLOAT: pSeq = reallocSeq( pSeq, sizeof(float), nAlloc ); if (pSeq != nullptr) { memcpy( pSeq->elements, pSourceElements, sizeof(float) * nStopIndex ); } break; case typelib_TypeClass_DOUBLE: pSeq = reallocSeq( pSeq, sizeof(double), nAlloc ); if (pSeq != nullptr) { memcpy( pSeq->elements, pSourceElements, sizeof(double) * nStopIndex ); } break; case typelib_TypeClass_ENUM: pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); if (pSeq != nullptr) { memcpy( pSeq->elements, pSourceElements, sizeof(sal_Int32) * nStopIndex ); } break; case typelib_TypeClass_STRING: { pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc ); if (pSeq != nullptr) { rtl_uString ** pDestElements = reinterpret_cast(pSeq->elements); for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos ) { // This code tends to trigger coverity's overrun-buffer-arg warning // coverity[index_parm_via_loop_bound] - https://communities.coverity.com/thread/2993 ::rtl_uString_acquire( static_cast(pSourceElements)[nPos] ); pDestElements[nPos] = static_cast(pSourceElements)[nPos]; } } break; } case typelib_TypeClass_TYPE: { pSeq = reallocSeq( pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc ); if (pSeq != nullptr) { typelib_TypeDescriptionReference ** pDestElements = reinterpret_cast(pSeq->elements); for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos ) { TYPE_ACQUIRE( static_cast( pSourceElements)[nPos] ); pDestElements[nPos] = static_cast( pSourceElements)[nPos]; } } break; } case typelib_TypeClass_ANY: { pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc ); if (pSeq != nullptr) { uno_Any * pDestElements = reinterpret_cast(pSeq->elements); for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos ) { uno_Any * pSource = static_cast(pSourceElements) + nPos; _copyConstructAny( &pDestElements[nPos], pSource->pData, pSource->pType, nullptr, acquire, nullptr ); } } break; } case typelib_TypeClass_STRUCT: case typelib_TypeClass_EXCEPTION: { typelib_TypeDescription * pElementTypeDescr = nullptr; TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); if (pElementTypeDescr == nullptr) { std::abort(); } sal_Int32 nElementSize = pElementTypeDescr->nSize; pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); if (pSeq != nullptr) { char * pDestElements = pSeq->elements; typelib_CompoundTypeDescription * pTypeDescr = reinterpret_cast(pElementTypeDescr); for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos ) { char * pDest = pDestElements + (nElementSize * nPos); char * pSource = static_cast(pSourceElements) + (nElementSize * nPos); if (pTypeDescr->pBaseTypeDescription) { // copy base value _copyConstructStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription, acquire, nullptr ); } // then copy members typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs; sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets; sal_Int32 nDescr = pTypeDescr->nMembers; while (nDescr--) { ::uno_type_copyData( pDest + pMemberOffsets[nDescr], pSource + pMemberOffsets[nDescr], ppTypeRefs[nDescr], acquire ); } } } TYPELIB_DANGER_RELEASE( pElementTypeDescr ); break; } case typelib_TypeClass_SEQUENCE: // sequence of sequence { // coverity[suspicious_sizeof : FALSE] - sizeof(uno_Sequence*) is correct here pSeq = reallocSeq(pSeq, sizeof(uno_Sequence*), nAlloc); if (pSeq != nullptr) { typelib_TypeDescription * pElementTypeDescr = nullptr; TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); if (pElementTypeDescr == nullptr) { std::abort(); } typelib_TypeDescriptionReference * pSeqElementType = reinterpret_cast(pElementTypeDescr)->pType; uno_Sequence ** pDestElements = reinterpret_cast(pSeq->elements); for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos ) { uno_Sequence * pNew = icopyConstructSequence( static_cast(pSourceElements)[nPos], pSeqElementType, acquire, nullptr ); OSL_ASSERT( pNew != nullptr ); // ought never be a memory allocation problem, // because of reference counted sequence handles pDestElements[ nPos ] = pNew; } TYPELIB_DANGER_RELEASE( pElementTypeDescr ); } break; } case typelib_TypeClass_INTERFACE: { pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc ); if (pSeq != nullptr) { void ** pDestElements = reinterpret_cast(pSeq->elements); for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos ) { pDestElements[nPos] = static_cast(pSourceElements)[nPos]; _acquire( pDestElements[nPos], acquire ); } } break; } default: OSL_FAIL( "### unexpected element type!" ); pSeq = nullptr; break; } if (pSeq == nullptr) { return false; // allocation failure } *ppSeq = pSeq; return true; } static bool ireallocSequence( uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pElementType, sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release ) { bool ret = true; uno_Sequence * pSeq = *ppSequence; sal_Int32 nElements = pSeq->nElements; if (pSeq->nRefCount > 1 || // not mem-copyable elements? typelib_TypeClass_ANY == pElementType->eTypeClass || typelib_TypeClass_STRUCT == pElementType->eTypeClass || typelib_TypeClass_EXCEPTION == pElementType->eTypeClass) { // split sequence and construct new one from scratch uno_Sequence * pNew = nullptr; sal_Int32 nRest = nSize - nElements; sal_Int32 nCopy = (nRest > 0 ? nElements : nSize); if (nCopy >= 0) { ret = icopyConstructFromElements( &pNew, pSeq->elements, pElementType, nCopy, acquire, nSize ); // alloc to nSize } if (ret && nRest > 0) { ret = idefaultConstructElements( &pNew, pElementType, nCopy, nSize, nCopy >= 0 ? -1 /* no mem allocation */ : nSize ); } if (ret) { // destruct sequence if (osl_atomic_decrement( &pSeq->nRefCount ) == 0) { if (nElements > 0) { idestructElements( pSeq->elements, pElementType, 0, nElements, release ); } std::free( pSeq ); } *ppSequence = pNew; } } else { OSL_ASSERT( pSeq->nRefCount == 1 ); if (nSize > nElements) // default construct the rest { ret = idefaultConstructElements( ppSequence, pElementType, nElements, nSize, nSize ); // realloc to nSize } else // or destruct the rest and realloc mem { sal_Int32 nElementSize = idestructElements( pSeq->elements, pElementType, nSize, nElements, release ); // warning: it is assumed that the following will never fail, // else this leads to a sequence null handle *ppSequence = reallocSeq( pSeq, nElementSize, nSize ); OSL_ASSERT( *ppSequence != nullptr ); ret = (*ppSequence != nullptr); } } return ret; } } extern "C" { sal_Bool SAL_CALL uno_type_sequence_construct( uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType, void * pElements, sal_Int32 len, uno_AcquireFunc acquire ) SAL_THROW_EXTERN_C() { assert( len >= 0 ); bool ret; if (len) { typelib_TypeDescription * pTypeDescr = nullptr; TYPELIB_DANGER_GET( &pTypeDescr, pType ); if (pTypeDescr == nullptr) { std::abort(); } typelib_TypeDescriptionReference * pElementType = reinterpret_cast(pTypeDescr)->pType; *ppSequence = nullptr; if (pElements == nullptr) { ret = idefaultConstructElements( ppSequence, pElementType, 0, len, len ); // alloc to len } else { ret = icopyConstructFromElements( ppSequence, pElements, pElementType, len, acquire, len ); // alloc to len } TYPELIB_DANGER_RELEASE( pTypeDescr ); } else { *ppSequence = createEmptySequence(); ret = true; } OSL_ASSERT( (*ppSequence != nullptr) == ret ); return ret; } sal_Bool SAL_CALL uno_sequence_construct( uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr, void * pElements, sal_Int32 len, uno_AcquireFunc acquire ) SAL_THROW_EXTERN_C() { bool ret; if (len > 0) { typelib_TypeDescriptionReference * pElementType = reinterpret_cast(pTypeDescr)->pType; *ppSequence = nullptr; if (pElements == nullptr) { ret = idefaultConstructElements( ppSequence, pElementType, 0, len, len ); // alloc to len } else { ret = icopyConstructFromElements( ppSequence, pElements, pElementType, len, acquire, len ); // alloc to len } } else { *ppSequence = createEmptySequence(); ret = true; } OSL_ASSERT( (*ppSequence != nullptr) == ret ); return ret; } sal_Bool SAL_CALL uno_type_sequence_realloc( uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType, sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release ) SAL_THROW_EXTERN_C() { assert(ppSequence && "### null ptr!"); assert(nSize >= 0 && "### new size must be at least 0!"); bool ret = true; if (nSize != (*ppSequence)->nElements) { typelib_TypeDescription * pTypeDescr = nullptr; TYPELIB_DANGER_GET( &pTypeDescr, pType ); ret = ireallocSequence( ppSequence, reinterpret_cast(pTypeDescr)->pType, nSize, acquire, release ); TYPELIB_DANGER_RELEASE( pTypeDescr ); } return ret; } sal_Bool SAL_CALL uno_sequence_realloc( uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr, sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release ) SAL_THROW_EXTERN_C() { assert(ppSequence && "### null ptr!"); OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" ); bool ret = true; if (nSize != (*ppSequence)->nElements) { ret = ireallocSequence( ppSequence, reinterpret_cast(pTypeDescr)->pType, nSize, acquire, release ); } return ret; } sal_Bool SAL_CALL uno_type_sequence_reference2One( uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType, uno_AcquireFunc acquire, uno_ReleaseFunc release ) SAL_THROW_EXTERN_C() { assert(ppSequence && "### null ptr!"); bool ret = true; uno_Sequence * pSequence = *ppSequence; if (pSequence->nRefCount > 1) { uno_Sequence * pNew = nullptr; if (pSequence->nElements > 0) { typelib_TypeDescription * pTypeDescr = nullptr; TYPELIB_DANGER_GET( &pTypeDescr, pType ); ret = icopyConstructFromElements( &pNew, pSequence->elements, reinterpret_cast(pTypeDescr)->pType, pSequence->nElements, acquire, pSequence->nElements ); // alloc nElements if (ret) { idestructSequence( *ppSequence, pType, pTypeDescr, release ); *ppSequence = pNew; } TYPELIB_DANGER_RELEASE( pTypeDescr ); } else { pNew = allocSeq( 0, 0 ); ret = (pNew != nullptr); if (ret) { // easy destruction of empty sequence: if (osl_atomic_decrement( &pSequence->nRefCount ) == 0) std::free( pSequence ); *ppSequence = pNew; } } } return ret; } sal_Bool SAL_CALL uno_sequence_reference2One( uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr, uno_AcquireFunc acquire, uno_ReleaseFunc release ) SAL_THROW_EXTERN_C() { assert(ppSequence && "### null ptr!"); bool ret = true; uno_Sequence * pSequence = *ppSequence; if (pSequence->nRefCount > 1) { uno_Sequence * pNew = nullptr; if (pSequence->nElements > 0) { ret = icopyConstructFromElements( &pNew, pSequence->elements, reinterpret_cast(pTypeDescr)->pType, pSequence->nElements, acquire, pSequence->nElements ); // alloc nElements if (ret) { idestructSequence( pSequence, pTypeDescr->pWeakRef, pTypeDescr, release ); *ppSequence = pNew; } } else { pNew = allocSeq( 0, 0 ); ret = (pNew != nullptr); if (ret) { // easy destruction of empty sequence: if (osl_atomic_decrement( &pSequence->nRefCount ) == 0) std::free( pSequence ); *ppSequence = pNew; } } } return ret; } void SAL_CALL uno_sequence_assign( uno_Sequence ** ppDest, uno_Sequence * pSource, typelib_TypeDescription * pTypeDescr, uno_ReleaseFunc release ) SAL_THROW_EXTERN_C() { if (*ppDest != pSource) { osl_atomic_increment( &pSource->nRefCount ); idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release ); *ppDest = pSource; } } void SAL_CALL uno_type_sequence_assign( uno_Sequence ** ppDest, uno_Sequence * pSource, typelib_TypeDescriptionReference * pType, uno_ReleaseFunc release ) SAL_THROW_EXTERN_C() { if (*ppDest != pSource) { osl_atomic_increment( &pSource->nRefCount ); idestructSequence( *ppDest, pType, nullptr, release ); *ppDest = pSource; } } void uno_type_sequence_destroy( uno_Sequence * sequence, typelib_TypeDescriptionReference * type, uno_ReleaseFunc release) SAL_THROW_EXTERN_C() { idestroySequence(sequence, type, nullptr, release); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */