/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"
#include <tools/stream.hxx>
#include <basic/sbx.hxx>
#include "runtime.hxx"
#include <vector>
using namespace std;

struct SbxDim {                 // eine Array-Dimension:
	SbxDim* pNext;              // Link
	sal_Int32 nLbound, nUbound;     // Begrenzungen
	sal_Int32 nSize;                // Anzahl Elemente
};

class SbxVarEntry : public SbxVariableRef {
public:
	XubString* pAlias;
	SbxVarEntry() : SbxVariableRef(), pAlias( NULL ) {}
   ~SbxVarEntry() { delete pAlias; }
};

typedef SbxVarEntry* SbxVarEntryPtr;
typedef vector< SbxVarEntryPtr > SbxVarEntryPtrVector;
class SbxVarRefs : public SbxVarEntryPtrVector
{
public:
    SbxVarRefs( void ) {}
};


TYPEINIT1(SbxArray,SbxBase)
TYPEINIT1(SbxDimArray,SbxArray)

//////////////////////////////////////////////////////////////////////////
//
//  SbxArray
//
//////////////////////////////////////////////////////////////////////////

SbxArray::SbxArray( SbxDataType t ) : SbxBase()
{
	pData = new SbxVarRefs;
	eType = t;
	if( t != SbxVARIANT )
		SetFlag( SBX_FIXED );
}

SbxArray::SbxArray( const SbxArray& rArray ) :
    SvRefBase( rArray ), SbxBase()
{
	pData = new SbxVarRefs;
	if( rArray.eType != SbxVARIANT )
		SetFlag( SBX_FIXED );
	*this = rArray;
}

SbxArray& SbxArray::operator=( const SbxArray& rArray )
{
	if( &rArray != this )
	{
		eType = rArray.eType;
		Clear();
		SbxVarRefs* pSrc = rArray.pData;
		for( sal_uInt32 i = 0; i < pSrc->size(); i++ )
		{
			SbxVarEntryPtr pSrcRef = (*pSrc)[i];
			const SbxVariable* pSrc_ = *pSrcRef;
			if( !pSrc_ )
				continue;
			SbxVarEntryPtr pDstRef = new SbxVarEntry;
			*((SbxVariableRef*) pDstRef) = *((SbxVariableRef*) pSrcRef);
			if( pSrcRef->pAlias )
				pDstRef->pAlias = new XubString( *pSrcRef->pAlias );
			if( eType != SbxVARIANT )
				// Keine Objekte konvertieren
				if( eType != SbxOBJECT || pSrc_->GetClass() != SbxCLASS_OBJECT )
					((SbxVariable*) pSrc_)->Convert( eType );
			pData->push_back( pDstRef );
		}
	}
	return *this;
}

SbxArray::~SbxArray()
{
    Clear();
	delete pData;
}

SbxDataType SbxArray::GetType() const
{
	return (SbxDataType) ( eType | SbxARRAY );
}

SbxClassType SbxArray::GetClass() const
{
	return SbxCLASS_ARRAY;
}

void SbxArray::Clear()
{
    sal_uInt32 nSize = pData->size();
	for( sal_uInt32 i = 0 ; i < nSize ; i++ )
    {
        SbxVarEntry* pEntry = (*pData)[i];
		delete pEntry;
    }
	pData->clear();
}

sal_uInt32 SbxArray::Count32() const
{
    return pData->size();
}

sal_uInt16 SbxArray::Count() const
{
    sal_uInt32 nCount = pData->size();
	DBG_ASSERT( nCount <= SBX_MAXINDEX, "SBX: Array-Index > SBX_MAXINDEX" );
	return (sal_uInt16)nCount;
}

SbxVariableRef& SbxArray::GetRef32( sal_uInt32 nIdx )
{
	// Array ggf. vergroessern
	DBG_ASSERT( nIdx <= SBX_MAXINDEX32, "SBX: Array-Index > SBX_MAXINDEX32" );
	// Very Hot Fix
	if( nIdx > SBX_MAXINDEX32 )
	{
		SetError( SbxERR_BOUNDS );
		nIdx = 0;
	}
	while( pData->size() <= nIdx )
	{
		const SbxVarEntryPtr p = new SbxVarEntry;
		pData->push_back( p );
	}
	return *((*pData)[nIdx]);
}

