summaryrefslogtreecommitdiff
path: root/cppu/source/uno/copy.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'cppu/source/uno/copy.hxx')
-rw-r--r--cppu/source/uno/copy.hxx889
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: */