LCOV - code coverage report
Current view: top level - libreoffice/cppu/source/uno - sequence.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 319 413 77.2 %
Date: 2012-12-17 Functions: 9 12 75.0 %
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 <string.h>
      21             : 
      22             : #include <rtl/alloc.h>
      23             : #include <osl/diagnose.h>
      24             : #include <osl/interlck.h>
      25             : #include <typelib/typedescription.h>
      26             : #include <uno/data.h>
      27             : #include <uno/dispatcher.h>
      28             : #include <uno/sequence2.h>
      29             : 
      30             : #include "constr.hxx"
      31             : #include "copy.hxx"
      32             : #include "destr.hxx"
      33             : 
      34             : 
      35             : using namespace cppu;
      36             : 
      37             : namespace cppu
      38             : {
      39             : 
      40             : //------------------------------------------------------------------------------
      41     2226203 : static inline uno_Sequence * reallocSeq(
      42             :     uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
      43             : {
      44             :     OSL_ASSERT( nElements >= 0 );
      45     2226203 :     uno_Sequence * pNew = 0;
      46     2226203 :     sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
      47     2226202 :     if (nSize > 0)
      48             :     {
      49     2226203 :         if (pReallocate == 0)
      50             :         {
      51     1896824 :             pNew = (uno_Sequence *) rtl_allocateMemory( nSize );
      52             :         }
      53             :         else
      54             :         {
      55      329379 :             pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize );
      56             :         }
      57     2226204 :         if (pNew != 0)
      58             :         {
      59             :             // header init
      60     2226203 :             pNew->nRefCount = 1;
      61     2226203 :             pNew->nElements = nElements;
      62             :         }
      63             :     }
      64     2226203 :     return pNew;
      65             : }
      66             : 
      67             : //------------------------------------------------------------------------------
      68     1704946 : static inline bool idefaultConstructElements(
      69             :     uno_Sequence ** ppSeq,
      70             :     typelib_TypeDescriptionReference * pElementType,
      71             :     sal_Int32 nStartIndex, sal_Int32 nStopIndex,
      72             :     sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
      73             : {
      74     1704946 :     uno_Sequence * pSeq = *ppSeq;
      75     1704946 :     switch (pElementType->eTypeClass)
      76             :     {
      77             :     case typelib_TypeClass_CHAR:
      78           0 :         if (nAlloc >= 0)
      79           0 :             pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
      80           0 :         if (pSeq != 0)
      81             :         {
      82             :             memset(
      83           0 :                 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
      84             :                 0,
      85           0 :                 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
      86             :         }
      87           0 :         break;
      88             :     case typelib_TypeClass_BOOLEAN:
      89         472 :         if (nAlloc >= 0)
      90         472 :             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
      91         472 :         if (pSeq != 0)
      92             :         {
      93             :             memset(
      94         472 :                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
      95             :                 0,
      96         944 :                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
      97             :         }
      98         472 :         break;
      99             :     case typelib_TypeClass_BYTE:
     100      177456 :         if (nAlloc >= 0)
     101      123664 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
     102      177456 :         if (pSeq != 0)
     103             :         {
     104             :             memset(
     105      177456 :                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
     106             :                 0,
     107      354912 :                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
     108             :         }
     109      177456 :         break;
     110             :     case typelib_TypeClass_SHORT:
     111             :     case typelib_TypeClass_UNSIGNED_SHORT:
     112        1399 :         if (nAlloc >= 0)
     113        1063 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
     114        1399 :         if (pSeq != 0)
     115             :         {
     116             :             memset(
     117        1399 :                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
     118             :                 0,
     119        2798 :                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
     120             :         }
     121        1399 :         break;
     122             :     case typelib_TypeClass_LONG:
     123             :     case typelib_TypeClass_UNSIGNED_LONG:
     124       22564 :         if (nAlloc >= 0)
     125       15171 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     126       22564 :         if (pSeq != 0)
     127             :         {
     128             :             memset(
     129       22564 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     130             :                 0,
     131       45128 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     132             :         }
     133       22564 :         break;
     134             :     case typelib_TypeClass_HYPER:
     135             :     case typelib_TypeClass_UNSIGNED_HYPER:
     136        1179 :         if (nAlloc >= 0)
     137        1040 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
     138        1179 :         if (pSeq != 0)
     139             :         {
     140             :             memset(
     141        1179 :                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
     142             :                 0,
     143        2358 :                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
     144             :         }
     145        1179 :         break;
     146             :     case typelib_TypeClass_FLOAT:
     147             :     {
     148           2 :         if (nAlloc >= 0)
     149           2 :             pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
     150           2 :         if (pSeq != 0)
     151             :         {
     152           2 :             float * pElements = (float *) pSeq->elements;
     153           4 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     154             :             {
     155           2 :                 pElements[nPos] = 0.0;
     156             :             }
     157             :         }
     158           2 :         break;
     159             :     }
     160             :     case typelib_TypeClass_DOUBLE:
     161             :     {
     162       36170 :         if (nAlloc >= 0)
     163       32152 :             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
     164       36170 :         if (pSeq != 0)
     165             :         {
     166       36170 :             double * pElements = (double *) pSeq->elements;
     167      121230 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     168             :             {
     169       85060 :                 pElements[nPos] = 0.0;
     170             :             }
     171             :         }
     172       36170 :         break;
     173             :     }
     174             :     case typelib_TypeClass_STRING:
     175             :     {
     176      220222 :         if (nAlloc >= 0)
     177      124053 :             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
     178      220222 :         if (pSeq != 0)
     179             :         {
     180      220222 :             rtl_uString ** pElements = (rtl_uString **) pSeq->elements;
     181     1095722 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     182             :             {
     183      875500 :                 pElements[nPos] = 0;
     184      875500 :                 rtl_uString_new( &pElements[nPos] );
     185             :             }
     186             :         }
     187      220222 :         break;
     188             :     }
     189             :     case typelib_TypeClass_TYPE:
     190             :     {
     191        6357 :         if (nAlloc >= 0)
     192             :         {
     193             :             pSeq = reallocSeq(
     194        6307 :                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
     195             :         }
     196        6357 :         if (pSeq != 0)
     197             :         {
     198             :             typelib_TypeDescriptionReference ** pElements =
     199        6357 :                 (typelib_TypeDescriptionReference **) pSeq->elements;
     200       85133 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     201             :             {
     202       78776 :                 pElements[nPos] = _getVoidType();
     203             :             }
     204             :         }
     205        6357 :         break;
     206             :     }
     207             :     case typelib_TypeClass_ANY:
     208             :     {
     209      134511 :         if (nAlloc >= 0)
     210      113658 :             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
     211      134511 :         if (pSeq != 0)
     212             :         {
     213      134511 :             uno_Any * pElements = (uno_Any *) pSeq->elements;
     214      461159 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     215             :             {
     216      326648 :                 CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
     217             :             }
     218             :         }
     219      134511 :         break;
     220             :     }
     221             :     case typelib_TypeClass_ENUM:
     222             :     {
     223         556 :         if (nAlloc >= 0)
     224         548 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     225         556 :         if (pSeq != 0)
     226             :         {
     227         556 :             typelib_TypeDescription * pElementTypeDescr = 0;
     228         556 :             TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     229             :             sal_Int32 eEnum =
     230             :                 ((typelib_EnumTypeDescription *)
     231         556 :                  pElementTypeDescr)->nDefaultEnumValue;
     232         556 :             TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     233             : 
     234         556 :             sal_Int32 * pElements = (sal_Int32 *) pSeq->elements;
     235       24178 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     236             :             {
     237       23622 :                 pElements[nPos] = eEnum;
     238             :             }
     239             :         }
     240         556 :         break;
     241             :     }
     242             :     case typelib_TypeClass_STRUCT:
     243             :     case typelib_TypeClass_EXCEPTION:
     244             :     {
     245      539994 :         typelib_TypeDescription * pElementTypeDescr = 0;
     246      539994 :         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     247      539994 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     248             : 
     249      539994 :         if (nAlloc >= 0)
     250      182586 :             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
     251      539994 :         if (pSeq != 0)
     252             :         {
     253      539994 :             char * pElements = pSeq->elements;
     254     2646172 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     255             :             {
     256             :                 _defaultConstructStruct(
     257     2106178 :                     pElements + (nElementSize * nPos),
     258     4212356 :                     (typelib_CompoundTypeDescription *)pElementTypeDescr );
     259             :             }
     260             :         }
     261             : 
     262      539994 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     263             :         break;
     264             :     }
     265             :     case typelib_TypeClass_ARRAY:
     266             :     {
     267           0 :         typelib_TypeDescription * pElementTypeDescr = 0;
     268           0 :         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     269           0 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     270             : 
     271           0 :         if (nAlloc >= 0)
     272           0 :             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
     273           0 :         if (pSeq != 0)
     274             :         {
     275           0 :             char * pElements = pSeq->elements;
     276           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     277             :             {
     278             :                 _defaultConstructArray(
     279           0 :                     pElements + (nElementSize * nPos),
     280           0 :                     (typelib_ArrayTypeDescription *)pElementTypeDescr );
     281             :             }
     282             :         }
     283             : 
     284           0 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     285             :         break;
     286             :     }
     287             :     case typelib_TypeClass_UNION:
     288             :     {
     289           0 :         typelib_TypeDescription * pElementTypeDescr = 0;
     290           0 :         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     291           0 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     292             : 
     293           0 :         if (nAlloc >= 0)
     294           0 :             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
     295           0 :         if (pSeq != 0)
     296             :         {
     297             :             sal_Int32 nValueOffset =
     298             :                 ((typelib_UnionTypeDescription *)
     299           0 :                  pElementTypeDescr)->nValueOffset;
     300             :             sal_Int64 nDefaultDiscr =
     301             :                 ((typelib_UnionTypeDescription *)
     302           0 :                  pElementTypeDescr)->nDefaultDiscriminant;
     303             : 
     304           0 :             typelib_TypeDescription * pDefaultTypeDescr = 0;
     305           0 :             TYPELIB_DANGER_GET(
     306             :                 &pDefaultTypeDescr,
     307             :                 ((typelib_UnionTypeDescription *)
     308             :                  pElementTypeDescr)->pDefaultTypeRef );
     309             : 
     310           0 :             char * pElements = pSeq->elements;
     311           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     312             :             {
     313           0 :                 char * pMem = pElements + (nElementSize * nPos);
     314             :                 ::uno_constructData(
     315           0 :                     (char *)pMem + nValueOffset, pDefaultTypeDescr );
     316           0 :                 *(sal_Int64 *)pMem = nDefaultDiscr;
     317             :             }
     318           0 :             TYPELIB_DANGER_RELEASE( pDefaultTypeDescr );
     319             :         }
     320             : 
     321           0 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     322             :         break;
     323             :     }
     324             :     case typelib_TypeClass_SEQUENCE:
     325             :     {
     326       13695 :         if (nAlloc >= 0)
     327        6647 :             pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
     328       13695 :         if (pSeq != 0)
     329             :         {
     330             :             uno_Sequence ** pElements =
     331       13695 :                 (uno_Sequence **) pSeq->elements;
     332       34202 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     333             :             {
     334       20507 :                 pElements[nPos] = createEmptySequence();
     335             :             }
     336             :         }
     337       13695 :         break;
     338             :     }
     339             :     case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
     340      550369 :         if (nAlloc >= 0)
     341      495982 :             pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
     342      550369 :         if (pSeq != 0)
     343             :         {
     344             :             memset(
     345      550369 :                 pSeq->elements + (sizeof(void *) * nStartIndex),
     346             :                 0,
     347     1100738 :                 sizeof(void *) * (nStopIndex - nStartIndex) );
     348             :         }
     349      550369 :         break;
     350             :     default:
     351             :         OSL_FAIL( "### unexpected element type!" );
     352           0 :         pSeq = 0;
     353           0 :         break;
     354             :     }
     355             : 
     356     1704946 :     if (pSeq == 0)
     357             :     {
     358             :         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
     359           0 :         return false;
     360             :     }
     361             :     else
     362             :     {
     363     1704946 :         *ppSeq = pSeq;
     364     1704946 :         return true;
     365             :     }
     366             : }
     367             : 
     368             : //------------------------------------------------------------------------------
     369     1057328 : static inline bool icopyConstructFromElements(
     370             :     uno_Sequence ** ppSeq, void * pSourceElements,
     371             :     typelib_TypeDescriptionReference * pElementType,
     372             :     sal_Int32 nStartIndex, sal_Int32 nStopIndex,
     373             :     uno_AcquireFunc acquire,
     374             :     sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
     375             : {
     376     1057328 :     uno_Sequence * pSeq = *ppSeq;
     377     1057328 :     switch (pElementType->eTypeClass)
     378             :     {
     379             :     case typelib_TypeClass_CHAR:
     380           0 :         if (nAlloc >= 0)
     381           0 :             pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
     382           0 :         if (pSeq != 0)
     383             :         {
     384             :             memcpy(
     385           0 :                 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
     386             :                 (char *)pSourceElements + (sizeof(sal_Unicode) * nStartIndex),
     387           0 :                 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
     388             :         }
     389           0 :         break;
     390             :     case typelib_TypeClass_BOOLEAN:
     391          14 :         if (nAlloc >= 0)
     392          14 :             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
     393          14 :         if (pSeq != 0)
     394             :         {
     395             :             memcpy(
     396          14 :                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
     397             :                 (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex),
     398          28 :                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
     399             :         }
     400          14 :         break;
     401             :     case typelib_TypeClass_BYTE:
     402      358652 :         if (nAlloc >= 0)
     403      358652 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
     404      358652 :         if (pSeq != 0)
     405             :         {
     406             :             memcpy(
     407      358652 :                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
     408             :                 (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex),
     409      717304 :                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
     410             :         }
     411      358652 :         break;
     412             :     case typelib_TypeClass_SHORT:
     413             :     case typelib_TypeClass_UNSIGNED_SHORT:
     414         358 :         if (nAlloc >= 0)
     415         358 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
     416         358 :         if (pSeq != 0)
     417             :         {
     418             :             memcpy(
     419         358 :                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
     420             :                 (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex),
     421         716 :                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
     422             :         }
     423         358 :         break;
     424             :     case typelib_TypeClass_LONG:
     425             :     case typelib_TypeClass_UNSIGNED_LONG:
     426        7479 :         if (nAlloc >= 0)
     427        7479 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     428        7479 :         if (pSeq != 0)
     429             :         {
     430             :             memcpy(
     431        7479 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     432             :                 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
     433       14958 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     434             :         }
     435        7479 :         break;
     436             :     case typelib_TypeClass_HYPER:
     437             :     case typelib_TypeClass_UNSIGNED_HYPER:
     438         239 :         if (nAlloc >= 0)
     439         239 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
     440         239 :         if (pSeq != 0)
     441             :         {
     442             :             memcpy(
     443         239 :                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
     444             :                 (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex),
     445         478 :                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
     446             :         }
     447         239 :         break;
     448             :     case typelib_TypeClass_FLOAT:
     449          10 :         if (nAlloc >= 0)
     450          10 :             pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
     451          10 :         if (pSeq != 0)
     452             :         {
     453             :             memcpy(
     454          10 :                 pSeq->elements + (sizeof(float) * nStartIndex),
     455             :                 (char *)pSourceElements + (sizeof(float) * nStartIndex),
     456          20 :                 sizeof(float) * (nStopIndex - nStartIndex) );
     457             :         }
     458          10 :         break;
     459             :     case typelib_TypeClass_DOUBLE:
     460        4192 :         if (nAlloc >= 0)
     461        4192 :             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
     462        4192 :         if (pSeq != 0)
     463             :         {
     464             :             memcpy(
     465        4192 :                 pSeq->elements + (sizeof(double) * nStartIndex),
     466             :                 (char *)pSourceElements + (sizeof(double) * nStartIndex),
     467        8384 :                 sizeof(double) * (nStopIndex - nStartIndex) );
     468             :         }
     469        4192 :         break;
     470             :     case typelib_TypeClass_ENUM:
     471         100 :         if (nAlloc >= 0)
     472         100 :             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
     473         100 :         if (pSeq != 0)
     474             :         {
     475             :             memcpy(
     476         100 :                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
     477             :                 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
     478         200 :                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
     479             :         }
     480         100 :         break;
     481             :     case typelib_TypeClass_STRING:
     482             :     {
     483      118304 :         if (nAlloc >= 0)
     484      118304 :             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
     485      118304 :         if (pSeq != 0)
     486             :         {
     487      118304 :             rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements;
     488      186841 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     489             :             {
     490             :                 ::rtl_uString_acquire(
     491       68537 :                     ((rtl_uString **)pSourceElements)[nPos] );
     492       68537 :                 pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos];
     493             :             }
     494             :         }
     495      118304 :         break;
     496             :     }
     497             :     case typelib_TypeClass_TYPE:
     498             :     {
     499          60 :         if (nAlloc >= 0)
     500             :         {
     501             :             pSeq = reallocSeq(
     502          60 :                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
     503             :         }
     504          60 :         if (pSeq != 0)
     505             :         {
     506             :             typelib_TypeDescriptionReference ** pDestElements =
     507          60 :                 (typelib_TypeDescriptionReference **) pSeq->elements;
     508          70 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     509             :             {
     510          10 :                 TYPE_ACQUIRE(
     511             :                     ((typelib_TypeDescriptionReference **)
     512             :                      pSourceElements)[nPos] );
     513          10 :                 pDestElements[nPos] =
     514             :                     ((typelib_TypeDescriptionReference **)
     515          10 :                      pSourceElements)[nPos];
     516             :             }
     517             :         }
     518          60 :         break;
     519             :     }
     520             :     case typelib_TypeClass_ANY:
     521             :     {
     522       25135 :         if (nAlloc >= 0)
     523       25135 :             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
     524       25135 :         if (pSeq != 0)
     525             :         {
     526       25135 :             uno_Any * pDestElements = (uno_Any *) pSeq->elements;
     527       39078 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     528             :             {
     529       13943 :                 uno_Any * pSource = (uno_Any *)pSourceElements + nPos;
     530             :                 _copyConstructAny(
     531             :                     &pDestElements[nPos],
     532             :                     pSource->pData,
     533             :                     pSource->pType, 0,
     534       13943 :                     acquire, 0 );
     535             :             }
     536             :         }
     537       25135 :         break;
     538             :     }
     539             :     case typelib_TypeClass_STRUCT:
     540             :     case typelib_TypeClass_EXCEPTION:
     541             :     {
     542      410980 :         typelib_TypeDescription * pElementTypeDescr = 0;
     543      410980 :         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     544      410980 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     545             : 
     546      410980 :         if (nAlloc >= 0)
     547      410980 :             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
     548      410980 :         if (pSeq != 0)
     549             :         {
     550      410980 :             char * pDestElements = pSeq->elements;
     551             : 
     552             :             typelib_CompoundTypeDescription * pTypeDescr =
     553      410980 :                 (typelib_CompoundTypeDescription *)pElementTypeDescr;
     554     2323426 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     555             :             {
     556             :                 char * pDest =
     557     1912446 :                     pDestElements + (nElementSize * nPos);
     558             :                 char * pSource =
     559     1912446 :                     (char *)pSourceElements + (nElementSize * nPos);
     560             : 
     561     1912446 :                 if (pTypeDescr->pBaseTypeDescription)
     562             :                 {
     563             :                     // copy base value
     564             :                     _copyConstructStruct(
     565             :                         pDest, pSource,
     566        4246 :                         pTypeDescr->pBaseTypeDescription, acquire, 0 );
     567             :                 }
     568             : 
     569             :                 // then copy members
     570             :                 typelib_TypeDescriptionReference ** ppTypeRefs =
     571     1912446 :                     pTypeDescr->ppTypeRefs;
     572     1912446 :                 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
     573     1912446 :                 sal_Int32 nDescr = pTypeDescr->nMembers;
     574             : 
     575    11323458 :                 while (nDescr--)
     576             :                 {
     577             :                     ::uno_type_copyData(
     578    14997132 :                         pDest + pMemberOffsets[nDescr],
     579    14997132 :                         pSource + pMemberOffsets[nDescr],
     580    29994264 :                         ppTypeRefs[nDescr], acquire );
     581             :                 }
     582             :             }
     583             :         }
     584             : 
     585      410980 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     586             :         break;
     587             :     }
     588             :     case typelib_TypeClass_UNION:
     589             :     {
     590           0 :         typelib_TypeDescription * pElementTypeDescr = 0;
     591           0 :         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     592           0 :         sal_Int32 nElementSize = pElementTypeDescr->nSize;
     593             : 
     594           0 :         if (nAlloc >= 0)
     595           0 :             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
     596           0 :         if (pSeq != 0)
     597             :         {
     598           0 :             char * pDestElements = pSeq->elements;
     599             : 
     600             :             sal_Int32 nValueOffset =
     601             :                 ((typelib_UnionTypeDescription *)
     602           0 :                  pElementTypeDescr)->nValueOffset;
     603           0 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     604             :             {
     605             :                 char * pDest =
     606           0 :                     pDestElements + (nElementSize * nPos);
     607             :                 char * pSource =
     608           0 :                     (char *)pSourceElements + (nElementSize * nPos);
     609             : 
     610             :                 typelib_TypeDescriptionReference * pSetType = _unionGetSetType(
     611           0 :                     pSource, pElementTypeDescr );
     612             :                 ::uno_type_copyData(
     613           0 :                     pDest + nValueOffset,
     614           0 :                     pSource + nValueOffset,
     615           0 :                     pSetType, acquire );
     616           0 :                 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
     617           0 :                 typelib_typedescriptionreference_release( pSetType );
     618             :             }
     619             :         }
     620             : 
     621           0 :         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     622             :         break;
     623             :     }
     624             :     case typelib_TypeClass_SEQUENCE: // sequence of sequence
     625             :     {
     626        9590 :         if (nAlloc >= 0)
     627        9590 :             pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
     628        9590 :         if (pSeq != 0)
     629             :         {
     630        9590 :             typelib_TypeDescription * pElementTypeDescr = 0;
     631        9590 :             TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
     632             :             typelib_TypeDescriptionReference * pSeqElementType =
     633        9590 :                 ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType;
     634        9590 :             uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements;
     635       19388 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     636             :             {
     637             :                 uno_Sequence * pNew = icopyConstructSequence(
     638        9798 :                     ((uno_Sequence **) pSourceElements)[nPos],
     639        9798 :                     pSeqElementType, acquire, 0 );
     640             :                 OSL_ASSERT( pNew != 0 );
     641             :                 // ought never be a memory allocation problem,
     642             :                 // because of reference counted sequence handles
     643        9798 :                 pDestElements[ nPos ] = pNew;
     644             :             }
     645        9590 :             TYPELIB_DANGER_RELEASE( pElementTypeDescr );
     646             :         }
     647        9590 :         break;
     648             :     }
     649             :     case typelib_TypeClass_INTERFACE:
     650             :     {
     651      122215 :         if (nAlloc >= 0)
     652      122215 :             pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
     653      122215 :         if (pSeq != 0)
     654             :         {
     655      122215 :             void ** pDestElements = (void **) pSeq->elements;
     656      231614 :             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
     657             :             {
     658      218798 :                 _acquire( pDestElements[nPos] =
     659      218798 :                           ((void **)pSourceElements)[nPos], acquire );
     660             :             }
     661             :         }
     662      122215 :         break;
     663             :     }
     664             :     default:
     665             :         OSL_FAIL( "### unexpected element type!" );
     666           0 :         pSeq = 0;
     667           0 :         break;
     668             :     }
     669             : 
     670     1057328 :     if (pSeq == 0)
     671             :     {
     672             :         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
     673           0 :         return false;
     674             :     }
     675             :     else
     676             :     {
     677     1057328 :         *ppSeq = pSeq;
     678     1057328 :         return true;
     679             :     }
     680             : }
     681             : 
     682             : //------------------------------------------------------------------------------
     683      944210 : static inline bool ireallocSequence(
     684             :     uno_Sequence ** ppSequence,
     685             :     typelib_TypeDescriptionReference * pElementType,
     686             :     sal_Int32 nSize,
     687             :     uno_AcquireFunc acquire, uno_ReleaseFunc release )
     688             : {
     689      944210 :     bool ret = true;
     690      944210 :     uno_Sequence * pSeq = *ppSequence;
     691      944210 :     sal_Int32 nElements = pSeq->nElements;
     692             : 
     693      944210 :     if (pSeq->nRefCount > 1 ||
     694             :         // not mem-copyable elements?
     695             :         typelib_TypeClass_ANY == pElementType->eTypeClass ||
     696             :         typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
     697             :         typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
     698             :     {
     699             :         // split sequence and construct new one from scratch
     700      614831 :         uno_Sequence * pNew = 0;
     701             : 
     702      614831 :         sal_Int32 nRest = nSize - nElements;
     703      614831 :         sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
     704             : 
     705      614831 :         if (nCopy >= 0)
     706             :         {
     707             :             ret = icopyConstructFromElements(
     708             :                 &pNew, pSeq->elements, pElementType,
     709             :                 0, nCopy, acquire,
     710      614831 :                 nSize ); // alloc to nSize
     711             :         }
     712      614831 :         if (ret && nRest > 0)
     713             :         {
     714             :             ret = idefaultConstructElements(
     715             :                 &pNew, pElementType,
     716             :                 nCopy, nSize,
     717      601601 :                 nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
     718             :         }
     719             : 
     720      614831 :         if (ret)
     721             :         {
     722             :             // destruct sequence
     723      614831 :             if (osl_atomic_decrement( &pSeq->nRefCount ) == 0)
     724             :             {
     725      295250 :                 if (nElements > 0)
     726             :                 {
     727             :                     idestructElements(
     728             :                         pSeq->elements, pElementType,
     729      294862 :                         0, nElements, release );
     730             :                 }
     731      295250 :                 rtl_freeMemory( pSeq );
     732             :             }
     733      614831 :             *ppSequence = pNew;
     734      614831 :         }
     735             :     }
     736             :     else
     737             :     {
     738             :         OSL_ASSERT( pSeq->nRefCount == 1 );
     739      329379 :         if (nSize > nElements) // default construct the rest
     740             :         {
     741             :             ret = idefaultConstructElements(
     742             :                 ppSequence, pElementType,
     743             :                 nElements, nSize,
     744      263849 :                 nSize ); // realloc to nSize
     745             :         }
     746             :         else // or destruct the rest and realloc mem
     747             :         {
     748             :             sal_Int32 nElementSize = idestructElements(
     749             :                 pSeq->elements, pElementType,
     750       65530 :                 nSize, nElements, release );
     751             :             // warning: it is assumed that the following will never fail,
     752             :             //          else this leads to a sequence null handle
     753       65530 :             *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
     754             :             OSL_ASSERT( *ppSequence != 0 );
     755       65530 :             ret = (*ppSequence != 0);
     756             :         }
     757             :     }
     758             : 
     759      944210 :     return ret;
     760             : }
     761             : 
     762             : }
     763             : 
     764             : extern "C"
     765             : {
     766             : 
     767             : //##############################################################################
     768     3505125 : sal_Bool SAL_CALL uno_type_sequence_construct(
     769             :     uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
     770             :     void * pElements, sal_Int32 len,
     771             :     uno_AcquireFunc acquire )
     772             :     SAL_THROW_EXTERN_C()
     773             : {
     774             :     bool ret;
     775     3505125 :     if (len)
     776             :     {
     777     1163703 :         typelib_TypeDescription * pTypeDescr = 0;
     778     1163703 :         TYPELIB_DANGER_GET( &pTypeDescr, pType );
     779             : 
     780             :         typelib_TypeDescriptionReference * pElementType =
     781     1163703 :             ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
     782             : 
     783     1163703 :         *ppSequence = 0;
     784     1163703 :         if (pElements == 0)
     785             :         {
     786             :             ret = idefaultConstructElements(
     787             :                 ppSequence, pElementType,
     788             :                 0, len,
     789      839460 :                 len ); // alloc to len
     790             :         }
     791             :         else
     792             :         {
     793             :             ret = icopyConstructFromElements(
     794             :                 ppSequence, pElements, pElementType,
     795             :                 0, len, acquire,
     796      324243 :                 len ); // alloc to len
     797             :         }
     798             : 
     799     1163703 :         TYPELIB_DANGER_RELEASE( pTypeDescr );
     800             :     }
     801             :     else
     802             :     {
     803     2341422 :         *ppSequence = createEmptySequence();
     804     2341422 :         ret = true;
     805             :     }
     806             : 
     807             :     OSL_ASSERT( (*ppSequence != 0) == ret );
     808     3505125 :     return ret;
     809             : }
     810             : 
     811             : //##############################################################################
     812         151 : sal_Bool SAL_CALL uno_sequence_construct(
     813             :     uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
     814             :     void * pElements, sal_Int32 len,
     815             :     uno_AcquireFunc acquire )
     816             :     SAL_THROW_EXTERN_C()
     817             : {
     818             :     bool ret;
     819         151 :     if (len > 0)
     820             :     {
     821             :         typelib_TypeDescriptionReference * pElementType =
     822          36 :             ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
     823             : 
     824          36 :         *ppSequence = 0;
     825          36 :         if (pElements == 0)
     826             :         {
     827             :             ret = idefaultConstructElements(
     828             :                 ppSequence, pElementType,
     829             :                 0, len,
     830          36 :                 len ); // alloc to len
     831             :         }
     832             :         else
     833             :         {
     834             :             ret = icopyConstructFromElements(
     835             :                 ppSequence, pElements, pElementType,
     836             :                 0, len, acquire,
     837           0 :                 len ); // alloc to len
     838             :         }
     839             :     }
     840             :     else
     841             :     {
     842         115 :         *ppSequence = createEmptySequence();
     843         115 :         ret = true;
     844             :     }
     845             : 
     846             :     OSL_ASSERT( (*ppSequence != 0) == ret );
     847         151 :     return ret;
     848             : }
     849             : 
     850             : //##############################################################################
     851     1089744 : sal_Bool SAL_CALL uno_type_sequence_realloc(
     852             :     uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
     853             :     sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
     854             :     SAL_THROW_EXTERN_C()
     855             : {
     856             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     857             :     OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
     858             : 
     859     1089744 :     bool ret = true;
     860     1089744 :     if (nSize != (*ppSequence)->nElements)
     861             :     {
     862      944210 :         typelib_TypeDescription * pTypeDescr = 0;
     863      944210 :         TYPELIB_DANGER_GET( &pTypeDescr, pType );
     864             :         ret = ireallocSequence(
     865             :             ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     866      944210 :             nSize, acquire, release );
     867      944210 :         TYPELIB_DANGER_RELEASE( pTypeDescr );
     868             :     }
     869     1089744 :     return ret;
     870             : }
     871             : 
     872             : //##############################################################################
     873           0 : sal_Bool SAL_CALL uno_sequence_realloc(
     874             :     uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
     875             :     sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
     876             :     SAL_THROW_EXTERN_C()
     877             : {
     878             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     879             :     OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
     880             : 
     881           0 :     bool ret = true;
     882           0 :     if (nSize != (*ppSequence)->nElements)
     883             :     {
     884             :         ret = ireallocSequence(
     885             :             ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     886           0 :             nSize, acquire, release );
     887             :     }
     888           0 :     return ret;
     889             : }
     890             : 
     891             : //##############################################################################
     892    11060006 : sal_Bool SAL_CALL uno_type_sequence_reference2One(
     893             :     uno_Sequence ** ppSequence,
     894             :     typelib_TypeDescriptionReference * pType,
     895             :     uno_AcquireFunc acquire, uno_ReleaseFunc release )
     896             :     SAL_THROW_EXTERN_C()
     897             : {
     898             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     899    11060006 :     bool ret = true;
     900    11060006 :     uno_Sequence * pSequence = *ppSequence;
     901    11060006 :     if (pSequence->nRefCount > 1)
     902             :     {
     903      201605 :         uno_Sequence * pNew = 0;
     904      201605 :         if (pSequence->nElements > 0)
     905             :         {
     906      118254 :             typelib_TypeDescription * pTypeDescr = 0;
     907      118254 :             TYPELIB_DANGER_GET( &pTypeDescr, pType );
     908             : 
     909             :             ret = icopyConstructFromElements(
     910             :                 &pNew, pSequence->elements,
     911             :                 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     912             :                 0, pSequence->nElements, acquire,
     913      118254 :                 pSequence->nElements ); // alloc nElements
     914      118254 :             if (ret)
     915             :             {
     916      118254 :                 idestructSequence( *ppSequence, pType, pTypeDescr, release );
     917      118254 :                 *ppSequence = pNew;
     918             :             }
     919             : 
     920      118254 :             TYPELIB_DANGER_RELEASE( pTypeDescr );
     921             :         }
     922             :         else
     923             :         {
     924       83351 :             pNew = allocSeq( 0, 0 );
     925       83351 :             ret = (pNew != 0);
     926       83351 :             if (ret)
     927             :             {
     928             :                 // easy destruction of empty sequence:
     929       83351 :                 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
     930           0 :                     rtl_freeMemory( pSequence );
     931       83351 :                 *ppSequence = pNew;
     932             :             }
     933             :         }
     934             :     }
     935    11060006 :     return ret;
     936             : }
     937             : 
     938             : //##############################################################################
     939           0 : sal_Bool SAL_CALL uno_sequence_reference2One(
     940             :     uno_Sequence ** ppSequence,
     941             :     typelib_TypeDescription * pTypeDescr,
     942             :     uno_AcquireFunc acquire, uno_ReleaseFunc release )
     943             :     SAL_THROW_EXTERN_C()
     944             : {
     945             :     OSL_ENSURE( ppSequence, "### null ptr!" );
     946           0 :     bool ret = true;
     947           0 :     uno_Sequence * pSequence = *ppSequence;
     948           0 :     if (pSequence->nRefCount > 1)
     949             :     {
     950           0 :         uno_Sequence * pNew = 0;
     951           0 :         if (pSequence->nElements > 0)
     952             :         {
     953             :             ret = icopyConstructFromElements(
     954             :                 &pNew, pSequence->elements,
     955             :                 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
     956             :                 0, pSequence->nElements, acquire,
     957           0 :                 pSequence->nElements ); // alloc nElements
     958           0 :             if (ret)
     959             :             {
     960             :                 idestructSequence(
     961           0 :                     pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
     962           0 :                 *ppSequence = pNew;
     963             :             }
     964             :         }
     965             :         else
     966             :         {
     967           0 :             pNew = allocSeq( 0, 0 );
     968           0 :             ret = (pNew != 0);
     969           0 :             if (ret)
     970             :             {
     971             :                 // easy destruction of empty sequence:
     972           0 :                 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
     973           0 :                     rtl_freeMemory( pSequence );
     974           0 :                 *ppSequence = pNew;
     975             :             }
     976             :         }
     977             : 
     978             :     }
     979           0 :     return ret;
     980             : }
     981             : 
     982             : //##############################################################################
     983           0 : void SAL_CALL uno_sequence_assign(
     984             :     uno_Sequence ** ppDest,
     985             :     uno_Sequence * pSource,
     986             :     typelib_TypeDescription * pTypeDescr,
     987             :     uno_ReleaseFunc release )
     988             :     SAL_THROW_EXTERN_C()
     989             : {
     990           0 :     if (*ppDest != pSource)
     991             :     {
     992           0 :         osl_atomic_increment( &pSource->nRefCount );
     993           0 :         idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
     994           0 :         *ppDest = pSource;
     995             :     }
     996           0 : }
     997             : 
     998             : //##############################################################################
     999      535737 : void SAL_CALL uno_type_sequence_assign(
    1000             :     uno_Sequence ** ppDest,
    1001             :     uno_Sequence * pSource,
    1002             :     typelib_TypeDescriptionReference * pType,
    1003             :     uno_ReleaseFunc release )
    1004             :     SAL_THROW_EXTERN_C()
    1005             : {
    1006      535737 :     if (*ppDest != pSource)
    1007             :     {
    1008      489620 :         osl_atomic_increment( &pSource->nRefCount );
    1009      489620 :         idestructSequence( *ppDest, pType, 0, release );
    1010      489620 :         *ppDest = pSource;
    1011             :     }
    1012      535737 : }
    1013             : 
    1014             : }
    1015             : 
    1016             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10