SbxVariableRef& SbxArray::GetRef( sal_uInt16 nIdx )
{
	// Array ggf. vergroessern
	DBG_ASSERT( nIdx <= SBX_MAXINDEX, "SBX: Array-Index > SBX_MAXINDEX" );
	// Very Hot Fix
	if( nIdx > SBX_MAXINDEX )
	{
		SetError( SbxERR_BOUNDS );
		nIdx = 0;
	}
	while( pData->size() <= nIdx )
	{
		const SbxVarEntryPtr p = new SbxVarEntry;
		pData->push_back( p );
	}
	return *((*pData)[nIdx]);
}

SbxVariable* SbxArray::Get32( sal_uInt32 nIdx )
{
	if( !CanRead() )
	{
		SetError( SbxERR_PROP_WRITEONLY );
		return NULL;
	}
	SbxVariableRef& rRef = GetRef32( nIdx );

	if ( !rRef.Is() )
		rRef = new SbxVariable( eType );
#ifdef DBG_UTIL
	else
		DBG_CHKOBJ( rRef, SbxBase, 0 );
#endif

	return rRef;
}

SbxVariable* SbxArray::Get( sal_uInt16 nIdx )
{
	if( !CanRead() )
	{
		SetError( SbxERR_PROP_WRITEONLY );
		return NULL;
	}
	SbxVariableRef& rRef = GetRef( nIdx );

	if ( !rRef.Is() )
		rRef = new SbxVariable( eType );
#ifdef DBG_UTIL
	else
		DBG_CHKOBJ( rRef, SbxBase, 0 );
#endif

	return rRef;
}

void SbxArray::Put32( SbxVariable* pVar, sal_uInt32 nIdx )
{
	if( !CanWrite() )
		SetError( SbxERR_PROP_READONLY );
	else
	{
		if( pVar )
			if( eType != SbxVARIANT )
				// Keine Objekte konvertieren
				if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT )
					pVar->Convert( eType );
		SbxVariableRef& rRef = GetRef32( nIdx );
		if( (SbxVariable*) rRef != pVar )
		{
			rRef = pVar;
			SetFlag( SBX_MODIFIED );
		}
	}
}

void SbxArray::Put( SbxVariable* pVar, sal_uInt16 nIdx )
{
	if( !CanWrite() )
		SetError( SbxERR_PROP_READONLY );
	else
	{
		if( pVar )
			if( eType != SbxVARIANT )
				// Keine Objekte konvertieren
				if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT )
					pVar->Convert( eType );
		SbxVariableRef& rRef = GetRef( nIdx );
		if( (SbxVariable*) rRef != pVar )
		{
			rRef = pVar;
			SetFlag( SBX_MODIFIED );
		}
	}
}

const XubString& SbxArray::GetAlias( sal_uInt16 nIdx )
{
	if( !CanRead() )
	{
		SetError( SbxERR_PROP_WRITEONLY );
		return String::EmptyString();
	}
	SbxVarEntry& rRef = (SbxVarEntry&) GetRef( nIdx );

	if ( !rRef.pAlias )
		return String::EmptyString();
#ifdef DBG_UTIL
	else
		DBG_CHKOBJ( rRef, SbxBase, 0 );
#endif

	return *rRef.pAlias;
}

void SbxArray::PutAlias( const XubString& rAlias, sal_uInt16 nIdx )
{
	if( !CanWrite() )
		SetError( SbxERR_PROP_READONLY );
	else
	{
		SbxVarEntry& rRef = (SbxVarEntry&) GetRef( nIdx );
		if( !rRef.pAlias )
			rRef.pAlias = new XubString( rAlias );
		else
			*rRef.pAlias = rAlias;
	}
}

void SbxArray::Insert32( SbxVariable* pVar, sal_uInt32 nIdx )
{
	DBG_ASSERT( pData->size() <= SBX_MAXINDEX32, "SBX: Array wird zu gross" );
	if( pData->size() > SBX_MAXINDEX32 )
			return;
	SbxVarEntryPtr p = new SbxVarEntry;
	*((SbxVariableRef*) p) = pVar;
    SbxVarEntryPtrVector::size_type nSize = pData->size();
	if( nIdx > nSize )
		nIdx = nSize;
	if( eType != SbxVARIANT && pVar )
		(*p)->Convert( eType );
	if( nIdx == nSize )
    {
        pData->push_back( p );
    }
    else
    {
	    pData->insert( pData->begin() + nIdx, p );
    }
	SetFlag( SBX_MODIFIED );
}

