LCOV - code coverage report
Current view: top level - cppu/source/uno - sequence.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 340 379 89.7 %
Date: 2014-04-11 Functions: 11 12 91.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    18510317 : static inline uno_Sequence * reallocSeq(
      45             :     uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
      46             : {
      47             :     OSL_ASSERT( nElements >= 0 );
      48    18510317 :     uno_Sequence * pNew = 0;
      49    18510317 :     sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
      50    18510317 :     if (nSize > 0)
      51             :     {
      52    18510317 :         if (pReallocate == 0)
      53             :         {
      54    14511501 :             pNew = (uno_Sequence *) rtl_allocateMemory( nSize );
      55             :         }
      56             :         else
      57             :         {
      58     3998816 :             pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize );
      59             :         }
      60    18510319 :         if (pNew != 0)
      61             :         {
      62             :             // header init
      63    18510318 :             pNew->nRefCount = 1;
      64    18510318 :             pNew->nElements = nElements;
      65             :         }
      66             :     }
      67    18510319 :     return pNew;
      68             : }
      69             : 
      70             : 
      71    15582398 : 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    15582398 :     uno_Sequence * pSeq = *ppSeq;
      78    15582398 :     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       23982 :         if (nAlloc >= 0)
      93       23942 :             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
      94       23982 :         if (pSeq != 0)
      95             :         {
      96             :             memset(
      97       23982 :                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
      98             :                 0,
      99       47964 :                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
     100             :         }
     101       23982 :         break;
     102             :     case typelib_TypeClass_BYTE:
     103     3429474 :         if (nAlloc >= 0)
     104     2083796 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
     105     3429474 :         if (pSeq != 0)
     106             :         {
     107             :             memset(
     108     3429473 :                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
     109             :                 0,
     110     6858946 :                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
     111             :         }
     112     3429474 :         break;
     113             :     case typelib_TypeClass_SHORT:
     114             :     case typelib_TypeClass_UNSIGNED_SHORT:
     115        1638 :         if (nAlloc >= 0)
     116         910 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
     117        1638 :         if (pSeq != 0)
     118             :         {
     119             :             memset(
     120        1638 :                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
     121             :                 0,
     122        3276 :                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
     123             :         }
     124        1638 :         break;
     125             :     case typelib_TypeClass_LONG:
     126             :     case typelib_TypeClass_UNSIGNED_LONG:
     127       71073 :         if (nAlloc >= 0)
     128       50568 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     129       71073 :         if (pSeq != 0)
     130             :         {
     131             :             memset(
     132       71073 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     133             :                 0,
     134      142146 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     135             :         }
     136       71073 :         break;
     137             :     case typelib_TypeClass_HYPER:
     138             :     case typelib_TypeClass_UNSIGNED_HYPER:
     139        2208 :         if (nAlloc >= 0)
     140        1940 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
     141        2208 :         if (pSeq != 0)
     142             :         {
     143             :             memset(
     144        2208 :                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
     145             :                 0,
     146        4416 :                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
     147             :         }
     148        2208 :         break;
     149             :     case typelib_TypeClass_FLOAT:
     150             :     {
     151           1 :         if (nAlloc >= 0)
     152           1 :             pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
     153           1 :         if (pSeq != 0)
     154             :         {
     155           1 :             float * pElements = (float *) pSeq->elements;
     156           2 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     157             :             {
     158           1 :                 pElements[nPos] = 0.0;
     159             :             }
     160             :         }
     161           1 :         break;
     162             :     }
     163             :     case typelib_TypeClass_DOUBLE:
     164             :     {
     165      346183 :         if (nAlloc >= 0)
     166      309913 :             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
     167      346183 :         if (pSeq != 0)
     168             :         {
     169      346183 :             double * pElements = (double *) pSeq->elements;
     170     1884073 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     171             :             {
     172     1537890 :                 pElements[nPos] = 0.0;
     173             :             }
     174             :         }
     175      346183 :         break;
     176             :     }
     177             :     case typelib_TypeClass_STRING:
     178             :     {
     179      980328 :         if (nAlloc >= 0)
     180      617930 :             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
     181      980328 :         if (pSeq != 0)
     182             :         {
     183      980328 :             rtl_uString ** pElements = (rtl_uString **) pSeq->elements;
     184     5272812 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     185             :             {
     186     4292484 :                 pElements[nPos] = 0;
     187     4292484 :                 rtl_uString_new( &pElements[nPos] );
     188             :             }
     189             :         }
     190      980328 :         break;
     191             :     }
     192             :     case typelib_TypeClass_TYPE:
     193             :     {
     194       26497 :         if (nAlloc >= 0)
     195             :         {
     196             :             pSeq = reallocSeq(
     197       26221 :                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
     198             :         }
     199       26497 :         if (pSeq != 0)
     200             :         {
     201             :             typelib_TypeDescriptionReference ** pElements =
     202       26497 :                 (typelib_TypeDescriptionReference **) pSeq->elements;
     203      509801 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     204             :             {
     205      483304 :                 pElements[nPos] = _getVoidType();
     206             :             }
     207             :         }
     208       26497 :         break;
     209             :     }
     210             :     case typelib_TypeClass_ANY:
     211             :     {
     212      760080 :         if (nAlloc >= 0)
     213      604928 :             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
     214      760080 :         if (pSeq != 0)
     215             :         {
     216      760080 :             uno_Any * pElements = (uno_Any *) pSeq->elements;
     217     3655024 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     218             :             {
     219     2894944 :                 CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
     220             :             }
     221             :         }
     222      760080 :         break;
     223             :     }
     224             :     case typelib_TypeClass_ENUM:
     225             :     {
     226       18520 :         if (nAlloc >= 0)
     227       13545 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     228       18520 :         if (pSeq != 0)
     229             :         {
     230       18520 :             typelib_TypeDescription * pElementTypeDescr = 0;
     231       18520 :             TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     232             :             sal_Int32 eEnum =
     233             :                 ((typelib_EnumTypeDescription *)
     234       18520 :                  pElementTypeDescr)->nDefaultEnumValue;
     235       18520 :             TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     236             : 
     237       18520 :             sal_Int32 * pElements = (sal_Int32 *) pSeq->elements;
     238      659176 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     239             :             {
     240      640656 :                 pElements[nPos] = eEnum;
     241             :             }
     242             :         }
     243       18520 :         break;
     244             :     }
     245             :     case typelib_TypeClass_STRUCT:
     246             :     case typelib_TypeClass_EXCEPTION:
     247             :     {
     248     2921223 :         typelib_TypeDescription * pElementTypeDescr = 0;
     249     2921223 :         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     250     2921223 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     251             : 
     252     2921223 :         if (nAlloc >= 0)
     253     1357875 :             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
     254     2921223 :         if (pSeq != 0)
     255             :         {
     256     2921223 :             char * pElements = pSeq->elements;
     257    11303075 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     258             :             {
     259             :                 _defaultConstructStruct(
     260    16763704 :                     pElements + (nElementSize * nPos),
     261    25145556 :                     (typelib_CompoundTypeDescription *)pElementTypeDescr );
     262             :             }
     263             :         }
     264             : 
     265     2921223 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     266     2921223 :         break;
     267             :     }
     268             :     case typelib_TypeClass_SEQUENCE:
     269             :     {
     270      106767 :         if (nAlloc >= 0)
     271       51470 :             pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
     272      106767 :         if (pSeq != 0)
     273             :         {
     274             :             uno_Sequence ** pElements =
     275      106767 :                 (uno_Sequence **) pSeq->elements;
     276      308305 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     277             :             {
     278      201538 :                 pElements[nPos] = createEmptySequence();
     279             :             }
     280             :         }
     281      106767 :         break;
     282             :     }
     283             :     case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
     284     6894424 :         if (nAlloc >= 0)
     285     6765937 :             pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
     286     6894424 :         if (pSeq != 0)
     287             :         {
     288             :             memset(
     289     6894424 :                 pSeq->elements + (sizeof(void *) * nStartIndex),
     290             :                 0,
     291    13788848 :                 sizeof(void *) * (nStopIndex - nStartIndex) );
     292             :         }
     293     6894424 :         break;
     294             :     default:
     295             :         OSL_FAIL( "### unexpected element type!" );
     296           0 :         pSeq = 0;
     297           0 :         break;
     298             :     }
     299             : 
     300    15582397 :     if (pSeq == 0)
     301             :     {
     302             :         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
     303           0 :         return false;
     304             :     }
     305             :     else
     306             :     {
     307    15582397 :         *ppSeq = pSeq;
     308    15582397 :         return true;
     309             :     }
     310             : }
     311             : 
     312             : 
     313     6311019 : 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     6311019 :     uno_Sequence * pSeq = *ppSeq;
     321     6311019 :     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          47 :         if (nAlloc >= 0)
     336          47 :             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
     337          47 :         if (pSeq != 0)
     338             :         {
     339             :             memcpy(
     340          47 :                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
     341             :                 (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex),
     342          94 :                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
     343             :         }
     344          47 :         break;
     345             :     case typelib_TypeClass_BYTE:
     346     2368661 :         if (nAlloc >= 0)
     347     2368661 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
     348     2368661 :         if (pSeq != 0)
     349             :         {
     350             :             memcpy(
     351     2368661 :                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
     352             :                 (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex),
     353     4737322 :                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
     354             :         }
     355     2368661 :         break;
     356             :     case typelib_TypeClass_SHORT:
     357             :     case typelib_TypeClass_UNSIGNED_SHORT:
     358         741 :         if (nAlloc >= 0)
     359         741 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
     360         741 :         if (pSeq != 0)
     361             :         {
     362             :             memcpy(
     363         741 :                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
     364         741 :                 (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex),
     365        2223 :                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
     366             :         }
     367         741 :         break;
     368             :     case typelib_TypeClass_LONG:
     369             :     case typelib_TypeClass_UNSIGNED_LONG:
     370       21524 :         if (nAlloc >= 0)
     371       21524 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     372       21524 :         if (pSeq != 0)
     373             :         {
     374             :             memcpy(
     375       21524 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     376       21524 :                 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
     377       64572 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     378             :         }
     379       21524 :         break;
     380             :     case typelib_TypeClass_HYPER:
     381             :     case typelib_TypeClass_UNSIGNED_HYPER:
     382         411 :         if (nAlloc >= 0)
     383         411 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
     384         411 :         if (pSeq != 0)
     385             :         {
     386             :             memcpy(
     387         411 :                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
     388         411 :                 (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex),
     389        1233 :                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
     390             :         }
     391         411 :         break;
     392             :     case typelib_TypeClass_FLOAT:
     393           5 :         if (nAlloc >= 0)
     394           5 :             pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
     395           5 :         if (pSeq != 0)
     396             :         {
     397             :             memcpy(
     398           5 :                 pSeq->elements + (sizeof(float) * nStartIndex),
     399           5 :                 (char *)pSourceElements + (sizeof(float) * nStartIndex),
     400          15 :                 sizeof(float) * (nStopIndex - nStartIndex) );
     401             :         }
     402           5 :         break;
     403             :     case typelib_TypeClass_DOUBLE:
     404       42756 :         if (nAlloc >= 0)
     405       42756 :             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
     406       42756 :         if (pSeq != 0)
     407             :         {
     408             :             memcpy(
     409       42756 :                 pSeq->elements + (sizeof(double) * nStartIndex),
     410       42756 :                 (char *)pSourceElements + (sizeof(double) * nStartIndex),
     411      128268 :                 sizeof(double) * (nStopIndex - nStartIndex) );
     412             :         }
     413       42756 :         break;
     414             :     case typelib_TypeClass_ENUM:
     415        5657 :         if (nAlloc >= 0)
     416        5657 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     417        5657 :         if (pSeq != 0)
     418             :         {
     419             :             memcpy(
     420        5657 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     421        5657 :                 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
     422       16971 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     423             :         }
     424        5657 :         break;
     425             :     case typelib_TypeClass_STRING:
     426             :     {
     427      707764 :         if (nAlloc >= 0)
     428      707764 :             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
     429      707764 :         if (pSeq != 0)
     430             :         {
     431      707764 :             rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements;
     432     1430121 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     433             :             {
     434             :                 ::rtl_uString_acquire(
     435      722357 :                     ((rtl_uString **)pSourceElements)[nPos] );
     436      722357 :                 pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos];
     437             :             }
     438             :         }
     439      707764 :         break;
     440             :     }
     441             :     case typelib_TypeClass_TYPE:
     442             :     {
     443         310 :         if (nAlloc >= 0)
     444             :         {
     445             :             pSeq = reallocSeq(
     446         310 :                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
     447             :         }
     448         310 :         if (pSeq != 0)
     449             :         {
     450             :             typelib_TypeDescriptionReference ** pDestElements =
     451         310 :                 (typelib_TypeDescriptionReference **) pSeq->elements;
     452         456 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     453             :             {
     454         146 :                 TYPE_ACQUIRE(
     455             :                     ((typelib_TypeDescriptionReference **)
     456             :                      pSourceElements)[nPos] );
     457         146 :                 pDestElements[nPos] =
     458             :                     ((typelib_TypeDescriptionReference **)
     459         146 :                      pSourceElements)[nPos];
     460             :             }
     461             :         }
     462         310 :         break;
     463             :     }
     464             :     case typelib_TypeClass_ANY:
     465             :     {
     466      412921 :         if (nAlloc >= 0)
     467      412921 :             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
     468      412921 :         if (pSeq != 0)
     469             :         {
     470      412921 :             uno_Any * pDestElements = (uno_Any *) pSeq->elements;
     471     1031099 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     472             :             {
     473      618178 :                 uno_Any * pSource = (uno_Any *)pSourceElements + nPos;
     474             :                 _copyConstructAny(
     475             :                     &pDestElements[nPos],
     476             :                     pSource->pData,
     477             :                     pSource->pType, 0,
     478      618178 :                     acquire, 0 );
     479             :             }
     480             :         }
     481      412921 :         break;
     482             :     }
     483             :     case typelib_TypeClass_STRUCT:
     484             :     case typelib_TypeClass_EXCEPTION:
     485             :     {
     486     2324211 :         typelib_TypeDescription * pElementTypeDescr = 0;
     487     2324211 :         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     488     2324211 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     489             : 
     490     2324211 :         if (nAlloc >= 0)
     491     2324211 :             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
     492     2324211 :         if (pSeq != 0)
     493             :         {
     494     2324211 :             char * pDestElements = pSeq->elements;
     495             : 
     496             :             typelib_CompoundTypeDescription * pTypeDescr =
     497     2324211 :                 (typelib_CompoundTypeDescription *)pElementTypeDescr;
     498    14929159 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     499             :             {
     500             :                 char * pDest =
     501    12604948 :                     pDestElements + (nElementSize * nPos);
     502             :                 char * pSource =
     503    12604948 :                     (char *)pSourceElements + (nElementSize * nPos);
     504             : 
     505    12604948 :                 if (pTypeDescr->pBaseTypeDescription)
     506             :                 {
     507             :                     // copy base value
     508             :                     _copyConstructStruct(
     509             :                         pDest, pSource,
     510       38878 :                         pTypeDescr->pBaseTypeDescription, acquire, 0 );
     511             :                 }
     512             : 
     513             :                 // then copy members
     514             :                 typelib_TypeDescriptionReference ** ppTypeRefs =
     515    12604948 :                     pTypeDescr->ppTypeRefs;
     516    12604948 :                 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
     517    12604948 :                 sal_Int32 nDescr = pTypeDescr->nMembers;
     518             : 
     519    69275478 :                 while (nDescr--)
     520             :                 {
     521             :                     ::uno_type_copyData(
     522    88131164 :                         pDest + pMemberOffsets[nDescr],
     523    88131164 :                         pSource + pMemberOffsets[nDescr],
     524   176262328 :                         ppTypeRefs[nDescr], acquire );
     525             :                 }
     526             :             }
     527             :         }
     528             : 
     529     2324211 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     530     2324211 :         break;
     531             :     }
     532             :     case typelib_TypeClass_SEQUENCE: // sequence of sequence
     533             :     {
     534      102182 :         if (nAlloc >= 0)
     535      102182 :             pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
     536      102182 :         if (pSeq != 0)
     537             :         {
     538      102182 :             typelib_TypeDescription * pElementTypeDescr = 0;
     539      102182 :             TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     540             :             typelib_TypeDescriptionReference * pSeqElementType =
     541      102182 :                 ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType;
     542      102182 :             uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements;
     543     5071994 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     544             :             {
     545             :                 uno_Sequence * pNew = icopyConstructSequence(
     546     4969812 :                     ((uno_Sequence **) pSourceElements)[nPos],
     547     4969812 :                     pSeqElementType, acquire, 0 );
     548             :                 OSL_ASSERT( pNew != 0 );
     549             :                 // ought never be a memory allocation problem,
     550             :                 // because of reference counted sequence handles
     551     4969812 :                 pDestElements[ nPos ] = pNew;
     552             :             }
     553      102182 :             TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     554             :         }
     555      102182 :         break;
     556             :     }
     557             :     case typelib_TypeClass_INTERFACE:
     558             :     {
     559      323829 :         if (nAlloc >= 0)
     560      323829 :             pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
     561      323829 :         if (pSeq != 0)
     562             :         {
     563      323829 :             void ** pDestElements = (void **) pSeq->elements;
     564      549703 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     565             :             {
     566      451748 :                 _acquire( pDestElements[nPos] =
     567      451748 :                           ((void **)pSourceElements)[nPos], acquire );
     568             :             }
     569             :         }
     570      323829 :         break;
     571             :     }
     572             :     default:
     573             :         OSL_FAIL( "### unexpected element type!" );
     574           0 :         pSeq = 0;
     575           0 :         break;
     576             :     }
     577             : 
     578     6311019 :     if (pSeq == 0)
     579             :     {
     580             :         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
     581           0 :         return false;
     582             :     }
     583             :     else
     584             :     {
     585     6311019 :         *ppSeq = pSeq;
     586     6311019 :         return true;
     587             :     }
     588             : }
     589             : 
     590             : 
     591     7732356 : 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     7732356 :     bool ret = true;
     598     7732356 :     uno_Sequence * pSeq = *ppSequence;
     599     7732356 :     sal_Int32 nElements = pSeq->nElements;
     600             : 
     601    12973788 :     if (pSeq->nRefCount > 1 ||
     602             :         // not mem-copyable elements?
     603    10471355 :         typelib_TypeClass_ANY == pElementType->eTypeClass ||
     604     9228739 :         typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
     605     3998816 :         typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
     606             :     {
     607             :         // split sequence and construct new one from scratch
     608     3733540 :         uno_Sequence * pNew = 0;
     609             : 
     610     3733540 :         sal_Int32 nRest = nSize - nElements;
     611     3733540 :         sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
     612             : 
     613     3733540 :         if (nCopy >= 0)
     614             :         {
     615             :             ret = icopyConstructFromElements(
     616             :                 &pNew, pSeq->elements, pElementType,
     617             :                 0, nCopy, acquire,
     618     3733540 :                 nSize ); // alloc to nSize
     619             :         }
     620     3733540 :         if (ret && nRest > 0)
     621             :         {
     622             :             ret = idefaultConstructElements(
     623             :                 &pNew, pElementType,
     624             :                 nCopy, nSize,
     625     3673425 :                 nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
     626             :         }
     627             : 
     628     3733540 :         if (ret)
     629             :         {
     630             :             // destruct sequence
     631     3733540 :             if (osl_atomic_decrement( &pSeq->nRefCount ) == 0)
     632             :             {
     633     1242616 :                 if (nElements > 0)
     634             :                 {
     635             :                     idestructElements(
     636             :                         pSeq->elements, pElementType,
     637     1240675 :                         0, nElements, release );
     638             :                 }
     639     1242616 :                 rtl_freeMemory( pSeq );
     640             :             }
     641     3733540 :             *ppSequence = pNew;
     642     3733540 :         }
     643             :     }
     644             :     else
     645             :     {
     646             :         OSL_ASSERT( pSeq->nRefCount == 1 );
     647     3998816 :         if (nSize > nElements) // default construct the rest
     648             :         {
     649             :             ret = idefaultConstructElements(
     650             :                 ppSequence, pElementType,
     651             :                 nElements, nSize,
     652     3708492 :                 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      290324 :                 nSize, nElements, release );
     659             :             // warning: it is assumed that the following will never fail,
     660             :             //          else this leads to a sequence null handle
     661      290324 :             *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
     662             :             OSL_ASSERT( *ppSequence != 0 );
     663      290324 :             ret = (*ppSequence != 0);
     664             :         }
     665             :     }
     666             : 
     667     7732356 :     return ret;
     668             : }
     669             : 
     670             : }
     671             : 
     672             : extern "C"
     673             : {
     674             : 
     675             : 
     676    22603157 : 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    22603157 :     if (len)
     685             :     {
     686     9896268 :         typelib_TypeDescription * pTypeDescr = 0;
     687     9896268 :         TYPELIB_DANGER_GET( &pTypeDescr, pType );
     688             : 
     689             :         typelib_TypeDescriptionReference * pElementType =
     690     9896269 :             ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
     691             : 
     692     9896269 :         *ppSequence = 0;
     693     9896269 :         if (pElements == 0)
     694             :         {
     695             :             ret = idefaultConstructElements(
     696             :                 ppSequence, pElementType,
     697             :                 0, len,
     698     8200430 :                 len ); // alloc to len
     699             :         }
     700             :         else
     701             :         {
     702             :             ret = icopyConstructFromElements(
     703             :                 ppSequence, pElements, pElementType,
     704             :                 0, len, acquire,
     705     1695839 :                 len ); // alloc to len
     706             :         }
     707             : 
     708     9896269 :         TYPELIB_DANGER_RELEASE( pTypeDescr );
     709             :     }
     710             :     else
     711             :     {
     712    12706889 :         *ppSequence = createEmptySequence();
     713    12706899 :         ret = true;
     714             :     }
     715             : 
     716             :     OSL_ASSERT( (*ppSequence != 0) == ret );
     717    22603168 :     return ret;
     718             : }
     719             : 
     720             : 
     721          57 : 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          57 :     if (len > 0)
     729             :     {
     730             :         typelib_TypeDescriptionReference * pElementType =
     731          54 :             ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
     732             : 
     733          54 :         *ppSequence = 0;
     734          54 :         if (pElements == 0)
     735             :         {
     736             :             ret = idefaultConstructElements(
     737             :                 ppSequence, pElementType,
     738             :                 0, len,
     739          54 :                 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           3 :         *ppSequence = createEmptySequence();
     752           3 :         ret = true;
     753             :     }
     754             : 
     755             :     OSL_ASSERT( (*ppSequence != 0) == ret );
     756          57 :     return ret;
     757             : }
     758             : 
     759             : 
     760     8466458 : 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     8466458 :     bool ret = true;
     769     8466458 :     if (nSize != (*ppSequence)->nElements)
     770             :     {
     771     7732314 :         typelib_TypeDescription * pTypeDescr = 0;
     772     7732314 :         TYPELIB_DANGER_GET( &pTypeDescr, pType );
     773             :         ret = ireallocSequence(
     774             :             ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     775     7732316 :             nSize, acquire, release );
     776     7732316 :         TYPELIB_DANGER_RELEASE( pTypeDescr );
     777             :     }
     778     8466459 :     return ret;
     779             : }
     780             : 
     781             : 
     782          45 : 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          45 :     bool ret = true;
     791          45 :     if (nSize != (*ppSequence)->nElements)
     792             :     {
     793             :         ret = ireallocSequence(
     794             :             ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     795          40 :             nSize, acquire, release );
     796             :     }
     797          45 :     return ret;
     798             : }
     799             : 
     800             : 
     801    64181390 : 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    64181390 :     bool ret = true;
     809    64181390 :     uno_Sequence * pSequence = *ppSequence;
     810    64181390 :     if (pSequence->nRefCount > 1)
     811             :     {
     812     1550397 :         uno_Sequence * pNew = 0;
     813     1550397 :         if (pSequence->nElements > 0)
     814             :         {
     815      881640 :             typelib_TypeDescription * pTypeDescr = 0;
     816      881640 :             TYPELIB_DANGER_GET( &pTypeDescr, pType );
     817             : 
     818             :             ret = icopyConstructFromElements(
     819             :                 &pNew, pSequence->elements,
     820             :                 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     821             :                 0, pSequence->nElements, acquire,
     822      881640 :                 pSequence->nElements ); // alloc nElements
     823      881640 :             if (ret)
     824             :             {
     825      881640 :                 idestructSequence( *ppSequence, pType, pTypeDescr, release );
     826      881640 :                 *ppSequence = pNew;
     827             :             }
     828             : 
     829      881640 :             TYPELIB_DANGER_RELEASE( pTypeDescr );
     830             :         }
     831             :         else
     832             :         {
     833      668757 :             pNew = allocSeq( 0, 0 );
     834      668757 :             ret = (pNew != 0);
     835      668757 :             if (ret)
     836             :             {
     837             :                 // easy destruction of empty sequence:
     838      668757 :                 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
     839           0 :                     rtl_freeMemory( pSequence );
     840      668757 :                 *ppSequence = pNew;
     841             :             }
     842             :         }
     843             :     }
     844    64181390 :     return ret;
     845             : }
     846             : 
     847             : 
     848          81 : 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          81 :     bool ret = true;
     856          81 :     uno_Sequence * pSequence = *ppSequence;
     857          81 :     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          81 :     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     4388695 : 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     4388695 :     if (*ppDest != pSource)
     916             :     {
     917     4080899 :         osl_atomic_increment( &pSource->nRefCount );
     918     4080899 :         idestructSequence( *ppDest, pType, 0, release );
     919     4080899 :         *ppDest = pSource;
     920             :     }
     921     4388695 : }
     922             : 
     923             : }
     924             : 
     925             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10