LCOV - code coverage report
Current view: top level - cppu/source/uno - sequence.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 345 384 89.8 %
Date: 2014-11-03 Functions: 12 13 92.3 %
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    44590456 : static inline uno_Sequence * reallocSeq(
      45             :     uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
      46             : {
      47             :     OSL_ASSERT( nElements >= 0 );
      48    44590456 :     uno_Sequence * pNew = 0;
      49    44590456 :     sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
      50    44590456 :     if (nSize > 0)
      51             :     {
      52    44590458 :         if (pReallocate == 0)
      53             :         {
      54    37068942 :             pNew = (uno_Sequence *) rtl_allocateMemory( nSize );
      55             :         }
      56             :         else
      57             :         {
      58     7521516 :             pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize );
      59             :         }
      60    44590520 :         if (pNew != 0)
      61             :         {
      62             :             // header init
      63    44590517 :             pNew->nRefCount = 1;
      64    44590517 :             pNew->nElements = nElements;
      65             :         }
      66             :     }
      67    44590518 :     return pNew;
      68             : }
      69             : 
      70             : 
      71    37517422 : 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    37517422 :     uno_Sequence * pSeq = *ppSeq;
      78    37517422 :     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      102834 :         if (nAlloc >= 0)
      93      102746 :             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
      94      102834 :         if (pSeq != 0)
      95             :         {
      96             :             memset(
      97      102834 :                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
      98             :                 0,
      99      205668 :                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
     100             :         }
     101      102834 :         break;
     102             :     case typelib_TypeClass_BYTE:
     103     3156045 :         if (nAlloc >= 0)
     104     1550806 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
     105     3156044 :         if (pSeq != 0)
     106             :         {
     107             :             memset(
     108     3156044 :                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
     109             :                 0,
     110     6312088 :                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
     111             :         }
     112     3156044 :         break;
     113             :     case typelib_TypeClass_SHORT:
     114             :     case typelib_TypeClass_UNSIGNED_SHORT:
     115        3553 :         if (nAlloc >= 0)
     116        1983 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
     117        3553 :         if (pSeq != 0)
     118             :         {
     119             :             memset(
     120        3553 :                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
     121             :                 0,
     122        7106 :                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
     123             :         }
     124        3553 :         break;
     125             :     case typelib_TypeClass_LONG:
     126             :     case typelib_TypeClass_UNSIGNED_LONG:
     127      185336 :         if (nAlloc >= 0)
     128      144238 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     129      185336 :         if (pSeq != 0)
     130             :         {
     131             :             memset(
     132      185336 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     133             :                 0,
     134      370672 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     135             :         }
     136      185336 :         break;
     137             :     case typelib_TypeClass_HYPER:
     138             :     case typelib_TypeClass_UNSIGNED_HYPER:
     139        5313 :         if (nAlloc >= 0)
     140        4684 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
     141        5313 :         if (pSeq != 0)
     142             :         {
     143             :             memset(
     144        5313 :                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
     145             :                 0,
     146       10626 :                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
     147             :         }
     148        5313 :         break;
     149             :     case typelib_TypeClass_FLOAT:
     150             :     {
     151           2 :         if (nAlloc >= 0)
     152           2 :             pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
     153           2 :         if (pSeq != 0)
     154             :         {
     155           2 :             float * pElements = (float *) pSeq->elements;
     156           4 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     157             :             {
     158           2 :                 pElements[nPos] = 0.0;
     159             :             }
     160             :         }
     161           2 :         break;
     162             :     }
     163             :     case typelib_TypeClass_DOUBLE:
     164             :     {
     165      462614 :         if (nAlloc >= 0)
     166      415977 :             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
     167      462614 :         if (pSeq != 0)
     168             :         {
     169      462614 :             double * pElements = (double *) pSeq->elements;
     170     3337724 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     171             :             {
     172     2875110 :                 pElements[nPos] = 0.0;
     173             :             }
     174             :         }
     175      462614 :         break;
     176             :     }
     177             :     case typelib_TypeClass_STRING:
     178             :     {
     179     2702931 :         if (nAlloc >= 0)
     180     1857708 :             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
     181     2702929 :         if (pSeq != 0)
     182             :         {
     183     2702929 :             rtl_uString ** pElements = (rtl_uString **) pSeq->elements;
     184    16279843 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     185             :             {
     186    13576912 :                 pElements[nPos] = 0;
     187    13576912 :                 rtl_uString_new( &pElements[nPos] );
     188             :             }
     189             :         }
     190     2702931 :         break;
     191             :     }
     192             :     case typelib_TypeClass_TYPE:
     193             :     {
     194      103114 :         if (nAlloc >= 0)
     195             :         {
     196             :             pSeq = reallocSeq(
     197      102500 :                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
     198             :         }
     199      103114 :         if (pSeq != 0)
     200             :         {
     201             :             typelib_TypeDescriptionReference ** pElements =
     202      103114 :                 (typelib_TypeDescriptionReference **) pSeq->elements;
     203     2436192 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     204             :             {
     205     2333078 :                 pElements[nPos] = _getVoidType();
     206             :             }
     207             :         }
     208      103114 :         break;
     209             :     }
     210             :     case typelib_TypeClass_ANY:
     211             :     {
     212     2125959 :         if (nAlloc >= 0)
     213     1723007 :             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
     214     2125959 :         if (pSeq != 0)
     215             :         {
     216     2125959 :             uno_Any * pElements = (uno_Any *) pSeq->elements;
     217     9842775 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     218             :             {
     219     7716816 :                 CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
     220             :             }
     221             :         }
     222     2125959 :         break;
     223             :     }
     224             :     case typelib_TypeClass_ENUM:
     225             :     {
     226       78844 :         if (nAlloc >= 0)
     227       63880 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     228       78844 :         if (pSeq != 0)
     229             :         {
     230       78844 :             typelib_TypeDescription * pElementTypeDescr = 0;
     231       78844 :             TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     232             :             sal_Int32 eEnum =
     233             :                 ((typelib_EnumTypeDescription *)
     234       78844 :                  pElementTypeDescr)->nDefaultEnumValue;
     235       78844 :             TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     236             : 
     237       78844 :             sal_Int32 * pElements = (sal_Int32 *) pSeq->elements;
     238     4863000 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     239             :             {
     240     4784156 :                 pElements[nPos] = eEnum;
     241             :             }
     242             :         }
     243       78844 :         break;
     244             :     }
     245             :     case typelib_TypeClass_STRUCT:
     246             :     case typelib_TypeClass_EXCEPTION:
     247             :     {
     248     7555434 :         typelib_TypeDescription * pElementTypeDescr = 0;
     249     7555434 :         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     250     7555434 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     251             : 
     252     7555434 :         if (nAlloc >= 0)
     253     3126339 :             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
     254     7555434 :         if (pSeq != 0)
     255             :         {
     256     7555434 :             char * pElements = pSeq->elements;
     257    29929764 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     258             :             {
     259             :                 _defaultConstructStruct(
     260    44748660 :                     pElements + (nElementSize * nPos),
     261    67122990 :                     (typelib_CompoundTypeDescription *)pElementTypeDescr );
     262             :             }
     263             :         }
     264             : 
     265     7555434 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     266     7555434 :         break;
     267             :     }
     268             :     case typelib_TypeClass_SEQUENCE:
     269             :     {
     270      250515 :         if (nAlloc >= 0)
     271      144687 :             pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
     272      250515 :         if (pSeq != 0)
     273             :         {
     274             :             uno_Sequence ** pElements =
     275      250515 :                 (uno_Sequence **) pSeq->elements;
     276      736291 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     277             :             {
     278      485776 :                 pElements[nPos] = createEmptySequence();
     279             :             }
     280             :         }
     281      250515 :         break;
     282             :     }
     283             :     case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
     284    20784928 :         if (nAlloc >= 0)
     285    20523183 :             pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
     286    20784928 :         if (pSeq != 0)
     287             :         {
     288             :             memset(
     289    20784928 :                 pSeq->elements + (sizeof(void *) * nStartIndex),
     290             :                 0,
     291    41569856 :                 sizeof(void *) * (nStopIndex - nStartIndex) );
     292             :         }
     293    20784928 :         break;
     294             :     default:
     295             :         OSL_FAIL( "### unexpected element type!" );
     296           0 :         pSeq = 0;
     297           0 :         break;
     298             :     }
     299             : 
     300    37517397 :     if (pSeq == 0)
     301             :     {
     302             :         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
     303           0 :         return false;
     304             :     }
     305             :     else
     306             :     {
     307    37517397 :         *ppSeq = pSeq;
     308    37517397 :         return true;
     309             :     }
     310             : }
     311             : 
     312             : 
     313    13979909 : 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    13979909 :     uno_Sequence * pSeq = *ppSeq;
     321    13979909 :     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         102 :         if (nAlloc >= 0)
     336         102 :             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
     337         102 :         if (pSeq != 0)
     338             :         {
     339             :             memcpy(
     340         102 :                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
     341         102 :                 (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex),
     342         306 :                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
     343             :         }
     344         102 :         break;
     345             :     case typelib_TypeClass_BYTE:
     346     3593275 :         if (nAlloc >= 0)
     347     3593275 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
     348     3593275 :         if (pSeq != 0)
     349             :         {
     350             :             memcpy(
     351     3593275 :                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
     352     3593275 :                 (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex),
     353    10779825 :                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
     354             :         }
     355     3593275 :         break;
     356             :     case typelib_TypeClass_SHORT:
     357             :     case typelib_TypeClass_UNSIGNED_SHORT:
     358        1596 :         if (nAlloc >= 0)
     359        1596 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
     360        1596 :         if (pSeq != 0)
     361             :         {
     362             :             memcpy(
     363        1596 :                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
     364        1596 :                 (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex),
     365        4788 :                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
     366             :         }
     367        1596 :         break;
     368             :     case typelib_TypeClass_LONG:
     369             :     case typelib_TypeClass_UNSIGNED_LONG:
     370       44024 :         if (nAlloc >= 0)
     371       44024 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     372       44024 :         if (pSeq != 0)
     373             :         {
     374             :             memcpy(
     375       44024 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     376       44024 :                 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
     377      132072 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     378             :         }
     379       44024 :         break;
     380             :     case typelib_TypeClass_HYPER:
     381             :     case typelib_TypeClass_UNSIGNED_HYPER:
     382         687 :         if (nAlloc >= 0)
     383         687 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
     384         687 :         if (pSeq != 0)
     385             :         {
     386             :             memcpy(
     387         687 :                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
     388         687 :                 (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex),
     389        2061 :                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
     390             :         }
     391         687 :         break;
     392             :     case typelib_TypeClass_FLOAT:
     393          10 :         if (nAlloc >= 0)
     394          10 :             pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
     395          10 :         if (pSeq != 0)
     396             :         {
     397             :             memcpy(
     398          10 :                 pSeq->elements + (sizeof(float) * nStartIndex),
     399          10 :                 (char *)pSourceElements + (sizeof(float) * nStartIndex),
     400          30 :                 sizeof(float) * (nStopIndex - nStartIndex) );
     401             :         }
     402          10 :         break;
     403             :     case typelib_TypeClass_DOUBLE:
     404       66384 :         if (nAlloc >= 0)
     405       66384 :             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
     406       66384 :         if (pSeq != 0)
     407             :         {
     408             :             memcpy(
     409       66384 :                 pSeq->elements + (sizeof(double) * nStartIndex),
     410       66384 :                 (char *)pSourceElements + (sizeof(double) * nStartIndex),
     411      199152 :                 sizeof(double) * (nStopIndex - nStartIndex) );
     412             :         }
     413       66384 :         break;
     414             :     case typelib_TypeClass_ENUM:
     415       16914 :         if (nAlloc >= 0)
     416       16914 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     417       16914 :         if (pSeq != 0)
     418             :         {
     419             :             memcpy(
     420       16914 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     421       16914 :                 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
     422       50742 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     423             :         }
     424       16914 :         break;
     425             :     case typelib_TypeClass_STRING:
     426             :     {
     427     1931390 :         if (nAlloc >= 0)
     428     1931390 :             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
     429     1931390 :         if (pSeq != 0)
     430             :         {
     431     1931390 :             rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements;
     432     4195831 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     433             :             {
     434             :                 // https://communities.coverity.com/thread/2993
     435             :                 /* coverity[overrun-buffer-arg] */
     436             :                 ::rtl_uString_acquire(
     437     2264441 :                     ((rtl_uString **)pSourceElements)[nPos] );
     438     2264441 :                 pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos];
     439             :             }
     440             :         }
     441     1931390 :         break;
     442             :     }
     443             :     case typelib_TypeClass_TYPE:
     444             :     {
     445         682 :         if (nAlloc >= 0)
     446             :         {
     447             :             pSeq = reallocSeq(
     448         682 :                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
     449             :         }
     450         682 :         if (pSeq != 0)
     451             :         {
     452             :             typelib_TypeDescriptionReference ** pDestElements =
     453         682 :                 (typelib_TypeDescriptionReference **) pSeq->elements;
     454         974 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     455             :             {
     456         292 :                 TYPE_ACQUIRE(
     457             :                     ((typelib_TypeDescriptionReference **)
     458             :                      pSourceElements)[nPos] );
     459         292 :                 pDestElements[nPos] =
     460             :                     ((typelib_TypeDescriptionReference **)
     461         292 :                      pSourceElements)[nPos];
     462             :             }
     463             :         }
     464         682 :         break;
     465             :     }
     466             :     case typelib_TypeClass_ANY:
     467             :     {
     468     1132614 :         if (nAlloc >= 0)
     469     1132614 :             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
     470     1132614 :         if (pSeq != 0)
     471             :         {
     472     1132614 :             uno_Any * pDestElements = (uno_Any *) pSeq->elements;
     473     2734246 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     474             :             {
     475     1601632 :                 uno_Any * pSource = (uno_Any *)pSourceElements + nPos;
     476             :                 _copyConstructAny(
     477             :                     &pDestElements[nPos],
     478             :                     pSource->pData,
     479             :                     pSource->pType, 0,
     480     1601632 :                     acquire, 0 );
     481             :             }
     482             :         }
     483     1132614 :         break;
     484             :     }
     485             :     case typelib_TypeClass_STRUCT:
     486             :     case typelib_TypeClass_EXCEPTION:
     487             :     {
     488     6379474 :         typelib_TypeDescription * pElementTypeDescr = 0;
     489     6379474 :         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     490     6379474 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     491             : 
     492     6379474 :         if (nAlloc >= 0)
     493     6379474 :             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
     494     6379474 :         if (pSeq != 0)
     495             :         {
     496     6379474 :             char * pDestElements = pSeq->elements;
     497             : 
     498             :             typelib_CompoundTypeDescription * pTypeDescr =
     499     6379474 :                 (typelib_CompoundTypeDescription *)pElementTypeDescr;
     500    44139231 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     501             :             {
     502             :                 char * pDest =
     503    37759757 :                     pDestElements + (nElementSize * nPos);
     504             :                 char * pSource =
     505    37759757 :                     (char *)pSourceElements + (nElementSize * nPos);
     506             : 
     507    37759757 :                 if (pTypeDescr->pBaseTypeDescription)
     508             :                 {
     509             :                     // copy base value
     510             :                     _copyConstructStruct(
     511             :                         pDest, pSource,
     512       82287 :                         pTypeDescr->pBaseTypeDescription, acquire, 0 );
     513             :                 }
     514             : 
     515             :                 // then copy members
     516             :                 typelib_TypeDescriptionReference ** ppTypeRefs =
     517    37759757 :                     pTypeDescr->ppTypeRefs;
     518    37759757 :                 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
     519    37759757 :                 sal_Int32 nDescr = pTypeDescr->nMembers;
     520             : 
     521   207436109 :                 while (nDescr--)
     522             :                 {
     523             :                     ::uno_type_copyData(
     524   263833190 :                         pDest + pMemberOffsets[nDescr],
     525   263833190 :                         pSource + pMemberOffsets[nDescr],
     526   527666380 :                         ppTypeRefs[nDescr], acquire );
     527             :                 }
     528             :             }
     529             :         }
     530             : 
     531     6379474 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     532     6379474 :         break;
     533             :     }
     534             :     case typelib_TypeClass_SEQUENCE: // sequence of sequence
     535             :     {
     536      251611 :         if (nAlloc >= 0)
     537      251611 :             pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
     538      251611 :         if (pSeq != 0)
     539             :         {
     540      251611 :             typelib_TypeDescription * pElementTypeDescr = 0;
     541      251611 :             TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     542             :             typelib_TypeDescriptionReference * pSeqElementType =
     543      251611 :                 ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType;
     544      251611 :             uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements;
     545    10445548 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     546             :             {
     547             :                 uno_Sequence * pNew = icopyConstructSequence(
     548    10193937 :                     ((uno_Sequence **) pSourceElements)[nPos],
     549    10193937 :                     pSeqElementType, acquire, 0 );
     550             :                 OSL_ASSERT( pNew != 0 );
     551             :                 // ought never be a memory allocation problem,
     552             :                 // because of reference counted sequence handles
     553    10193937 :                 pDestElements[ nPos ] = pNew;
     554             :             }
     555      251611 :             TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     556             :         }
     557      251611 :         break;
     558             :     }
     559             :     case typelib_TypeClass_INTERFACE:
     560             :     {
     561      561146 :         if (nAlloc >= 0)
     562      561146 :             pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
     563      561146 :         if (pSeq != 0)
     564             :         {
     565      561146 :             void ** pDestElements = (void **) pSeq->elements;
     566      917564 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     567             :             {
     568      712836 :                 _acquire( pDestElements[nPos] =
     569      712836 :                           ((void **)pSourceElements)[nPos], acquire );
     570             :             }
     571             :         }
     572      561146 :         break;
     573             :     }
     574             :     default:
     575             :         OSL_FAIL( "### unexpected element type!" );
     576           0 :         pSeq = 0;
     577           0 :         break;
     578             :     }
     579             : 
     580    13979905 :     if (pSeq == 0)
     581             :     {
     582             :         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
     583           0 :         return false;
     584             :     }
     585             :     else
     586             :     {
     587    13979905 :         *ppSeq = pSeq;
     588    13979905 :         return true;
     589             :     }
     590             : }
     591             : 
     592             : 
     593    15454170 : static inline bool ireallocSequence(
     594             :     uno_Sequence ** ppSequence,
     595             :     typelib_TypeDescriptionReference * pElementType,
     596             :     sal_Int32 nSize,
     597             :     uno_AcquireFunc acquire, uno_ReleaseFunc release )
     598             : {
     599    15454170 :     bool ret = true;
     600    15454170 :     uno_Sequence * pSeq = *ppSequence;
     601    15454170 :     sal_Int32 nElements = pSeq->nElements;
     602             : 
     603    26364765 :     if (pSeq->nRefCount > 1 ||
     604             :         // not mem-copyable elements?
     605    21787806 :         typelib_TypeClass_ANY == pElementType->eTypeClass ||
     606    18398727 :         typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
     607     7521516 :         typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
     608             :     {
     609             :         // split sequence and construct new one from scratch
     610     7932654 :         uno_Sequence * pNew = 0;
     611             : 
     612     7932654 :         sal_Int32 nRest = nSize - nElements;
     613     7932654 :         sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
     614             : 
     615     7932654 :         if (nCopy >= 0)
     616             :         {
     617             :             ret = icopyConstructFromElements(
     618             :                 &pNew, pSeq->elements, pElementType,
     619             :                 0, nCopy, acquire,
     620     7932656 :                 nSize ); // alloc to nSize
     621             :         }
     622     7932655 :         if (ret && nRest > 0)
     623             :         {
     624             :             ret = idefaultConstructElements(
     625             :                 &pNew, pElementType,
     626             :                 nCopy, nSize,
     627     7755685 :                 nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
     628             :         }
     629             : 
     630     7932651 :         if (ret)
     631             :         {
     632             :             // destruct sequence
     633     7932653 :             if (osl_atomic_decrement( &pSeq->nRefCount ) == 0)
     634             :             {
     635     3389079 :                 if (nElements > 0)
     636             :                 {
     637             :                     idestructElements(
     638             :                         pSeq->elements, pElementType,
     639     3384744 :                         0, nElements, release );
     640             :                 }
     641     3389079 :                 rtl_freeMemory( pSeq );
     642             :             }
     643     7932658 :             *ppSequence = pNew;
     644     7932656 :         }
     645             :     }
     646             :     else
     647             :     {
     648             :         OSL_ASSERT( pSeq->nRefCount == 1 );
     649     7521516 :         if (nSize > nElements) // default construct the rest
     650             :         {
     651             :             ret = idefaultConstructElements(
     652             :                 ppSequence, pElementType,
     653             :                 nElements, nSize,
     654     6672645 :                 nSize ); // realloc to nSize
     655             :         }
     656             :         else // or destruct the rest and realloc mem
     657             :         {
     658             :             sal_Int32 nElementSize = idestructElements(
     659             :                 pSeq->elements, pElementType,
     660      848871 :                 nSize, nElements, release );
     661             :             // warning: it is assumed that the following will never fail,
     662             :             //          else this leads to a sequence null handle
     663      848871 :             *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
     664             :             OSL_ASSERT( *ppSequence != 0 );
     665      848871 :             ret = (*ppSequence != 0);
     666             :         }
     667             :     }
     668             : 
     669    15454172 :     return ret;
     670             : }
     671             : 
     672             : }
     673             : 
     674             : extern "C"
     675             : {
     676             : 
     677             : 
     678    58339639 : sal_Bool SAL_CALL uno_type_sequence_construct(
     679             :     uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
     680             :     void * pElements, sal_Int32 len,
     681             :     uno_AcquireFunc acquire )
     682             :     SAL_THROW_EXTERN_C()
     683             : {
     684             :     assert( len >= 0 );
     685             :     bool ret;
     686    58339639 :     if (len)
     687             :     {
     688    26881720 :         typelib_TypeDescription * pTypeDescr = 0;
     689    26881720 :         TYPELIB_DANGER_GET( &pTypeDescr, pType );
     690             : 
     691             :         typelib_TypeDescriptionReference * pElementType =
     692    26881722 :             ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
     693             : 
     694    26881722 :         *ppSequence = 0;
     695    26881722 :         if (pElements == 0)
     696             :         {
     697             :             ret = idefaultConstructElements(
     698             :                 ppSequence, pElementType,
     699             :                 0, len,
     700    23088834 :                 len ); // alloc to len
     701             :         }
     702             :         else
     703             :         {
     704             :             ret = icopyConstructFromElements(
     705             :                 ppSequence, pElements, pElementType,
     706             :                 0, len, acquire,
     707     3792888 :                 len ); // alloc to len
     708             :         }
     709             : 
     710    26881726 :         TYPELIB_DANGER_RELEASE( pTypeDescr );
     711             :     }
     712             :     else
     713             :     {
     714    31457919 :         *ppSequence = createEmptySequence();
     715    31457922 :         ret = true;
     716             :     }
     717             : 
     718             :     OSL_ASSERT( (*ppSequence != 0) == ret );
     719    58339609 :     return ret;
     720             : }
     721             : 
     722             : 
     723         264 : sal_Bool SAL_CALL uno_sequence_construct(
     724             :     uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
     725             :     void * pElements, sal_Int32 len,
     726             :     uno_AcquireFunc acquire )
     727             :     SAL_THROW_EXTERN_C()
     728             : {
     729             :     bool ret;
     730         264 :     if (len > 0)
     731             :     {
     732             :         typelib_TypeDescriptionReference * pElementType =
     733         258 :             ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
     734             : 
     735         258 :         *ppSequence = 0;
     736         258 :         if (pElements == 0)
     737             :         {
     738             :             ret = idefaultConstructElements(
     739             :                 ppSequence, pElementType,
     740             :                 0, len,
     741         258 :                 len ); // alloc to len
     742             :         }
     743             :         else
     744             :         {
     745             :             ret = icopyConstructFromElements(
     746             :                 ppSequence, pElements, pElementType,
     747             :                 0, len, acquire,
     748           0 :                 len ); // alloc to len
     749             :         }
     750             :     }
     751             :     else
     752             :     {
     753           6 :         *ppSequence = createEmptySequence();
     754           6 :         ret = true;
     755             :     }
     756             : 
     757             :     OSL_ASSERT( (*ppSequence != 0) == ret );
     758         264 :     return ret;
     759             : }
     760             : 
     761             : 
     762    17364730 : sal_Bool SAL_CALL uno_type_sequence_realloc(
     763             :     uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
     764             :     sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
     765             :     SAL_THROW_EXTERN_C()
     766             : {
     767             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     768             :     OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
     769             : 
     770    17364730 :     bool ret = true;
     771    17364730 :     if (nSize != (*ppSequence)->nElements)
     772             :     {
     773    15454093 :         typelib_TypeDescription * pTypeDescr = 0;
     774    15454093 :         TYPELIB_DANGER_GET( &pTypeDescr, pType );
     775             :         ret = ireallocSequence(
     776             :             ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     777    15454092 :             nSize, acquire, release );
     778    15454092 :         TYPELIB_DANGER_RELEASE( pTypeDescr );
     779             :     }
     780    17364729 :     return ret;
     781             : }
     782             : 
     783             : 
     784          90 : sal_Bool SAL_CALL uno_sequence_realloc(
     785             :     uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
     786             :     sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
     787             :     SAL_THROW_EXTERN_C()
     788             : {
     789             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     790             :     OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
     791             : 
     792          90 :     bool ret = true;
     793          90 :     if (nSize != (*ppSequence)->nElements)
     794             :     {
     795             :         ret = ireallocSequence(
     796             :             ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     797          80 :             nSize, acquire, release );
     798             :     }
     799          90 :     return ret;
     800             : }
     801             : 
     802             : 
     803   168771234 : sal_Bool SAL_CALL uno_type_sequence_reference2One(
     804             :     uno_Sequence ** ppSequence,
     805             :     typelib_TypeDescriptionReference * pType,
     806             :     uno_AcquireFunc acquire, uno_ReleaseFunc release )
     807             :     SAL_THROW_EXTERN_C()
     808             : {
     809             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     810   168771234 :     bool ret = true;
     811   168771234 :     uno_Sequence * pSequence = *ppSequence;
     812   168771234 :     if (pSequence->nRefCount > 1)
     813             :     {
     814     3650466 :         uno_Sequence * pNew = 0;
     815     3650466 :         if (pSequence->nElements > 0)
     816             :         {
     817     2254363 :             typelib_TypeDescription * pTypeDescr = 0;
     818     2254363 :             TYPELIB_DANGER_GET( &pTypeDescr, pType );
     819             : 
     820             :             ret = icopyConstructFromElements(
     821             :                 &pNew, pSequence->elements,
     822             :                 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     823             :                 0, pSequence->nElements, acquire,
     824     2254363 :                 pSequence->nElements ); // alloc nElements
     825     2254363 :             if (ret)
     826             :             {
     827     2254363 :                 idestructSequence( *ppSequence, pType, pTypeDescr, release );
     828     2254363 :                 *ppSequence = pNew;
     829             :             }
     830             : 
     831     2254363 :             TYPELIB_DANGER_RELEASE( pTypeDescr );
     832             :         }
     833             :         else
     834             :         {
     835     1396103 :             pNew = allocSeq( 0, 0 );
     836     1396103 :             ret = (pNew != 0);
     837     1396103 :             if (ret)
     838             :             {
     839             :                 // easy destruction of empty sequence:
     840     1396103 :                 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
     841           0 :                     rtl_freeMemory( pSequence );
     842     1396103 :                 *ppSequence = pNew;
     843             :             }
     844             :         }
     845             :     }
     846   168771234 :     return ret;
     847             : }
     848             : 
     849             : 
     850         162 : sal_Bool SAL_CALL uno_sequence_reference2One(
     851             :     uno_Sequence ** ppSequence,
     852             :     typelib_TypeDescription * pTypeDescr,
     853             :     uno_AcquireFunc acquire, uno_ReleaseFunc release )
     854             :     SAL_THROW_EXTERN_C()
     855             : {
     856             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     857         162 :     bool ret = true;
     858         162 :     uno_Sequence * pSequence = *ppSequence;
     859         162 :     if (pSequence->nRefCount > 1)
     860             :     {
     861           0 :         uno_Sequence * pNew = 0;
     862           0 :         if (pSequence->nElements > 0)
     863             :         {
     864             :             ret = icopyConstructFromElements(
     865             :                 &pNew, pSequence->elements,
     866             :                 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     867             :                 0, pSequence->nElements, acquire,
     868           0 :                 pSequence->nElements ); // alloc nElements
     869           0 :             if (ret)
     870             :             {
     871             :                 idestructSequence(
     872           0 :                     pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
     873           0 :                 *ppSequence = pNew;
     874             :             }
     875             :         }
     876             :         else
     877             :         {
     878           0 :             pNew = allocSeq( 0, 0 );
     879           0 :             ret = (pNew != 0);
     880           0 :             if (ret)
     881             :             {
     882             :                 // easy destruction of empty sequence:
     883           0 :                 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
     884           0 :                     rtl_freeMemory( pSequence );
     885           0 :                 *ppSequence = pNew;
     886             :             }
     887             :         }
     888             : 
     889             :     }
     890         162 :     return ret;
     891             : }
     892             : 
     893             : 
     894           0 : void SAL_CALL uno_sequence_assign(
     895             :     uno_Sequence ** ppDest,
     896             :     uno_Sequence * pSource,
     897             :     typelib_TypeDescription * pTypeDescr,
     898             :     uno_ReleaseFunc release )
     899             :     SAL_THROW_EXTERN_C()
     900             : {
     901           0 :     if (*ppDest != pSource)
     902             :     {
     903           0 :         osl_atomic_increment( &pSource->nRefCount );
     904           0 :         idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
     905           0 :         *ppDest = pSource;
     906             :     }
     907           0 : }
     908             : 
     909             : 
     910    13272525 : void SAL_CALL uno_type_sequence_assign(
     911             :     uno_Sequence ** ppDest,
     912             :     uno_Sequence * pSource,
     913             :     typelib_TypeDescriptionReference * pType,
     914             :     uno_ReleaseFunc release )
     915             :     SAL_THROW_EXTERN_C()
     916             : {
     917    13272525 :     if (*ppDest != pSource)
     918             :     {
     919    12277018 :         osl_atomic_increment( &pSource->nRefCount );
     920    12277018 :         idestructSequence( *ppDest, pType, 0, release );
     921    12277018 :         *ppDest = pSource;
     922             :     }
     923    13272525 : }
     924             : 
     925    23783737 : void uno_type_sequence_destroy(
     926             :     uno_Sequence * sequence, typelib_TypeDescriptionReference * type,
     927             :     uno_ReleaseFunc release)
     928             :     SAL_THROW_EXTERN_C()
     929             : {
     930    23783737 :     idestroySequence(sequence, type, nullptr, release);
     931    23783769 : }
     932             : 
     933             : }
     934             : 
     935             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10