void SbxArray::Insert( SbxVariable* pVar, sal_uInt16 nIdx )
{
	DBG_ASSERT( pData->size() <= 0x3FF0, "SBX: Array wird zu gross" );
	if( pData->size() > 0x3FF0 )
			return;
    Insert32( pVar, nIdx );
}

void SbxArray::Remove32( sal_uInt32 nIdx )
{
	if( nIdx < pData->size() )
	{
		SbxVariableRef* pRef = (*pData)[nIdx];
	    pData->erase( pData->begin() + nIdx );
		delete pRef;
		SetFlag( SBX_MODIFIED );
	}
}

void SbxArray::Remove( sal_uInt16 nIdx )
{
	if( nIdx < pData->size() )
	{
		SbxVariableRef* pRef = (*pData)[nIdx];
	    pData->erase( pData->begin() + nIdx );
		delete pRef;
		SetFlag( SBX_MODIFIED );
	}
}

void SbxArray::Remove( SbxVariable* pVar )
{
	if( pVar )
	{
		for( sal_uInt32 i = 0; i < pData->size(); i++ )
		{
			SbxVariableRef* pRef = (*pData)[i];
			// SbxVariableRef* pRef = pData->GetObject( i );
			if( *pRef == pVar )
			{
				Remove32( i ); break;
			}
		}
	}
}

// Uebernahme der Daten aus dem uebergebenen Array, wobei
// gleichnamige Variable ueberschrieben werden.

void SbxArray::Merge( SbxArray* p )
{
	if( p )
	{
		sal_uInt32 nSize = p->Count();
		for( sal_uInt32 i = 0; i < nSize; i++ )
		{
			SbxVarEntryPtr pRef1 = (*(p->pData))[i];
			// Ist das Element by name schon drin?
			// Dann ueberschreiben!
			SbxVariable* pVar = *pRef1;
			if( pVar )
			{
				XubString aName = pVar->GetName();
				sal_uInt16 nHash = pVar->GetHashCode();
				for( sal_uInt32 j = 0; j < pData->size(); j++ )
				{
					SbxVariableRef* pRef2 = (*pData)[j];
					if( (*pRef2)->GetHashCode() == nHash
					 && (*pRef2)->GetName().EqualsIgnoreCaseAscii( aName ) )
					{
						*pRef2 = pVar; pRef1 = NULL;
						break;
					}
				}
				if( pRef1 )
				{
					SbxVarEntryPtr pRef = new SbxVarEntry;
					const SbxVarEntryPtr pTemp = pRef;
					pData->push_back( pTemp );
					*((SbxVariableRef*) pRef) = *((SbxVariableRef*) pRef1);
					if( pRef1->pAlias )
						pRef->pAlias = new XubString( *pRef1->pAlias );
				}
			}
		}
	}
}

// Suchen eines Elements ueber die Userdaten. Falls ein Element
// ein Objekt ist, wird dieses ebenfalls durchsucht.

SbxVariable* SbxArray::FindUserData( sal_uInt32 nData )
{
	SbxVariable* p = NULL;
	for( sal_uInt32 i = 0; i < pData->size(); i++ )
	{
		SbxVariableRef* pRef = (*pData)[i];
		SbxVariable* pVar = *pRef;
		if( pVar )
		{
			if( pVar->IsVisible() && pVar->GetUserData() == nData )
			{
				p = pVar;
				p->ResetFlag( SBX_EXTFOUND );
				break;	// JSM 06.10.95
			}
			// Haben wir ein Array/Objekt mit Extended Search?
			else if( pVar->IsSet( SBX_EXTSEARCH ) )
			{
				switch( pVar->GetClass() )
				{
					case SbxCLASS_OBJECT:
					{
						// Objekte duerfen ihren Parent nicht durchsuchen
						sal_uInt16 nOld = pVar->GetFlags();
						pVar->ResetFlag( SBX_GBLSEARCH );
						p = ((SbxObject*) pVar)->FindUserData( nData );
						pVar->SetFlags( nOld );
						break;
					}
					case SbxCLASS_ARRAY:
						p = ((SbxArray*) pVar)->FindUserData( nData );
						break;
					default: break;
				}
				if( p )
				{
					p->SetFlag( SBX_EXTFOUND );
					break;
				}
			}
		}
	}
	return p;
}

