LCOV - code coverage report
Current view: top level - cppu/source/uno - sequence.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 350 384 91.1 %
Date: 2015-06-13 12:38:46 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   247428744 : static inline uno_Sequence * reallocSeq(
      45             :     uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
      46             : {
      47             :     OSL_ASSERT( nElements >= 0 );
      48   247428744 :     uno_Sequence * pNew = 0;
      49   247428744 :     sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
      50   247428740 :     if (nSize > 0)
      51             :     {
      52   247428740 :         if (pReallocate == 0)
      53             :         {
      54   243044931 :             pNew = static_cast<uno_Sequence *>(rtl_allocateMemory( nSize ));
      55             :         }
      56             :         else
      57             :         {
      58     4383809 :             pNew = static_cast<uno_Sequence *>(rtl_reallocateMemory( pReallocate, nSize ));
      59             :         }
      60   247428759 :         if (pNew != 0)
      61             :         {
      62             :             // header init
      63   247428759 :             pNew->nRefCount = 1;
      64   247428759 :             pNew->nElements = nElements;
      65             :         }
      66             :     }
      67   247428759 :     return pNew;
      68             : }
      69             : 
      70             : 
      71   242550231 : 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   242550231 :     uno_Sequence * pSeq = *ppSeq;
      78   242550231 :     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       55881 :         if (nAlloc >= 0)
      93       55807 :             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
      94       55881 :         if (pSeq != 0)
      95             :         {
      96             :             memset(
      97       55881 :                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
      98             :                 0,
      99      111762 :                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
     100             :         }
     101       55881 :         break;
     102             :     case typelib_TypeClass_BYTE:
     103     1849459 :         if (nAlloc >= 0)
     104      884699 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
     105     1849458 :         if (pSeq != 0)
     106             :         {
     107             :             memset(
     108     1849458 :                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
     109             :                 0,
     110     3698916 :                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
     111             :         }
     112     1849458 :         break;
     113             :     case typelib_TypeClass_SHORT:
     114             :     case typelib_TypeClass_UNSIGNED_SHORT:
     115        2054 :         if (nAlloc >= 0)
     116        1135 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
     117        2054 :         if (pSeq != 0)
     118             :         {
     119             :             memset(
     120        2054 :                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
     121             :                 0,
     122        4108 :                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
     123             :         }
     124        2054 :         break;
     125             :     case typelib_TypeClass_LONG:
     126             :     case typelib_TypeClass_UNSIGNED_LONG:
     127      112949 :         if (nAlloc >= 0)
     128       89171 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     129      112949 :         if (pSeq != 0)
     130             :         {
     131             :             memset(
     132      112949 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     133             :                 0,
     134      225898 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     135             :         }
     136      112949 :         break;
     137             :     case typelib_TypeClass_HYPER:
     138             :     case typelib_TypeClass_UNSIGNED_HYPER:
     139         926 :         if (nAlloc >= 0)
     140         856 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
     141         926 :         if (pSeq != 0)
     142             :         {
     143             :             memset(
     144         926 :                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
     145             :                 0,
     146        1852 :                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
     147             :         }
     148         926 :         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 = reinterpret_cast<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      555227 :         if (nAlloc >= 0)
     166      487790 :             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
     167      555227 :         if (pSeq != 0)
     168             :         {
     169      555227 :             double * pElements = reinterpret_cast<double *>(pSeq->elements);
     170     2891534 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     171             :             {
     172     2336307 :                 pElements[nPos] = 0.0;
     173             :             }
     174             :         }
     175      555227 :         break;
     176             :     }
     177             :     case typelib_TypeClass_STRING:
     178             :     {
     179     1175610 :         if (nAlloc >= 0)
     180     1039193 :             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
     181     1175610 :         if (pSeq != 0)
     182             :         {
     183     1175610 :             rtl_uString ** pElements = reinterpret_cast<rtl_uString **>(pSeq->elements);
     184     5887863 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     185             :             {
     186     4712253 :                 pElements[nPos] = 0;
     187     4712253 :                 rtl_uString_new( &pElements[nPos] );
     188             :             }
     189             :         }
     190     1175610 :         break;
     191             :     }
     192             :     case typelib_TypeClass_TYPE:
     193             :     {
     194       58738 :         if (nAlloc >= 0)
     195             :         {
     196             :             pSeq = reallocSeq(
     197       58387 :                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
     198             :         }
     199       58738 :         if (pSeq != 0)
     200             :         {
     201             :             typelib_TypeDescriptionReference ** pElements =
     202       58738 :                 reinterpret_cast<typelib_TypeDescriptionReference **>(pSeq->elements);
     203     1409405 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     204             :             {
     205     1350667 :                 pElements[nPos] = _getVoidType();
     206             :             }
     207             :         }
     208       58738 :         break;
     209             :     }
     210             :     case typelib_TypeClass_ANY:
     211             :     {
     212    28018706 :         if (nAlloc >= 0)
     213    27792701 :             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
     214    28018706 :         if (pSeq != 0)
     215             :         {
     216    28018706 :             uno_Any * pElements = reinterpret_cast<uno_Any *>(pSeq->elements);
     217    59656658 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     218             :             {
     219    31637952 :                 CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
     220             :             }
     221             :         }
     222    28018706 :         break;
     223             :     }
     224             :     case typelib_TypeClass_ENUM:
     225             :     {
     226       47608 :         if (nAlloc >= 0)
     227       39687 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     228       47608 :         if (pSeq != 0)
     229             :         {
     230       47608 :             typelib_TypeDescription * pElementTypeDescr = 0;
     231       47608 :             TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     232             :             sal_Int32 eEnum =
     233             :                 reinterpret_cast<typelib_EnumTypeDescription *>(
     234       47608 :                  pElementTypeDescr)->nDefaultEnumValue;
     235       47608 :             TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     236             : 
     237       47608 :             sal_Int32 * pElements = reinterpret_cast<sal_Int32 *>(pSeq->elements);
     238     2991806 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     239             :             {
     240     2944198 :                 pElements[nPos] = eEnum;
     241             :             }
     242             :         }
     243       47608 :         break;
     244             :     }
     245             :     case typelib_TypeClass_STRUCT:
     246             :     case typelib_TypeClass_EXCEPTION:
     247             :     {
     248     4119426 :         typelib_TypeDescription * pElementTypeDescr = 0;
     249     4119426 :         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     250     4119426 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     251             : 
     252     4119426 :         if (nAlloc >= 0)
     253     1767226 :             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
     254     4119425 :         if (pSeq != 0)
     255             :         {
     256     4119425 :             char * pElements = pSeq->elements;
     257    15952209 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     258             :             {
     259             :                 _defaultConstructStruct(
     260    23665566 :                     pElements + (nElementSize * nPos),
     261    35498349 :                     reinterpret_cast<typelib_CompoundTypeDescription *>(pElementTypeDescr) );
     262             :             }
     263             :         }
     264             : 
     265     4119426 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     266     4119426 :         break;
     267             :     }
     268             :     case typelib_TypeClass_SEQUENCE:
     269             :     {
     270      185074 :         if (nAlloc >= 0)
     271             :         {
     272             :             // coverity[suspicious_sizeof] - sizeof(uno_Sequence*) is correct here
     273       84257 :             pSeq = reallocSeq(pSeq, sizeof(uno_Sequence*), nAlloc);
     274             :         }
     275      185074 :         if (pSeq != 0)
     276             :         {
     277             :             uno_Sequence ** pElements =
     278      185074 :                 reinterpret_cast<uno_Sequence **>(pSeq->elements);
     279      514327 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     280             :             {
     281      329253 :                 pElements[nPos] = createEmptySequence();
     282             :             }
     283             :         }
     284      185074 :         break;
     285             :     }
     286             :     case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
     287   206368572 :         if (nAlloc >= 0)
     288   206161174 :             pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
     289   206368573 :         if (pSeq != 0)
     290             :         {
     291             :             memset(
     292   206368573 :                 pSeq->elements + (sizeof(void *) * nStartIndex),
     293             :                 0,
     294   412737146 :                 sizeof(void *) * (nStopIndex - nStartIndex) );
     295             :         }
     296   206368573 :         break;
     297             :     default:
     298             :         OSL_FAIL( "### unexpected element type!" );
     299           0 :         pSeq = 0;
     300           0 :         break;
     301             :     }
     302             : 
     303   242550228 :     if (pSeq == 0)
     304             :     {
     305             :         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
     306           0 :         return false;
     307             :     }
     308             :     else
     309             :     {
     310   242550228 :         *ppSeq = pSeq;
     311   242550228 :         return true;
     312             :     }
     313             : }
     314             : 
     315             : 
     316     8460287 : static inline bool icopyConstructFromElements(
     317             :     uno_Sequence ** ppSeq, void * pSourceElements,
     318             :     typelib_TypeDescriptionReference * pElementType,
     319             :     sal_Int32 nStartIndex, sal_Int32 nStopIndex,
     320             :     uno_AcquireFunc acquire,
     321             :     sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
     322             : {
     323     8460287 :     uno_Sequence * pSeq = *ppSeq;
     324     8460287 :     switch (pElementType->eTypeClass)
     325             :     {
     326             :     case typelib_TypeClass_CHAR:
     327           1 :         if (nAlloc >= 0)
     328           1 :             pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
     329           0 :         if (pSeq != 0)
     330             :         {
     331             :             memcpy(
     332           1 :                 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
     333           1 :                 static_cast<char *>(pSourceElements) + (sizeof(sal_Unicode) * nStartIndex),
     334           3 :                 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
     335             :         }
     336           0 :         break;
     337             :     case typelib_TypeClass_BOOLEAN:
     338          90 :         if (nAlloc >= 0)
     339          90 :             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
     340          90 :         if (pSeq != 0)
     341             :         {
     342             :             memcpy(
     343          90 :                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
     344          90 :                 static_cast<char *>(pSourceElements) + (sizeof(sal_Bool) * nStartIndex),
     345         270 :                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
     346             :         }
     347          90 :         break;
     348             :     case typelib_TypeClass_BYTE:
     349     2147737 :         if (nAlloc >= 0)
     350     2147737 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
     351     2147737 :         if (pSeq != 0)
     352             :         {
     353             :             memcpy(
     354     2147737 :                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
     355     2147737 :                 static_cast<char *>(pSourceElements) + (sizeof(sal_Int8) * nStartIndex),
     356     6443211 :                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
     357             :         }
     358     2147737 :         break;
     359             :     case typelib_TypeClass_SHORT:
     360             :     case typelib_TypeClass_UNSIGNED_SHORT:
     361         931 :         if (nAlloc >= 0)
     362         931 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
     363         931 :         if (pSeq != 0)
     364             :         {
     365             :             memcpy(
     366         931 :                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
     367         931 :                 static_cast<char *>(pSourceElements) + (sizeof(sal_Int16) * nStartIndex),
     368        2793 :                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
     369             :         }
     370         931 :         break;
     371             :     case typelib_TypeClass_LONG:
     372             :     case typelib_TypeClass_UNSIGNED_LONG:
     373       26181 :         if (nAlloc >= 0)
     374       26181 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     375       26181 :         if (pSeq != 0)
     376             :         {
     377             :             memcpy(
     378       26181 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     379       26181 :                 static_cast<char *>(pSourceElements) + (sizeof(sal_Int32) * nStartIndex),
     380       78543 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     381             :         }
     382       26181 :         break;
     383             :     case typelib_TypeClass_HYPER:
     384             :     case typelib_TypeClass_UNSIGNED_HYPER:
     385         351 :         if (nAlloc >= 0)
     386         351 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
     387         351 :         if (pSeq != 0)
     388             :         {
     389             :             memcpy(
     390         351 :                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
     391         351 :                 static_cast<char *>(pSourceElements) + (sizeof(sal_Int64) * nStartIndex),
     392        1053 :                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
     393             :         }
     394         351 :         break;
     395             :     case typelib_TypeClass_FLOAT:
     396           5 :         if (nAlloc >= 0)
     397           5 :             pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
     398           5 :         if (pSeq != 0)
     399             :         {
     400             :             memcpy(
     401           5 :                 pSeq->elements + (sizeof(float) * nStartIndex),
     402           5 :                 static_cast<char *>(pSourceElements) + (sizeof(float) * nStartIndex),
     403          15 :                 sizeof(float) * (nStopIndex - nStartIndex) );
     404             :         }
     405           5 :         break;
     406             :     case typelib_TypeClass_DOUBLE:
     407       90076 :         if (nAlloc >= 0)
     408       90076 :             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
     409       90076 :         if (pSeq != 0)
     410             :         {
     411             :             memcpy(
     412       90076 :                 pSeq->elements + (sizeof(double) * nStartIndex),
     413       90076 :                 static_cast<char *>(pSourceElements) + (sizeof(double) * nStartIndex),
     414      270228 :                 sizeof(double) * (nStopIndex - nStartIndex) );
     415             :         }
     416       90076 :         break;
     417             :     case typelib_TypeClass_ENUM:
     418        8936 :         if (nAlloc >= 0)
     419        8936 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     420        8936 :         if (pSeq != 0)
     421             :         {
     422             :             memcpy(
     423        8936 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     424        8936 :                 static_cast<char *>(pSourceElements) + (sizeof(sal_Int32) * nStartIndex),
     425       26808 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     426             :         }
     427        8936 :         break;
     428             :     case typelib_TypeClass_STRING:
     429             :     {
     430     1107805 :         if (nAlloc >= 0)
     431     1107805 :             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
     432     1107805 :         if (pSeq != 0)
     433             :         {
     434     1107805 :             rtl_uString ** pDestElements = reinterpret_cast<rtl_uString **>(pSeq->elements);
     435     6235351 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     436             :             {
     437             :                 // This code tends to trigger coverity's overrun-buffer-arg warning
     438             :                 // coverity[index_parm_via_loop_bound] - https://communities.coverity.com/thread/2993
     439             :                 ::rtl_uString_acquire(
     440     5127546 :                     static_cast<rtl_uString **>(pSourceElements)[nPos] );
     441     5127546 :                 pDestElements[nPos] = static_cast<rtl_uString **>(pSourceElements)[nPos];
     442             :             }
     443             :         }
     444     1107805 :         break;
     445             :     }
     446             :     case typelib_TypeClass_TYPE:
     447             :     {
     448         829 :         if (nAlloc >= 0)
     449             :         {
     450             :             pSeq = reallocSeq(
     451         829 :                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
     452             :         }
     453         829 :         if (pSeq != 0)
     454             :         {
     455             :             typelib_TypeDescriptionReference ** pDestElements =
     456         829 :                 reinterpret_cast<typelib_TypeDescriptionReference **>(pSeq->elements);
     457        2787 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     458             :             {
     459        1958 :                 TYPE_ACQUIRE(
     460             :                     static_cast<typelib_TypeDescriptionReference **>(
     461             :                      pSourceElements)[nPos] );
     462        1958 :                 pDestElements[nPos] =
     463             :                     static_cast<typelib_TypeDescriptionReference **>(
     464        1958 :                      pSourceElements)[nPos];
     465             :             }
     466             :         }
     467         829 :         break;
     468             :     }
     469             :     case typelib_TypeClass_ANY:
     470             :     {
     471      657848 :         if (nAlloc >= 0)
     472      657848 :             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
     473      657848 :         if (pSeq != 0)
     474             :         {
     475      657848 :             uno_Any * pDestElements = reinterpret_cast<uno_Any *>(pSeq->elements);
     476     1668613 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     477             :             {
     478     1010765 :                 uno_Any * pSource = static_cast<uno_Any *>(pSourceElements) + nPos;
     479             :                 _copyConstructAny(
     480             :                     &pDestElements[nPos],
     481             :                     pSource->pData,
     482             :                     pSource->pType, 0,
     483     1010765 :                     acquire, 0 );
     484             :             }
     485             :         }
     486      657848 :         break;
     487             :     }
     488             :     case typelib_TypeClass_STRUCT:
     489             :     case typelib_TypeClass_EXCEPTION:
     490             :     {
     491     3661986 :         typelib_TypeDescription * pElementTypeDescr = 0;
     492     3661986 :         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     493     3661986 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     494             : 
     495     3661986 :         if (nAlloc >= 0)
     496     3661986 :             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
     497     3661986 :         if (pSeq != 0)
     498             :         {
     499     3661986 :             char * pDestElements = pSeq->elements;
     500             : 
     501             :             typelib_CompoundTypeDescription * pTypeDescr =
     502     3661986 :                 reinterpret_cast<typelib_CompoundTypeDescription *>(pElementTypeDescr);
     503    26148715 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     504             :             {
     505             :                 char * pDest =
     506    22486729 :                     pDestElements + (nElementSize * nPos);
     507             :                 char * pSource =
     508    22486729 :                     static_cast<char *>(pSourceElements) + (nElementSize * nPos);
     509             : 
     510    22486729 :                 if (pTypeDescr->pBaseTypeDescription)
     511             :                 {
     512             :                     // copy base value
     513             :                     _copyConstructStruct(
     514             :                         pDest, pSource,
     515       43689 :                         pTypeDescr->pBaseTypeDescription, acquire, 0 );
     516             :                 }
     517             : 
     518             :                 // then copy members
     519             :                 typelib_TypeDescriptionReference ** ppTypeRefs =
     520    22486729 :                     pTypeDescr->ppTypeRefs;
     521    22486729 :                 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
     522    22486729 :                 sal_Int32 nDescr = pTypeDescr->nMembers;
     523             : 
     524   124380866 :                 while (nDescr--)
     525             :                 {
     526             :                     ::uno_type_copyData(
     527   158814816 :                         pDest + pMemberOffsets[nDescr],
     528   158814816 :                         pSource + pMemberOffsets[nDescr],
     529   317629632 :                         ppTypeRefs[nDescr], acquire );
     530             :                 }
     531             :             }
     532             :         }
     533             : 
     534     3661986 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     535     3661986 :         break;
     536             :     }
     537             :     case typelib_TypeClass_SEQUENCE: // sequence of sequence
     538             :     {
     539      190270 :         if (nAlloc >= 0)
     540             :         {
     541             :             // coverity[suspicious_sizeof] - sizeof(uno_Sequence*) is correct here
     542      190270 :             pSeq = reallocSeq(pSeq, sizeof(uno_Sequence*), nAlloc);
     543             :         }
     544      190270 :         if (pSeq != 0)
     545             :         {
     546      190270 :             typelib_TypeDescription * pElementTypeDescr = 0;
     547      190270 :             TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     548             :             typelib_TypeDescriptionReference * pSeqElementType =
     549      190270 :                 reinterpret_cast<typelib_IndirectTypeDescription *>(pElementTypeDescr)->pType;
     550      190270 :             uno_Sequence ** pDestElements = reinterpret_cast<uno_Sequence **>(pSeq->elements);
     551     5331259 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     552             :             {
     553             :                 uno_Sequence * pNew = icopyConstructSequence(
     554     5140989 :                     static_cast<uno_Sequence **>(pSourceElements)[nPos],
     555     5140989 :                     pSeqElementType, acquire, 0 );
     556             :                 OSL_ASSERT( pNew != 0 );
     557             :                 // ought never be a memory allocation problem,
     558             :                 // because of reference counted sequence handles
     559     5140989 :                 pDestElements[ nPos ] = pNew;
     560             :             }
     561      190270 :             TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     562             :         }
     563      190270 :         break;
     564             :     }
     565             :     case typelib_TypeClass_INTERFACE:
     566             :     {
     567      567241 :         if (nAlloc >= 0)
     568      567241 :             pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
     569      567241 :         if (pSeq != 0)
     570             :         {
     571      567241 :             void ** pDestElements = reinterpret_cast<void **>(pSeq->elements);
     572      982464 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     573             :             {
     574      830446 :                 _acquire( pDestElements[nPos] =
     575      830446 :                           static_cast<void **>(pSourceElements)[nPos], acquire );
     576             :             }
     577             :         }
     578      567241 :         break;
     579             :     }
     580             :     default:
     581             :         OSL_FAIL( "### unexpected element type!" );
     582           0 :         pSeq = 0;
     583           0 :         break;
     584             :     }
     585             : 
     586     8460286 :     if (pSeq == 0)
     587             :     {
     588             :         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
     589           0 :         return false;
     590             :     }
     591             :     else
     592             :     {
     593     8460286 :         *ppSeq = pSeq;
     594     8460286 :         return true;
     595             :     }
     596             : }
     597             : 
     598             : 
     599     8576868 : static inline bool ireallocSequence(
     600             :     uno_Sequence ** ppSequence,
     601             :     typelib_TypeDescriptionReference * pElementType,
     602             :     sal_Int32 nSize,
     603             :     uno_AcquireFunc acquire, uno_ReleaseFunc release )
     604             : {
     605     8576868 :     bool ret = true;
     606     8576868 :     uno_Sequence * pSeq = *ppSequence;
     607     8576868 :     sal_Int32 nElements = pSeq->nElements;
     608             : 
     609    14930939 :     if (pSeq->nRefCount > 1 ||
     610             :         // not mem-copyable elements?
     611    12687071 :         typelib_TypeClass_ANY == pElementType->eTypeClass ||
     612    10716809 :         typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
     613     4383809 :         typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
     614             :     {
     615             :         // split sequence and construct new one from scratch
     616     4193059 :         uno_Sequence * pNew = 0;
     617             : 
     618     4193059 :         sal_Int32 nRest = nSize - nElements;
     619     4193059 :         sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
     620             : 
     621     4193059 :         if (nCopy >= 0)
     622             :         {
     623             :             ret = icopyConstructFromElements(
     624             :                 &pNew, pSeq->elements, pElementType,
     625             :                 0, nCopy, acquire,
     626     4193059 :                 nSize ); // alloc to nSize
     627             :         }
     628     4193058 :         if (ret && nRest > 0)
     629             :         {
     630             :             ret = idefaultConstructElements(
     631             :                 &pNew, pElementType,
     632             :                 nCopy, nSize,
     633     4088150 :                 nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
     634             :         }
     635             : 
     636     4193059 :         if (ret)
     637             :         {
     638             :             // destruct sequence
     639     4193059 :             if (osl_atomic_decrement( &pSeq->nRefCount ) == 0)
     640             :             {
     641     1970262 :                 if (nElements > 0)
     642             :                 {
     643             :                     idestructElements(
     644             :                         pSeq->elements, pElementType,
     645     1968825 :                         0, nElements, release );
     646             :                 }
     647     1970262 :                 rtl_freeMemory( pSeq );
     648             :             }
     649     4193057 :             *ppSequence = pNew;
     650     4193057 :         }
     651             :     }
     652             :     else
     653             :     {
     654             :         OSL_ASSERT( pSeq->nRefCount == 1 );
     655     4383809 :         if (nSize > nElements) // default construct the rest
     656             :         {
     657             :             ret = idefaultConstructElements(
     658             :                 ppSequence, pElementType,
     659             :                 nElements, nSize,
     660     3877420 :                 nSize ); // realloc to nSize
     661             :         }
     662             :         else // or destruct the rest and realloc mem
     663             :         {
     664             :             sal_Int32 nElementSize = idestructElements(
     665             :                 pSeq->elements, pElementType,
     666      506389 :                 nSize, nElements, release );
     667             :             // warning: it is assumed that the following will never fail,
     668             :             //          else this leads to a sequence null handle
     669      506389 :             *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
     670             :             OSL_ASSERT( *ppSequence != 0 );
     671      506389 :             ret = (*ppSequence != 0);
     672             :         }
     673             :     }
     674             : 
     675     8576866 :     return ret;
     676             : }
     677             : 
     678             : }
     679             : 
     680             : extern "C"
     681             : {
     682             : 
     683             : 
     684   380734270 : sal_Bool SAL_CALL uno_type_sequence_construct(
     685             :     uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
     686             :     void * pElements, sal_Int32 len,
     687             :     uno_AcquireFunc acquire )
     688             :     SAL_THROW_EXTERN_C()
     689             : {
     690             :     assert( len >= 0 );
     691             :     bool ret;
     692   380734270 :     if (len)
     693             :     {
     694   237680373 :         typelib_TypeDescription * pTypeDescr = 0;
     695   237680373 :         TYPELIB_DANGER_GET( &pTypeDescr, pType );
     696             : 
     697             :         typelib_TypeDescriptionReference * pElementType =
     698   237680375 :             reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType;
     699             : 
     700   237680375 :         *ppSequence = 0;
     701   237680375 :         if (pElements == 0)
     702             :         {
     703             :             ret = idefaultConstructElements(
     704             :                 ppSequence, pElementType,
     705             :                 0, len,
     706   234584458 :                 len ); // alloc to len
     707             :         }
     708             :         else
     709             :         {
     710             :             ret = icopyConstructFromElements(
     711             :                 ppSequence, pElements, pElementType,
     712             :                 0, len, acquire,
     713     3095917 :                 len ); // alloc to len
     714             :         }
     715             : 
     716   237680377 :         TYPELIB_DANGER_RELEASE( pTypeDescr );
     717             :     }
     718             :     else
     719             :     {
     720   143053897 :         *ppSequence = createEmptySequence();
     721   143053898 :         ret = true;
     722             :     }
     723             : 
     724             :     OSL_ASSERT( (*ppSequence != 0) == ret );
     725   380734249 :     return ret;
     726             : }
     727             : 
     728             : 
     729         228 : sal_Bool SAL_CALL uno_sequence_construct(
     730             :     uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
     731             :     void * pElements, sal_Int32 len,
     732             :     uno_AcquireFunc acquire )
     733             :     SAL_THROW_EXTERN_C()
     734             : {
     735             :     bool ret;
     736         228 :     if (len > 0)
     737             :     {
     738             :         typelib_TypeDescriptionReference * pElementType =
     739         205 :             reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType;
     740             : 
     741         205 :         *ppSequence = 0;
     742         205 :         if (pElements == 0)
     743             :         {
     744             :             ret = idefaultConstructElements(
     745             :                 ppSequence, pElementType,
     746             :                 0, len,
     747         205 :                 len ); // alloc to len
     748             :         }
     749             :         else
     750             :         {
     751             :             ret = icopyConstructFromElements(
     752             :                 ppSequence, pElements, pElementType,
     753             :                 0, len, acquire,
     754           0 :                 len ); // alloc to len
     755             :         }
     756             :     }
     757             :     else
     758             :     {
     759          23 :         *ppSequence = createEmptySequence();
     760          23 :         ret = true;
     761             :     }
     762             : 
     763             :     OSL_ASSERT( (*ppSequence != 0) == ret );
     764         228 :     return ret;
     765             : }
     766             : 
     767             : 
     768     9616640 : sal_Bool SAL_CALL uno_type_sequence_realloc(
     769             :     uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
     770             :     sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
     771             :     SAL_THROW_EXTERN_C()
     772             : {
     773             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     774             :     OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
     775             : 
     776     9616640 :     bool ret = true;
     777     9616640 :     if (nSize != (*ppSequence)->nElements)
     778             :     {
     779     8576826 :         typelib_TypeDescription * pTypeDescr = 0;
     780     8576826 :         TYPELIB_DANGER_GET( &pTypeDescr, pType );
     781             :         ret = ireallocSequence(
     782             :             ppSequence, reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
     783     8576827 :             nSize, acquire, release );
     784     8576826 :         TYPELIB_DANGER_RELEASE( pTypeDescr );
     785             :     }
     786     9616638 :     return ret;
     787             : }
     788             : 
     789             : 
     790          45 : sal_Bool SAL_CALL uno_sequence_realloc(
     791             :     uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
     792             :     sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
     793             :     SAL_THROW_EXTERN_C()
     794             : {
     795             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     796             :     OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
     797             : 
     798          45 :     bool ret = true;
     799          45 :     if (nSize != (*ppSequence)->nElements)
     800             :     {
     801             :         ret = ireallocSequence(
     802             :             ppSequence, reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
     803          40 :             nSize, acquire, release );
     804             :     }
     805          45 :     return ret;
     806             : }
     807             : 
     808             : 
     809   320326616 : sal_Bool SAL_CALL uno_type_sequence_reference2One(
     810             :     uno_Sequence ** ppSequence,
     811             :     typelib_TypeDescriptionReference * pType,
     812             :     uno_AcquireFunc acquire, uno_ReleaseFunc release )
     813             :     SAL_THROW_EXTERN_C()
     814             : {
     815             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     816   320326616 :     bool ret = true;
     817   320326616 :     uno_Sequence * pSequence = *ppSequence;
     818   320326616 :     if (pSequence->nRefCount > 1)
     819             :     {
     820     1862210 :         uno_Sequence * pNew = 0;
     821     1862210 :         if (pSequence->nElements > 0)
     822             :         {
     823     1171311 :             typelib_TypeDescription * pTypeDescr = 0;
     824     1171311 :             TYPELIB_DANGER_GET( &pTypeDescr, pType );
     825             : 
     826             :             ret = icopyConstructFromElements(
     827             :                 &pNew, pSequence->elements,
     828             :                 reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
     829             :                 0, pSequence->nElements, acquire,
     830     1171311 :                 pSequence->nElements ); // alloc nElements
     831     1171311 :             if (ret)
     832             :             {
     833     1171311 :                 idestructSequence( *ppSequence, pType, pTypeDescr, release );
     834     1171311 :                 *ppSequence = pNew;
     835             :             }
     836             : 
     837     1171311 :             TYPELIB_DANGER_RELEASE( pTypeDescr );
     838             :         }
     839             :         else
     840             :         {
     841      690899 :             pNew = allocSeq( 0, 0 );
     842      690899 :             ret = (pNew != 0);
     843      690899 :             if (ret)
     844             :             {
     845             :                 // easy destruction of empty sequence:
     846      690899 :                 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
     847           0 :                     rtl_freeMemory( pSequence );
     848      690899 :                 *ppSequence = pNew;
     849             :             }
     850             :         }
     851             :     }
     852   320326616 :     return ret;
     853             : }
     854             : 
     855             : 
     856          81 : sal_Bool SAL_CALL uno_sequence_reference2One(
     857             :     uno_Sequence ** ppSequence,
     858             :     typelib_TypeDescription * pTypeDescr,
     859             :     uno_AcquireFunc acquire, uno_ReleaseFunc release )
     860             :     SAL_THROW_EXTERN_C()
     861             : {
     862             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     863          81 :     bool ret = true;
     864          81 :     uno_Sequence * pSequence = *ppSequence;
     865          81 :     if (pSequence->nRefCount > 1)
     866             :     {
     867           0 :         uno_Sequence * pNew = 0;
     868           0 :         if (pSequence->nElements > 0)
     869             :         {
     870             :             ret = icopyConstructFromElements(
     871             :                 &pNew, pSequence->elements,
     872             :                 reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
     873             :                 0, pSequence->nElements, acquire,
     874           0 :                 pSequence->nElements ); // alloc nElements
     875           0 :             if (ret)
     876             :             {
     877             :                 idestructSequence(
     878           0 :                     pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
     879           0 :                 *ppSequence = pNew;
     880             :             }
     881             :         }
     882             :         else
     883             :         {
     884           0 :             pNew = allocSeq( 0, 0 );
     885           0 :             ret = (pNew != 0);
     886           0 :             if (ret)
     887             :             {
     888             :                 // easy destruction of empty sequence:
     889           0 :                 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
     890           0 :                     rtl_freeMemory( pSequence );
     891           0 :                 *ppSequence = pNew;
     892             :             }
     893             :         }
     894             : 
     895             :     }
     896          81 :     return ret;
     897             : }
     898             : 
     899             : 
     900           0 : void SAL_CALL uno_sequence_assign(
     901             :     uno_Sequence ** ppDest,
     902             :     uno_Sequence * pSource,
     903             :     typelib_TypeDescription * pTypeDescr,
     904             :     uno_ReleaseFunc release )
     905             :     SAL_THROW_EXTERN_C()
     906             : {
     907           0 :     if (*ppDest != pSource)
     908             :     {
     909           0 :         osl_atomic_increment( &pSource->nRefCount );
     910           0 :         idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
     911           0 :         *ppDest = pSource;
     912             :     }
     913           0 : }
     914             : 
     915             : 
     916     7935918 : void SAL_CALL uno_type_sequence_assign(
     917             :     uno_Sequence ** ppDest,
     918             :     uno_Sequence * pSource,
     919             :     typelib_TypeDescriptionReference * pType,
     920             :     uno_ReleaseFunc release )
     921             :     SAL_THROW_EXTERN_C()
     922             : {
     923     7935918 :     if (*ppDest != pSource)
     924             :     {
     925     7232391 :         osl_atomic_increment( &pSource->nRefCount );
     926     7232391 :         idestructSequence( *ppDest, pType, 0, release );
     927     7232391 :         *ppDest = pSource;
     928             :     }
     929     7935918 : }
     930             : 
     931   235262993 : void uno_type_sequence_destroy(
     932             :     uno_Sequence * sequence, typelib_TypeDescriptionReference * type,
     933             :     uno_ReleaseFunc release)
     934             :     SAL_THROW_EXTERN_C()
     935             : {
     936   235262993 :     idestroySequence(sequence, type, nullptr, release);
     937   235263005 : }
     938             : 
     939             : }
     940             : 
     941             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11