LCOV - code coverage report
Current view: top level - cppu/source/uno - sequence.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 142 379 37.5 %
Date: 2014-04-14 Functions: 8 12 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "sal/config.h"
      21             : 
      22             : #include <cassert>
      23             : #include <string.h>
      24             : 
      25             : #include <rtl/alloc.h>
      26             : #include <osl/diagnose.h>
      27             : #include <osl/interlck.h>
      28             : #include <typelib/typedescription.h>
      29             : #include <uno/data.h>
      30             : #include <uno/dispatcher.h>
      31             : #include <uno/sequence2.h>
      32             : 
      33             : #include "constr.hxx"
      34             : #include "copy.hxx"
      35             : #include "destr.hxx"
      36             : 
      37             : 
      38             : using namespace cppu;
      39             : 
      40             : namespace cppu
      41             : {
      42             : 
      43             : 
      44         793 : static inline uno_Sequence * reallocSeq(
      45             :     uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
      46             : {
      47             :     OSL_ASSERT( nElements >= 0 );
      48         793 :     uno_Sequence * pNew = 0;
      49         793 :     sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
      50         793 :     if (nSize > 0)
      51             :     {
      52         793 :         if (pReallocate == 0)
      53             :         {
      54         793 :             pNew = (uno_Sequence *) rtl_allocateMemory( nSize );
      55             :         }
      56             :         else
      57             :         {
      58           0 :             pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize );
      59             :         }
      60         793 :         if (pNew != 0)
      61             :         {
      62             :             // header init
      63         793 :             pNew->nRefCount = 1;
      64         793 :             pNew->nElements = nElements;
      65             :         }
      66             :     }
      67         793 :     return pNew;
      68             : }
      69             : 
      70             : 
      71         791 : static inline bool idefaultConstructElements(
      72             :     uno_Sequence ** ppSeq,
      73             :     typelib_TypeDescriptionReference * pElementType,
      74             :     sal_Int32 nStartIndex, sal_Int32 nStopIndex,
      75             :     sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
      76             : {
      77         791 :     uno_Sequence * pSeq = *ppSeq;
      78         791 :     switch (pElementType->eTypeClass)
      79             :     {
      80             :     case typelib_TypeClass_CHAR:
      81           0 :         if (nAlloc >= 0)
      82           0 :             pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
      83           0 :         if (pSeq != 0)
      84             :         {
      85             :             memset(
      86           0 :                 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
      87             :                 0,
      88           0 :                 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
      89             :         }
      90           0 :         break;
      91             :     case typelib_TypeClass_BOOLEAN:
      92           0 :         if (nAlloc >= 0)
      93           0 :             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
      94           0 :         if (pSeq != 0)
      95             :         {
      96             :             memset(
      97           0 :                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
      98             :                 0,
      99           0 :                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
     100             :         }
     101           0 :         break;
     102             :     case typelib_TypeClass_BYTE:
     103          33 :         if (nAlloc >= 0)
     104           0 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
     105          33 :         if (pSeq != 0)
     106             :         {
     107             :             memset(
     108          33 :                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
     109             :                 0,
     110          66 :                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
     111             :         }
     112          33 :         break;
     113             :     case typelib_TypeClass_SHORT:
     114             :     case typelib_TypeClass_UNSIGNED_SHORT:
     115           0 :         if (nAlloc >= 0)
     116           0 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
     117           0 :         if (pSeq != 0)
     118             :         {
     119             :             memset(
     120           0 :                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
     121             :                 0,
     122           0 :                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
     123             :         }
     124           0 :         break;
     125             :     case typelib_TypeClass_LONG:
     126             :     case typelib_TypeClass_UNSIGNED_LONG:
     127           3 :         if (nAlloc >= 0)
     128           0 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     129           3 :         if (pSeq != 0)
     130             :         {
     131             :             memset(
     132           3 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     133             :                 0,
     134           6 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     135             :         }
     136           3 :         break;
     137             :     case typelib_TypeClass_HYPER:
     138             :     case typelib_TypeClass_UNSIGNED_HYPER:
     139           1 :         if (nAlloc >= 0)
     140           0 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
     141           1 :         if (pSeq != 0)
     142             :         {
     143             :             memset(
     144           1 :                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
     145             :                 0,
     146           2 :                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
     147             :         }
     148           1 :         break;
     149             :     case typelib_TypeClass_FLOAT:
     150             :     {
     151           0 :         if (nAlloc >= 0)
     152           0 :             pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
     153           0 :         if (pSeq != 0)
     154             :         {
     155           0 :             float * pElements = (float *) pSeq->elements;
     156           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     157             :             {
     158           0 :                 pElements[nPos] = 0.0;
     159             :             }
     160             :         }
     161           0 :         break;
     162             :     }
     163             :     case typelib_TypeClass_DOUBLE:
     164             :     {
     165           0 :         if (nAlloc >= 0)
     166           0 :             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
     167           0 :         if (pSeq != 0)
     168             :         {
     169           0 :             double * pElements = (double *) pSeq->elements;
     170           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     171             :             {
     172           0 :                 pElements[nPos] = 0.0;
     173             :             }
     174             :         }
     175           0 :         break;
     176             :     }
     177             :     case typelib_TypeClass_STRING:
     178             :     {
     179         734 :         if (nAlloc >= 0)
     180          31 :             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
     181         734 :         if (pSeq != 0)
     182             :         {
     183         734 :             rtl_uString ** pElements = (rtl_uString **) pSeq->elements;
     184        2986 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     185             :             {
     186        2252 :                 pElements[nPos] = 0;
     187        2252 :                 rtl_uString_new( &pElements[nPos] );
     188             :             }
     189             :         }
     190         734 :         break;
     191             :     }
     192             :     case typelib_TypeClass_TYPE:
     193             :     {
     194           0 :         if (nAlloc >= 0)
     195             :         {
     196             :             pSeq = reallocSeq(
     197           0 :                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
     198             :         }
     199           0 :         if (pSeq != 0)
     200             :         {
     201             :             typelib_TypeDescriptionReference ** pElements =
     202           0 :                 (typelib_TypeDescriptionReference **) pSeq->elements;
     203           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     204             :             {
     205           0 :                 pElements[nPos] = _getVoidType();
     206             :             }
     207             :         }
     208           0 :         break;
     209             :     }
     210             :     case typelib_TypeClass_ANY:
     211             :     {
     212           3 :         if (nAlloc >= 0)
     213           3 :             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
     214           3 :         if (pSeq != 0)
     215             :         {
     216           3 :             uno_Any * pElements = (uno_Any *) pSeq->elements;
     217           6 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     218             :             {
     219           3 :                 CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
     220             :             }
     221             :         }
     222           3 :         break;
     223             :     }
     224             :     case typelib_TypeClass_ENUM:
     225             :     {
     226           0 :         if (nAlloc >= 0)
     227           0 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     228           0 :         if (pSeq != 0)
     229             :         {
     230           0 :             typelib_TypeDescription * pElementTypeDescr = 0;
     231           0 :             TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     232             :             sal_Int32 eEnum =
     233             :                 ((typelib_EnumTypeDescription *)
     234           0 :                  pElementTypeDescr)->nDefaultEnumValue;
     235           0 :             TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     236             : 
     237           0 :             sal_Int32 * pElements = (sal_Int32 *) pSeq->elements;
     238           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     239             :             {
     240           0 :                 pElements[nPos] = eEnum;
     241             :             }
     242             :         }
     243           0 :         break;
     244             :     }
     245             :     case typelib_TypeClass_STRUCT:
     246             :     case typelib_TypeClass_EXCEPTION:
     247             :     {
     248           0 :         typelib_TypeDescription * pElementTypeDescr = 0;
     249           0 :         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     250           0 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     251             : 
     252           0 :         if (nAlloc >= 0)
     253           0 :             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
     254           0 :         if (pSeq != 0)
     255             :         {
     256           0 :             char * pElements = pSeq->elements;
     257           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     258             :             {
     259             :                 _defaultConstructStruct(
     260           0 :                     pElements + (nElementSize * nPos),
     261           0 :                     (typelib_CompoundTypeDescription *)pElementTypeDescr );
     262             :             }
     263             :         }
     264             : 
     265           0 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     266           0 :         break;
     267             :     }
     268             :     case typelib_TypeClass_SEQUENCE:
     269             :     {
     270           0 :         if (nAlloc >= 0)
     271           0 :             pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
     272           0 :         if (pSeq != 0)
     273             :         {
     274             :             uno_Sequence ** pElements =
     275           0 :                 (uno_Sequence **) pSeq->elements;
     276           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     277             :             {
     278           0 :                 pElements[nPos] = createEmptySequence();
     279             :             }
     280             :         }
     281           0 :         break;
     282             :     }
     283             :     case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
     284          17 :         if (nAlloc >= 0)
     285          17 :             pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
     286          17 :         if (pSeq != 0)
     287             :         {
     288             :             memset(
     289          17 :                 pSeq->elements + (sizeof(void *) * nStartIndex),
     290             :                 0,
     291          34 :                 sizeof(void *) * (nStopIndex - nStartIndex) );
     292             :         }
     293          17 :         break;
     294             :     default:
     295             :         OSL_FAIL( "### unexpected element type!" );
     296           0 :         pSeq = 0;
     297           0 :         break;
     298             :     }
     299             : 
     300         791 :     if (pSeq == 0)
     301             :     {
     302             :         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
     303           0 :         return false;
     304             :     }
     305             :     else
     306             :     {
     307         791 :         *ppSeq = pSeq;
     308         791 :         return true;
     309             :     }
     310             : }
     311             : 
     312             : 
     313         742 : static inline bool icopyConstructFromElements(
     314             :     uno_Sequence ** ppSeq, void * pSourceElements,
     315             :     typelib_TypeDescriptionReference * pElementType,
     316             :     sal_Int32 nStartIndex, sal_Int32 nStopIndex,
     317             :     uno_AcquireFunc acquire,
     318             :     sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
     319             : {
     320         742 :     uno_Sequence * pSeq = *ppSeq;
     321         742 :     switch (pElementType->eTypeClass)
     322             :     {
     323             :     case typelib_TypeClass_CHAR:
     324           0 :         if (nAlloc >= 0)
     325           0 :             pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
     326           0 :         if (pSeq != 0)
     327             :         {
     328             :             memcpy(
     329           0 :                 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
     330           0 :                 (char *)pSourceElements + (sizeof(sal_Unicode) * nStartIndex),
     331           0 :                 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
     332             :         }
     333           0 :         break;
     334             :     case typelib_TypeClass_BOOLEAN:
     335           0 :         if (nAlloc >= 0)
     336           0 :             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
     337           0 :         if (pSeq != 0)
     338             :         {
     339             :             memcpy(
     340           0 :                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
     341             :                 (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex),
     342           0 :                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
     343             :         }
     344           0 :         break;
     345             :     case typelib_TypeClass_BYTE:
     346          33 :         if (nAlloc >= 0)
     347          33 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
     348          33 :         if (pSeq != 0)
     349             :         {
     350             :             memcpy(
     351          33 :                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
     352             :                 (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex),
     353          66 :                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
     354             :         }
     355          33 :         break;
     356             :     case typelib_TypeClass_SHORT:
     357             :     case typelib_TypeClass_UNSIGNED_SHORT:
     358           0 :         if (nAlloc >= 0)
     359           0 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
     360           0 :         if (pSeq != 0)
     361             :         {
     362             :             memcpy(
     363           0 :                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
     364           0 :                 (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex),
     365           0 :                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
     366             :         }
     367           0 :         break;
     368             :     case typelib_TypeClass_LONG:
     369             :     case typelib_TypeClass_UNSIGNED_LONG:
     370           3 :         if (nAlloc >= 0)
     371           3 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     372           3 :         if (pSeq != 0)
     373             :         {
     374             :             memcpy(
     375           3 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     376           3 :                 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
     377           9 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     378             :         }
     379           3 :         break;
     380             :     case typelib_TypeClass_HYPER:
     381             :     case typelib_TypeClass_UNSIGNED_HYPER:
     382           1 :         if (nAlloc >= 0)
     383           1 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
     384           1 :         if (pSeq != 0)
     385             :         {
     386             :             memcpy(
     387           1 :                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
     388           1 :                 (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex),
     389           3 :                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
     390             :         }
     391           1 :         break;
     392             :     case typelib_TypeClass_FLOAT:
     393           0 :         if (nAlloc >= 0)
     394           0 :             pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
     395           0 :         if (pSeq != 0)
     396             :         {
     397             :             memcpy(
     398           0 :                 pSeq->elements + (sizeof(float) * nStartIndex),
     399           0 :                 (char *)pSourceElements + (sizeof(float) * nStartIndex),
     400           0 :                 sizeof(float) * (nStopIndex - nStartIndex) );
     401             :         }
     402           0 :         break;
     403             :     case typelib_TypeClass_DOUBLE:
     404           0 :         if (nAlloc >= 0)
     405           0 :             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
     406           0 :         if (pSeq != 0)
     407             :         {
     408             :             memcpy(
     409           0 :                 pSeq->elements + (sizeof(double) * nStartIndex),
     410           0 :                 (char *)pSourceElements + (sizeof(double) * nStartIndex),
     411           0 :                 sizeof(double) * (nStopIndex - nStartIndex) );
     412             :         }
     413           0 :         break;
     414             :     case typelib_TypeClass_ENUM:
     415           0 :         if (nAlloc >= 0)
     416           0 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     417           0 :         if (pSeq != 0)
     418             :         {
     419             :             memcpy(
     420           0 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     421           0 :                 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
     422           0 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     423             :         }
     424           0 :         break;
     425             :     case typelib_TypeClass_STRING:
     426             :     {
     427         705 :         if (nAlloc >= 0)
     428         705 :             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
     429         705 :         if (pSeq != 0)
     430             :         {
     431         705 :             rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements;
     432         707 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     433             :             {
     434             :                 ::rtl_uString_acquire(
     435           2 :                     ((rtl_uString **)pSourceElements)[nPos] );
     436           2 :                 pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos];
     437             :             }
     438             :         }
     439         705 :         break;
     440             :     }
     441             :     case typelib_TypeClass_TYPE:
     442             :     {
     443           0 :         if (nAlloc >= 0)
     444             :         {
     445             :             pSeq = reallocSeq(
     446           0 :                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
     447             :         }
     448           0 :         if (pSeq != 0)
     449             :         {
     450             :             typelib_TypeDescriptionReference ** pDestElements =
     451           0 :                 (typelib_TypeDescriptionReference **) pSeq->elements;
     452           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     453             :             {
     454           0 :                 TYPE_ACQUIRE(
     455             :                     ((typelib_TypeDescriptionReference **)
     456             :                      pSourceElements)[nPos] );
     457           0 :                 pDestElements[nPos] =
     458             :                     ((typelib_TypeDescriptionReference **)
     459           0 :                      pSourceElements)[nPos];
     460             :             }
     461             :         }
     462           0 :         break;
     463             :     }
     464             :     case typelib_TypeClass_ANY:
     465             :     {
     466           0 :         if (nAlloc >= 0)
     467           0 :             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
     468           0 :         if (pSeq != 0)
     469             :         {
     470           0 :             uno_Any * pDestElements = (uno_Any *) pSeq->elements;
     471           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     472             :             {
     473           0 :                 uno_Any * pSource = (uno_Any *)pSourceElements + nPos;
     474             :                 _copyConstructAny(
     475             :                     &pDestElements[nPos],
     476             :                     pSource->pData,
     477             :                     pSource->pType, 0,
     478           0 :                     acquire, 0 );
     479             :             }
     480             :         }
     481           0 :         break;
     482             :     }
     483             :     case typelib_TypeClass_STRUCT:
     484             :     case typelib_TypeClass_EXCEPTION:
     485             :     {
     486           0 :         typelib_TypeDescription * pElementTypeDescr = 0;
     487           0 :         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     488           0 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     489             : 
     490           0 :         if (nAlloc >= 0)
     491           0 :             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
     492           0 :         if (pSeq != 0)
     493             :         {
     494           0 :             char * pDestElements = pSeq->elements;
     495             : 
     496             :             typelib_CompoundTypeDescription * pTypeDescr =
     497           0 :                 (typelib_CompoundTypeDescription *)pElementTypeDescr;
     498           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     499             :             {
     500             :                 char * pDest =
     501           0 :                     pDestElements + (nElementSize * nPos);
     502             :                 char * pSource =
     503           0 :                     (char *)pSourceElements + (nElementSize * nPos);
     504             : 
     505           0 :                 if (pTypeDescr->pBaseTypeDescription)
     506             :                 {
     507             :                     // copy base value
     508             :                     _copyConstructStruct(
     509             :                         pDest, pSource,
     510           0 :                         pTypeDescr->pBaseTypeDescription, acquire, 0 );
     511             :                 }
     512             : 
     513             :                 // then copy members
     514             :                 typelib_TypeDescriptionReference ** ppTypeRefs =
     515           0 :                     pTypeDescr->ppTypeRefs;
     516           0 :                 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
     517           0 :                 sal_Int32 nDescr = pTypeDescr->nMembers;
     518             : 
     519           0 :                 while (nDescr--)
     520             :                 {
     521             :                     ::uno_type_copyData(
     522           0 :                         pDest + pMemberOffsets[nDescr],
     523           0 :                         pSource + pMemberOffsets[nDescr],
     524           0 :                         ppTypeRefs[nDescr], acquire );
     525             :                 }
     526             :             }
     527             :         }
     528             : 
     529           0 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     530           0 :         break;
     531             :     }
     532             :     case typelib_TypeClass_SEQUENCE: // sequence of sequence
     533             :     {
     534           0 :         if (nAlloc >= 0)
     535           0 :             pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
     536           0 :         if (pSeq != 0)
     537             :         {
     538           0 :             typelib_TypeDescription * pElementTypeDescr = 0;
     539           0 :             TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     540             :             typelib_TypeDescriptionReference * pSeqElementType =
     541           0 :                 ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType;
     542           0 :             uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements;
     543           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     544             :             {
     545             :                 uno_Sequence * pNew = icopyConstructSequence(
     546           0 :                     ((uno_Sequence **) pSourceElements)[nPos],
     547           0 :                     pSeqElementType, acquire, 0 );
     548             :                 OSL_ASSERT( pNew != 0 );
     549             :                 // ought never be a memory allocation problem,
     550             :                 // because of reference counted sequence handles
     551           0 :                 pDestElements[ nPos ] = pNew;
     552             :             }
     553           0 :             TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     554             :         }
     555           0 :         break;
     556             :     }
     557             :     case typelib_TypeClass_INTERFACE:
     558             :     {
     559           0 :         if (nAlloc >= 0)
     560           0 :             pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
     561           0 :         if (pSeq != 0)
     562             :         {
     563           0 :             void ** pDestElements = (void **) pSeq->elements;
     564           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     565             :             {
     566           0 :                 _acquire( pDestElements[nPos] =
     567           0 :                           ((void **)pSourceElements)[nPos], acquire );
     568             :             }
     569             :         }
     570           0 :         break;
     571             :     }
     572             :     default:
     573             :         OSL_FAIL( "### unexpected element type!" );
     574           0 :         pSeq = 0;
     575           0 :         break;
     576             :     }
     577             : 
     578         742 :     if (pSeq == 0)
     579             :     {
     580             :         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
     581           0 :         return false;
     582             :     }
     583             :     else
     584             :     {
     585         742 :         *ppSeq = pSeq;
     586         742 :         return true;
     587             :     }
     588             : }
     589             : 
     590             : 
     591         740 : static inline bool ireallocSequence(
     592             :     uno_Sequence ** ppSequence,
     593             :     typelib_TypeDescriptionReference * pElementType,
     594             :     sal_Int32 nSize,
     595             :     uno_AcquireFunc acquire, uno_ReleaseFunc release )
     596             : {
     597         740 :     bool ret = true;
     598         740 :     uno_Sequence * pSeq = *ppSequence;
     599         740 :     sal_Int32 nElements = pSeq->nElements;
     600             : 
     601         740 :     if (pSeq->nRefCount > 1 ||
     602             :         // not mem-copyable elements?
     603           0 :         typelib_TypeClass_ANY == pElementType->eTypeClass ||
     604           0 :         typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
     605           0 :         typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
     606             :     {
     607             :         // split sequence and construct new one from scratch
     608         740 :         uno_Sequence * pNew = 0;
     609             : 
     610         740 :         sal_Int32 nRest = nSize - nElements;
     611         740 :         sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
     612             : 
     613         740 :         if (nCopy >= 0)
     614             :         {
     615             :             ret = icopyConstructFromElements(
     616             :                 &pNew, pSeq->elements, pElementType,
     617             :                 0, nCopy, acquire,
     618         740 :                 nSize ); // alloc to nSize
     619             :         }
     620         740 :         if (ret && nRest > 0)
     621             :         {
     622             :             ret = idefaultConstructElements(
     623             :                 &pNew, pElementType,
     624             :                 nCopy, nSize,
     625         740 :                 nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
     626             :         }
     627             : 
     628         740 :         if (ret)
     629             :         {
     630             :             // destruct sequence
     631         740 :             if (osl_atomic_decrement( &pSeq->nRefCount ) == 0)
     632             :             {
     633           0 :                 if (nElements > 0)
     634             :                 {
     635             :                     idestructElements(
     636             :                         pSeq->elements, pElementType,
     637           0 :                         0, nElements, release );
     638             :                 }
     639           0 :                 rtl_freeMemory( pSeq );
     640             :             }
     641         740 :             *ppSequence = pNew;
     642         740 :         }
     643             :     }
     644             :     else
     645             :     {
     646             :         OSL_ASSERT( pSeq->nRefCount == 1 );
     647           0 :         if (nSize > nElements) // default construct the rest
     648             :         {
     649             :             ret = idefaultConstructElements(
     650             :                 ppSequence, pElementType,
     651             :                 nElements, nSize,
     652           0 :                 nSize ); // realloc to nSize
     653             :         }
     654             :         else // or destruct the rest and realloc mem
     655             :         {
     656             :             sal_Int32 nElementSize = idestructElements(
     657             :                 pSeq->elements, pElementType,
     658           0 :                 nSize, nElements, release );
     659             :             // warning: it is assumed that the following will never fail,
     660             :             //          else this leads to a sequence null handle
     661           0 :             *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
     662             :             OSL_ASSERT( *ppSequence != 0 );
     663           0 :             ret = (*ppSequence != 0);
     664             :         }
     665             :     }
     666             : 
     667         740 :     return ret;
     668             : }
     669             : 
     670             : }
     671             : 
     672             : extern "C"
     673             : {
     674             : 
     675             : 
     676         978 : sal_Bool SAL_CALL uno_type_sequence_construct(
     677             :     uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
     678             :     void * pElements, sal_Int32 len,
     679             :     uno_AcquireFunc acquire )
     680             :     SAL_THROW_EXTERN_C()
     681             : {
     682             :     assert( len >= 0 );
     683             :     bool ret;
     684         978 :     if (len)
     685             :     {
     686          53 :         typelib_TypeDescription * pTypeDescr = 0;
     687          53 :         TYPELIB_DANGER_GET( &pTypeDescr, pType );
     688             : 
     689             :         typelib_TypeDescriptionReference * pElementType =
     690          53 :             ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
     691             : 
     692          53 :         *ppSequence = 0;
     693          53 :         if (pElements == 0)
     694             :         {
     695             :             ret = idefaultConstructElements(
     696             :                 ppSequence, pElementType,
     697             :                 0, len,
     698          51 :                 len ); // alloc to len
     699             :         }
     700             :         else
     701             :         {
     702             :             ret = icopyConstructFromElements(
     703             :                 ppSequence, pElements, pElementType,
     704             :                 0, len, acquire,
     705           2 :                 len ); // alloc to len
     706             :         }
     707             : 
     708          53 :         TYPELIB_DANGER_RELEASE( pTypeDescr );
     709             :     }
     710             :     else
     711             :     {
     712         925 :         *ppSequence = createEmptySequence();
     713         925 :         ret = true;
     714             :     }
     715             : 
     716             :     OSL_ASSERT( (*ppSequence != 0) == ret );
     717         978 :     return ret;
     718             : }
     719             : 
     720             : 
     721           0 : sal_Bool SAL_CALL uno_sequence_construct(
     722             :     uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
     723             :     void * pElements, sal_Int32 len,
     724             :     uno_AcquireFunc acquire )
     725             :     SAL_THROW_EXTERN_C()
     726             : {
     727             :     bool ret;
     728           0 :     if (len > 0)
     729             :     {
     730             :         typelib_TypeDescriptionReference * pElementType =
     731           0 :             ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
     732             : 
     733           0 :         *ppSequence = 0;
     734           0 :         if (pElements == 0)
     735             :         {
     736             :             ret = idefaultConstructElements(
     737             :                 ppSequence, pElementType,
     738             :                 0, len,
     739           0 :                 len ); // alloc to len
     740             :         }
     741             :         else
     742             :         {
     743             :             ret = icopyConstructFromElements(
     744             :                 ppSequence, pElements, pElementType,
     745             :                 0, len, acquire,
     746           0 :                 len ); // alloc to len
     747             :         }
     748             :     }
     749             :     else
     750             :     {
     751           0 :         *ppSequence = createEmptySequence();
     752           0 :         ret = true;
     753             :     }
     754             : 
     755             :     OSL_ASSERT( (*ppSequence != 0) == ret );
     756           0 :     return ret;
     757             : }
     758             : 
     759             : 
     760         871 : sal_Bool SAL_CALL uno_type_sequence_realloc(
     761             :     uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
     762             :     sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
     763             :     SAL_THROW_EXTERN_C()
     764             : {
     765             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     766             :     OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
     767             : 
     768         871 :     bool ret = true;
     769         871 :     if (nSize != (*ppSequence)->nElements)
     770             :     {
     771         740 :         typelib_TypeDescription * pTypeDescr = 0;
     772         740 :         TYPELIB_DANGER_GET( &pTypeDescr, pType );
     773             :         ret = ireallocSequence(
     774             :             ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     775         740 :             nSize, acquire, release );
     776         740 :         TYPELIB_DANGER_RELEASE( pTypeDescr );
     777             :     }
     778         871 :     return ret;
     779             : }
     780             : 
     781             : 
     782           0 : sal_Bool SAL_CALL uno_sequence_realloc(
     783             :     uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
     784             :     sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
     785             :     SAL_THROW_EXTERN_C()
     786             : {
     787             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     788             :     OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
     789             : 
     790           0 :     bool ret = true;
     791           0 :     if (nSize != (*ppSequence)->nElements)
     792             :     {
     793             :         ret = ireallocSequence(
     794             :             ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     795           0 :             nSize, acquire, release );
     796             :     }
     797           0 :     return ret;
     798             : }
     799             : 
     800             : 
     801        1078 : sal_Bool SAL_CALL uno_type_sequence_reference2One(
     802             :     uno_Sequence ** ppSequence,
     803             :     typelib_TypeDescriptionReference * pType,
     804             :     uno_AcquireFunc acquire, uno_ReleaseFunc release )
     805             :     SAL_THROW_EXTERN_C()
     806             : {
     807             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     808        1078 :     bool ret = true;
     809        1078 :     uno_Sequence * pSequence = *ppSequence;
     810        1078 :     if (pSequence->nRefCount > 1)
     811             :     {
     812         131 :         uno_Sequence * pNew = 0;
     813         131 :         if (pSequence->nElements > 0)
     814             :         {
     815           0 :             typelib_TypeDescription * pTypeDescr = 0;
     816           0 :             TYPELIB_DANGER_GET( &pTypeDescr, pType );
     817             : 
     818             :             ret = icopyConstructFromElements(
     819             :                 &pNew, pSequence->elements,
     820             :                 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     821             :                 0, pSequence->nElements, acquire,
     822           0 :                 pSequence->nElements ); // alloc nElements
     823           0 :             if (ret)
     824             :             {
     825           0 :                 idestructSequence( *ppSequence, pType, pTypeDescr, release );
     826           0 :                 *ppSequence = pNew;
     827             :             }
     828             : 
     829           0 :             TYPELIB_DANGER_RELEASE( pTypeDescr );
     830             :         }
     831             :         else
     832             :         {
     833         131 :             pNew = allocSeq( 0, 0 );
     834         131 :             ret = (pNew != 0);
     835         131 :             if (ret)
     836             :             {
     837             :                 // easy destruction of empty sequence:
     838         131 :                 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
     839           0 :                     rtl_freeMemory( pSequence );
     840         131 :                 *ppSequence = pNew;
     841             :             }
     842             :         }
     843             :     }
     844        1078 :     return ret;
     845             : }
     846             : 
     847             : 
     848           0 : sal_Bool SAL_CALL uno_sequence_reference2One(
     849             :     uno_Sequence ** ppSequence,
     850             :     typelib_TypeDescription * pTypeDescr,
     851             :     uno_AcquireFunc acquire, uno_ReleaseFunc release )
     852             :     SAL_THROW_EXTERN_C()
     853             : {
     854             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     855           0 :     bool ret = true;
     856           0 :     uno_Sequence * pSequence = *ppSequence;
     857           0 :     if (pSequence->nRefCount > 1)
     858             :     {
     859           0 :         uno_Sequence * pNew = 0;
     860           0 :         if (pSequence->nElements > 0)
     861             :         {
     862             :             ret = icopyConstructFromElements(
     863             :                 &pNew, pSequence->elements,
     864             :                 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     865             :                 0, pSequence->nElements, acquire,
     866           0 :                 pSequence->nElements ); // alloc nElements
     867           0 :             if (ret)
     868             :             {
     869             :                 idestructSequence(
     870           0 :                     pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
     871           0 :                 *ppSequence = pNew;
     872             :             }
     873             :         }
     874             :         else
     875             :         {
     876           0 :             pNew = allocSeq( 0, 0 );
     877           0 :             ret = (pNew != 0);
     878           0 :             if (ret)
     879             :             {
     880             :                 // easy destruction of empty sequence:
     881           0 :                 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
     882           0 :                     rtl_freeMemory( pSequence );
     883           0 :                 *ppSequence = pNew;
     884             :             }
     885             :         }
     886             : 
     887             :     }
     888           0 :     return ret;
     889             : }
     890             : 
     891             : 
     892           0 : void SAL_CALL uno_sequence_assign(
     893             :     uno_Sequence ** ppDest,
     894             :     uno_Sequence * pSource,
     895             :     typelib_TypeDescription * pTypeDescr,
     896             :     uno_ReleaseFunc release )
     897             :     SAL_THROW_EXTERN_C()
     898             : {
     899           0 :     if (*ppDest != pSource)
     900             :     {
     901           0 :         osl_atomic_increment( &pSource->nRefCount );
     902           0 :         idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
     903           0 :         *ppDest = pSource;
     904             :     }
     905           0 : }
     906             : 
     907             : 
     908          39 : void SAL_CALL uno_type_sequence_assign(
     909             :     uno_Sequence ** ppDest,
     910             :     uno_Sequence * pSource,
     911             :     typelib_TypeDescriptionReference * pType,
     912             :     uno_ReleaseFunc release )
     913             :     SAL_THROW_EXTERN_C()
     914             : {
     915          39 :     if (*ppDest != pSource)
     916             :     {
     917          38 :         osl_atomic_increment( &pSource->nRefCount );
     918          38 :         idestructSequence( *ppDest, pType, 0, release );
     919          38 :         *ppDest = pSource;
     920             :     }
     921          39 : }
     922             : 
     923             : }
     924             : 
     925             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10