// Suchen eines Elements ueber den Namen und den Typ. Falls ein Element
// ein Objekt ist, wird dieses ebenfalls durchsucht.

SbxVariable* SbxArray::Find( const XubString& rName, SbxClassType t )
{
	SbxVariable* p = NULL;
	sal_uInt32 nCount = pData->size();
	if( !nCount )
		return NULL;
	sal_Bool bExtSearch = IsSet( SBX_EXTSEARCH );
	sal_uInt16 nHash = SbxVariable::MakeHashCode( rName );
	for( sal_uInt32 i = 0; i < nCount; i++ )
	{
		SbxVariableRef* pRef = (*pData)[i];
		SbxVariable* pVar = *pRef;
		if( pVar && pVar->IsVisible() )
		{
			// Die ganz sichere Suche klappt auch, wenn es
			// keinen Hascode gibt!
			sal_uInt16 nVarHash = pVar->GetHashCode();
			if( ( !nVarHash || nVarHash == nHash )
				&& ( t == SbxCLASS_DONTCARE || pVar->GetClass() == t )
				&& ( pVar->GetName().EqualsIgnoreCaseAscii( rName ) ) )
			{
				p = pVar;
				p->ResetFlag( SBX_EXTFOUND );
				break;
			}
			// Haben wir ein Array/Objekt mit Extended Search?
			else if( bExtSearch && pVar->IsSet( SBX_EXTSEARCH ) )
			{
				switch( pVar->GetClass() )
				{
					case SbxCLASS_OBJECT:
					{
						// Objekte duerfen ihren Parent nicht durchsuchen
						sal_uInt16 nOld = pVar->GetFlags();
						pVar->ResetFlag( SBX_GBLSEARCH );
						p = ((SbxObject*) pVar)->Find( rName, t );
						pVar->SetFlags( nOld );
						break;
					}
					case SbxCLASS_ARRAY:
						p = ((SbxArray*) pVar)->Find( rName, t );
						break;
					default: break;
				}
				if( p )
				{
					p->SetFlag( SBX_EXTFOUND );
					break;
				}
			}
		}
	}
	return p;
}

sal_Bool SbxArray::LoadData( SvStream& rStrm, sal_uInt16 nVer )
{
	sal_uInt16 nElem;
	Clear();
	sal_Bool bRes = sal_True;
	sal_uInt16 f = nFlags;
	nFlags |= SBX_WRITE;
	rStrm >> nElem;
	nElem &= 0x7FFF;
	for( sal_uInt32 n = 0; n < nElem; n++ )
	{
		sal_uInt16 nIdx;
		rStrm >> nIdx;
		SbxVariable* pVar = (SbxVariable*) Load( rStrm );
		if( pVar )
		{
			SbxVariableRef& rRef = GetRef( nIdx );
			rRef = pVar;
		}
		else
		{
			bRes = sal_False; break;
		}
	}
	if( bRes )
		bRes = LoadPrivateData( rStrm, nVer );
	nFlags = f;
	return bRes;
}

sal_Bool SbxArray::StoreData( SvStream& rStrm ) const
{
	sal_uInt32 nElem = 0;
	sal_uInt32 n;
	// Welche Elemente sind ueberhaupt definiert?
	for( n = 0; n < pData->size(); n++ )
	{
		SbxVariableRef* pRef = (*pData)[n];
		SbxVariable* p = *pRef;
		if( p && !( p->GetFlags() & SBX_DONTSTORE ) )
			nElem++;
	}
	rStrm << (sal_uInt16) nElem;
	for( n = 0; n < pData->size(); n++ )
	{
		SbxVariableRef* pRef = (*pData)[n];
		SbxVariable* p = *pRef;
		if( p && !( p->GetFlags() & SBX_DONTSTORE ) )
		{
			rStrm << (sal_uInt16) n;
			if( !p->Store( rStrm ) )
				return sal_False;
		}
	}
	return StorePrivateData( rStrm );
}

// #100883 Method to set method directly to parameter array
void SbxArray::PutDirect( SbxVariable* pVar, sal_uInt32 nIdx )
{
	SbxVariableRef& rRef = GetRef32( nIdx );
	rRef = pVar;
}


