/**************************************************************
 * 
 * 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 );
}

