LCOV - code coverage report
Current view: top level - basic/source/sbx - sbxarray.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 227 408 55.6 %
Date: 2014-11-03 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      504726 : struct SbxVarEntry
      32             : {
      33             :     SbxVariableRef mpVar;
      34             :     boost::optional<OUString> maAlias;
      35             : };
      36             : 
      37         594 : TYPEINIT1(SbxArray,SbxBase)
      38       50120 : TYPEINIT1(SbxDimArray,SbxArray)
      39             : 
      40             : //  SbxArray
      41             : 
      42      217924 : SbxArray::SbxArray( SbxDataType t ) : SbxBase()
      43             : {
      44      217924 :     mpVarEntries = new VarEntriesType;
      45      217924 :     eType = t;
      46      217924 :     if( t != SbxVARIANT )
      47       64052 :         SetFlag( SBX_FIXED );
      48      217924 : }
      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          12 : SbxArray& SbxArray::operator=( const SbxArray& rArray )
      60             : {
      61          12 :     if( &rArray != this )
      62             :     {
      63          12 :         eType = rArray.eType;
      64          12 :         Clear();
      65          12 :         VarEntriesType* pSrc = rArray.mpVarEntries;
      66          20 :         for( sal_uInt32 i = 0; i < pSrc->size(); i++ )
      67             :         {
      68           8 :             SbxVarEntry* pSrcRef = (*pSrc)[i];
      69           8 :             SbxVariableRef pSrc_ = pSrcRef->mpVar;
      70           8 :             if( !pSrc_ )
      71           0 :                 continue;
      72           8 :             SbxVarEntry* pDstRef = new SbxVarEntry;
      73           8 :             pDstRef->mpVar = pSrcRef->mpVar;
      74             : 
      75           8 :             if (pSrcRef->maAlias)
      76           0 :                 pDstRef->maAlias.reset(*pSrcRef->maAlias);
      77             : 
      78           8 :             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           8 :             mpVarEntries->push_back( pDstRef );
      87           8 :         }
      88             :     }
      89          12 :     return *this;
      90             : }
      91             : 
      92      617252 : SbxArray::~SbxArray()
      93             : {
      94      205840 :     Clear();
      95      205840 :     delete mpVarEntries;
      96      411412 : }
      97             : 
      98        2778 : SbxDataType SbxArray::GetType() const
      99             : {
     100        2778 :     return (SbxDataType) ( eType | SbxARRAY );
     101             : }
     102             : 
     103           0 : SbxClassType SbxArray::GetClass() const
     104             : {
     105           0 :     return SbxCLASS_ARRAY;
     106             : }
     107             : 
     108      229510 : void SbxArray::Clear()
     109             : {
     110      229510 :     sal_uInt32 nSize = mpVarEntries->size();
     111      378586 :     for( sal_uInt32 i = 0 ; i < nSize ; i++ )
     112             :     {
     113      149076 :         SbxVarEntry* pEntry = (*mpVarEntries)[i];
     114      149076 :         delete pEntry;
     115             :     }
     116      229510 :     mpVarEntries->clear();
     117      229510 : }
     118             : 
     119          10 : sal_uInt32 SbxArray::Count32() const
     120             : {
     121          10 :     return mpVarEntries->size();
     122             : }
     123             : 
     124     2422932 : sal_uInt16 SbxArray::Count() const
     125             : {
     126     2422932 :     sal_uInt32 nCount = mpVarEntries->size();
     127             :     DBG_ASSERT( nCount <= SBX_MAXINDEX, "SBX: Array-Index > SBX_MAXINDEX" );
     128     2422932 :     return (sal_uInt16)nCount;
     129             : }
     130             : 
     131        9334 : 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        9334 :     if( nIdx > SBX_MAXINDEX32 )
     137             :     {
     138           0 :         SetError( SbxERR_BOUNDS );
     139           0 :         nIdx = 0;
     140             :     }
     141       26014 :     while( mpVarEntries->size() <= nIdx )
     142             :     {
     143        7346 :         mpVarEntries->push_back(new SbxVarEntry);
     144             :     }
     145        9334 :     return (*mpVarEntries)[nIdx]->mpVar;
     146             : }
     147             : 
     148     1144802 : 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     1144802 :     if( nIdx > SBX_MAXINDEX )
     154             :     {
     155           0 :         SetError( SbxERR_BOUNDS );
     156           0 :         nIdx = 0;
     157             :     }
     158     2540666 :     while( mpVarEntries->size() <= nIdx )
     159             :     {
     160      251062 :         mpVarEntries->push_back(new SbxVarEntry);
     161             :     }
     162     1144802 :     return (*mpVarEntries)[nIdx]->mpVar;
     163             : }
     164             : 
     165        1630 : SbxVariable* SbxArray::Get32( sal_uInt32 nIdx )
     166             : {
     167        1630 :     if( !CanRead() )
     168             :     {
     169           0 :         SetError( SbxERR_PROP_WRITEONLY );
     170           0 :         return NULL;
     171             :     }
     172        1630 :     SbxVariableRef& rRef = GetRef32( nIdx );
     173             : 
     174        1630 :     if ( !rRef.Is() )
     175         480 :         rRef = new SbxVariable( eType );
     176             : 
     177        1630 :     return rRef;
     178             : }
     179             : 
     180      290618 : SbxVariable* SbxArray::Get( sal_uInt16 nIdx )
     181             : {
     182      290618 :     if( !CanRead() )
     183             :     {
     184           0 :         SetError( SbxERR_PROP_WRITEONLY );
     185           0 :         return NULL;
     186             :     }
     187      290618 :     SbxVariableRef& rRef = GetRef( nIdx );
     188             : 
     189      290618 :     if ( !rRef.Is() )
     190         188 :         rRef = new SbxVariable( eType );
     191             : 
     192      290618 :     return rRef;
     193             : }
     194             : 
     195        6860 : void SbxArray::Put32( SbxVariable* pVar, sal_uInt32 nIdx )
     196             : {
     197        6860 :     if( !CanWrite() )
     198           0 :         SetError( SbxERR_PROP_READONLY );
     199             :     else
     200             :     {
     201        6860 :         if( pVar )
     202        6860 :             if( eType != SbxVARIANT )
     203             :                 // Convert no objects
     204          18 :                 if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT )
     205          14 :                     pVar->Convert( eType );
     206        6860 :         SbxVariableRef& rRef = GetRef32( nIdx );
     207        6860 :         if( (SbxVariable*) rRef != pVar )
     208             :         {
     209        6860 :             rRef = pVar;
     210        6860 :             SetFlag( SBX_MODIFIED );
     211             :         }
     212             :     }
     213        6860 : }
     214             : 
     215      304830 : void SbxArray::Put( SbxVariable* pVar, sal_uInt16 nIdx )
     216             : {
     217      304830 :     if( !CanWrite() )
     218           0 :         SetError( SbxERR_PROP_READONLY );
     219             :     else
     220             :     {
     221      304830 :         if( pVar )
     222      303378 :             if( eType != SbxVARIANT )
     223             :                 // Convert no objects
     224       45308 :                 if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT )
     225          24 :                     pVar->Convert( eType );
     226      304830 :         SbxVariableRef& rRef = GetRef( nIdx );
     227      304830 :         if( (SbxVariable*) rRef != pVar )
     228             :         {
     229      304636 :             rRef = pVar;
     230      304636 :             SetFlag( SBX_MODIFIED );
     231             :         }
     232             :     }
     233      304830 : }
     234             : 
     235       11618 : OUString SbxArray::GetAlias( sal_uInt16 nIdx )
     236             : {
     237       11618 :     if( !CanRead() )
     238             :     {
     239           0 :         SetError( SbxERR_PROP_WRITEONLY );
     240           0 :         return OUString();
     241             :     }
     242       11618 :     SbxVarEntry& rRef = reinterpret_cast<SbxVarEntry&>(GetRef( nIdx ));
     243             : 
     244       11618 :     if (!rRef.maAlias)
     245       11210 :         return OUString();
     246             : 
     247         408 :     return *rRef.maAlias;
     248             : }
     249             : 
     250        4798 : void SbxArray::PutAlias( const OUString& rAlias, sal_uInt16 nIdx )
     251             : {
     252        4798 :     if( !CanWrite() )
     253             :     {
     254           0 :         SetError( SbxERR_PROP_READONLY );
     255             :     }
     256             :     else
     257             :     {
     258        4798 :         SbxVarEntry& rRef = reinterpret_cast<SbxVarEntry&>( GetRef( nIdx ) );
     259        4798 :         rRef.maAlias.reset(rAlias);
     260             :     }
     261        4798 : }
     262             : 
     263         470 : void SbxArray::Insert32( SbxVariable* pVar, sal_uInt32 nIdx )
     264             : {
     265             :     DBG_ASSERT( mpVarEntries->size() <= SBX_MAXINDEX32, "SBX: Array gets too big" );
     266         470 :     if( mpVarEntries->size() > SBX_MAXINDEX32 )
     267             :     {
     268         470 :             return;
     269             :     }
     270         470 :     SbxVarEntry* p = new SbxVarEntry;
     271         470 :     *((SbxVariableRef*) p) = pVar;
     272         470 :     size_t nSize = mpVarEntries->size();
     273         470 :     if( nIdx > nSize )
     274             :     {
     275           0 :         nIdx = nSize;
     276             :     }
     277         470 :     if( eType != SbxVARIANT && pVar )
     278             :     {
     279           0 :         p->mpVar->Convert(eType);
     280             :     }
     281         470 :     if( nIdx == nSize )
     282             :     {
     283         470 :         mpVarEntries->push_back( p );
     284             :     }
     285             :     else
     286             :     {
     287           0 :         mpVarEntries->insert( mpVarEntries->begin() + nIdx, p );
     288             :     }
     289         470 :     SetFlag( SBX_MODIFIED );
     290             : }
     291             : 
     292         470 : void SbxArray::Insert( SbxVariable* pVar, sal_uInt16 nIdx )
     293             : {
     294             :     DBG_ASSERT( mpVarEntries->size() <= 0x3FF0, "SBX: Array gets too big" );
     295         470 :     if( mpVarEntries->size() > 0x3FF0 )
     296             :     {
     297         470 :         return;
     298             :     }
     299         470 :     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       96764 : void SbxArray::Remove( sal_uInt16 nIdx )
     314             : {
     315       96764 :     if( nIdx < mpVarEntries->size() )
     316             :     {
     317       96764 :         SbxVarEntry* pRef = (*mpVarEntries)[nIdx];
     318       96764 :         mpVarEntries->erase( mpVarEntries->begin() + nIdx );
     319       96764 :         delete pRef;
     320       96764 :         SetFlag( SBX_MODIFIED );
     321             :     }
     322       96764 : }
     323             : 
     324           0 : void SbxArray::Remove( SbxVariable* pVar )
     325             : {
     326           0 :     if( pVar )
     327             :     {
     328           0 :         for( sal_uInt32 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     5762088 : SbxVariable* SbxArray::Find( const OUString& rName, SbxClassType t )
     441             : {
     442     5762088 :     SbxVariable* p = NULL;
     443     5762088 :     sal_uInt32 nCount = mpVarEntries->size();
     444     5762088 :     if( !nCount )
     445     3293960 :         return NULL;
     446     2468128 :     bool bExtSearch = IsSet( SBX_EXTSEARCH );
     447     2468128 :     sal_uInt16 nHash = SbxVariable::MakeHashCode( rName );
     448     8198726 :     for( sal_uInt32 i = 0; i < nCount; i++ )
     449             :     {
     450     6034934 :         SbxVarEntry* pEntry = (*mpVarEntries)[i];
     451     6034934 :         if (!pEntry->mpVar || !pEntry->mpVar->IsVisible())
     452           0 :             continue;
     453             : 
     454             :         // The very secure search works as well, if there is no hashcode!
     455     6034934 :         sal_uInt16 nVarHash = pEntry->mpVar->GetHashCode();
     456    12069868 :         if ( (!nVarHash || nVarHash == nHash)
     457      324436 :             && (t == SbxCLASS_DONTCARE || pEntry->mpVar->GetClass() == t)
     458     6359370 :             && (pEntry->mpVar->GetName().equalsIgnoreAsciiCase(rName)))
     459             :         {
     460      304334 :             p = &pEntry->mpVar;
     461      304334 :             p->ResetFlag(SBX_EXTFOUND);
     462      304334 :             break;
     463             :         }
     464             : 
     465             :         // Did we have an array/object with extended search?
     466     5730600 :         if (bExtSearch && pEntry->mpVar->IsSet(SBX_EXTSEARCH))
     467             :         {
     468      947682 :             switch (pEntry->mpVar->GetClass())
     469             :             {
     470             :                 case SbxCLASS_OBJECT:
     471             :                 {
     472             :                     // Objects are not allowed to scan their parent.
     473      947682 :                     SbxFlagBits nOld = pEntry->mpVar->GetFlags();
     474      947682 :                     pEntry->mpVar->ResetFlag(SBX_GBLSEARCH);
     475      947682 :                     p = static_cast<SbxObject&>(*pEntry->mpVar).Find(rName, t);
     476      947682 :                     pEntry->mpVar->SetFlags(nOld);
     477             :                 }
     478      947682 :                 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      947682 :             if (p)
     488             :             {
     489           2 :                 p->SetFlag(SBX_EXTFOUND);
     490           2 :                 break;
     491             :             }
     492             :         }
     493             :     }
     494     2468128 :     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         844 : void SbxArray::PutDirect( SbxVariable* pVar, sal_uInt32 nIdx )
     555             : {
     556         844 :     SbxVariableRef& rRef = GetRef32( nIdx );
     557         844 :     rRef = pVar;
     558         844 : }
     559             : 
     560             : 
     561             : //  SbxArray
     562             : 
     563         268 : SbxDimArray::SbxDimArray( SbxDataType t ) : SbxArray( t ), mbHasFixedSize( false )
     564             : {
     565         268 : }
     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         804 : SbxDimArray::~SbxDimArray()
     585             : {
     586         268 :     Clear();
     587         536 : }
     588             : 
     589         284 : void SbxDimArray::Clear()
     590             : {
     591         284 :     m_vDimensions.clear();
     592         284 : }
     593             : 
     594             : // Add a dimension
     595             : 
     596         334 : void SbxDimArray::AddDimImpl32( sal_Int32 lb, sal_Int32 ub, bool bAllowSize0 )
     597             : {
     598         334 :     SbxError eRes = SbxERR_OK;
     599         334 :     if( ub < lb && !bAllowSize0 )
     600             :     {
     601           0 :         eRes = SbxERR_BOUNDS;
     602           0 :         ub = lb;
     603             :     }
     604             :     SbxDim d;
     605         334 :     d.nLbound = lb;
     606         334 :     d.nUbound = ub;
     607         334 :     d.nSize   = ub - lb + 1;
     608         334 :     m_vDimensions.push_back(d);
     609         334 :     if( eRes )
     610           0 :         SetError( eRes );
     611         334 : }
     612             : 
     613             : 
     614          48 : void SbxDimArray::AddDim( short lb, short ub )
     615             : {
     616          48 :     AddDimImpl32( lb, ub, false );
     617          48 : }
     618             : 
     619          68 : void SbxDimArray::unoAddDim( short lb, short ub )
     620             : {
     621          68 :     AddDimImpl32( lb, ub, true );
     622          68 : }
     623             : 
     624          80 : void SbxDimArray::AddDim32( sal_Int32 lb, sal_Int32 ub )
     625             : {
     626          80 :     AddDimImpl32( lb, ub, false );
     627          80 : }
     628             : 
     629         138 : void SbxDimArray::unoAddDim32( sal_Int32 lb, sal_Int32 ub )
     630             : {
     631         138 :     AddDimImpl32( lb, ub, true );
     632         138 : }
     633             : 
     634             : 
     635             : // Readout dimension data
     636             : 
     637         296 : bool SbxDimArray::GetDim32( sal_Int32 n, sal_Int32& rlb, sal_Int32& rub ) const
     638             : {
     639         296 :     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         296 :     SbxDim d = m_vDimensions[n - 1];
     646         296 :     rub = d.nUbound;
     647         296 :     rlb = d.nLbound;
     648         296 :     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        7056 : sal_uInt32 SbxDimArray::Offset32( const sal_Int32* pIdx )
     671             : {
     672        7056 :     sal_uInt32 nPos = 0;
     673       62916 :     for( std::vector<SbxDim>::const_iterator it = m_vDimensions.begin();
     674       41944 :          it != m_vDimensions.end(); ++it )
     675             :     {
     676       13916 :         sal_Int32 nIdx = *pIdx++;
     677       13916 :         if( nIdx < it->nLbound || nIdx > it->nUbound )
     678             :         {
     679           0 :             nPos = (sal_uInt32)SBX_MAXINDEX32 + 1; break;
     680             :         }
     681       13916 :         nPos = nPos * it->nSize + nIdx - it->nLbound;
     682             :     }
     683        7056 :     if( m_vDimensions.empty() || nPos > SBX_MAXINDEX32 )
     684             :     {
     685           0 :         SetError( SbxERR_BOUNDS );
     686           0 :         nPos = 0;
     687             :     }
     688        7056 :     return nPos;
     689             : }
     690             : 
     691         156 : sal_uInt16 SbxDimArray::Offset( const short* pIdx )
     692             : {
     693         156 :     long nPos = 0;
     694         936 :     for( std::vector<SbxDim>::const_iterator it = m_vDimensions.begin();
     695         624 :          it != m_vDimensions.end(); ++it )
     696             :     {
     697         156 :         short nIdx = *pIdx++;
     698         156 :         if( nIdx < it->nLbound || nIdx > it->nUbound )
     699             :         {
     700           0 :             nPos = SBX_MAXINDEX + 1;
     701           0 :             break;
     702             :         }
     703         156 :         nPos = nPos * it->nSize + nIdx - it->nLbound;
     704             :     }
     705         156 :     if( m_vDimensions.empty() || nPos > SBX_MAXINDEX )
     706             :     {
     707           0 :         SetError( SbxERR_BOUNDS );
     708           0 :         nPos = 0;
     709             :     }
     710         156 :     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         156 : void SbxDimArray::Put( SbxVariable* p, const short* pIdx  )
     719             : {
     720         156 :     SbxArray::Put( p, Offset( pIdx ) );
     721         156 : }
     722             : 
     723         200 : SbxVariable* SbxDimArray::Get32( const sal_Int32* pIdx )
     724             : {
     725         200 :     return SbxArray::Get32( Offset32( pIdx ) );
     726             : }
     727             : 
     728        6856 : void SbxDimArray::Put32( SbxVariable* p, const sal_Int32* pIdx  )
     729             : {
     730        6856 :     SbxArray::Put32( p, Offset32( pIdx ) );
     731        6856 : }
     732             : 
     733             : // Element-Number with the help of Parameter-Array
     734        1370 : sal_uInt32 SbxDimArray::Offset32( SbxArray* pPar )
     735             : {
     736             : #if HAVE_FEATURE_SCRIPTING
     737        2740 :     if (m_vDimensions.empty() || !pPar ||
     738        1370 :         ((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        1370 :     sal_uInt32 nPos = 0;
     746        1370 :     sal_uInt16 nOff = 1;    // Non element 0!
     747       10806 :     for( std::vector<SbxDim>::const_iterator it = m_vDimensions.begin();
     748       10806 :          it != m_vDimensions.end() && !IsError(); ++it )
     749             :     {
     750        2232 :         sal_Int32 nIdx = pPar->Get( nOff++ )->GetLong();
     751        2232 :         if( nIdx < it->nLbound || nIdx > it->nUbound )
     752             :         {
     753           0 :             nPos = (sal_uInt32) SBX_MAXINDEX32+1;
     754           0 :             break;
     755             :         }
     756        2232 :         nPos = nPos * it->nSize + nIdx - it->nLbound;
     757             :     }
     758        1370 :     if( nPos > (sal_uInt32) SBX_MAXINDEX32 )
     759             :     {
     760           0 :         SetError( SbxERR_BOUNDS );
     761           0 :         nPos = 0;
     762             :     }
     763        1370 :     return nPos;
     764             : }
     765             : 
     766        1370 : SbxVariable* SbxDimArray::Get( SbxArray* pPar )
     767             : {
     768        1370 :     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.10