//////////////////////////////////////////////////////////////////////////
//
//  SbxArray
//
//////////////////////////////////////////////////////////////////////////

SbxDimArray::SbxDimArray( SbxDataType t ) : SbxArray( t ), mbHasFixedSize( false )
{
	pFirst = pLast = NULL;
	nDim = 0;
}

SbxDimArray::SbxDimArray( const SbxDimArray& rArray )
    : SvRefBase( rArray ), SbxArray( rArray.eType )
{
	pFirst = pLast = NULL;
	nDim = 0;
	*this = rArray;
}

SbxDimArray& SbxDimArray::operator=( const SbxDimArray& rArray )
{
	if( &rArray != this )
	{
		SbxArray::operator=( (const SbxArray&) rArray );
		SbxDim* p = rArray.pFirst;
		while( p )
		{
			AddDim32( p->nLbound, p->nUbound );
			p = p->pNext;
		}
		this->mbHasFixedSize = rArray.mbHasFixedSize;
	}
	return *this;
}

SbxDimArray::~SbxDimArray()
{
	Clear();
}

void SbxDimArray::Clear()
{
	SbxDim* p = pFirst;
	while( p )
	{
		SbxDim* q = p->pNext;
		delete p;
		p = q;
	}
	pFirst = pLast = NULL;
	nDim   = 0;
}

// Dimension hinzufuegen

void SbxDimArray::AddDimImpl32( sal_Int32 lb, sal_Int32 ub, sal_Bool bAllowSize0 )
{
	SbxError eRes = SbxERR_OK;
	if( ub < lb && !bAllowSize0 )
	{
		eRes = SbxERR_BOUNDS;
		ub = lb;
	}
	SbxDim* p = new SbxDim;
	p->nLbound = lb;
	p->nUbound = ub;
	p->nSize   = ub - lb + 1;
	p->pNext   = NULL;
	if( !pFirst )
		pFirst = pLast = p;
	else
		pLast->pNext = p, pLast = p;
	nDim++;
	if( eRes )
		SetError( eRes );
}

void SbxDimArray::AddDim( short lb, short ub )
{
	AddDimImpl32( lb, ub, sal_False );
}

void SbxDimArray::unoAddDim( short lb, short ub )
{
	AddDimImpl32( lb, ub, sal_True );
}

void SbxDimArray::AddDim32( sal_Int32 lb, sal_Int32 ub )
{
	AddDimImpl32( lb, ub, sal_False );
}

void SbxDimArray::unoAddDim32( sal_Int32 lb, sal_Int32 ub )
{
	AddDimImpl32( lb, ub, sal_True );
}


// Dimensionsdaten auslesen

sal_Bool SbxDimArray::GetDim32( sal_Int32 n, sal_Int32& rlb, sal_Int32& rub ) const
{
	if( n < 1 || n > nDim )
	{
		SetError( SbxERR_BOUNDS ); rub = rlb = 0; return sal_False;
	}
	SbxDim* p = pFirst;
	while( --n )
		p = p->pNext;
	rub = p->nUbound;
	rlb = p->nLbound;
	return sal_True;
}

sal_Bool SbxDimArray::GetDim( short n, short& rlb, short& rub ) const
{
    sal_Int32 rlb32, rub32;
    sal_Bool bRet = GetDim32( n, rlb32, rub32 );
    if( bRet )
    {
	    if( rlb32 < -SBX_MAXINDEX || rub32 > SBX_MAXINDEX )
	    {
		    SetError( SbxERR_BOUNDS );
            return sal_False;
        }
	    rub = (short)rub32;
	    rlb = (short)rlb32;
    }
	return bRet;
}

// Element-Ptr anhand einer Index-Liste

sal_uInt32 SbxDimArray::Offset32( const sal_Int32* pIdx )
{
	sal_uInt32 nPos = 0;
	for( SbxDim* p = pFirst; p; p = p->pNext )
	{
		sal_Int32 nIdx = *pIdx++;
		if( nIdx < p->nLbound || nIdx > p->nUbound )
		{
			nPos = (sal_uInt32)SBX_MAXINDEX32 + 1; break;
		}
		nPos = nPos * p->nSize + nIdx - p->nLbound;
	}
	if( nDim == 0 || nPos > SBX_MAXINDEX32 )
	{
		SetError( SbxERR_BOUNDS ); nPos = 0;
	}
	return nPos;
}

