/**************************************************************
 *
 * 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;
	}
}

}
