LCOV - code coverage report
Current view: top level - basic/source/sbx - sbxarray.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 227 408 55.6 %
Date: 2015-06-13 12:38:46 Functions: 47 70 67.1 %
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 <config_features.h>
      21             : 
      22             : #include <tools/debug.hxx>
      23             : #include <tools/stream.hxx>
      24             : #include <basic/sbx.hxx>
      25             : #include "runtime.hxx"
      26             : 
      27             : #include <boost/optional.hpp>
      28             : 
      29             : using namespace std;
      30             : 
      31      284663 : struct SbxVarEntry
      32             : {
      33             :     SbxVariableRef mpVar;
      34             :     boost::optional<OUString> maAlias;
      35             : };
      36             : 
      37         297 : TYPEINIT1(SbxArray,SbxBase)
      38       28531 : TYPEINIT1(SbxDimArray,SbxArray)
      39             : 
      40             : //  SbxArray
      41             : 
      42      125332 : SbxArray::SbxArray( SbxDataType t ) : SbxBase()
      43             : {
      44      125332 :     mpVarEntries = new VarEntriesType;
      45      125332 :     eType = t;
      46      125332 :     if( t != SbxVARIANT )
      47       37085 :         SetFlag( SBX_FIXED );
      48      125332 : }
      49             : 
      50           0 : SbxArray::SbxArray( const SbxArray& rArray ) :
      51           0 :     SvRefBase( rArray ), SbxBase()
      52             : {
      53           0 :     mpVarEntries = new VarEntriesType;
      54           0 :     if( rArray.eType != SbxVARIANT )
      55           0 :         SetFlag( SBX_FIXED );
      56           0 :     *this = rArray;
      57           0 : }
      58             : 
      59           6 : SbxArray& SbxArray::operator=( const SbxArray& rArray )
      60             : {
      61           6 :     if( &rArray != this )
      62             :     {
      63           6 :         eType = rArray.eType;
      64           6 :         Clear();
      65           6 :         VarEntriesType* pSrc = rArray.mpVarEntries;
      66          10 :         for( size_t i = 0; i < pSrc->size(); i++ )
      67             :         {
      68           4 :             SbxVarEntry* pSrcRef = (*pSrc)[i];
      69           4 :             SbxVariableRef pSrc_ = pSrcRef->mpVar;
      70           4 :             if( !pSrc_ )
      71           0 :                 continue;
      72           4 :             SbxVarEntry* pDstRef = new SbxVarEntry;
      73           4 :             pDstRef->mpVar = pSrcRef->mpVar;
      74             : 
      75           4 :             if (pSrcRef->maAlias)
      76           0 :                 pDstRef->maAlias.reset(*pSrcRef->maAlias);
      77             : 
      78           4 :             if( eType != SbxVARIANT )
      79             :             {
      80             :                 // Convert no objects
      81           0 :                 if( eType != SbxOBJECT || pSrc_->GetClass() != SbxCLASS_OBJECT )
      82             :                 {
      83           0 :                     pSrc_->Convert(eType);
      84             :                 }
      85             :             }
      86           4 :             mpVarEntries->push_back( pDstRef );
      87           4 :         }
      88             :     }
      89           6 :     return *this;
      90             : }
      91             : 
      92      470004 : SbxArray::~SbxArray()
      93             : {
      94      117568 :     Clear();
      95      117568 :     delete mpVarEntries;
      96      352436 : }
      97             : 
      98        1389 : SbxDataType SbxArray::GetType() const
      99             : {
     100        1389 :     return (SbxDataType) ( eType | SbxARRAY );
     101             : }
     102             : 
     103           0 : SbxClassType SbxArray::GetClass() const
     104             : {
     105           0 :     return SbxCLASS_ARRAY;
     106             : }
     107             : 
     108      129619 : void SbxArray::Clear()
     109             : {
     110      129619 :     sal_uInt32 nSize = mpVarEntries->size();
     111      211666 :     for( sal_uInt32 i = 0 ; i < nSize ; i++ )
     112             :     {
     113       82047 :         SbxVarEntry* pEntry = (*mpVarEntries)[i];
     114       82047 :         delete pEntry;
     115             :     }
     116      129619 :     mpVarEntries->clear();
     117      129619 : }
     118             : 
     119           5 : sal_uInt32 SbxArray::Count32() const
     120             : {
     121           5 :     return mpVarEntries->size();
     122             : }
     123             : 
     124     1384820 : sal_uInt16 SbxArray::Count() const
     125             : {
     126     1384820 :     sal_uInt32 nCount = mpVarEntries->size();
     127             :     DBG_ASSERT( nCount <= SBX_MAXINDEX, "SBX: Array-Index > SBX_MAXINDEX" );
     128     1384820 :     return (sal_uInt16)nCount;
     129             : }
     130             : 
     131        4669 : SbxVariableRef& SbxArray::GetRef32( sal_uInt32 nIdx )
     132             : {
     133             :     // If necessary extend the array
     134             :     DBG_ASSERT( nIdx <= SBX_MAXINDEX32, "SBX: Array-Index > SBX_MAXINDEX32" );
     135             :     // Very Hot Fix
     136        4669 :     if( nIdx > SBX_MAXINDEX32 )
     137             :     {
     138           0 :         SetError( SbxERR_BOUNDS );
     139           0 :         nIdx = 0;
     140             :     }
     141       13011 :     while( mpVarEntries->size() <= nIdx )
     142             :     {
     143        3673 :         mpVarEntries->push_back(new SbxVarEntry);
     144             :     }
     145        4669 :     return (*mpVarEntries)[nIdx]->mpVar;
     146             : }
     147             : 
     148      655430 : SbxVariableRef& SbxArray::GetRef( sal_uInt16 nIdx )
     149             : {
     150             :     // If necessary extend the array
     151             :     DBG_ASSERT( nIdx <= SBX_MAXINDEX, "SBX: Array-Index > SBX_MAXINDEX" );
     152             :     // Very Hot Fix
     153      655430 :     if( nIdx > SBX_MAXINDEX )
     154             :     {
     155           0 :         SetError( SbxERR_BOUNDS );
     156           0 :         nIdx = 0;
     157             :     }
     158     1453417 :     while( mpVarEntries->size() <= nIdx )
     159             :     {
     160      142557 :         mpVarEntries->push_back(new SbxVarEntry);
     161             :     }
     162      655430 :     return (*mpVarEntries)[nIdx]->mpVar;
     163             : }
     164             : 
     165         815 : SbxVariable* SbxArray::Get32( sal_uInt32 nIdx )
     166             : {
     167         815 :     if( !CanRead() )
     168             :     {
     169           0 :         SetError( SbxERR_PROP_WRITEONLY );
     170           0 :         return NULL;
     171             :     }
     172         815 :     SbxVariableRef& rRef = GetRef32( nIdx );
     173             : 
     174         815 :     if ( !rRef.Is() )
     175         240 :         rRef = new SbxVariable( eType );
     176             : 
     177         815 :     return rRef;
     178             : }
     179             : 
     180      165338 : SbxVariable* SbxArray::Get( sal_uInt16 nIdx )
     181             : {
     182      165338 :     if( !CanRead() )
     183             :     {
     184           0 :         SetError( SbxERR_PROP_WRITEONLY );
     185           0 :         return NULL;
     186             :     }
     187      165338 :     SbxVariableRef& rRef = GetRef( nIdx );
     188             : 
     189      165338 :     if ( !rRef.Is() )
     190          94 :         rRef = new SbxVariable( eType );
     191             : 
     192      165338 :     return rRef;
     193             : }
     194             : 
     195        3430 : void SbxArray::Put32( SbxVariable* pVar, sal_uInt32 nIdx )
     196             : {
     197        3430 :     if( !CanWrite() )
     198           0 :         SetError( SbxERR_PROP_READONLY );
     199             :     else
     200             :     {
     201        3430 :         if( pVar )
     202        3430 :             if( eType != SbxVARIANT )
     203             :                 // Convert no objects
     204           9 :                 if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT )
     205           7 :                     pVar->Convert( eType );
     206        3430 :         SbxVariableRef& rRef = GetRef32( nIdx );
     207        3430 :         if( static_cast<SbxVariable*>(rRef) != pVar )
     208             :         {
     209        3430 :             rRef = pVar;
     210        3430 :             SetFlag( SBX_MODIFIED );
     211             :         }
     212             :     }
     213        3430 : }
     214             : 
     215      172777 : void SbxArray::Put( SbxVariable* pVar, sal_uInt16 nIdx )
     216             : {
     217      172777 :     if( !CanWrite() )
     218           0 :         SetError( SbxERR_PROP_READONLY );
     219             :     else
     220             :     {
     221      172777 :         if( pVar )
     222      172051 :             if( eType != SbxVARIANT )
     223             :                 // Convert no objects
     224       26167 :                 if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT )
     225          12 :                     pVar->Convert( eType );
     226      172777 :         SbxVariableRef& rRef = GetRef( nIdx );
     227      172777 :         if( static_cast<SbxVariable*>(rRef) != pVar )
     228             :         {
     229      172680 :             rRef = pVar;
     230      172680 :             SetFlag( SBX_MODIFIED );
     231             :         }
     232             :     }
     233      172777 : }
     234             : 
     235        6656 : OUString SbxArray::GetAlias( sal_uInt16 nIdx )
     236             : {
     237        6656 :     if( !CanRead() )
     238             :     {
     239           0 :         SetError( SbxERR_PROP_WRITEONLY );
     240           0 :         return OUString();
     241             :     }
     242        6656 :     SbxVarEntry& rRef = reinterpret_cast<SbxVarEntry&>(GetRef( nIdx ));
     243             : 
     244        6656 :     if (!rRef.maAlias)
     245        6452 :         return OUString();
     246             : 
     247         204 :     return *rRef.maAlias;
     248             : }
     249             : 
     250        2419 : void SbxArray::PutAlias( const OUString& rAlias, sal_uInt16 nIdx )
     251             : {
     252        2419 :     if( !CanWrite() )
     253             :     {
     254           0 :         SetError( SbxERR_PROP_READONLY );
     255             :     }
     256             :     else
     257             :     {
     258        2419 :         SbxVarEntry& rRef = reinterpret_cast<SbxVarEntry&>( GetRef( nIdx ) );
     259        2419 :         rRef.maAlias.reset(rAlias);
     260             :     }
     261        2419 : }
     262             : 
     263         278 : void SbxArray::Insert32( SbxVariable* pVar, sal_uInt32 nIdx )
     264             : {
     265             :     DBG_ASSERT( mpVarEntries->size() <= SBX_MAXINDEX32, "SBX: Array gets too big" );
     266         278 :     if( mpVarEntries->size() > SBX_MAXINDEX32 )
     267             :     {
     268         278 :             return;
     269             :     }
     270         278 :     SbxVarEntry* p = new SbxVarEntry;
     271         278 :     p->mpVar = pVar;
     272         278 :     size_t nSize = mpVarEntries->size();
     273         278 :     if( nIdx > nSize )
     274             :     {
     275           0 :         nIdx = nSize;
     276             :     }
     277         278 :     if( eType != SbxVARIANT && pVar )
     278             :     {
     279           0 :         p->mpVar->Convert(eType);
     280             :     }
     281         278 :     if( nIdx == nSize )
     282             :     {
     283         278 :         mpVarEntries->push_back( p );
     284             :     }
     285             :     else
     286             :     {
     287           0 :         mpVarEntries->insert( mpVarEntries->begin() + nIdx, p );
     288             :     }
     289         278 :     SetFlag( SBX_MODIFIED );
     290             : }
     291             : 
     292         278 : void SbxArray::Insert( SbxVariable* pVar, sal_uInt16 nIdx )
     293             : {
     294             :     DBG_ASSERT( mpVarEntries->size() <= 0x3FF0, "SBX: Array gets too big" );
     295         278 :     if( mpVarEntries->size() > 0x3FF0 )
     296             :     {
     297         278 :         return;
     298             :     }
     299         278 :     Insert32( pVar, nIdx );
     300             : }
     301             : 
     302           0 : void SbxArray::Remove32( sal_uInt32 nIdx )
     303             : {
     304           0 :     if( nIdx < mpVarEntries->size() )
     305             :     {
     306           0 :         SbxVarEntry* pRef = (*mpVarEntries)[nIdx];
     307           0 :         mpVarEntries->erase( mpVarEntries->begin() + nIdx );
     308           0 :         delete pRef;
     309           0 :         SetFlag( SBX_MODIFIED );
     310             :     }
     311           0 : }
     312             : 
     313       56104 : void SbxArray::Remove( sal_uInt16 nIdx )
     314             : {
     315       56104 :     if( nIdx < mpVarEntries->size() )
     316             :     {
     317       56104 :         SbxVarEntry* pRef = (*mpVarEntries)[nIdx];
     318       56104 :         mpVarEntries->erase( mpVarEntries->begin() + nIdx );
     319       56104 :         delete pRef;
     320       56104 :         SetFlag( SBX_MODIFIED );
     321             :     }
     322       56104 : }
     323             : 
     324           0 : void SbxArray::Remove( SbxVariable* pVar )
     325             : {
     326           0 :     if( pVar )
     327             :     {
     328           0 :         for( size_t i = 0; i < mpVarEntries->size(); i++ )
     329             :         {
     330           0 :             SbxVarEntry* pRef = (*mpVarEntries)[i];
     331           0 :             if (&pRef->mpVar == pVar)
     332             :             {
     333           0 :                 Remove32( i ); break;
     334             :             }
     335             :         }
     336             :     }
     337           0 : }
     338             : 
     339             : // Taking over of the data from the passed array, at which
     340             : // the variable of the same name will be overwritten.
     341             : 
     342           0 : void SbxArray::Merge( SbxArray* p )
     343             : {
     344           0 :     if (!p)
     345           0 :         return;
     346             : 
     347           0 :     for (sal_uInt16 i = 0; i < p->Count(); ++i)
     348             :     {
     349           0 :         SbxVarEntry* pEntry1 = (*p->mpVarEntries)[i];
     350           0 :         if (!pEntry1->mpVar)
     351           0 :             continue;
     352             : 
     353           0 :         OUString aName = pEntry1->mpVar->GetName();
     354           0 :         sal_uInt16 nHash = pEntry1->mpVar->GetHashCode();
     355             : 
     356             :         // Is the element by the same name already inside?
     357             :         // Then overwrite!
     358           0 :         for (size_t j = 0; j < mpVarEntries->size(); ++j)
     359             :         {
     360           0 :             SbxVarEntry* pEntry2 = (*mpVarEntries)[j];
     361           0 :             if (!pEntry2->mpVar)
     362           0 :                 continue;
     363             : 
     364           0 :             if (pEntry2->mpVar->GetHashCode() == nHash &&
     365           0 :                 pEntry2->mpVar->GetName().equalsIgnoreAsciiCase(aName))
     366             :             {
     367             :                 // Take this element and clear the original.
     368           0 :                 pEntry2->mpVar = pEntry1->mpVar;
     369           0 :                 pEntry1->mpVar.Clear();
     370           0 :                 break;
     371             :             }
     372             :         }
     373             : 
     374           0 :         if (pEntry1->mpVar)
     375             :         {
     376             :             // We don't have element with the same name.  Add a new entry.
     377           0 :             SbxVarEntry* pNewEntry = new SbxVarEntry;
     378           0 :             mpVarEntries->push_back(pNewEntry);
     379           0 :             pNewEntry->mpVar = pEntry1->mpVar;
     380           0 :             if (pEntry1->maAlias)
     381           0 :                 pNewEntry->maAlias.reset(*pEntry1->maAlias);
     382             :         }
     383           0 :     }
     384             : }
     385             : 
     386             : // Search of an element via the user data. If the element is
     387             : // object, it will also be scanned.
     388             : 
     389           0 : SbxVariable* SbxArray::FindUserData( sal_uInt32 nData )
     390             : {
     391           0 :     SbxVariable* p = NULL;
     392           0 :     for (size_t i = 0; i < mpVarEntries->size(); ++i)
     393             :     {
     394           0 :         SbxVarEntry* pEntry = (*mpVarEntries)[i];
     395           0 :         if (!pEntry->mpVar)
     396           0 :             continue;
     397             : 
     398           0 :         if (pEntry->mpVar->IsVisible() && pEntry->mpVar->GetUserData() == nData)
     399             :         {
     400           0 :             p = &pEntry->mpVar;
     401           0 :             p->ResetFlag( SBX_EXTFOUND );
     402           0 :             break;  // JSM 1995-10-06
     403             :         }
     404             : 
     405             :         // Did we have an array/object with extended search?
     406           0 :         if (pEntry->mpVar->IsSet(SBX_EXTSEARCH))
     407             :         {
     408           0 :             switch (pEntry->mpVar->GetClass())
     409             :             {
     410             :                 case SbxCLASS_OBJECT:
     411             :                 {
     412             :                     // Objects are not allowed to scan their parent.
     413           0 :                     SbxFlagBits nOld = pEntry->mpVar->GetFlags();
     414           0 :                     pEntry->mpVar->ResetFlag(SBX_GBLSEARCH);
     415           0 :                     p = static_cast<SbxObject&>(*pEntry->mpVar).FindUserData(nData);
     416           0 :                     pEntry->mpVar->SetFlags(nOld);
     417             :                 }
     418           0 :                 break;
     419             :                 case SbxCLASS_ARRAY:
     420             :                     // Casting SbxVariable to SbxArray?  Really?
     421           0 :                     p = reinterpret_cast<SbxArray&>(*pEntry->mpVar).FindUserData(nData);
     422           0 :                 break;
     423             :                 default:
     424             :                     ;
     425             :             }
     426             : 
     427           0 :             if (p)
     428             :             {
     429           0 :                 p->SetFlag(SBX_EXTFOUND);
     430           0 :                 break;
     431             :             }
     432             :         }
     433             :     }
     434           0 :     return p;
     435             : }
     436             : 
     437             : // Search of an element by his name and type. If an element is an object,
     438             : // it will also be scanned..
     439             : 
     440     3217727 : SbxVariable* SbxArray::Find( const OUString& rName, SbxClassType t )
     441             : {
     442     3217727 :     SbxVariable* p = NULL;
     443     3217727 :     sal_uInt32 nCount = mpVarEntries->size();
     444     3217727 :     if( !nCount )
     445     1835664 :         return NULL;
     446     1382063 :     bool bExtSearch = IsSet( SBX_EXTSEARCH );
     447     1382063 :     sal_uInt16 nHash = SbxVariable::MakeHashCode( rName );
     448     4537886 :     for( sal_uInt32 i = 0; i < nCount; i++ )
     449             :     {
     450     3330820 :         SbxVarEntry* pEntry = (*mpVarEntries)[i];
     451     3330820 :         if (!pEntry->mpVar || !pEntry->mpVar->IsVisible())
     452           0 :             continue;
     453             : 
     454             :         // The very secure search works as well, if there is no hashcode!
     455     3330820 :         sal_uInt16 nVarHash = pEntry->mpVar->GetHashCode();
     456     6661640 :         if ( (!nVarHash || nVarHash == nHash)
     457      186091 :             && (t == SbxCLASS_DONTCARE || pEntry->mpVar->GetClass() == t)
     458     3516911 :             && (pEntry->mpVar->GetName().equalsIgnoreAsciiCase(rName)))
     459             :         {
     460      174996 :             p = &pEntry->mpVar;
     461      174996 :             p->ResetFlag(SBX_EXTFOUND);
     462      174996 :             break;
     463             :         }
     464             : 
     465             :         // Did we have an array/object with extended search?
     466     3155824 :         if (bExtSearch && pEntry->mpVar->IsSet(SBX_EXTSEARCH))
     467             :         {
     468      535401 :             switch (pEntry->mpVar->GetClass())
     469             :             {
     470             :                 case SbxCLASS_OBJECT:
     471             :                 {
     472             :                     // Objects are not allowed to scan their parent.
     473      535401 :                     SbxFlagBits nOld = pEntry->mpVar->GetFlags();
     474      535401 :                     pEntry->mpVar->ResetFlag(SBX_GBLSEARCH);
     475      535401 :                     p = static_cast<SbxObject&>(*pEntry->mpVar).Find(rName, t);
     476      535401 :                     pEntry->mpVar->SetFlags(nOld);
     477             :                 }
     478      535401 :                 break;
     479             :                 case SbxCLASS_ARRAY:
     480             :                     // Casting SbxVariable to SbxArray?  Really?
     481           0 :                     p = reinterpret_cast<SbxArray&>(*pEntry->mpVar).Find(rName, t);
     482           0 :                 break;
     483             :                 default:
     484             :                     ;
     485             :             }
     486             : 
     487      535401 :             if (p)
     488             :             {
     489           1 :                 p->SetFlag(SBX_EXTFOUND);
     490           1 :                 break;
     491             :             }
     492             :         }
     493             :     }
     494     1382063 :     return p;
     495             : }
     496             : 
     497           0 : bool SbxArray::LoadData( SvStream& rStrm, sal_uInt16 nVer )
     498             : {
     499             :     sal_uInt16 nElem;
     500           0 :     Clear();
     501           0 :     bool bRes = true;
     502           0 :     SbxFlagBits f = nFlags;
     503           0 :     nFlags |= SBX_WRITE;
     504           0 :     rStrm.ReadUInt16( nElem );
     505           0 :     nElem &= 0x7FFF;
     506           0 :     for( sal_uInt32 n = 0; n < nElem; n++ )
     507             :     {
     508             :         sal_uInt16 nIdx;
     509           0 :         rStrm.ReadUInt16( nIdx );
     510           0 :         SbxVariable* pVar = static_cast<SbxVariable*>(Load( rStrm ));
     511           0 :         if( pVar )
     512             :         {
     513           0 :             SbxVariableRef& rRef = GetRef( nIdx );
     514           0 :             rRef = pVar;
     515             :         }
     516             :         else
     517             :         {
     518           0 :             bRes = false;
     519           0 :             break;
     520             :         }
     521             :     }
     522           0 :     if( bRes )
     523           0 :         bRes = LoadPrivateData( rStrm, nVer );
     524           0 :     nFlags = f;
     525           0 :     return bRes;
     526             : }
     527             : 
     528           0 : bool SbxArray::StoreData( SvStream& rStrm ) const
     529             : {
     530           0 :     sal_uInt32 nElem = 0;
     531             :     sal_uInt32 n;
     532             :     // Which elements are even defined?
     533           0 :     for( n = 0; n < mpVarEntries->size(); n++ )
     534             :     {
     535           0 :         SbxVarEntry* pEntry = (*mpVarEntries)[n];
     536           0 :         if (pEntry->mpVar && (pEntry->mpVar->GetFlags() & SBX_DONTSTORE) == SBX_NONE)
     537           0 :             nElem++;
     538             :     }
     539           0 :     rStrm.WriteUInt16( nElem );
     540           0 :     for( n = 0; n < mpVarEntries->size(); n++ )
     541             :     {
     542           0 :         SbxVarEntry* pEntry = (*mpVarEntries)[n];
     543           0 :         if (pEntry->mpVar && (pEntry->mpVar->GetFlags() & SBX_DONTSTORE) == SBX_NONE)
     544             :         {
     545           0 :             rStrm.WriteUInt16( n );
     546           0 :             if (!pEntry->mpVar->Store(rStrm))
     547           0 :                 return false;
     548             :         }
     549             :     }
     550           0 :     return StorePrivateData( rStrm );
     551             : }
     552             : 
     553             : // #100883 Method to set method directly to parameter array
     554         424 : void SbxArray::PutDirect( SbxVariable* pVar, sal_uInt32 nIdx )
     555             : {
     556         424 :     SbxVariableRef& rRef = GetRef32( nIdx );
     557         424 :     rRef = pVar;
     558         424 : }
     559             : 
     560             : 
     561             : //  SbxArray
     562             : 
     563         134 : SbxDimArray::SbxDimArray( SbxDataType t ) : SbxArray( t ), mbHasFixedSize( false )
     564             : {
     565         134 : }
     566             : 
     567           0 : SbxDimArray::SbxDimArray( const SbxDimArray& rArray )
     568           0 :     : SvRefBase( rArray ), SbxArray( rArray.eType )
     569             : {
     570           0 :     *this = rArray;
     571           0 : }
     572             : 
     573           0 : SbxDimArray& SbxDimArray::operator=( const SbxDimArray& rArray )
     574             : {
     575           0 :     if( &rArray != this )
     576             :     {
     577           0 :         SbxArray::operator=( (const SbxArray&) rArray );
     578           0 :         m_vDimensions = rArray.m_vDimensions;
     579           0 :         this->mbHasFixedSize = rArray.mbHasFixedSize;
     580             :     }
     581           0 :     return *this;
     582             : }
     583             : 
     584         536 : SbxDimArray::~SbxDimArray()
     585             : {
     586         134 :     Clear();
     587         402 : }
     588             : 
     589         142 : void SbxDimArray::Clear()
     590             : {
     591         142 :     m_vDimensions.clear();
     592         142 : }
     593             : 
     594             : // Add a dimension
     595             : 
     596         167 : void SbxDimArray::AddDimImpl32( sal_Int32 lb, sal_Int32 ub, bool bAllowSize0 )
     597             : {
     598         167 :     SbxError eRes = SbxERR_OK;
     599         167 :     if( ub < lb && !bAllowSize0 )
     600             :     {
     601           0 :         eRes = SbxERR_BOUNDS;
     602           0 :         ub = lb;
     603             :     }
     604             :     SbxDim d;
     605         167 :     d.nLbound = lb;
     606         167 :     d.nUbound = ub;
     607         167 :     d.nSize   = ub - lb + 1;
     608         167 :     m_vDimensions.push_back(d);
     609         167 :     if( eRes )
     610           0 :         SetError( eRes );
     611         167 : }
     612             : 
     613             : 
     614          24 : void SbxDimArray::AddDim( short lb, short ub )
     615             : {
     616          24 :     AddDimImpl32( lb, ub, false );
     617          24 : }
     618             : 
     619          34 : void SbxDimArray::unoAddDim( short lb, short ub )
     620             : {
     621          34 :     AddDimImpl32( lb, ub, true );
     622          34 : }
     623             : 
     624          40 : void SbxDimArray::AddDim32( sal_Int32 lb, sal_Int32 ub )
     625             : {
     626          40 :     AddDimImpl32( lb, ub, false );
     627          40 : }
     628             : 
     629          69 : void SbxDimArray::unoAddDim32( sal_Int32 lb, sal_Int32 ub )
     630             : {
     631          69 :     AddDimImpl32( lb, ub, true );
     632          69 : }
     633             : 
     634             : 
     635             : // Readout dimension data
     636             : 
     637         148 : bool SbxDimArray::GetDim32( sal_Int32 n, sal_Int32& rlb, sal_Int32& rub ) const
     638             : {
     639         148 :     if( n < 1 || n > static_cast<sal_Int32>(m_vDimensions.size()) )
     640             :     {
     641           0 :         SetError( SbxERR_BOUNDS );
     642           0 :         rub = rlb = 0;
     643           0 :         return false;
     644             :     }
     645         148 :     SbxDim d = m_vDimensions[n - 1];
     646         148 :     rub = d.nUbound;
     647         148 :     rlb = d.nLbound;
     648         148 :     return true;
     649             : }
     650             : 
     651           0 : bool SbxDimArray::GetDim( short n, short& rlb, short& rub ) const
     652             : {
     653             :     sal_Int32 rlb32, rub32;
     654           0 :     bool bRet = GetDim32( n, rlb32, rub32 );
     655           0 :     rub = (short)rub32;
     656           0 :     rlb = (short)rlb32;
     657           0 :     if( bRet )
     658             :     {
     659           0 :         if( rlb32 < -SBX_MAXINDEX || rub32 > SBX_MAXINDEX )
     660             :         {
     661           0 :             SetError( SbxERR_BOUNDS );
     662           0 :             return false;
     663             :         }
     664             :     }
     665           0 :     return bRet;
     666             : }
     667             : 
     668             : // Element-Ptr with the help of an index list
     669             : 
     670        3528 : sal_uInt32 SbxDimArray::Offset32( const sal_Int32* pIdx )
     671             : {
     672        3528 :     sal_uInt32 nPos = 0;
     673       31458 :     for( std::vector<SbxDim>::const_iterator it = m_vDimensions.begin();
     674       20972 :          it != m_vDimensions.end(); ++it )
     675             :     {
     676        6958 :         sal_Int32 nIdx = *pIdx++;
     677        6958 :         if( nIdx < it->nLbound || nIdx > it->nUbound )
     678             :         {
     679           0 :             nPos = (sal_uInt32)SBX_MAXINDEX32 + 1; break;
     680             :         }
     681        6958 :         nPos = nPos * it->nSize + nIdx - it->nLbound;
     682             :     }
     683        3528 :     if( m_vDimensions.empty() || nPos > SBX_MAXINDEX32 )
     684             :     {
     685           0 :         SetError( SbxERR_BOUNDS );
     686           0 :         nPos = 0;
     687             :     }
     688        3528 :     return nPos;
     689             : }
     690             : 
     691          78 : sal_uInt16 SbxDimArray::Offset( const short* pIdx )
     692             : {
     693          78 :     long nPos = 0;
     694         468 :     for( std::vector<SbxDim>::const_iterator it = m_vDimensions.begin();
     695         312 :          it != m_vDimensions.end(); ++it )
     696             :     {
     697          78 :         short nIdx = *pIdx++;
     698          78 :         if( nIdx < it->nLbound || nIdx > it->nUbound )
     699             :         {
     700           0 :             nPos = SBX_MAXINDEX + 1;
     701           0 :             break;
     702             :         }
     703          78 :         nPos = nPos * it->nSize + nIdx - it->nLbound;
     704             :     }
     705          78 :     if( m_vDimensions.empty() || nPos > SBX_MAXINDEX )
     706             :     {
     707           0 :         SetError( SbxERR_BOUNDS );
     708           0 :         nPos = 0;
     709             :     }
     710          78 :     return (sal_uInt16) nPos;
     711             : }
     712             : 
     713           0 : SbxVariable* SbxDimArray::Get( const short* pIdx )
     714             : {
     715           0 :     return SbxArray::Get( Offset( pIdx ) );
     716             : }
     717             : 
     718          78 : void SbxDimArray::Put( SbxVariable* p, const short* pIdx  )
     719             : {
     720          78 :     SbxArray::Put( p, Offset( pIdx ) );
     721          78 : }
     722             : 
     723         100 : SbxVariable* SbxDimArray::Get32( const sal_Int32* pIdx )
     724             : {
     725         100 :     return SbxArray::Get32( Offset32( pIdx ) );
     726             : }
     727             : 
     728        3428 : void SbxDimArray::Put32( SbxVariable* p, const sal_Int32* pIdx  )
     729             : {
     730        3428 :     SbxArray::Put32( p, Offset32( pIdx ) );
     731        3428 : }
     732             : 
     733             : // Element-Number with the help of Parameter-Array
     734         685 : sal_uInt32 SbxDimArray::Offset32( SbxArray* pPar )
     735             : {
     736             : #if HAVE_FEATURE_SCRIPTING
     737        1370 :     if (m_vDimensions.empty() || !pPar ||
     738         685 :         ((m_vDimensions.size() != sal::static_int_cast<size_t>(pPar->Count() - 1))
     739           0 :             && SbiRuntime::isVBAEnabled()))
     740             :     {
     741           0 :         SetError( SbxERR_BOUNDS );
     742           0 :         return 0;
     743             :     }
     744             : #endif
     745         685 :     sal_uInt32 nPos = 0;
     746         685 :     sal_uInt16 nOff = 1;    // Non element 0!
     747        5403 :     for( std::vector<SbxDim>::const_iterator it = m_vDimensions.begin();
     748        5403 :          it != m_vDimensions.end() && !IsError(); ++it )
     749             :     {
     750        1116 :         sal_Int32 nIdx = pPar->Get( nOff++ )->GetLong();
     751        1116 :         if( nIdx < it->nLbound || nIdx > it->nUbound )
     752             :         {
     753           0 :             nPos = (sal_uInt32) SBX_MAXINDEX32+1;
     754           0 :             break;
     755             :         }
     756        1116 :         nPos = nPos * it->nSize + nIdx - it->nLbound;
     757             :     }
     758         685 :     if( nPos > (sal_uInt32) SBX_MAXINDEX32 )
     759             :     {
     760           0 :         SetError( SbxERR_BOUNDS );
     761           0 :         nPos = 0;
     762             :     }
     763         685 :     return nPos;
     764             : }
     765             : 
     766         685 : SbxVariable* SbxDimArray::Get( SbxArray* pPar )
     767             : {
     768         685 :     return SbxArray::Get32( Offset32( pPar ) );
     769             : }
     770             : 
     771           0 : bool SbxDimArray::LoadData( SvStream& rStrm, sal_uInt16 nVer )
     772             : {
     773             :     short nDimension;
     774           0 :     rStrm.ReadInt16( nDimension );
     775           0 :     for( short i = 0; i < nDimension && rStrm.GetError() == SVSTREAM_OK; i++ )
     776             :     {
     777           0 :         sal_Int16 lb(0), ub(0);
     778           0 :         rStrm.ReadInt16( lb ).ReadInt16( ub );
     779           0 :         AddDim( lb, ub );
     780             :     }
     781           0 :     return SbxArray::LoadData( rStrm, nVer );
     782             : }
     783             : 
     784           0 : bool SbxDimArray::StoreData( SvStream& rStrm ) const
     785             : {
     786           0 :     rStrm.WriteInt16( m_vDimensions.size() );
     787           0 :     for( short i = 0; i < static_cast<short>(m_vDimensions.size()); i++ )
     788             :     {
     789             :         short lb, ub;
     790           0 :         GetDim( i, lb, ub );
     791           0 :         rStrm.WriteInt16( lb ).WriteInt16( ub );
     792             :     }
     793           0 :     return SbxArray::StoreData( rStrm );
     794             : }
     795             : 
     796             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11