sal_uInt16 SbxDimArray::Offset( const short* pIdx )
{
	long nPos = 0;
	for( SbxDim* p = pFirst; p; p = p->pNext )
	{
		short nIdx = *pIdx++;
		if( nIdx < p->nLbound || nIdx > p->nUbound )
		{
			nPos = SBX_MAXINDEX + 1; break;
		}
		nPos = nPos * p->nSize + nIdx - p->nLbound;
	}
	if( nDim == 0 || nPos > SBX_MAXINDEX )
	{
		SetError( SbxERR_BOUNDS ); nPos = 0;
	}
	return (sal_uInt16) nPos;
}

SbxVariableRef& SbxDimArray::GetRef( const short* pIdx )
{
	return SbxArray::GetRef( Offset( pIdx ) );
}

SbxVariable* SbxDimArray::Get( const short* pIdx )
{
	return SbxArray::Get( Offset( pIdx ) );
}

void SbxDimArray::Put( SbxVariable* p, const short* pIdx  )
{
	SbxArray::Put( p, Offset( pIdx ) );
}

SbxVariableRef& SbxDimArray::GetRef32( const sal_Int32* pIdx )
{
	return SbxArray::GetRef32( Offset32( pIdx ) );
}

SbxVariable* SbxDimArray::Get32( const sal_Int32* pIdx )
{
	return SbxArray::Get32( Offset32( pIdx ) );
}

void SbxDimArray::Put32( SbxVariable* p, const sal_Int32* pIdx  )
{
	SbxArray::Put32( p, Offset32( pIdx ) );
}


// Element-Nr anhand eines Parameter-Arrays

sal_uInt32 SbxDimArray::Offset32( SbxArray* pPar )
{
	if( nDim == 0 || !pPar || ( ( nDim != ( pPar->Count() - 1 ) ) && SbiRuntime::isVBAEnabled() ) )
	{
		SetError( SbxERR_BOUNDS ); return 0;
	}
	sal_uInt32 nPos = 0;
	sal_uInt16 nOff = 1;	// Nicht Element 0!
	for( SbxDim* p = pFirst; p && !IsError(); p = p->pNext )
	{
		sal_Int32 nIdx = pPar->Get( nOff++ )->GetLong();
		if( nIdx < p->nLbound || nIdx > p->nUbound )
		{
			nPos = (sal_uInt32) SBX_MAXINDEX32+1; break;
		}
		nPos = nPos * p->nSize + nIdx - p->nLbound;
	}
	if( nPos > (sal_uInt32) SBX_MAXINDEX32 )
	{
		SetError( SbxERR_BOUNDS ); nPos = 0;
	}
	return nPos;
}

sal_uInt16 SbxDimArray::Offset( SbxArray* pPar )
{
    sal_uInt32 nPos = Offset32( pPar );
	if( nPos > (long) SBX_MAXINDEX )
	{
		SetError( SbxERR_BOUNDS ); nPos = 0;
	}
	return (sal_uInt16) nPos;
}

SbxVariableRef& SbxDimArray::GetRef( SbxArray* pPar )
{
	return SbxArray::GetRef32( Offset32( pPar ) );
}

SbxVariable* SbxDimArray::Get( SbxArray* pPar )
{
	return SbxArray::Get32( Offset32( pPar ) );
}

void SbxDimArray::Put( SbxVariable* p, SbxArray* pPar  )
{
	SbxArray::Put32( p, Offset32( pPar ) );
}

sal_Bool SbxDimArray::LoadData( SvStream& rStrm, sal_uInt16 nVer )
{
	short nDimension;
	rStrm >> nDimension;
	for( short i = 0; i < nDimension && rStrm.GetError() == SVSTREAM_OK; i++ )
	{
		sal_Int16 lb, ub;
		rStrm >> lb >> ub;
		AddDim( lb, ub );
	}
	return SbxArray::LoadData( rStrm, nVer );
}

sal_Bool SbxDimArray::StoreData( SvStream& rStrm ) const
{
	rStrm << (sal_Int16) nDim;
	for( short i = 0; i < nDim; i++ )
	{
		short lb, ub;
		GetDim( i, lb, ub );
		rStrm << (sal_Int16) lb << (sal_Int16) ub;
	}
	return SbxArray::StoreData( rStrm );
}
