diff options
Diffstat (limited to 'cppu/source/uno/copy.hxx')
-rw-r--r-- | cppu/source/uno/copy.hxx | 889 |
1 files changed, 889 insertions, 0 deletions
diff --git a/cppu/source/uno/copy.hxx b/cppu/source/uno/copy.hxx new file mode 100644 index 000000000000..7750a686b694 --- /dev/null +++ b/cppu/source/uno/copy.hxx @@ -0,0 +1,889 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef COPY_HXX +#define COPY_HXX + +#include "prim.hxx" +#include "constr.hxx" + + +namespace cppu +{ + +//################################################################################################## +//#### copy construction ########################################################################### +//################################################################################################## + +//------------------------------------------------------------------------------ +inline uno_Sequence * allocSeq( + sal_Int32 nElementSize, sal_Int32 nElements ) +{ + OSL_ASSERT( nElements >= 0 && nElementSize >= 0 ); + uno_Sequence * pSeq = 0; + sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements ); + if (nSize > 0) + { + pSeq = (uno_Sequence *) rtl_allocateMemory( nSize ); + if (pSeq != 0) + { + // header init + pSeq->nRefCount = 1; + pSeq->nElements = nElements; + } + } + return pSeq; +} + +//-------------------------------------------------------------------------------------------------- +void copyConstructStruct( + void * pDest, void * pSource, + typelib_CompoundTypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) + SAL_THROW ( () ); +//-------------------------------------------------------------------------------------------------- +inline void _copyConstructStruct( + void * pDest, void * pSource, + typelib_CompoundTypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) + SAL_THROW ( () ) +{ + if (pTypeDescr->pBaseTypeDescription) + { + // copy base value + copyConstructStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription, acquire, mapping ); + } + + // then copy members + typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs; + sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets; + sal_Int32 nDescr = pTypeDescr->nMembers; + + if (mapping) + { + while (nDescr--) + { + ::uno_type_copyAndConvertData( + (char *)pDest + pMemberOffsets[nDescr], + (char *)pSource + pMemberOffsets[nDescr], + ppTypeRefs[nDescr], mapping ); + } + } + else + { + while (nDescr--) + { + ::uno_type_copyData( + (char *)pDest + pMemberOffsets[nDescr], + (char *)pSource + pMemberOffsets[nDescr], + ppTypeRefs[nDescr], acquire ); + } + } +} +//-------------------------------------------------------------------------------------------------- +inline void _copyConstructArray( + void * pDest, void * pSource, + typelib_ArrayTypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) +{ + typelib_TypeDescriptionReference * pElementTypeRef = ((typelib_IndirectTypeDescription *)pTypeDescr)->pType; + typelib_TypeDescription * pElementTypeDescr = NULL; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementTypeRef ); + sal_Int32 nElementSize = ((typelib_TypeDescription*)pElementTypeDescr)->nSize; + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + sal_Int32 nTotalElements = pTypeDescr->nTotalElements; + + if (mapping) + { + for(sal_Int32 i = 0; i < nTotalElements; i++) + { + ::uno_type_copyAndConvertData( + (sal_Char *)pDest + i * nElementSize, + (sal_Char *)pSource + i * nElementSize, + pElementTypeRef, mapping ); + } + } + else + { + for(sal_Int32 i = 0; i < nTotalElements; i++) + { + ::uno_type_copyData( + (sal_Char *)pDest + (i * nElementSize), + (sal_Char *)pSource + (i * nElementSize), + pElementTypeRef, acquire ); + } + } +} +//-------------------------------------------------------------------------------------------------- +inline void _copyConstructUnion( + void * pDest, void * pSource, + typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) + SAL_THROW ( () ) +{ + typelib_TypeDescriptionReference * pSetType = _unionGetSetType( pSource, pTypeDescr ); + if (mapping) + { + ::uno_type_copyAndConvertData( + (char *)pDest + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, + (char *)pSource + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, + pSetType, mapping ); + } + else + { + ::uno_type_copyData( + (char *)pDest + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, + (char *)pSource + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, + pSetType, acquire ); + } + *(sal_Int64 *)pDest = *(sal_Int64 *)pSource; + typelib_typedescriptionreference_release( pSetType ); +} + +//------------------------------------------------------------------------------ +uno_Sequence * copyConstructSequence( + uno_Sequence * pSource, + typelib_TypeDescriptionReference * pElementType, + uno_AcquireFunc acquire, uno_Mapping * mapping ); + +//-------------------------------------------------------------------------------------------------- +inline void _copyConstructAnyFromData( + uno_Any * pDestAny, void * pSource, + typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) + SAL_THROW ( () ) +{ + TYPE_ACQUIRE( pType ); + pDestAny->pType = pType; + + switch (pType->eTypeClass) + { + case typelib_TypeClass_CHAR: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Unicode *)&pDestAny->pReserved = *(sal_Unicode *)pSource; + break; + case typelib_TypeClass_BOOLEAN: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Bool *)&pDestAny->pReserved = (*(sal_Bool *)pSource != sal_False); + break; + case typelib_TypeClass_BYTE: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int8 *)&pDestAny->pReserved = *(sal_Int8 *)pSource; + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int16 *)&pDestAny->pReserved = *(sal_Int16 *)pSource; + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int32 *)&pDestAny->pReserved = *(sal_Int32 *)pSource; + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + if (sizeof(void *) >= sizeof(sal_Int64)) + { + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int64 *)&pDestAny->pReserved = *(sal_Int64 *)pSource; + } + else + { + pDestAny->pData = ::rtl_allocateMemory( sizeof(sal_Int64) ); + *(sal_Int64 *)pDestAny->pData = *(sal_Int64 *)pSource; + } + break; + case typelib_TypeClass_FLOAT: + if (sizeof(void *) >= sizeof(float)) + { + pDestAny->pData = &pDestAny->pReserved; + *(float *)&pDestAny->pReserved = *(float *)pSource; + } + else + { + pDestAny->pData = ::rtl_allocateMemory( sizeof(float) ); + *(float *)pDestAny->pData = *(float *)pSource; + } + break; + case typelib_TypeClass_DOUBLE: + if (sizeof(void *) >= sizeof(double)) + { + pDestAny->pData = &pDestAny->pReserved; + *(double *)&pDestAny->pReserved = *(double *)pSource; + } + else + { + pDestAny->pData = ::rtl_allocateMemory( sizeof(double) ); + *(double *)pDestAny->pData = *(double *)pSource; + } + break; + case typelib_TypeClass_STRING: + ::rtl_uString_acquire( *(rtl_uString **)pSource ); + pDestAny->pData = &pDestAny->pReserved; + *(rtl_uString **)&pDestAny->pReserved = *(rtl_uString **)pSource; + break; + case typelib_TypeClass_TYPE: + TYPE_ACQUIRE( *(typelib_TypeDescriptionReference **)pSource ); + pDestAny->pData = &pDestAny->pReserved; + *(typelib_TypeDescriptionReference **)&pDestAny->pReserved = *(typelib_TypeDescriptionReference **)pSource; + break; + case typelib_TypeClass_ANY: + OSL_ENSURE( 0, "### unexpected nested any!" ); + break; + case typelib_TypeClass_ENUM: + pDestAny->pData = &pDestAny->pReserved; + // enum is forced to 32bit long + *(sal_Int32 *)&pDestAny->pReserved = *(sal_Int32 *)pSource; + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + if (pTypeDescr) + { + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _copyConstructStruct( + pDestAny->pData, pSource, + (typelib_CompoundTypeDescription *)pTypeDescr, + acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _copyConstructStruct( + pDestAny->pData, pSource, + (typelib_CompoundTypeDescription *)pTypeDescr, + acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_ARRAY: + if (pTypeDescr) + { + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _copyConstructArray( + pDestAny->pData, pSource, + (typelib_ArrayTypeDescription *)pTypeDescr, + acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _copyConstructArray( + pDestAny->pData, pSource, + (typelib_ArrayTypeDescription *)pTypeDescr, + acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_UNION: + if (pTypeDescr) + { + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _copyConstructUnion( pDestAny->pData, pSource, pTypeDescr, acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _copyConstructUnion( pDestAny->pData, pSource, pTypeDescr, acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_SEQUENCE: + pDestAny->pData = &pDestAny->pReserved; + if (pTypeDescr) + { + *(uno_Sequence **)&pDestAny->pReserved = copyConstructSequence( + *(uno_Sequence **)pSource, + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, + acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + *(uno_Sequence **)&pDestAny->pReserved = copyConstructSequence( + *(uno_Sequence **)pSource, + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, + acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_INTERFACE: + pDestAny->pData = &pDestAny->pReserved; + if (mapping) + { + pDestAny->pReserved = _map( *(void **)pSource, pType, pTypeDescr, mapping ); + } + else + { + _acquire( pDestAny->pReserved = *(void **)pSource, acquire ); + } + break; + default: + OSL_ASSERT(false); + break; + } +} +//-------------------------------------------------------------------------------------------------- +inline void _copyConstructAny( + uno_Any * pDestAny, void * pSource, + typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) + SAL_THROW ( () ) +{ + if (typelib_TypeClass_VOID == pType->eTypeClass) + { + CONSTRUCT_EMPTY_ANY( pDestAny ); + } + else + { + if (typelib_TypeClass_ANY == pType->eTypeClass) + { + if (pSource) + { + pType = ((uno_Any *)pSource)->pType; + if (typelib_TypeClass_VOID == pType->eTypeClass) + { + CONSTRUCT_EMPTY_ANY( pDestAny ); + return; + } + pTypeDescr = 0; + pSource = ((uno_Any *)pSource)->pData; + } + else + { + CONSTRUCT_EMPTY_ANY( pDestAny ); + return; + } + } + if (pSource) + { + _copyConstructAnyFromData( pDestAny, pSource, pType, pTypeDescr, acquire, mapping ); + } + else // default construct + { + TYPE_ACQUIRE( pType ); + pDestAny->pType = pType; + switch (pType->eTypeClass) + { + case typelib_TypeClass_CHAR: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Unicode *)&pDestAny->pReserved = '\0'; + break; + case typelib_TypeClass_BOOLEAN: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Bool *)&pDestAny->pReserved = sal_False; + break; + case typelib_TypeClass_BYTE: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int8 *)&pDestAny->pReserved = 0; + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int16 *)&pDestAny->pReserved = 0; + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int32 *)&pDestAny->pReserved = 0; + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + if (sizeof(void *) >= sizeof(sal_Int64)) + { + pDestAny->pData = &pDestAny->pReserved; + *(sal_Int64 *)&pDestAny->pReserved = 0; + } + else + { + pDestAny->pData = ::rtl_allocateMemory( sizeof(sal_Int64) ); + *(sal_Int64 *)pDestAny->pData = 0; + } + break; + case typelib_TypeClass_FLOAT: + if (sizeof(void *) >= sizeof(float)) + { + pDestAny->pData = &pDestAny->pReserved; + *(float *)&pDestAny->pReserved = 0.0; + } + else + { + pDestAny->pData = ::rtl_allocateMemory( sizeof(float) ); + *(float *)pDestAny->pData = 0.0; + } + break; + case typelib_TypeClass_DOUBLE: + if (sizeof(void *) >= sizeof(double)) + { + pDestAny->pData = &pDestAny->pReserved; + *(double *)&pDestAny->pReserved = 0.0; + } + else + { + pDestAny->pData = ::rtl_allocateMemory( sizeof(double) ); + *(double *)pDestAny->pData = 0.0; + } + break; + case typelib_TypeClass_STRING: + pDestAny->pData = &pDestAny->pReserved; + *(rtl_uString **)&pDestAny->pReserved = 0; + ::rtl_uString_new( (rtl_uString **)&pDestAny->pReserved ); + break; + case typelib_TypeClass_TYPE: + pDestAny->pData = &pDestAny->pReserved; + *(typelib_TypeDescriptionReference **)&pDestAny->pReserved = _getVoidType(); + break; + case typelib_TypeClass_ENUM: + pDestAny->pData = &pDestAny->pReserved; + if (pTypeDescr) + { + *(sal_Int32 *)&pDestAny->pReserved = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue; + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + *(sal_Int32 *)&pDestAny->pReserved = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue; + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + if (pTypeDescr) + { + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _defaultConstructStruct( + pDestAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _defaultConstructStruct( + pDestAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_ARRAY: + if (pTypeDescr) + { + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _defaultConstructArray( + pDestAny->pData, (typelib_ArrayTypeDescription *)pTypeDescr ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _defaultConstructArray( + pDestAny->pData, (typelib_ArrayTypeDescription *)pTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_UNION: + if (pTypeDescr) + { + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _defaultConstructUnion( pDestAny->pData, pTypeDescr ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); + _defaultConstructUnion( pDestAny->pData, pTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_SEQUENCE: + pDestAny->pData = &pDestAny->pReserved; + *(uno_Sequence **)&pDestAny->pReserved = createEmptySequence(); + break; + case typelib_TypeClass_INTERFACE: + pDestAny->pData = &pDestAny->pReserved; + pDestAny->pReserved = 0; // either cpp or c-uno interface + break; + default: + OSL_ASSERT(false); + break; + } + } + } +} +//------------------------------------------------------------------------------ +inline uno_Sequence * icopyConstructSequence( + uno_Sequence * pSource, + typelib_TypeDescriptionReference * pElementType, + uno_AcquireFunc acquire, uno_Mapping * mapping ) +{ + typelib_TypeClass eTypeClass = pElementType->eTypeClass; + if (!mapping || + (eTypeClass <= typelib_TypeClass_ENUM && + eTypeClass != typelib_TypeClass_ANY)) + { + ::osl_incrementInterlockedCount( &pSource->nRefCount ); + return pSource; + } + else // create new sequence + { + uno_Sequence * pDest; + sal_Int32 nElements = pSource->nElements; + if (nElements) + { + switch (eTypeClass) + { + case typelib_TypeClass_ANY: + { + pDest = allocSeq( sizeof (uno_Any), nElements ); + if (pDest != 0) + { + uno_Any * pDestElements = (uno_Any *)pDest->elements; + uno_Any * pSourceElements = (uno_Any *)pSource->elements; + for ( sal_Int32 nPos = nElements; nPos--; ) + { + typelib_TypeDescriptionReference * pType = + pSourceElements[nPos].pType; + if (typelib_TypeClass_VOID == pType->eTypeClass) + { + CONSTRUCT_EMPTY_ANY( &pDestElements[nPos] ); + } + else + { + _copyConstructAnyFromData( + &pDestElements[nPos], + pSourceElements[nPos].pData, + pType, 0, + acquire, mapping ); + } + } + } + break; + } + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + char * pSourceElements = pSource->elements; + pDest = allocSeq( nElementSize, nElements ); + if (pDest != 0) + { + char * pElements = pDest->elements; + for ( sal_Int32 nPos = nElements; nPos--; ) + { + _copyConstructStruct( + pElements + (nPos * nElementSize), + pSourceElements + (nPos * nElementSize), + (typelib_CompoundTypeDescription *) + pElementTypeDescr, + acquire, mapping ); + } + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + break; + } + case typelib_TypeClass_ARRAY: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + char * pSourceElements = pSource->elements; + pDest = allocSeq( nElementSize, nElements ); + if (pDest != 0) + { + char * pElements = pDest->elements; + for ( sal_Int32 nPos = nElements; nPos--; ) + { + _copyConstructArray( + pElements + (nPos * nElementSize), + pSourceElements + (nPos * nElementSize), + (typelib_ArrayTypeDescription *)pElementTypeDescr, + acquire, mapping ); + } + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + break; + } + case typelib_TypeClass_UNION: + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + sal_Int32 nElementSize = pElementTypeDescr->nSize; + sal_Int32 nValueOffset = + ((typelib_UnionTypeDescription *) + pElementTypeDescr)->nValueOffset; + pDest = allocSeq( nElementSize, nElements ); + if (pDest != 0) + { + char * pElements = pDest->elements; + char * pSourceElements = pSource->elements; + for ( sal_Int32 nPos = nElements; nPos--; ) + { + char * pDest2 = + pElements + (nPos * nElementSize); + char * pSource2 = + pSourceElements + (nPos * nElementSize); + + typelib_TypeDescriptionReference * pSetType = + _unionGetSetType( pSource2, pElementTypeDescr ); + ::uno_type_copyAndConvertData( + pDest2 + nValueOffset, pSource2 + nValueOffset, + pSetType, mapping ); + *(sal_Int64 *)pDest2 = *(sal_Int64 *)pSource2; + ::typelib_typedescriptionreference_release( pSetType ); + } + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + break; + } + case typelib_TypeClass_SEQUENCE: // sequence of sequence + { + pDest = allocSeq( sizeof (uno_Sequence *), nElements ); + if (pDest != 0) + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + typelib_TypeDescriptionReference * pSeqElementType = + ((typelib_IndirectTypeDescription *) + pElementTypeDescr)->pType; + + uno_Sequence ** pDestElements = + (uno_Sequence **) pDest->elements; + uno_Sequence ** pSourceElements = + (uno_Sequence **) pSource->elements; + for ( sal_Int32 nPos = nElements; nPos--; ) + { + uno_Sequence * pNew = copyConstructSequence( + pSourceElements[nPos], + pSeqElementType, + acquire, mapping ); + 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: + { + pDest = allocSeq( sizeof (void *), nElements ); + if (pDest != 0) + { + char * pElements = pDest->elements; + void ** pSourceElements = (void **)pSource->elements; + if (mapping) + { + typelib_TypeDescription * pElementTypeDescr = 0; + TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); + for ( sal_Int32 nPos = nElements; nPos--; ) + { + ((void **)pElements)[nPos] = 0; + if (((void **)pSourceElements)[nPos]) + { + (*mapping->mapInterface)( + mapping, (void **)pElements + nPos, + pSourceElements[nPos], + (typelib_InterfaceTypeDescription *) + pElementTypeDescr ); + } + } + TYPELIB_DANGER_RELEASE( pElementTypeDescr ); + } + else + { + for ( sal_Int32 nPos = nElements; nPos--; ) + { + ((void **)pElements)[nPos] = pSourceElements[nPos]; + _acquire( ((void **)pElements)[nPos], acquire ); + } + } + } + break; + } + default: + OSL_ENSURE( 0, "### unexepcted sequence element type!" ); + pDest = 0; + break; + } + } + else // empty sequence + { + pDest = allocSeq( 0, 0 ); + } + + return pDest; + } +} + +//-------------------------------------------------------------------------------------------------- +inline void _copyConstructData( + void * pDest, void * pSource, + typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr, + uno_AcquireFunc acquire, uno_Mapping * mapping ) + SAL_THROW ( () ) +{ + switch (pType->eTypeClass) + { + case typelib_TypeClass_CHAR: + *(sal_Unicode *)pDest = *(sal_Unicode *)pSource; + break; + case typelib_TypeClass_BOOLEAN: + *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False); + break; + case typelib_TypeClass_BYTE: + *(sal_Int8 *)pDest = *(sal_Int8 *)pSource; + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + *(sal_Int16 *)pDest = *(sal_Int16 *)pSource; + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + *(sal_Int32 *)pDest = *(sal_Int32 *)pSource; + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + *(sal_Int64 *)pDest = *(sal_Int64 *)pSource; + break; + case typelib_TypeClass_FLOAT: + *(float *)pDest = *(float *)pSource; + break; + case typelib_TypeClass_DOUBLE: + *(double *)pDest = *(double *)pSource; + break; + case typelib_TypeClass_STRING: + ::rtl_uString_acquire( *(rtl_uString **)pSource ); + *(rtl_uString **)pDest = *(rtl_uString **)pSource; + break; + case typelib_TypeClass_TYPE: + TYPE_ACQUIRE( *(typelib_TypeDescriptionReference **)pSource ); + *(typelib_TypeDescriptionReference **)pDest = *(typelib_TypeDescriptionReference **)pSource; + break; + case typelib_TypeClass_ANY: + _copyConstructAny( + (uno_Any *)pDest, ((uno_Any *)pSource)->pData, + ((uno_Any *)pSource)->pType, 0, + acquire, mapping ); + break; + case typelib_TypeClass_ENUM: + *(sal_Int32 *)pDest = *(sal_Int32 *)pSource; + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + if (pTypeDescr) + { + _copyConstructStruct( + pDest, pSource, + (typelib_CompoundTypeDescription *)pTypeDescr, + acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _copyConstructStruct( + pDest, pSource, + (typelib_CompoundTypeDescription *)pTypeDescr, + acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_ARRAY: + if (pTypeDescr) + { + _copyConstructArray( + pDest, pSource, + (typelib_ArrayTypeDescription *)pTypeDescr, + acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _copyConstructArray( + pDest, pSource, + (typelib_ArrayTypeDescription *)pTypeDescr, + acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_UNION: + if (pTypeDescr) + { + _copyConstructUnion( pDest, pSource, pTypeDescr, acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + _copyConstructUnion( pDest, pSource, pTypeDescr, acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + break; + case typelib_TypeClass_SEQUENCE: + if (mapping) + { + if (pTypeDescr) + { + *(uno_Sequence **)pDest = icopyConstructSequence( + *(uno_Sequence **)pSource, + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, + acquire, mapping ); + } + else + { + TYPELIB_DANGER_GET( &pTypeDescr, pType ); + *(uno_Sequence **)pDest = icopyConstructSequence( + *(uno_Sequence **)pSource, + ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, + acquire, mapping ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + } + } + else + { + ::osl_incrementInterlockedCount( &(*(uno_Sequence **)pSource)->nRefCount ); + *(uno_Sequence **)pDest = *(uno_Sequence **)pSource; + } + break; + case typelib_TypeClass_INTERFACE: + if (mapping) + *(void **)pDest = _map( *(void **)pSource, pType, pTypeDescr, mapping ); + else + _acquire( *(void **)pDest = *(void **)pSource, acquire ); + break; + default: + break; + } +} + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |