| /************************************************************** | |
| * | |
| * 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 | |
| * | |
| * Unless required by applicable law or agreed to in writing, | |
| * software distributed under the License is distributed on an | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| * KIND, either express or implied. See the License for the | |
| * specific language governing permissions and limitations | |
| * under the License. | |
| * | |
| *************************************************************/ | |
| // MARKER(update_precomp.py): autogen include statement, do not remove | |
| #include "precompiled_cppu.hxx" | |
| #include <rtl/memory.h> | |
| #include <rtl/alloc.h> | |
| #include <osl/diagnose.h> | |
| #include <osl/interlck.h> | |
| #include <typelib/typedescription.h> | |
| #include <uno/data.h> | |
| #include <uno/dispatcher.h> | |
| #include <uno/sequence2.h> | |
| #include "constr.hxx" | |
| #include "copy.hxx" | |
| #include "destr.hxx" | |
| using namespace cppu; | |
| namespace cppu | |
| { | |
| //------------------------------------------------------------------------------ | |
| static inline uno_Sequence * reallocSeq( | |
| uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements ) | |
| { | |
| OSL_ASSERT( nElements >= 0 ); | |
| uno_Sequence * pNew = 0; | |
| sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements ); | |
| if (nSize > 0) | |
| { | |
| if (pReallocate == 0) | |
| { | |
| pNew = (uno_Sequence *) rtl_allocateMemory( nSize ); | |
| } | |
| else | |
| { | |
| pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize ); | |
| } | |
| if (pNew != 0) | |
| { | |
| // header init | |
| pNew->nRefCount = 1; | |
| pNew->nElements = nElements; | |
| } | |
| } | |
| return pNew; | |
| } | |
| //------------------------------------------------------------------------------ | |
| static inline bool idefaultConstructElements( | |
| uno_Sequence ** ppSeq, | |
| typelib_TypeDescriptionReference * pElementType, | |
| sal_Int32 nStartIndex, sal_Int32 nStopIndex, | |
| sal_Int32 nAlloc = -1 ) // >= 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 != 0) | |
| { | |
| ::rtl_zeroMemory( | |
| pSeq->elements + (sizeof(sal_Unicode) * nStartIndex), | |
| sizeof(sal_Unicode) * (nStopIndex - nStartIndex) ); | |
| } | |
| break; | |
| case typelib_TypeClass_BOOLEAN: | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| ::rtl_zeroMemory( | |
| pSeq->elements + (sizeof(sal_Bool) * nStartIndex), | |
| sizeof(sal_Bool) * (nStopIndex - nStartIndex) ); | |
| } | |
| break; | |
| case typelib_TypeClass_BYTE: | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| ::rtl_zeroMemory( | |
| pSeq->elements + (sizeof(sal_Int8) * nStartIndex), | |
| 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 != 0) | |
| { | |
| ::rtl_zeroMemory( | |
| pSeq->elements + (sizeof(sal_Int16) * nStartIndex), | |
| 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 != 0) | |
| { | |
| ::rtl_zeroMemory( | |
| pSeq->elements + (sizeof(sal_Int32) * nStartIndex), | |
| 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 != 0) | |
| { | |
| ::rtl_zeroMemory( | |
| pSeq->elements + (sizeof(sal_Int64) * nStartIndex), | |
| sizeof(sal_Int64) * (nStopIndex - nStartIndex) ); | |
| } | |
| break; | |
| case typelib_TypeClass_FLOAT: | |
| { | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, sizeof(float), nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| float * pElements = (float *) 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 != 0) | |
| { | |
| double * pElements = (double *) 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 != 0) | |
| { | |
| rtl_uString ** pElements = (rtl_uString **) pSeq->elements; | |
| for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) | |
| { | |
| pElements[nPos] = 0; | |
| rtl_uString_new( &pElements[nPos] ); | |
| } | |
| } | |
| break; | |
| } | |
| case typelib_TypeClass_TYPE: | |
| { | |
| if (nAlloc >= 0) | |
| { | |
| pSeq = reallocSeq( | |
| pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc ); | |
| } | |
| if (pSeq != 0) | |
| { | |
| typelib_TypeDescriptionReference ** pElements = | |
| (typelib_TypeDescriptionReference **) 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 != 0) | |
| { | |
| uno_Any * pElements = (uno_Any *) 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 != 0) | |
| { | |
| typelib_TypeDescription * pElementTypeDescr = 0; | |
| TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); | |
| sal_Int32 eEnum = | |
| ((typelib_EnumTypeDescription *) | |
| pElementTypeDescr)->nDefaultEnumValue; | |
| TYPELIB_DANGER_RELEASE( pElementTypeDescr ); | |
| sal_Int32 * pElements = (sal_Int32 *) 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 = 0; | |
| TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); | |
| sal_Int32 nElementSize = pElementTypeDescr->nSize; | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| char * pElements = pSeq->elements; | |
| for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) | |
| { | |
| _defaultConstructStruct( | |
| pElements + (nElementSize * nPos), | |
| (typelib_CompoundTypeDescription *)pElementTypeDescr ); | |
| } | |
| } | |
| TYPELIB_DANGER_RELEASE( pElementTypeDescr ); | |
| break; | |
| } | |
| case typelib_TypeClass_ARRAY: | |
| { | |
| typelib_TypeDescription * pElementTypeDescr = 0; | |
| TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); | |
| sal_Int32 nElementSize = pElementTypeDescr->nSize; | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| char * pElements = pSeq->elements; | |
| for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) | |
| { | |
| _defaultConstructArray( | |
| pElements + (nElementSize * nPos), | |
| (typelib_ArrayTypeDescription *)pElementTypeDescr ); | |
| } | |
| } | |
| TYPELIB_DANGER_RELEASE( pElementTypeDescr ); | |
| break; | |
| } | |
| case typelib_TypeClass_UNION: | |
| { | |
| typelib_TypeDescription * pElementTypeDescr = 0; | |
| TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); | |
| sal_Int32 nElementSize = pElementTypeDescr->nSize; | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| sal_Int32 nValueOffset = | |
| ((typelib_UnionTypeDescription *) | |
| pElementTypeDescr)->nValueOffset; | |
| sal_Int64 nDefaultDiscr = | |
| ((typelib_UnionTypeDescription *) | |
| pElementTypeDescr)->nDefaultDiscriminant; | |
| typelib_TypeDescription * pDefaultTypeDescr = 0; | |
| TYPELIB_DANGER_GET( | |
| &pDefaultTypeDescr, | |
| ((typelib_UnionTypeDescription *) | |
| pElementTypeDescr)->pDefaultTypeRef ); | |
| char * pElements = pSeq->elements; | |
| for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) | |
| { | |
| char * pMem = pElements + (nElementSize * nPos); | |
| ::uno_constructData( | |
| (char *)pMem + nValueOffset, pDefaultTypeDescr ); | |
| *(sal_Int64 *)pMem = nDefaultDiscr; | |
| } | |
| TYPELIB_DANGER_RELEASE( pDefaultTypeDescr ); | |
| } | |
| TYPELIB_DANGER_RELEASE( pElementTypeDescr ); | |
| break; | |
| } | |
| case typelib_TypeClass_SEQUENCE: | |
| { | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| uno_Sequence ** pElements = | |
| (uno_Sequence **) 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 != 0) | |
| { | |
| ::rtl_zeroMemory( | |
| pSeq->elements + (sizeof(void *) * nStartIndex), | |
| sizeof(void *) * (nStopIndex - nStartIndex) ); | |
| } | |
| break; | |
| default: | |
| OSL_ENSURE( 0, "### unexpected element type!" ); | |
| pSeq = 0; | |
| break; | |
| } | |
| if (pSeq == 0) | |
| { | |
| OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure | |
| return false; | |
| } | |
| else | |
| { | |
| *ppSeq = pSeq; | |
| return true; | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| static inline bool icopyConstructFromElements( | |
| uno_Sequence ** ppSeq, void * pSourceElements, | |
| typelib_TypeDescriptionReference * pElementType, | |
| sal_Int32 nStartIndex, sal_Int32 nStopIndex, | |
| uno_AcquireFunc acquire, | |
| sal_Int32 nAlloc = -1 ) // >= 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 != 0) | |
| { | |
| ::rtl_copyMemory( | |
| pSeq->elements + (sizeof(sal_Unicode) * nStartIndex), | |
| (char *)pSourceElements + (sizeof(sal_Unicode) * nStartIndex), | |
| sizeof(sal_Unicode) * (nStopIndex - nStartIndex) ); | |
| } | |
| break; | |
| case typelib_TypeClass_BOOLEAN: | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| ::rtl_copyMemory( | |
| pSeq->elements + (sizeof(sal_Bool) * nStartIndex), | |
| (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex), | |
| sizeof(sal_Bool) * (nStopIndex - nStartIndex) ); | |
| } | |
| break; | |
| case typelib_TypeClass_BYTE: | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| ::rtl_copyMemory( | |
| pSeq->elements + (sizeof(sal_Int8) * nStartIndex), | |
| (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex), | |
| 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 != 0) | |
| { | |
| ::rtl_copyMemory( | |
| pSeq->elements + (sizeof(sal_Int16) * nStartIndex), | |
| (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex), | |
| 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 != 0) | |
| { | |
| ::rtl_copyMemory( | |
| pSeq->elements + (sizeof(sal_Int32) * nStartIndex), | |
| (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex), | |
| 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 != 0) | |
| { | |
| ::rtl_copyMemory( | |
| pSeq->elements + (sizeof(sal_Int64) * nStartIndex), | |
| (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex), | |
| sizeof(sal_Int64) * (nStopIndex - nStartIndex) ); | |
| } | |
| break; | |
| case typelib_TypeClass_FLOAT: | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, sizeof(float), nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| ::rtl_copyMemory( | |
| pSeq->elements + (sizeof(float) * nStartIndex), | |
| (char *)pSourceElements + (sizeof(float) * nStartIndex), | |
| sizeof(float) * (nStopIndex - nStartIndex) ); | |
| } | |
| break; | |
| case typelib_TypeClass_DOUBLE: | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, sizeof(double), nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| ::rtl_copyMemory( | |
| pSeq->elements + (sizeof(double) * nStartIndex), | |
| (char *)pSourceElements + (sizeof(double) * nStartIndex), | |
| sizeof(double) * (nStopIndex - nStartIndex) ); | |
| } | |
| break; | |
| case typelib_TypeClass_ENUM: | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| ::rtl_copyMemory( | |
| pSeq->elements + (sizeof(sal_Int32) * nStartIndex), | |
| (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex), | |
| sizeof(sal_Int32) * (nStopIndex - nStartIndex) ); | |
| } | |
| break; | |
| case typelib_TypeClass_STRING: | |
| { | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements; | |
| for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) | |
| { | |
| ::rtl_uString_acquire( | |
| ((rtl_uString **)pSourceElements)[nPos] ); | |
| pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos]; | |
| } | |
| } | |
| break; | |
| } | |
| case typelib_TypeClass_TYPE: | |
| { | |
| if (nAlloc >= 0) | |
| { | |
| pSeq = reallocSeq( | |
| pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc ); | |
| } | |
| if (pSeq != 0) | |
| { | |
| typelib_TypeDescriptionReference ** pDestElements = | |
| (typelib_TypeDescriptionReference **) pSeq->elements; | |
| for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) | |
| { | |
| TYPE_ACQUIRE( | |
| ((typelib_TypeDescriptionReference **) | |
| pSourceElements)[nPos] ); | |
| pDestElements[nPos] = | |
| ((typelib_TypeDescriptionReference **) | |
| pSourceElements)[nPos]; | |
| } | |
| } | |
| break; | |
| } | |
| case typelib_TypeClass_ANY: | |
| { | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| uno_Any * pDestElements = (uno_Any *) pSeq->elements; | |
| for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) | |
| { | |
| uno_Any * pSource = (uno_Any *)pSourceElements + nPos; | |
| _copyConstructAny( | |
| &pDestElements[nPos], | |
| pSource->pData, | |
| pSource->pType, 0, | |
| acquire, 0 ); | |
| } | |
| } | |
| break; | |
| } | |
| case typelib_TypeClass_STRUCT: | |
| case typelib_TypeClass_EXCEPTION: | |
| { | |
| typelib_TypeDescription * pElementTypeDescr = 0; | |
| TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); | |
| sal_Int32 nElementSize = pElementTypeDescr->nSize; | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| char * pDestElements = pSeq->elements; | |
| typelib_CompoundTypeDescription * pTypeDescr = | |
| (typelib_CompoundTypeDescription *)pElementTypeDescr; | |
| for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) | |
| { | |
| char * pDest = | |
| pDestElements + (nElementSize * nPos); | |
| char * pSource = | |
| (char *)pSourceElements + (nElementSize * nPos); | |
| if (pTypeDescr->pBaseTypeDescription) | |
| { | |
| // copy base value | |
| _copyConstructStruct( | |
| pDest, pSource, | |
| pTypeDescr->pBaseTypeDescription, acquire, 0 ); | |
| } | |
| // 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_UNION: | |
| { | |
| typelib_TypeDescription * pElementTypeDescr = 0; | |
| TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); | |
| sal_Int32 nElementSize = pElementTypeDescr->nSize; | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| char * pDestElements = pSeq->elements; | |
| sal_Int32 nValueOffset = | |
| ((typelib_UnionTypeDescription *) | |
| pElementTypeDescr)->nValueOffset; | |
| for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) | |
| { | |
| char * pDest = | |
| pDestElements + (nElementSize * nPos); | |
| char * pSource = | |
| (char *)pSourceElements + (nElementSize * nPos); | |
| typelib_TypeDescriptionReference * pSetType = _unionGetSetType( | |
| pSource, pElementTypeDescr ); | |
| ::uno_type_copyData( | |
| pDest + nValueOffset, | |
| pSource + nValueOffset, | |
| pSetType, acquire ); | |
| *(sal_Int64 *)pDest = *(sal_Int64 *)pSource; | |
| typelib_typedescriptionreference_release( pSetType ); | |
| } | |
| } | |
| TYPELIB_DANGER_RELEASE( pElementTypeDescr ); | |
| break; | |
| } | |
| case typelib_TypeClass_SEQUENCE: // sequence of sequence | |
| { | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| typelib_TypeDescription * pElementTypeDescr = 0; | |
| TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); | |
| typelib_TypeDescriptionReference * pSeqElementType = | |
| ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType; | |
| uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements; | |
| for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) | |
| { | |
| uno_Sequence * pNew = icopyConstructSequence( | |
| ((uno_Sequence **) pSourceElements)[nPos], | |
| pSeqElementType, acquire, 0 ); | |
| OSL_ASSERT( pNew != 0 ); | |
| // 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: | |
| { | |
| if (nAlloc >= 0) | |
| pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc ); | |
| if (pSeq != 0) | |
| { | |
| void ** pDestElements = (void **) pSeq->elements; | |
| for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) | |
| { | |
| _acquire( pDestElements[nPos] = | |
| ((void **)pSourceElements)[nPos], acquire ); | |
| } | |
| } | |
| break; | |
| } | |
| default: | |
| OSL_ENSURE( 0, "### unexpected element type!" ); | |
| pSeq = 0; | |
| break; | |
| } | |
| if (pSeq == 0) | |
| { | |
| OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure | |
| return false; | |
| } | |
| else | |
| { | |
| *ppSeq = pSeq; | |
| return true; | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| static inline 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 = 0; | |
| sal_Int32 nRest = nSize - nElements; | |
| sal_Int32 nCopy = (nRest > 0 ? nElements : nSize); | |
| if (nCopy >= 0) | |
| { | |
| ret = icopyConstructFromElements( | |
| &pNew, pSeq->elements, pElementType, | |
| 0, 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_decrementInterlockedCount( &pSeq->nRefCount ) == 0) | |
| { | |
| if (nElements > 0) | |
| { | |
| idestructElements( | |
| pSeq->elements, pElementType, | |
| 0, nElements, release ); | |
| } | |
| rtl_freeMemory( 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 != 0 ); | |
| ret = (*ppSequence != 0); | |
| } | |
| } | |
| 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() | |
| { | |
| bool ret; | |
| if (len) | |
| { | |
| typelib_TypeDescription * pTypeDescr = 0; | |
| TYPELIB_DANGER_GET( &pTypeDescr, pType ); | |
| typelib_TypeDescriptionReference * pElementType = | |
| ((typelib_IndirectTypeDescription *)pTypeDescr)->pType; | |
| *ppSequence = 0; | |
| if (pElements == 0) | |
| { | |
| ret = idefaultConstructElements( | |
| ppSequence, pElementType, | |
| 0, len, | |
| len ); // alloc to len | |
| } | |
| else | |
| { | |
| ret = icopyConstructFromElements( | |
| ppSequence, pElements, pElementType, | |
| 0, len, acquire, | |
| len ); // alloc to len | |
| } | |
| TYPELIB_DANGER_RELEASE( pTypeDescr ); | |
| } | |
| else | |
| { | |
| *ppSequence = createEmptySequence(); | |
| ret = true; | |
| } | |
| OSL_ASSERT( (*ppSequence != 0) == 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 = | |
| ((typelib_IndirectTypeDescription *)pTypeDescr)->pType; | |
| *ppSequence = 0; | |
| if (pElements == 0) | |
| { | |
| ret = idefaultConstructElements( | |
| ppSequence, pElementType, | |
| 0, len, | |
| len ); // alloc to len | |
| } | |
| else | |
| { | |
| ret = icopyConstructFromElements( | |
| ppSequence, pElements, pElementType, | |
| 0, len, acquire, | |
| len ); // alloc to len | |
| } | |
| } | |
| else | |
| { | |
| *ppSequence = createEmptySequence(); | |
| ret = true; | |
| } | |
| OSL_ASSERT( (*ppSequence != 0) == 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() | |
| { | |
| OSL_ENSURE( ppSequence, "### null ptr!" ); | |
| OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" ); | |
| bool ret = true; | |
| if (nSize != (*ppSequence)->nElements) | |
| { | |
| typelib_TypeDescription * pTypeDescr = 0; | |
| TYPELIB_DANGER_GET( &pTypeDescr, pType ); | |
| ret = ireallocSequence( | |
| ppSequence, ((typelib_IndirectTypeDescription *)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() | |
| { | |
| OSL_ENSURE( ppSequence, "### null ptr!" ); | |
| OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" ); | |
| bool ret = true; | |
| if (nSize != (*ppSequence)->nElements) | |
| { | |
| ret = ireallocSequence( | |
| ppSequence, ((typelib_IndirectTypeDescription *)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() | |
| { | |
| OSL_ENSURE( ppSequence, "### null ptr!" ); | |
| bool ret = true; | |
| uno_Sequence * pSequence = *ppSequence; | |
| if (pSequence->nRefCount > 1) | |
| { | |
| uno_Sequence * pNew = 0; | |
| if (pSequence->nElements > 0) | |
| { | |
| typelib_TypeDescription * pTypeDescr = 0; | |
| TYPELIB_DANGER_GET( &pTypeDescr, pType ); | |
| ret = icopyConstructFromElements( | |
| &pNew, pSequence->elements, | |
| ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, | |
| 0, 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 != 0); | |
| if (ret) | |
| { | |
| // easy destruction of empty sequence: | |
| if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0) | |
| rtl_freeMemory( 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() | |
| { | |
| OSL_ENSURE( ppSequence, "### null ptr!" ); | |
| bool ret = true; | |
| uno_Sequence * pSequence = *ppSequence; | |
| if (pSequence->nRefCount > 1) | |
| { | |
| uno_Sequence * pNew = 0; | |
| if (pSequence->nElements > 0) | |
| { | |
| ret = icopyConstructFromElements( | |
| &pNew, pSequence->elements, | |
| ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, | |
| 0, pSequence->nElements, acquire, | |
| pSequence->nElements ); // alloc nElements | |
| if (ret) | |
| { | |
| idestructSequence( | |
| pSequence, pTypeDescr->pWeakRef, pTypeDescr, release ); | |
| *ppSequence = pNew; | |
| } | |
| } | |
| else | |
| { | |
| pNew = allocSeq( 0, 0 ); | |
| ret = (pNew != 0); | |
| if (ret) | |
| { | |
| // easy destruction of empty sequence: | |
| if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0) | |
| rtl_freeMemory( 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_incrementInterlockedCount( &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_incrementInterlockedCount( &pSource->nRefCount ); | |
| idestructSequence( *ppDest, pType, 0, release ); | |
| *ppDest = pSource; | |
| } | |
| } | |
| } |