xref: /aoo42x/main/basic/source/sbx/sbxvalue.cxx (revision 870262e3)
1e1f63238SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3e1f63238SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4e1f63238SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5e1f63238SAndrew Rist  * distributed with this work for additional information
6e1f63238SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7e1f63238SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8e1f63238SAndrew Rist  * "License"); you may not use this file except in compliance
9e1f63238SAndrew Rist  * with the License.  You may obtain a copy of the License at
10e1f63238SAndrew Rist  *
11e1f63238SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12e1f63238SAndrew Rist  *
13e1f63238SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14e1f63238SAndrew Rist  * software distributed under the License is distributed on an
15e1f63238SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16e1f63238SAndrew Rist  * KIND, either express or implied.  See the License for the
17e1f63238SAndrew Rist  * specific language governing permissions and limitations
18e1f63238SAndrew Rist  * under the License.
19e1f63238SAndrew Rist  *
20e1f63238SAndrew Rist  *************************************************************/
21e1f63238SAndrew Rist 
22e1f63238SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_basic.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #define _TLBIGINT_INT64
28cdf0e10cSrcweir #include <tools/bigint.hxx>
29cdf0e10cSrcweir #include <tools/stream.hxx>
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <basic/sbx.hxx>
32cdf0e10cSrcweir #include "sbxconv.hxx"
33cdf0e10cSrcweir #include <math.h>
34cdf0e10cSrcweir #include "runtime.hxx"
35cdf0e10cSrcweir // AB 29.10.99 Unicode
36cdf0e10cSrcweir #ifndef _USE_NO_NAMESPACE
37cdf0e10cSrcweir using namespace rtl;
38cdf0e10cSrcweir #endif
39cdf0e10cSrcweir 
40cdf0e10cSrcweir 
41cdf0e10cSrcweir TYPEINIT1(SbxValue,SbxBase)
42cdf0e10cSrcweir 
43cdf0e10cSrcweir /////////////////////////// SbxINT64 /////////////////////////////////////
44cdf0e10cSrcweir SbxINT64 &SbxINT64::operator -= ( const SbxINT64 &r )
45cdf0e10cSrcweir {
46cdf0e10cSrcweir 	BigInt b( *this );
47cdf0e10cSrcweir 	b -= BigInt( r );
48cdf0e10cSrcweir 	b.INT64( this );
49cdf0e10cSrcweir 	return *this;
50cdf0e10cSrcweir }
operator +=(const SbxINT64 & r)51cdf0e10cSrcweir SbxINT64 &SbxINT64::operator += ( const SbxINT64 &r )
52cdf0e10cSrcweir {
53cdf0e10cSrcweir 	BigInt b( *this );
54cdf0e10cSrcweir 	b += BigInt( r );
55cdf0e10cSrcweir 	b.INT64( this );
56cdf0e10cSrcweir 	return *this;
57cdf0e10cSrcweir }
operator *=(const SbxINT64 & r)58cdf0e10cSrcweir SbxINT64 &SbxINT64::operator *= ( const SbxINT64 &r )
59cdf0e10cSrcweir {
60cdf0e10cSrcweir 	BigInt b( *this );
61cdf0e10cSrcweir 	b *= BigInt( r );
62cdf0e10cSrcweir 	b.INT64( this );
63cdf0e10cSrcweir 	return *this;
64cdf0e10cSrcweir }
operator %=(const SbxINT64 & r)65cdf0e10cSrcweir SbxINT64 &SbxINT64::operator %= ( const SbxINT64 &r )
66cdf0e10cSrcweir {
67cdf0e10cSrcweir 	BigInt b( *this );
68cdf0e10cSrcweir 	b %= BigInt( r );
69cdf0e10cSrcweir 	b.INT64( this );
70cdf0e10cSrcweir 	return *this;
71cdf0e10cSrcweir }
operator /=(const SbxINT64 & r)72cdf0e10cSrcweir SbxINT64 &SbxINT64::operator /= ( const SbxINT64 &r )
73cdf0e10cSrcweir {
74cdf0e10cSrcweir 	BigInt b( *this );
75cdf0e10cSrcweir 	b /= BigInt( r );
76cdf0e10cSrcweir 	b.INT64( this );
77cdf0e10cSrcweir 	return *this;
78cdf0e10cSrcweir }
operator &=(const SbxINT64 & r)79cdf0e10cSrcweir SbxINT64 &SbxINT64::operator &= ( const SbxINT64 &r )
80cdf0e10cSrcweir {
81cdf0e10cSrcweir 	nHigh &= r.nHigh;
82cdf0e10cSrcweir 	nLow  &= r.nLow;
83cdf0e10cSrcweir 	return *this;
84cdf0e10cSrcweir }
operator |=(const SbxINT64 & r)85cdf0e10cSrcweir SbxINT64 &SbxINT64::operator |= ( const SbxINT64 &r )
86cdf0e10cSrcweir {
87cdf0e10cSrcweir 	nHigh |= r.nHigh;
88cdf0e10cSrcweir 	nLow  |= r.nLow;
89cdf0e10cSrcweir 	return *this;
90cdf0e10cSrcweir }
operator ^=(const SbxINT64 & r)91cdf0e10cSrcweir SbxINT64 &SbxINT64::operator ^= ( const SbxINT64 &r )
92cdf0e10cSrcweir {
93cdf0e10cSrcweir 	nHigh ^= r.nHigh;
94cdf0e10cSrcweir 	nLow  ^= r.nLow;
95cdf0e10cSrcweir 	return *this;
96cdf0e10cSrcweir }
97cdf0e10cSrcweir 
operator -(const SbxINT64 & l,const SbxINT64 & r)98cdf0e10cSrcweir SbxINT64 operator - ( const SbxINT64 &l, const SbxINT64 &r )
99cdf0e10cSrcweir {
100cdf0e10cSrcweir 	SbxINT64 a(l);
101cdf0e10cSrcweir 	a -= r;
102cdf0e10cSrcweir 	return a;
103cdf0e10cSrcweir }
operator +(const SbxINT64 & l,const SbxINT64 & r)104cdf0e10cSrcweir SbxINT64 operator + ( const SbxINT64 &l, const SbxINT64 &r )
105cdf0e10cSrcweir {
106cdf0e10cSrcweir 	SbxINT64 a(l);
107cdf0e10cSrcweir 	a += r;
108cdf0e10cSrcweir 	return a;
109cdf0e10cSrcweir }
operator /(const SbxINT64 & l,const SbxINT64 & r)110cdf0e10cSrcweir SbxINT64 operator / ( const SbxINT64 &l, const SbxINT64 &r )
111cdf0e10cSrcweir {
112cdf0e10cSrcweir 	SbxINT64 a(l);
113cdf0e10cSrcweir 	a /= r;
114cdf0e10cSrcweir 	return a;
115cdf0e10cSrcweir }
operator %(const SbxINT64 & l,const SbxINT64 & r)116cdf0e10cSrcweir SbxINT64 operator % ( const SbxINT64 &l, const SbxINT64 &r )
117cdf0e10cSrcweir {
118cdf0e10cSrcweir 	SbxINT64 a(l);
119cdf0e10cSrcweir 	a %= r;
120cdf0e10cSrcweir 	return a;
121cdf0e10cSrcweir }
operator *(const SbxINT64 & l,const SbxINT64 & r)122cdf0e10cSrcweir SbxINT64 operator * ( const SbxINT64 &l, const SbxINT64 &r )
123cdf0e10cSrcweir {
124cdf0e10cSrcweir 	SbxINT64 a(l);
125cdf0e10cSrcweir 	a *= r;
126cdf0e10cSrcweir 	return a;
127cdf0e10cSrcweir }
operator &(const SbxINT64 & l,const SbxINT64 & r)128cdf0e10cSrcweir SbxINT64 operator & ( const SbxINT64 &l, const SbxINT64 &r )
129cdf0e10cSrcweir {
130cdf0e10cSrcweir 	SbxINT64 a;
131cdf0e10cSrcweir 	a.nHigh = r.nHigh & l.nHigh;
132cdf0e10cSrcweir 	a.nLow  = r.nLow  & l.nLow;
133cdf0e10cSrcweir 	return a;
134cdf0e10cSrcweir }
operator |(const SbxINT64 & l,const SbxINT64 & r)135cdf0e10cSrcweir SbxINT64 operator | ( const SbxINT64 &l, const SbxINT64 &r )
136cdf0e10cSrcweir {
137cdf0e10cSrcweir 	SbxINT64 a;
138cdf0e10cSrcweir 	a.nHigh = r.nHigh | l.nHigh;
139cdf0e10cSrcweir 	a.nLow  = r.nLow  | l.nLow;
140cdf0e10cSrcweir 	return a;
141cdf0e10cSrcweir }
operator ^(const SbxINT64 & r,const SbxINT64 & l)142cdf0e10cSrcweir SbxINT64 operator ^ ( const SbxINT64 &r, const SbxINT64 &l )
143cdf0e10cSrcweir {
144cdf0e10cSrcweir 	SbxINT64 a;
145cdf0e10cSrcweir 	a.nHigh = r.nHigh ^ l.nHigh;
146cdf0e10cSrcweir 	a.nLow  = r.nLow  ^ l.nLow;
147cdf0e10cSrcweir 	return a;
148cdf0e10cSrcweir }
149cdf0e10cSrcweir 
operator -(const SbxINT64 & r)150cdf0e10cSrcweir SbxINT64 operator - ( const SbxINT64 &r )
151cdf0e10cSrcweir {
152cdf0e10cSrcweir 	SbxINT64 a( r );
153cdf0e10cSrcweir 	a.CHS();
154cdf0e10cSrcweir 	return a;
155cdf0e10cSrcweir }
operator ~(const SbxINT64 & r)156cdf0e10cSrcweir SbxINT64 operator ~ ( const SbxINT64 &r )
157cdf0e10cSrcweir {
158cdf0e10cSrcweir 	SbxINT64 a;
159cdf0e10cSrcweir 	a.nHigh = ~r.nHigh;
160cdf0e10cSrcweir 	a.nLow  = ~r.nLow;
161cdf0e10cSrcweir 	return a;
162cdf0e10cSrcweir }
163cdf0e10cSrcweir 
operator %=(const SbxUINT64 & r)164cdf0e10cSrcweir SbxUINT64 &SbxUINT64::operator %= ( const SbxUINT64 &r )
165cdf0e10cSrcweir {
166cdf0e10cSrcweir 	BigInt b( *this );
167cdf0e10cSrcweir 	b %= BigInt( r );
168cdf0e10cSrcweir 	b.UINT64( this );
169cdf0e10cSrcweir 	return *this;
170cdf0e10cSrcweir }
operator /=(const SbxUINT64 & r)171cdf0e10cSrcweir SbxUINT64 &SbxUINT64::operator /= ( const SbxUINT64 &r )
172cdf0e10cSrcweir {
173cdf0e10cSrcweir 	BigInt b( *this );
174cdf0e10cSrcweir 	b /= BigInt( r );
175cdf0e10cSrcweir 	b.UINT64( this );
176cdf0e10cSrcweir 	return *this;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir /////////////////////////// Fehlerbehandlung /////////////////////////////
179cdf0e10cSrcweir 
180cdf0e10cSrcweir #ifdef _USED
181cdf0e10cSrcweir // NOCH NACHZUBAUEN!
182cdf0e10cSrcweir 
183cdf0e10cSrcweir // Das Default-Handling setzt nur den Fehlercode.
184cdf0e10cSrcweir 
185cdf0e10cSrcweir #ifndef WNT
186cdf0e10cSrcweir #if defined ( UNX )
matherr(struct exception * p)187cdf0e10cSrcweir int matherr( struct exception* p )
188cdf0e10cSrcweir #else
189cdf0e10cSrcweir int matherr( struct _exception* p )
190cdf0e10cSrcweir #endif
191cdf0e10cSrcweir {
192cdf0e10cSrcweir 	switch( p->type )
193cdf0e10cSrcweir 	{
194cdf0e10cSrcweir #if defined ( UNX )
195cdf0e10cSrcweir 		case OVERFLOW: SbxBase::SetError( SbxERR_OVERFLOW ); break;
196cdf0e10cSrcweir #else
197cdf0e10cSrcweir 		case _OVERFLOW: SbxBase::SetError( SbxERR_OVERFLOW ); break;
198cdf0e10cSrcweir #endif
199cdf0e10cSrcweir 		default:		SbxBase::SetError( SbxERR_NOTIMP ); break;
200cdf0e10cSrcweir 	}
201cdf0e10cSrcweir 	return sal_True;
202cdf0e10cSrcweir }
203cdf0e10cSrcweir #endif
204cdf0e10cSrcweir 
205cdf0e10cSrcweir #endif // _USED
206cdf0e10cSrcweir 
207cdf0e10cSrcweir 
208cdf0e10cSrcweir ///////////////////////////// Konstruktoren //////////////////////////////
209cdf0e10cSrcweir 
SbxValue()210cdf0e10cSrcweir SbxValue::SbxValue() : SbxBase()
211cdf0e10cSrcweir {
212cdf0e10cSrcweir 	aData.eType = SbxEMPTY;
213cdf0e10cSrcweir }
214cdf0e10cSrcweir 
SbxValue(SbxDataType t,void * p)215cdf0e10cSrcweir SbxValue::SbxValue( SbxDataType t, void* p ) : SbxBase()
216cdf0e10cSrcweir {
217cdf0e10cSrcweir 	int n = t & 0x0FFF;
218cdf0e10cSrcweir 	if( p )
219cdf0e10cSrcweir 		n |= SbxBYREF;
220cdf0e10cSrcweir 	if( n == SbxVARIANT )
221cdf0e10cSrcweir 		n = SbxEMPTY;
222cdf0e10cSrcweir 	else
223cdf0e10cSrcweir 		SetFlag( SBX_FIXED );
224cdf0e10cSrcweir 	if( p )
225cdf0e10cSrcweir 	switch( t & 0x0FFF )
226cdf0e10cSrcweir 	{
227cdf0e10cSrcweir 		case SbxINTEGER:	n |= SbxBYREF; aData.pInteger = (sal_Int16*) p; break;
228cdf0e10cSrcweir 		case SbxULONG64:	n |= SbxBYREF; aData.pULong64 = (SbxUINT64*) p; break;
229cdf0e10cSrcweir 		case SbxLONG64:
230cdf0e10cSrcweir 		case SbxCURRENCY:	n |= SbxBYREF; aData.pLong64 = (SbxINT64*) p; break;
231cdf0e10cSrcweir 		case SbxLONG:		n |= SbxBYREF; aData.pLong = (sal_Int32*) p; break;
232cdf0e10cSrcweir 		case SbxSINGLE:		n |= SbxBYREF; aData.pSingle = (float*) p; break;
233cdf0e10cSrcweir 		case SbxDATE:
234cdf0e10cSrcweir 		case SbxDOUBLE:		n |= SbxBYREF; aData.pDouble = (double*) p; break;
235cdf0e10cSrcweir         case SbxSTRING:		n |= SbxBYREF; aData.pOUString = (::rtl::OUString*) p; break;
236cdf0e10cSrcweir 		case SbxERROR:
237cdf0e10cSrcweir 		case SbxUSHORT:
238cdf0e10cSrcweir 		case SbxBOOL:		n |= SbxBYREF; aData.pUShort = (sal_uInt16*) p; break;
239cdf0e10cSrcweir 		case SbxULONG:		n |= SbxBYREF; aData.pULong = (sal_uInt32*) p; break;
240cdf0e10cSrcweir 		case SbxCHAR:		n |= SbxBYREF; aData.pChar = (xub_Unicode*) p; break;
241cdf0e10cSrcweir 		case SbxBYTE:		n |= SbxBYREF; aData.pByte = (sal_uInt8*) p; break;
242cdf0e10cSrcweir 		case SbxINT:		n |= SbxBYREF; aData.pInt = (int*) p; break;
243cdf0e10cSrcweir 		case SbxOBJECT:
244cdf0e10cSrcweir 			aData.pObj = (SbxBase*) p;
245cdf0e10cSrcweir 			if( p )
246cdf0e10cSrcweir 				aData.pObj->AddRef();
247cdf0e10cSrcweir 			break;
248cdf0e10cSrcweir 		case SbxDECIMAL:
249cdf0e10cSrcweir 			aData.pDecimal = (SbxDecimal*) p;
250cdf0e10cSrcweir 			if( p )
251cdf0e10cSrcweir 				aData.pDecimal->addRef();
252cdf0e10cSrcweir 			break;
253cdf0e10cSrcweir 		default:
254*870262e3SDon Lewis 			DBG_ASSERT( sal_False, "Indication of an invalid pointer" );
255cdf0e10cSrcweir 			n = SbxNULL;
256cdf0e10cSrcweir 	}
257cdf0e10cSrcweir 	else
258cdf0e10cSrcweir 		memset( &aData, 0, sizeof( SbxValues ) );
259cdf0e10cSrcweir 	aData.eType = SbxDataType( n );
260cdf0e10cSrcweir }
261cdf0e10cSrcweir 
SbxValue(const SbxValue & r)262cdf0e10cSrcweir SbxValue::SbxValue( const SbxValue& r )
263cdf0e10cSrcweir     : SvRefBase( r ), SbxBase( r )
264cdf0e10cSrcweir {
265cdf0e10cSrcweir 	if( !r.CanRead() )
266cdf0e10cSrcweir 	{
267cdf0e10cSrcweir 		SetError( SbxERR_PROP_WRITEONLY );
268cdf0e10cSrcweir 		if( !IsFixed() )
269cdf0e10cSrcweir 			aData.eType = SbxNULL;
270cdf0e10cSrcweir 	}
271cdf0e10cSrcweir 	else
272cdf0e10cSrcweir 	{
273cdf0e10cSrcweir 		((SbxValue*) &r)->Broadcast( SBX_HINT_DATAWANTED );
274cdf0e10cSrcweir 		aData = r.aData;
275cdf0e10cSrcweir 		// Pointer kopieren, Referenzen inkrementieren
276cdf0e10cSrcweir 		switch( aData.eType )
277cdf0e10cSrcweir 		{
278cdf0e10cSrcweir 			case SbxSTRING:
279cdf0e10cSrcweir 				if( aData.pOUString )
280cdf0e10cSrcweir 					aData.pOUString = new ::rtl::OUString( *aData.pOUString );
281cdf0e10cSrcweir 				break;
282cdf0e10cSrcweir 			case SbxOBJECT:
283cdf0e10cSrcweir 				if( aData.pObj )
284cdf0e10cSrcweir 					aData.pObj->AddRef();
285cdf0e10cSrcweir 				break;
286cdf0e10cSrcweir 			case SbxDECIMAL:
287cdf0e10cSrcweir 				if( aData.pDecimal )
288cdf0e10cSrcweir 					aData.pDecimal->addRef();
289cdf0e10cSrcweir 				break;
290cdf0e10cSrcweir 			default: break;
291cdf0e10cSrcweir 		}
292cdf0e10cSrcweir 	}
293cdf0e10cSrcweir }
294cdf0e10cSrcweir 
operator =(const SbxValue & r)295cdf0e10cSrcweir SbxValue& SbxValue::operator=( const SbxValue& r )
296cdf0e10cSrcweir {
297cdf0e10cSrcweir 	if( &r != this )
298cdf0e10cSrcweir 	{
299cdf0e10cSrcweir 		if( !CanWrite() )
300cdf0e10cSrcweir 			SetError( SbxERR_PROP_READONLY );
301cdf0e10cSrcweir 		else
302cdf0e10cSrcweir 		{
303cdf0e10cSrcweir 			// string -> byte array
304cdf0e10cSrcweir 			if( IsFixed() && (aData.eType == SbxOBJECT)
305cdf0e10cSrcweir 				&& aData.pObj && ( aData.pObj->GetType() == (SbxARRAY | SbxBYTE) )
306cdf0e10cSrcweir 				&& (r.aData.eType == SbxSTRING) )
307cdf0e10cSrcweir 			{
308cdf0e10cSrcweir 				::rtl::OUString aStr = r.GetString();
309cdf0e10cSrcweir 				SbxArray* pArr = StringToByteArray(aStr);
310cdf0e10cSrcweir 				PutObject(pArr);
311cdf0e10cSrcweir 				return *this;
312cdf0e10cSrcweir 			}
313cdf0e10cSrcweir 			// byte array -> string
314cdf0e10cSrcweir 			if( r.IsFixed() && (r.aData.eType == SbxOBJECT)
315cdf0e10cSrcweir 				&& r.aData.pObj && ( r.aData.pObj->GetType() == (SbxARRAY | SbxBYTE) )
316cdf0e10cSrcweir 				&& (aData.eType == SbxSTRING) )
317cdf0e10cSrcweir 			{
318cdf0e10cSrcweir 				SbxBase* pObj = r.GetObject();
319cdf0e10cSrcweir 				SbxArray* pArr = PTR_CAST(SbxArray, pObj);
320cdf0e10cSrcweir 				if( pArr )
321cdf0e10cSrcweir 				{
322cdf0e10cSrcweir 					::rtl::OUString aStr = ByteArrayToString( pArr );
323cdf0e10cSrcweir 					PutString(aStr);
324cdf0e10cSrcweir 					return *this;
325cdf0e10cSrcweir 				}
326cdf0e10cSrcweir 			}
327cdf0e10cSrcweir 			// Den Inhalt der Variablen auslesen
328cdf0e10cSrcweir 			SbxValues aNew;
329cdf0e10cSrcweir 			if( IsFixed() )
330cdf0e10cSrcweir 				// fest: dann muss der Typ stimmen
331cdf0e10cSrcweir 				aNew.eType = aData.eType;
332cdf0e10cSrcweir 			else if( r.IsFixed() )
333cdf0e10cSrcweir 				// Quelle fest: Typ uebernehmen
334cdf0e10cSrcweir 				aNew.eType = SbxDataType( r.aData.eType & 0x0FFF );
335cdf0e10cSrcweir 			else
336cdf0e10cSrcweir 				// beides Variant: dann isses egal
337cdf0e10cSrcweir 				aNew.eType = SbxVARIANT;
338cdf0e10cSrcweir 			if( r.Get( aNew ) )
339cdf0e10cSrcweir 				Put( aNew );
340cdf0e10cSrcweir 		}
341cdf0e10cSrcweir 	}
342cdf0e10cSrcweir 	return *this;
343cdf0e10cSrcweir }
344cdf0e10cSrcweir 
~SbxValue()345cdf0e10cSrcweir SbxValue::~SbxValue()
346cdf0e10cSrcweir {
347cdf0e10cSrcweir #ifndef C50
348cdf0e10cSrcweir 	Broadcast( SBX_HINT_DYING );
349cdf0e10cSrcweir 	SetFlag( SBX_WRITE );
350cdf0e10cSrcweir 	SbxValue::Clear();
351cdf0e10cSrcweir #else
352cdf0e10cSrcweir 	// Provisorischer Fix fuer Solaris 5.0 Compiler Bug
353cdf0e10cSrcweir 	// bei Nutzung virtueller Vererbung. Virtuelle Calls
354cdf0e10cSrcweir 	// im Destruktor vermeiden. Statt Clear() zu rufen
355cdf0e10cSrcweir 	// moegliche Objekt-Referenzen direkt freigeben.
356cdf0e10cSrcweir 	if( aData.eType == SbxOBJECT )
357cdf0e10cSrcweir 	{
358cdf0e10cSrcweir 		if( aData.pObj && aData.pObj != this )
359cdf0e10cSrcweir 		{
360cdf0e10cSrcweir 			HACK(nicht bei Parent-Prop - sonst CyclicRef)
361cdf0e10cSrcweir 			SbxVariable *pThisVar = PTR_CAST(SbxVariable, this);
362cdf0e10cSrcweir 			sal_Bool bParentProp = pThisVar && 5345 ==
363cdf0e10cSrcweir 			( (sal_Int16) ( pThisVar->GetUserData() & 0xFFFF ) );
364cdf0e10cSrcweir 			if ( !bParentProp )
365cdf0e10cSrcweir 				aData.pObj->ReleaseRef();
366cdf0e10cSrcweir 		}
367cdf0e10cSrcweir 	}
368cdf0e10cSrcweir 	else if( aData.eType == SbxDECIMAL )
369cdf0e10cSrcweir 	{
370cdf0e10cSrcweir 		releaseDecimalPtr( aData.pDecimal );
371cdf0e10cSrcweir 	}
372cdf0e10cSrcweir #endif
373cdf0e10cSrcweir }
374cdf0e10cSrcweir 
Clear()375cdf0e10cSrcweir void SbxValue::Clear()
376cdf0e10cSrcweir {
377cdf0e10cSrcweir 	switch( aData.eType )
378cdf0e10cSrcweir 	{
379cdf0e10cSrcweir 		case SbxNULL:
380cdf0e10cSrcweir 		case SbxEMPTY:
381cdf0e10cSrcweir 		case SbxVOID:
382cdf0e10cSrcweir 			break;
383cdf0e10cSrcweir 		case SbxSTRING:
384cdf0e10cSrcweir 			delete aData.pOUString; aData.pOUString = NULL;
385cdf0e10cSrcweir 			break;
386cdf0e10cSrcweir 		case SbxOBJECT:
387cdf0e10cSrcweir 			if( aData.pObj )
388cdf0e10cSrcweir 			{
389cdf0e10cSrcweir 				if( aData.pObj != this )
390cdf0e10cSrcweir 				{
391cdf0e10cSrcweir 					HACK(nicht bei Parent-Prop - sonst CyclicRef)
392cdf0e10cSrcweir 					SbxVariable *pThisVar = PTR_CAST(SbxVariable, this);
393cdf0e10cSrcweir 					sal_Bool bParentProp = pThisVar && 5345 ==
394cdf0e10cSrcweir 					( (sal_Int16) ( pThisVar->GetUserData() & 0xFFFF ) );
395cdf0e10cSrcweir 					if ( !bParentProp )
396cdf0e10cSrcweir 						aData.pObj->ReleaseRef();
397cdf0e10cSrcweir 				}
398cdf0e10cSrcweir 				aData.pObj = NULL;
399cdf0e10cSrcweir 			}
400cdf0e10cSrcweir 			break;
401cdf0e10cSrcweir 		case SbxDECIMAL:
402cdf0e10cSrcweir 			if( aData.eType == SbxDECIMAL )
403cdf0e10cSrcweir 				releaseDecimalPtr( aData.pDecimal );
404cdf0e10cSrcweir 			break;
405cdf0e10cSrcweir 		case SbxDATAOBJECT:
406cdf0e10cSrcweir 			aData.pData = NULL; break;
407cdf0e10cSrcweir 		default:
408cdf0e10cSrcweir 		{
409cdf0e10cSrcweir 			SbxValues aEmpty;
410cdf0e10cSrcweir 			memset( &aEmpty, 0, sizeof( SbxValues ) );
411cdf0e10cSrcweir 			aEmpty.eType = GetType();
412cdf0e10cSrcweir 			Put( aEmpty );
413cdf0e10cSrcweir 		}
414cdf0e10cSrcweir 	}
415cdf0e10cSrcweir }
416cdf0e10cSrcweir 
417cdf0e10cSrcweir // Dummy
418cdf0e10cSrcweir 
Broadcast(sal_uIntPtr)419cdf0e10cSrcweir void SbxValue::Broadcast( sal_uIntPtr )
420cdf0e10cSrcweir {}
421cdf0e10cSrcweir 
422cdf0e10cSrcweir //////////////////////////// Daten auslesen //////////////////////////////
423cdf0e10cSrcweir 
424cdf0e10cSrcweir // Ermitteln der "richtigen" Variablen. Falls es ein Objekt ist, wird
425cdf0e10cSrcweir // entweder das Objekt selbst oder dessen Default-Property angesprochen.
426cdf0e10cSrcweir // Falls die Variable eine Variable oder ein Objekt enthaelt, wird
427cdf0e10cSrcweir // dieses angesprochen.
428cdf0e10cSrcweir 
TheRealValue() const429cdf0e10cSrcweir SbxValue* SbxValue::TheRealValue() const
430cdf0e10cSrcweir {
431cdf0e10cSrcweir 	return TheRealValue( sal_True );
432cdf0e10cSrcweir }
433cdf0e10cSrcweir 
434cdf0e10cSrcweir // #55226 Zusaetzliche Info transportieren
435cdf0e10cSrcweir bool handleToStringForCOMObjects( SbxObject* pObj, SbxValue* pVal );	// sbunoobj.cxx
436cdf0e10cSrcweir 
TheRealValue(sal_Bool bObjInObjError) const437cdf0e10cSrcweir SbxValue* SbxValue::TheRealValue( sal_Bool bObjInObjError ) const
438cdf0e10cSrcweir {
439cdf0e10cSrcweir 	SbxValue* p = (SbxValue*) this;
440cdf0e10cSrcweir 	for( ;; )
441cdf0e10cSrcweir 	{
442cdf0e10cSrcweir 		SbxDataType t = SbxDataType( p->aData.eType & 0x0FFF );
443cdf0e10cSrcweir 		if( t == SbxOBJECT )
444cdf0e10cSrcweir 		{
445cdf0e10cSrcweir 			// Der Block enthaelt ein Objekt oder eine Variable
446cdf0e10cSrcweir 			SbxObject* pObj = PTR_CAST(SbxObject,p->aData.pObj);
447cdf0e10cSrcweir 			if( pObj )
448cdf0e10cSrcweir 			{
449cdf0e10cSrcweir 				// Hat das Objekt eine Default-Property?
450cdf0e10cSrcweir 				SbxVariable* pDflt = pObj->GetDfltProperty();
451cdf0e10cSrcweir 
452cdf0e10cSrcweir 				// Falls dies ein Objekt ist und sich selbst enthaelt,
453cdf0e10cSrcweir 				// koennen wir nicht darauf zugreifen
454cdf0e10cSrcweir 				// #55226# Die alte Bedingung, um einen Fehler zu setzen,
455cdf0e10cSrcweir 				// ist nicht richtig, da z.B. eine ganz normale Variant-
456cdf0e10cSrcweir 				// Variable mit Objekt davon betroffen sein kann, wenn ein
457cdf0e10cSrcweir 				// anderer Wert zugewiesen werden soll. Daher mit Flag.
458cdf0e10cSrcweir 				if( bObjInObjError && !pDflt &&
459cdf0e10cSrcweir 					((SbxValue*) pObj)->aData.eType == SbxOBJECT &&
460cdf0e10cSrcweir 					((SbxValue*) pObj)->aData.pObj == pObj )
461cdf0e10cSrcweir 				{
462cdf0e10cSrcweir 					bool bSuccess = handleToStringForCOMObjects( pObj, p );
463cdf0e10cSrcweir 					if( !bSuccess )
464cdf0e10cSrcweir 					{
465cdf0e10cSrcweir 						SetError( SbxERR_BAD_PROP_VALUE );
466cdf0e10cSrcweir 						p = NULL;
467cdf0e10cSrcweir 					}
468cdf0e10cSrcweir 				}
469cdf0e10cSrcweir 				else if( pDflt )
470cdf0e10cSrcweir 					p = pDflt;
471cdf0e10cSrcweir 				/* ALT:
472cdf0e10cSrcweir 				else
473cdf0e10cSrcweir 					p = pDflt ? pDflt : (SbxVariable*) pObj;
474cdf0e10cSrcweir 				*/
475cdf0e10cSrcweir 				break;
476cdf0e10cSrcweir 			}
477cdf0e10cSrcweir 			// Haben wir ein Array?
478cdf0e10cSrcweir 			SbxArray* pArray = PTR_CAST(SbxArray,p->aData.pObj);
479cdf0e10cSrcweir 			if( pArray )
480cdf0e10cSrcweir 			{
481cdf0e10cSrcweir 				// Ggf. Parameter holen
482cdf0e10cSrcweir 				SbxArray* pPar = NULL;
483cdf0e10cSrcweir 				SbxVariable* pVar = PTR_CAST(SbxVariable,p);
484cdf0e10cSrcweir 				if( pVar )
485cdf0e10cSrcweir 					pPar = pVar->GetParameters();
486cdf0e10cSrcweir 				if( pPar )
487cdf0e10cSrcweir 				{
488cdf0e10cSrcweir 					// Haben wir ein dimensioniertes Array?
489cdf0e10cSrcweir 					SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,p->aData.pObj);
490cdf0e10cSrcweir 					if( pDimArray )
491cdf0e10cSrcweir 						p = pDimArray->Get( pPar );
492cdf0e10cSrcweir 					else
493cdf0e10cSrcweir 						p = pArray->Get( pPar->Get( 1 )->GetInteger() );
494cdf0e10cSrcweir 					break;
495cdf0e10cSrcweir 				}
496cdf0e10cSrcweir 			}
497cdf0e10cSrcweir 			// Sonst einen SbxValue annehmen
498cdf0e10cSrcweir 			SbxValue* pVal = PTR_CAST(SbxValue,p->aData.pObj);
499cdf0e10cSrcweir 			if( pVal )
500cdf0e10cSrcweir 				p = pVal;
501cdf0e10cSrcweir 			else
502cdf0e10cSrcweir 				break;
503cdf0e10cSrcweir 		}
504cdf0e10cSrcweir 		else
505cdf0e10cSrcweir 			break;
506cdf0e10cSrcweir 	}
507cdf0e10cSrcweir 	return p;
508cdf0e10cSrcweir }
509cdf0e10cSrcweir 
Get(SbxValues & rRes) const510cdf0e10cSrcweir sal_Bool SbxValue::Get( SbxValues& rRes ) const
511cdf0e10cSrcweir {
512cdf0e10cSrcweir 	sal_Bool bRes = sal_False;
513cdf0e10cSrcweir 	SbxError eOld = GetError();
514cdf0e10cSrcweir 	if( eOld != SbxERR_OK )
515cdf0e10cSrcweir 		ResetError();
516cdf0e10cSrcweir 	if( !CanRead() )
517cdf0e10cSrcweir 	{
518cdf0e10cSrcweir 		SetError( SbxERR_PROP_WRITEONLY );
519cdf0e10cSrcweir 		rRes.pObj = NULL;
520cdf0e10cSrcweir 	}
521cdf0e10cSrcweir 	else
522cdf0e10cSrcweir 	{
523cdf0e10cSrcweir 		// Falls nach einem Objekt oder einem VARIANT gefragt wird, nicht
524cdf0e10cSrcweir 		// die wahren Werte suchen
525cdf0e10cSrcweir 		SbxValue* p = (SbxValue*) this;
526cdf0e10cSrcweir 		if( rRes.eType != SbxOBJECT && rRes.eType != SbxVARIANT )
527cdf0e10cSrcweir 			p = TheRealValue();
528cdf0e10cSrcweir 		if( p )
529cdf0e10cSrcweir 		{
530cdf0e10cSrcweir 			p->Broadcast( SBX_HINT_DATAWANTED );
531cdf0e10cSrcweir 			switch( rRes.eType )
532cdf0e10cSrcweir 			{
533cdf0e10cSrcweir 				case SbxEMPTY:
534cdf0e10cSrcweir 				case SbxVOID:
535cdf0e10cSrcweir 				case SbxNULL:	 break;
536cdf0e10cSrcweir 				case SbxVARIANT: rRes = p->aData; break;
537cdf0e10cSrcweir 				case SbxINTEGER: rRes.nInteger = ImpGetInteger( &p->aData ); break;
538cdf0e10cSrcweir 				case SbxLONG:	 rRes.nLong = ImpGetLong( &p->aData ); break;
539cdf0e10cSrcweir 				case SbxSALINT64:	rRes.nInt64 = ImpGetInt64( &p->aData ); break;
540cdf0e10cSrcweir 				case SbxSALUINT64:	rRes.uInt64 = ImpGetUInt64( &p->aData ); break;
541cdf0e10cSrcweir 				case SbxSINGLE:	 rRes.nSingle = ImpGetSingle( &p->aData ); break;
542cdf0e10cSrcweir 				case SbxDOUBLE:	 rRes.nDouble = ImpGetDouble( &p->aData ); break;
543cdf0e10cSrcweir 				case SbxCURRENCY:rRes.nLong64 = ImpGetCurrency( &p->aData ); break;
544cdf0e10cSrcweir 				case SbxDECIMAL: rRes.pDecimal = ImpGetDecimal( &p->aData ); break;
545cdf0e10cSrcweir 				case SbxDATE:	 rRes.nDouble = ImpGetDate( &p->aData ); break;
546cdf0e10cSrcweir 				case SbxBOOL:
547cdf0e10cSrcweir                     rRes.nUShort = sal::static_int_cast< sal_uInt16 >(
548cdf0e10cSrcweir                         ImpGetBool( &p->aData ) );
549cdf0e10cSrcweir                     break;
550cdf0e10cSrcweir 				case SbxCHAR:	 rRes.nChar = ImpGetChar( &p->aData ); break;
551cdf0e10cSrcweir 				case SbxBYTE:	 rRes.nByte = ImpGetByte( &p->aData ); break;
552cdf0e10cSrcweir 				case SbxUSHORT:	 rRes.nUShort = ImpGetUShort( &p->aData ); break;
553cdf0e10cSrcweir 				case SbxULONG:	 rRes.nULong = ImpGetULong( &p->aData ); break;
554cdf0e10cSrcweir 				case SbxLPSTR:
555cdf0e10cSrcweir 				case SbxSTRING:	 p->aPic = ImpGetString( &p->aData );
556cdf0e10cSrcweir 								 rRes.pOUString = &p->aPic; break;
557cdf0e10cSrcweir 				case SbxCoreSTRING:	p->aPic = ImpGetCoreString( &p->aData );
558cdf0e10cSrcweir 									rRes.pOUString = &p->aPic; break;
559cdf0e10cSrcweir 				case SbxINT:
560cdf0e10cSrcweir #if SAL_TYPES_SIZEOFINT == 2
561cdf0e10cSrcweir 					rRes.nInt = (int) ImpGetInteger( &p->aData );
562cdf0e10cSrcweir #else
563cdf0e10cSrcweir 					rRes.nInt = (int) ImpGetLong( &p->aData );
564cdf0e10cSrcweir #endif
565cdf0e10cSrcweir 					break;
566cdf0e10cSrcweir 				case SbxUINT:
567cdf0e10cSrcweir #if SAL_TYPES_SIZEOFINT == 2
568cdf0e10cSrcweir 					rRes.nUInt = (int) ImpGetUShort( &p->aData );
569cdf0e10cSrcweir #else
570cdf0e10cSrcweir 					rRes.nUInt = (int) ImpGetULong( &p->aData );
571cdf0e10cSrcweir #endif
572cdf0e10cSrcweir 					break;
573cdf0e10cSrcweir 				case SbxOBJECT:
574cdf0e10cSrcweir 					if( p->aData.eType == SbxOBJECT )
575cdf0e10cSrcweir 						rRes.pObj = p->aData.pObj;
576cdf0e10cSrcweir 					else
577cdf0e10cSrcweir 					{
578cdf0e10cSrcweir 						SetError( SbxERR_NO_OBJECT );
579cdf0e10cSrcweir 						rRes.pObj = NULL;
580cdf0e10cSrcweir 					}
581cdf0e10cSrcweir 					break;
582cdf0e10cSrcweir 				default:
583cdf0e10cSrcweir 					if( p->aData.eType == rRes.eType )
584cdf0e10cSrcweir 						rRes = p->aData;
585cdf0e10cSrcweir 					else
586cdf0e10cSrcweir 					{
587cdf0e10cSrcweir 						SetError( SbxERR_CONVERSION );
588cdf0e10cSrcweir 						rRes.pObj = NULL;
589cdf0e10cSrcweir 					}
590cdf0e10cSrcweir 			}
591cdf0e10cSrcweir 		}
592cdf0e10cSrcweir 		else
593cdf0e10cSrcweir 		{
594cdf0e10cSrcweir 			// Objekt enthielt sich selbst
595cdf0e10cSrcweir 			SbxDataType eTemp = rRes.eType;
596cdf0e10cSrcweir 			memset( &rRes, 0, sizeof( SbxValues ) );
597cdf0e10cSrcweir 			rRes.eType = eTemp;
598cdf0e10cSrcweir 		}
599cdf0e10cSrcweir 	}
600cdf0e10cSrcweir 	if( !IsError() )
601cdf0e10cSrcweir 	{
602cdf0e10cSrcweir 		bRes = sal_True;
603cdf0e10cSrcweir 		if( eOld != SbxERR_OK )
604cdf0e10cSrcweir 			SetError( eOld );
605cdf0e10cSrcweir 	}
606cdf0e10cSrcweir 	return bRes;
607cdf0e10cSrcweir }
608cdf0e10cSrcweir 
GetNoBroadcast(SbxValues & rRes)609cdf0e10cSrcweir sal_Bool SbxValue::GetNoBroadcast( SbxValues& rRes )
610cdf0e10cSrcweir {
611cdf0e10cSrcweir 	sal_uInt16 nFlags_ = GetFlags();
612cdf0e10cSrcweir 	SetFlag( SBX_NO_BROADCAST );
613cdf0e10cSrcweir 	sal_Bool bRes = Get( rRes );
614cdf0e10cSrcweir 	SetFlags( nFlags_ );
615cdf0e10cSrcweir 	return bRes;
616cdf0e10cSrcweir }
617cdf0e10cSrcweir 
GetString() const618cdf0e10cSrcweir const XubString& SbxValue::GetString() const
619cdf0e10cSrcweir {
620cdf0e10cSrcweir 	SbxValues aRes;
621cdf0e10cSrcweir 	aRes.eType = SbxSTRING;
622cdf0e10cSrcweir 	if( Get( aRes ) )
623cdf0e10cSrcweir 		((SbxValue*) this)->aToolString = *aRes.pOUString;
624cdf0e10cSrcweir 	else
625cdf0e10cSrcweir 		((SbxValue*) this)->aToolString.Erase();
626cdf0e10cSrcweir 
627cdf0e10cSrcweir     return aToolString;
628cdf0e10cSrcweir }
629cdf0e10cSrcweir 
GetCoreString() const630cdf0e10cSrcweir const XubString& SbxValue::GetCoreString() const
631cdf0e10cSrcweir {
632cdf0e10cSrcweir 	SbxValues aRes;
633cdf0e10cSrcweir 	aRes.eType = SbxCoreSTRING;
634cdf0e10cSrcweir 	if( Get( aRes ) )
635cdf0e10cSrcweir 		((SbxValue*) this)->aToolString = *aRes.pOUString;
636cdf0e10cSrcweir 	else
637cdf0e10cSrcweir 		((SbxValue*) this)->aToolString.Erase();
638cdf0e10cSrcweir 
639cdf0e10cSrcweir     return aToolString;
640cdf0e10cSrcweir }
641cdf0e10cSrcweir 
GetOUString() const642cdf0e10cSrcweir ::rtl::OUString SbxValue::GetOUString() const
643cdf0e10cSrcweir {
644cdf0e10cSrcweir     ::rtl::OUString aResult;
645cdf0e10cSrcweir     SbxValues aRes;
646cdf0e10cSrcweir     aRes.eType = SbxSTRING;
647cdf0e10cSrcweir     if( Get( aRes ) )
648cdf0e10cSrcweir         aResult = *aRes.pOUString;
649cdf0e10cSrcweir 
650cdf0e10cSrcweir     return aResult;
651cdf0e10cSrcweir }
652cdf0e10cSrcweir 
HasObject() const653cdf0e10cSrcweir sal_Bool SbxValue::HasObject() const
654cdf0e10cSrcweir {
655cdf0e10cSrcweir 	ErrCode eErr = GetError();
656cdf0e10cSrcweir 	SbxValues aRes;
657cdf0e10cSrcweir 	aRes.eType = SbxOBJECT;
658cdf0e10cSrcweir 	Get( aRes );
659cdf0e10cSrcweir 	SetError( eErr );
660cdf0e10cSrcweir 	return 0 != aRes.pObj;
661cdf0e10cSrcweir }
662cdf0e10cSrcweir 
GetBool() const663cdf0e10cSrcweir sal_Bool SbxValue::GetBool() const
664cdf0e10cSrcweir {
665cdf0e10cSrcweir 	SbxValues aRes;
666cdf0e10cSrcweir 	aRes.eType = SbxBOOL;
667cdf0e10cSrcweir 	Get( aRes );
668cdf0e10cSrcweir 	return sal_Bool( aRes.nUShort != 0 );
669cdf0e10cSrcweir }
670cdf0e10cSrcweir 
671cdf0e10cSrcweir #define GET( g, e, t, m ) \
672cdf0e10cSrcweir t SbxValue::g() const { SbxValues aRes(e); Get( aRes ); return aRes.m; }
673cdf0e10cSrcweir 
GET(GetByte,SbxBYTE,sal_uInt8,nByte)674cdf0e10cSrcweir GET( GetByte,     SbxBYTE,       sal_uInt8,             nByte )
675cdf0e10cSrcweir GET( GetChar,     SbxCHAR,       xub_Unicode,           nChar )
676cdf0e10cSrcweir GET( GetCurrency, SbxCURRENCY,   SbxINT64,         nLong64 )
677cdf0e10cSrcweir GET( GetDate,     SbxDATE,       double,           nDouble )
678cdf0e10cSrcweir GET( GetData,     SbxDATAOBJECT, void*,            pData )
679cdf0e10cSrcweir GET( GetDouble,   SbxDOUBLE,     double,           nDouble )
680cdf0e10cSrcweir GET( GetErr,      SbxERROR,      sal_uInt16,           nUShort )
681cdf0e10cSrcweir GET( GetInt,      SbxINT,        int,              nInt )
682cdf0e10cSrcweir GET( GetInteger,  SbxINTEGER,    sal_Int16,            nInteger )
683cdf0e10cSrcweir GET( GetLong,     SbxLONG,       sal_Int32,            nLong )
684cdf0e10cSrcweir GET( GetLong64,   SbxLONG64,     SbxINT64,         nLong64 )
685cdf0e10cSrcweir GET( GetObject,   SbxOBJECT,     SbxBase*,         pObj )
686cdf0e10cSrcweir GET( GetSingle,   SbxSINGLE,     float,            nSingle )
687cdf0e10cSrcweir GET( GetULong,    SbxULONG,      sal_uInt32,           nULong )
688cdf0e10cSrcweir GET( GetULong64,  SbxULONG64,    SbxUINT64,        nULong64 )
689cdf0e10cSrcweir GET( GetUShort,   SbxUSHORT,     sal_uInt16,           nUShort )
690cdf0e10cSrcweir GET( GetInt64,    SbxSALINT64,   sal_Int64,        nInt64 )
691cdf0e10cSrcweir GET( GetUInt64,   SbxSALUINT64,  sal_uInt64,       uInt64 )
692cdf0e10cSrcweir GET( GetDecimal,  SbxDECIMAL,    SbxDecimal*,      pDecimal )
693cdf0e10cSrcweir 
694cdf0e10cSrcweir 
695cdf0e10cSrcweir //////////////////////////// Daten schreiben /////////////////////////////
696cdf0e10cSrcweir 
697cdf0e10cSrcweir sal_Bool SbxValue::Put( const SbxValues& rVal )
698cdf0e10cSrcweir {
699cdf0e10cSrcweir 	sal_Bool bRes = sal_False;
700cdf0e10cSrcweir 	SbxError eOld = GetError();
701cdf0e10cSrcweir 	if( eOld != SbxERR_OK )
702cdf0e10cSrcweir 		ResetError();
703cdf0e10cSrcweir 	if( !CanWrite() )
704cdf0e10cSrcweir 		SetError( SbxERR_PROP_READONLY );
705cdf0e10cSrcweir 	else if( rVal.eType & 0xF000 )
706cdf0e10cSrcweir 		SetError( SbxERR_NOTIMP );
707cdf0e10cSrcweir 	else
708cdf0e10cSrcweir 	{
709cdf0e10cSrcweir 		// Falls nach einem Objekt gefragt wird, nicht
710cdf0e10cSrcweir 		// die wahren Werte suchen
711cdf0e10cSrcweir 		SbxValue* p = this;
712cdf0e10cSrcweir 		if( rVal.eType != SbxOBJECT )
713cdf0e10cSrcweir 			p = TheRealValue( sal_False );	// #55226 Hier keinen Fehler erlauben
714cdf0e10cSrcweir 		if( p )
715cdf0e10cSrcweir 		{
716cdf0e10cSrcweir 			if( !p->CanWrite() )
717cdf0e10cSrcweir 				SetError( SbxERR_PROP_READONLY );
718cdf0e10cSrcweir 			else if( p->IsFixed() || p->SetType( (SbxDataType) ( rVal.eType & 0x0FFF ) ) )
719cdf0e10cSrcweir 			  switch( rVal.eType & 0x0FFF )
720cdf0e10cSrcweir 			{
721cdf0e10cSrcweir 				case SbxEMPTY:
722cdf0e10cSrcweir 				case SbxVOID:
723cdf0e10cSrcweir 				case SbxNULL:		break;
724cdf0e10cSrcweir 				case SbxINTEGER:	ImpPutInteger( &p->aData, rVal.nInteger ); break;
725cdf0e10cSrcweir 				case SbxLONG:		ImpPutLong( &p->aData, rVal.nLong ); break;
726cdf0e10cSrcweir 				case SbxSALINT64:	ImpPutInt64( &p->aData, rVal.nInt64 ); break;
727cdf0e10cSrcweir 				case SbxSALUINT64:	ImpPutUInt64( &p->aData, rVal.uInt64 ); break;
728cdf0e10cSrcweir 				case SbxSINGLE:		ImpPutSingle( &p->aData, rVal.nSingle ); break;
729cdf0e10cSrcweir 				case SbxDOUBLE:		ImpPutDouble( &p->aData, rVal.nDouble ); break;
730cdf0e10cSrcweir 				case SbxCURRENCY:	ImpPutCurrency( &p->aData, rVal.nLong64 ); break;
731cdf0e10cSrcweir 				case SbxDECIMAL:	ImpPutDecimal( &p->aData, rVal.pDecimal ); break;
732cdf0e10cSrcweir 				case SbxDATE:		ImpPutDate( &p->aData, rVal.nDouble ); break;
733cdf0e10cSrcweir 				case SbxBOOL:		ImpPutBool( &p->aData, rVal.nInteger ); break;
734cdf0e10cSrcweir 				case SbxCHAR:		ImpPutChar( &p->aData, rVal.nChar ); break;
735cdf0e10cSrcweir 				case SbxBYTE:		ImpPutByte( &p->aData, rVal.nByte ); break;
736cdf0e10cSrcweir 				case SbxUSHORT:		ImpPutUShort( &p->aData, rVal.nUShort ); break;
737cdf0e10cSrcweir 				case SbxULONG:		ImpPutULong( &p->aData, rVal.nULong ); break;
738cdf0e10cSrcweir 				case SbxLPSTR:
739cdf0e10cSrcweir 				case SbxSTRING:		ImpPutString( &p->aData, rVal.pOUString ); break;
740cdf0e10cSrcweir 				case SbxINT:
741cdf0e10cSrcweir #if SAL_TYPES_SIZEOFINT == 2
742cdf0e10cSrcweir 					ImpPutInteger( &p->aData, (sal_Int16) rVal.nInt );
743cdf0e10cSrcweir #else
744cdf0e10cSrcweir 					ImpPutLong( &p->aData, (sal_Int32) rVal.nInt );
745cdf0e10cSrcweir #endif
746cdf0e10cSrcweir 					break;
747cdf0e10cSrcweir 				case SbxUINT:
748cdf0e10cSrcweir #if SAL_TYPES_SIZEOFINT == 2
749cdf0e10cSrcweir 					ImpPutUShort( &p->aData, (sal_uInt16) rVal.nUInt );
750cdf0e10cSrcweir #else
751cdf0e10cSrcweir 					ImpPutULong( &p->aData, (sal_uInt32) rVal.nUInt );
752cdf0e10cSrcweir #endif
753cdf0e10cSrcweir 					break;
754cdf0e10cSrcweir 				case SbxOBJECT:
755cdf0e10cSrcweir 					if( !p->IsFixed() || p->aData.eType == SbxOBJECT )
756cdf0e10cSrcweir 					{
757cdf0e10cSrcweir 						// ist schon drin
758cdf0e10cSrcweir 						if( p->aData.eType == SbxOBJECT && p->aData.pObj == rVal.pObj )
759cdf0e10cSrcweir 							break;
760cdf0e10cSrcweir 
761cdf0e10cSrcweir 						// Nur den Werteteil loeschen!
762cdf0e10cSrcweir 						p->SbxValue::Clear();
763cdf0e10cSrcweir 
764cdf0e10cSrcweir 						// eingentliche Zuweisung
765cdf0e10cSrcweir 						p->aData.pObj = rVal.pObj;
766cdf0e10cSrcweir 
767cdf0e10cSrcweir 						// ggf. Ref-Count mitzaehlen
768cdf0e10cSrcweir 						if( p->aData.pObj && p->aData.pObj != p )
769cdf0e10cSrcweir 						{
770cdf0e10cSrcweir 							if ( p != this )
771cdf0e10cSrcweir                             {
772cdf0e10cSrcweir 								DBG_ERROR( "TheRealValue" );
773cdf0e10cSrcweir                             }
774cdf0e10cSrcweir 							HACK(nicht bei Parent-Prop - sonst CyclicRef)
775cdf0e10cSrcweir 							SbxVariable *pThisVar = PTR_CAST(SbxVariable, this);
776cdf0e10cSrcweir 							sal_Bool bParentProp = pThisVar && 5345 ==
777cdf0e10cSrcweir 									( (sal_Int16) ( pThisVar->GetUserData() & 0xFFFF ) );
778cdf0e10cSrcweir 							if ( !bParentProp )
779cdf0e10cSrcweir 								p->aData.pObj->AddRef();
780cdf0e10cSrcweir 						}
781cdf0e10cSrcweir 					}
782cdf0e10cSrcweir 					else
783cdf0e10cSrcweir 						SetError( SbxERR_CONVERSION );
784cdf0e10cSrcweir 					break;
785cdf0e10cSrcweir 				default:
786cdf0e10cSrcweir 					if( p->aData.eType == rVal.eType )
787cdf0e10cSrcweir 						p->aData = rVal;
788cdf0e10cSrcweir 					else
789cdf0e10cSrcweir 					{
790cdf0e10cSrcweir 						SetError( SbxERR_CONVERSION );
791cdf0e10cSrcweir 						if( !p->IsFixed() )
792cdf0e10cSrcweir 							p->aData.eType = SbxNULL;
793cdf0e10cSrcweir 					}
794cdf0e10cSrcweir 			}
795cdf0e10cSrcweir 			if( !IsError() )
796cdf0e10cSrcweir 			{
797cdf0e10cSrcweir 				p->SetModified( sal_True );
798cdf0e10cSrcweir 				p->Broadcast( SBX_HINT_DATACHANGED );
799cdf0e10cSrcweir 				if( eOld != SbxERR_OK )
800cdf0e10cSrcweir 					SetError( eOld );
801cdf0e10cSrcweir 				bRes = sal_True;
802cdf0e10cSrcweir 			}
803cdf0e10cSrcweir 		}
804cdf0e10cSrcweir 	}
805cdf0e10cSrcweir 	return bRes;
806cdf0e10cSrcweir }
807cdf0e10cSrcweir 
808cdf0e10cSrcweir // AB, 28.3.96:
809cdf0e10cSrcweir // Methode, um bei speziellen Typen eine Vorbehandlung des Strings
810cdf0e10cSrcweir // durchzufuehren. Insbesondere erforderlich fuer BASIC-IDE, damit
811cdf0e10cSrcweir // die Ausgaben im Watch-Fenster mit PutStringExt zurueckgeschrieben
812cdf0e10cSrcweir // werden koennen, wenn Floats mit ',' als Dezimaltrenner oder BOOLs
813cdf0e10cSrcweir // explizit mit "TRUE" oder "FALSE" angegeben werden.
814cdf0e10cSrcweir // Implementierung in ImpConvStringExt (SBXSCAN.CXX)
PutStringExt(const::rtl::OUString & r)815cdf0e10cSrcweir sal_Bool SbxValue::PutStringExt( const ::rtl::OUString& r )
816cdf0e10cSrcweir {
817cdf0e10cSrcweir 	// Kopieren, bei Unicode gleich konvertieren
818cdf0e10cSrcweir 	::rtl::OUString aStr( r );
819cdf0e10cSrcweir 
820cdf0e10cSrcweir 	// Eigenen Typ bestimmen (nicht wie in Put() mit TheRealValue(),
821cdf0e10cSrcweir 	// Objekte werden sowieso nicht behandelt)
822cdf0e10cSrcweir 	SbxDataType eTargetType = SbxDataType( aData.eType & 0x0FFF );
823cdf0e10cSrcweir 
824cdf0e10cSrcweir 	// Source-Value basteln
825cdf0e10cSrcweir 	SbxValues aRes;
826cdf0e10cSrcweir 	aRes.eType = SbxSTRING;
827cdf0e10cSrcweir 
828cdf0e10cSrcweir 	// Nur, wenn wirklich was konvertiert wurde, Kopie nehmen,
829cdf0e10cSrcweir 	// sonst Original (Unicode bleibt erhalten)
830cdf0e10cSrcweir 	sal_Bool bRet;
831cdf0e10cSrcweir 	if( ImpConvStringExt( aStr, eTargetType ) )
832cdf0e10cSrcweir 		aRes.pOUString = (::rtl::OUString*)&aStr;
833cdf0e10cSrcweir 	else
834cdf0e10cSrcweir 		aRes.pOUString = (::rtl::OUString*)&r;
835cdf0e10cSrcweir 
836cdf0e10cSrcweir 	// #34939: Bei Strings. die eine Zahl enthalten und wenn this einen
837cdf0e10cSrcweir 	// Num-Typ hat, Fixed-Flag setzen, damit der Typ nicht veraendert wird
838cdf0e10cSrcweir 	sal_uInt16 nFlags_ = GetFlags();
839cdf0e10cSrcweir 	if( ( eTargetType >= SbxINTEGER && eTargetType <= SbxCURRENCY ) ||
840cdf0e10cSrcweir 		( eTargetType >= SbxCHAR && eTargetType <= SbxUINT ) ||
841cdf0e10cSrcweir 		eTargetType == SbxBOOL )
842cdf0e10cSrcweir 	{
843cdf0e10cSrcweir 		SbxValue aVal;
844cdf0e10cSrcweir 		aVal.Put( aRes );
845cdf0e10cSrcweir 		if( aVal.IsNumeric() )
846cdf0e10cSrcweir 			SetFlag( SBX_FIXED );
847cdf0e10cSrcweir 	}
848cdf0e10cSrcweir 
849cdf0e10cSrcweir 	Put( aRes );
850cdf0e10cSrcweir 	bRet = sal_Bool( !IsError() );
851cdf0e10cSrcweir 
852cdf0e10cSrcweir 	// Falls das mit dem FIXED einen Error gegeben hat, zuruecksetzen
853cdf0e10cSrcweir 	// (UI-Aktion sollte keinen Error ergeben, sondern nur scheitern)
854cdf0e10cSrcweir 	if( !bRet )
855cdf0e10cSrcweir 		ResetError();
856cdf0e10cSrcweir 
857cdf0e10cSrcweir 	SetFlags( nFlags_ );
858cdf0e10cSrcweir 	return bRet;
859cdf0e10cSrcweir }
860cdf0e10cSrcweir 
PutString(const xub_Unicode * p)861cdf0e10cSrcweir sal_Bool SbxValue::PutString( const xub_Unicode* p )
862cdf0e10cSrcweir {
863cdf0e10cSrcweir 	::rtl::OUString aVal( p );
864cdf0e10cSrcweir 	SbxValues aRes;
865cdf0e10cSrcweir 	aRes.eType = SbxSTRING;
866cdf0e10cSrcweir 	aRes.pOUString = &aVal;
867cdf0e10cSrcweir 	Put( aRes );
868cdf0e10cSrcweir 	return sal_Bool( !IsError() );
869cdf0e10cSrcweir }
870cdf0e10cSrcweir 
PutBool(sal_Bool b)871cdf0e10cSrcweir sal_Bool SbxValue::PutBool( sal_Bool b )
872cdf0e10cSrcweir {
873cdf0e10cSrcweir 	SbxValues aRes;
874cdf0e10cSrcweir 	aRes.eType = SbxBOOL;
875cdf0e10cSrcweir 	aRes.nUShort = sal::static_int_cast< sal_uInt16 >(b ? SbxTRUE : SbxFALSE);
876cdf0e10cSrcweir 	Put( aRes );
877cdf0e10cSrcweir 	return sal_Bool( !IsError() );
878cdf0e10cSrcweir }
879cdf0e10cSrcweir 
PutEmpty()880cdf0e10cSrcweir sal_Bool SbxValue::PutEmpty()
881cdf0e10cSrcweir {
882cdf0e10cSrcweir 	sal_Bool bRet = SetType( SbxEMPTY );
883cdf0e10cSrcweir 		SetModified( sal_True );
884cdf0e10cSrcweir 	return bRet;
885cdf0e10cSrcweir }
886cdf0e10cSrcweir 
PutNull()887cdf0e10cSrcweir sal_Bool SbxValue::PutNull()
888cdf0e10cSrcweir {
889cdf0e10cSrcweir 	sal_Bool bRet = SetType( SbxNULL );
890cdf0e10cSrcweir 	if( bRet )
891cdf0e10cSrcweir 		SetModified( sal_True );
892cdf0e10cSrcweir 	return bRet;
893cdf0e10cSrcweir }
894cdf0e10cSrcweir 
895cdf0e10cSrcweir 
896cdf0e10cSrcweir // Special decimal methods
PutDecimal(com::sun::star::bridge::oleautomation::Decimal & rAutomationDec)897cdf0e10cSrcweir sal_Bool SbxValue::PutDecimal( com::sun::star::bridge::oleautomation::Decimal& rAutomationDec )
898cdf0e10cSrcweir {
899cdf0e10cSrcweir 	SbxValue::Clear();
900cdf0e10cSrcweir 	aData.pDecimal = new SbxDecimal( rAutomationDec );
901cdf0e10cSrcweir 	aData.pDecimal->addRef();
902cdf0e10cSrcweir 	aData.eType = SbxDECIMAL;
903cdf0e10cSrcweir 	return sal_True;
904cdf0e10cSrcweir }
905cdf0e10cSrcweir 
fillAutomationDecimal(com::sun::star::bridge::oleautomation::Decimal & rAutomationDec)906cdf0e10cSrcweir sal_Bool SbxValue::fillAutomationDecimal
907cdf0e10cSrcweir 	( com::sun::star::bridge::oleautomation::Decimal& rAutomationDec )
908cdf0e10cSrcweir {
909cdf0e10cSrcweir 	SbxDecimal* pDecimal = GetDecimal();
910cdf0e10cSrcweir 	if( pDecimal != NULL )
911cdf0e10cSrcweir 	{
912cdf0e10cSrcweir 		pDecimal->fillAutomationDecimal( rAutomationDec );
913cdf0e10cSrcweir 		return sal_True;
914cdf0e10cSrcweir 	}
915cdf0e10cSrcweir 	return sal_False;
916cdf0e10cSrcweir }
917cdf0e10cSrcweir 
918cdf0e10cSrcweir 
PutpChar(const xub_Unicode * p)919cdf0e10cSrcweir sal_Bool SbxValue::PutpChar( const xub_Unicode* p )
920cdf0e10cSrcweir {
921cdf0e10cSrcweir 	::rtl::OUString aVal( p );
922cdf0e10cSrcweir 	SbxValues aRes;
923cdf0e10cSrcweir 	aRes.eType = SbxLPSTR;
924cdf0e10cSrcweir 	aRes.pOUString = &aVal;
925cdf0e10cSrcweir 	Put( aRes );
926cdf0e10cSrcweir 	return sal_Bool( !IsError() );
927cdf0e10cSrcweir }
928cdf0e10cSrcweir 
PutString(const::rtl::OUString & r)929cdf0e10cSrcweir sal_Bool SbxValue::PutString( const ::rtl::OUString& r )
930cdf0e10cSrcweir {
931cdf0e10cSrcweir 	SbxValues aRes;
932cdf0e10cSrcweir 	aRes.eType = SbxSTRING;
933cdf0e10cSrcweir 	aRes.pOUString = (::rtl::OUString*) &r;
934cdf0e10cSrcweir 	Put( aRes );
935cdf0e10cSrcweir 	return sal_Bool( !IsError() );
936cdf0e10cSrcweir }
937cdf0e10cSrcweir 
938cdf0e10cSrcweir 
939cdf0e10cSrcweir #define PUT( p, e, t, m ) \
940cdf0e10cSrcweir sal_Bool SbxValue::p( t n ) \
941cdf0e10cSrcweir { SbxValues aRes(e); aRes.m = n; Put( aRes ); return sal_Bool( !IsError() ); }
942cdf0e10cSrcweir 
PUT(PutByte,SbxBYTE,sal_uInt8,nByte)943cdf0e10cSrcweir PUT( PutByte,     SbxBYTE,       sal_uInt8,             nByte )
944cdf0e10cSrcweir PUT( PutChar,     SbxCHAR,       xub_Unicode,      nChar )
945cdf0e10cSrcweir PUT( PutCurrency, SbxCURRENCY,   const SbxINT64&,  nLong64 )
946cdf0e10cSrcweir PUT( PutDate,     SbxDATE,       double,           nDouble )
947cdf0e10cSrcweir PUT( PutData,     SbxDATAOBJECT, void*,            pData )
948cdf0e10cSrcweir PUT( PutDouble,   SbxDOUBLE,     double,           nDouble )
949cdf0e10cSrcweir PUT( PutErr,      SbxERROR,      sal_uInt16,           nUShort )
950cdf0e10cSrcweir PUT( PutInt,      SbxINT,        int,              nInt )
951cdf0e10cSrcweir PUT( PutInteger,  SbxINTEGER,    sal_Int16,            nInteger )
952cdf0e10cSrcweir PUT( PutLong,     SbxLONG,       sal_Int32,            nLong )
953cdf0e10cSrcweir PUT( PutLong64,   SbxLONG64,     const SbxINT64&,  nLong64 )
954cdf0e10cSrcweir PUT( PutObject,   SbxOBJECT,     SbxBase*,         pObj )
955cdf0e10cSrcweir PUT( PutSingle,   SbxSINGLE,     float,            nSingle )
956cdf0e10cSrcweir PUT( PutULong,    SbxULONG,      sal_uInt32,           nULong )
957cdf0e10cSrcweir PUT( PutULong64,  SbxULONG64,    const SbxUINT64&, nULong64 )
958cdf0e10cSrcweir PUT( PutUShort,   SbxUSHORT,     sal_uInt16,           nUShort )
959cdf0e10cSrcweir PUT( PutInt64,    SbxSALINT64,   sal_Int64,        nInt64 )
960cdf0e10cSrcweir PUT( PutUInt64,   SbxSALUINT64,  sal_uInt64,       uInt64 )
961cdf0e10cSrcweir PUT( PutDecimal,  SbxDECIMAL,    SbxDecimal*,      pDecimal )
962cdf0e10cSrcweir 
963cdf0e10cSrcweir 
964cdf0e10cSrcweir ////////////////////////// Setzen des Datentyps ///////////////////////////
965cdf0e10cSrcweir 
966cdf0e10cSrcweir sal_Bool SbxValue::IsFixed() const
967cdf0e10cSrcweir {
968cdf0e10cSrcweir 	return ( (GetFlags() & SBX_FIXED) | (aData.eType & SbxBYREF) ) != 0;
969cdf0e10cSrcweir }
970cdf0e10cSrcweir 
971cdf0e10cSrcweir // Eine Variable ist numerisch, wenn sie EMPTY oder wirklich numerisch ist
972cdf0e10cSrcweir // oder einen vollstaendig konvertierbaren String enthaelt
973cdf0e10cSrcweir 
974cdf0e10cSrcweir // #41692, fuer RTL und Basic-Core getrennt implementieren
IsNumeric() const975cdf0e10cSrcweir sal_Bool SbxValue::IsNumeric() const
976cdf0e10cSrcweir {
977cdf0e10cSrcweir 	return ImpIsNumeric( /*bOnlyIntntl*/sal_False );
978cdf0e10cSrcweir }
979cdf0e10cSrcweir 
IsNumericRTL() const980cdf0e10cSrcweir sal_Bool SbxValue::IsNumericRTL() const
981cdf0e10cSrcweir {
982cdf0e10cSrcweir 	return ImpIsNumeric( /*bOnlyIntntl*/sal_True );
983cdf0e10cSrcweir }
984cdf0e10cSrcweir 
ImpIsNumeric(sal_Bool bOnlyIntntl) const985cdf0e10cSrcweir sal_Bool SbxValue::ImpIsNumeric( sal_Bool bOnlyIntntl ) const
986cdf0e10cSrcweir {
987cdf0e10cSrcweir 
988cdf0e10cSrcweir 	if( !CanRead() )
989cdf0e10cSrcweir 	{
990cdf0e10cSrcweir 		SetError( SbxERR_PROP_WRITEONLY ); return sal_False;
991cdf0e10cSrcweir 	}
992cdf0e10cSrcweir 	// Downcast pruefen!!!
993cdf0e10cSrcweir 	if( this->ISA(SbxVariable) )
994cdf0e10cSrcweir 		((SbxVariable*)this)->Broadcast( SBX_HINT_DATAWANTED );
995cdf0e10cSrcweir 	SbxDataType t = GetType();
996cdf0e10cSrcweir 	if( t == SbxSTRING )
997cdf0e10cSrcweir 	{
998cdf0e10cSrcweir 		if( aData.pOUString )
999cdf0e10cSrcweir 		{
1000cdf0e10cSrcweir 			::rtl::OUString s( *aData.pOUString );
1001cdf0e10cSrcweir 			double n;
1002cdf0e10cSrcweir 			SbxDataType t2;
1003cdf0e10cSrcweir 			sal_uInt16 nLen = 0;
1004cdf0e10cSrcweir 			if( ImpScan( s, n, t2, &nLen, /*bAllowIntntl*/sal_False, bOnlyIntntl ) == SbxERR_OK )
1005cdf0e10cSrcweir 				return sal_Bool( nLen == s.getLength() );
1006cdf0e10cSrcweir 		}
1007cdf0e10cSrcweir 		return sal_False;
1008cdf0e10cSrcweir 	}
1009cdf0e10cSrcweir 	else
1010cdf0e10cSrcweir 		return sal_Bool( t == SbxEMPTY
1011cdf0e10cSrcweir 			|| ( t >= SbxINTEGER && t <= SbxCURRENCY )
1012cdf0e10cSrcweir 			|| ( t >= SbxCHAR && t <= SbxUINT ) );
1013cdf0e10cSrcweir }
1014cdf0e10cSrcweir 
GetClass() const1015cdf0e10cSrcweir SbxClassType SbxValue::GetClass() const
1016cdf0e10cSrcweir {
1017cdf0e10cSrcweir 	return SbxCLASS_VALUE;
1018cdf0e10cSrcweir }
1019cdf0e10cSrcweir 
GetType() const1020cdf0e10cSrcweir SbxDataType SbxValue::GetType() const
1021cdf0e10cSrcweir {
1022cdf0e10cSrcweir 	return SbxDataType( aData.eType & 0x0FFF );
1023cdf0e10cSrcweir }
1024cdf0e10cSrcweir 
GetFullType() const1025cdf0e10cSrcweir SbxDataType SbxValue::GetFullType() const
1026cdf0e10cSrcweir {
1027cdf0e10cSrcweir 	return aData.eType;
1028cdf0e10cSrcweir }
1029cdf0e10cSrcweir 
SetType(SbxDataType t)1030cdf0e10cSrcweir sal_Bool SbxValue::SetType( SbxDataType t )
1031cdf0e10cSrcweir {
1032cdf0e10cSrcweir 	DBG_ASSERT( !( t & 0xF000 ), "Setzen von BYREF|ARRAY verboten!" );
1033cdf0e10cSrcweir 	if( ( t == SbxEMPTY && aData.eType == SbxVOID )
1034cdf0e10cSrcweir 	 || ( aData.eType == SbxEMPTY && t == SbxVOID ) )
1035cdf0e10cSrcweir 		return sal_True;
1036cdf0e10cSrcweir 	if( ( t & 0x0FFF ) == SbxVARIANT )
1037cdf0e10cSrcweir 	{
1038cdf0e10cSrcweir 		// Versuch, den Datentyp auf Variant zu setzen
1039cdf0e10cSrcweir 		ResetFlag( SBX_FIXED );
1040cdf0e10cSrcweir 		if( IsFixed() )
1041cdf0e10cSrcweir 		{
1042cdf0e10cSrcweir 			SetError( SbxERR_CONVERSION ); return sal_False;
1043cdf0e10cSrcweir 		}
1044cdf0e10cSrcweir 		t = SbxEMPTY;
1045cdf0e10cSrcweir 	}
1046cdf0e10cSrcweir 	if( ( t & 0x0FFF ) != ( aData.eType & 0x0FFF ) )
1047cdf0e10cSrcweir 	{
1048cdf0e10cSrcweir 		if( !CanWrite() || IsFixed() )
1049cdf0e10cSrcweir 		{
1050cdf0e10cSrcweir 			SetError( SbxERR_CONVERSION ); return sal_False;
1051cdf0e10cSrcweir 		}
1052cdf0e10cSrcweir 		else
1053cdf0e10cSrcweir 		{
1054cdf0e10cSrcweir 			// Eventuelle Objekte freigeben
1055cdf0e10cSrcweir 			switch( aData.eType )
1056cdf0e10cSrcweir 			{
1057cdf0e10cSrcweir 				case SbxSTRING:
1058cdf0e10cSrcweir 					delete aData.pOUString;
1059cdf0e10cSrcweir 					break;
1060cdf0e10cSrcweir 				case SbxOBJECT:
1061cdf0e10cSrcweir 					if( aData.pObj && aData.pObj != this )
1062cdf0e10cSrcweir 					{
1063cdf0e10cSrcweir 						HACK(nicht bei Parent-Prop - sonst CyclicRef)
1064cdf0e10cSrcweir 						SbxVariable *pThisVar = PTR_CAST(SbxVariable, this);
1065cdf0e10cSrcweir 						sal_uInt16 nSlotId = pThisVar
1066cdf0e10cSrcweir 									? ( (sal_Int16) ( pThisVar->GetUserData() & 0xFFFF ) )
1067cdf0e10cSrcweir 									: 0;
1068cdf0e10cSrcweir 						DBG_ASSERT( nSlotId != 5345 || pThisVar->GetName() == UniString::CreateFromAscii( "Parent" ),
1069cdf0e10cSrcweir 									"SID_PARENTOBJECT heisst nicht 'Parent'" );
1070cdf0e10cSrcweir 						sal_Bool bParentProp = 5345 == nSlotId;
1071cdf0e10cSrcweir 						if ( !bParentProp )
1072cdf0e10cSrcweir 							aData.pObj->ReleaseRef();
1073cdf0e10cSrcweir 					}
1074cdf0e10cSrcweir 					break;
1075cdf0e10cSrcweir 				default: break;
1076cdf0e10cSrcweir 			}
1077cdf0e10cSrcweir 			// Das klappt immer, da auch die Float-Repraesentationen 0 sind.
1078cdf0e10cSrcweir 			memset( &aData, 0, sizeof( SbxValues ) );
1079cdf0e10cSrcweir 			aData.eType = t;
1080cdf0e10cSrcweir 		}
1081cdf0e10cSrcweir 	}
1082cdf0e10cSrcweir 	return sal_True;
1083cdf0e10cSrcweir }
1084cdf0e10cSrcweir 
Convert(SbxDataType eTo)1085cdf0e10cSrcweir sal_Bool SbxValue::Convert( SbxDataType eTo )
1086cdf0e10cSrcweir {
1087cdf0e10cSrcweir 	eTo = SbxDataType( eTo & 0x0FFF );
1088cdf0e10cSrcweir 	if( ( aData.eType & 0x0FFF ) == eTo )
1089cdf0e10cSrcweir 		return sal_True;
1090cdf0e10cSrcweir 	if( !CanWrite() )
1091cdf0e10cSrcweir 		return sal_False;
1092cdf0e10cSrcweir 	if( eTo == SbxVARIANT )
1093cdf0e10cSrcweir 	{
1094cdf0e10cSrcweir 		// Versuch, den Datentyp auf Variant zu setzen
1095cdf0e10cSrcweir 		ResetFlag( SBX_FIXED );
1096cdf0e10cSrcweir 		if( IsFixed() )
1097cdf0e10cSrcweir 		{
1098cdf0e10cSrcweir 			SetError( SbxERR_CONVERSION ); return sal_False;
1099cdf0e10cSrcweir 		}
1100cdf0e10cSrcweir 		else
1101cdf0e10cSrcweir 			return sal_True;
1102cdf0e10cSrcweir 	}
1103cdf0e10cSrcweir 	// Convert from Null geht niemals. Einmal Null, immer Null!
1104cdf0e10cSrcweir 	if( aData.eType == SbxNULL )
1105cdf0e10cSrcweir 	{
1106cdf0e10cSrcweir 		SetError( SbxERR_CONVERSION ); return sal_False;
1107cdf0e10cSrcweir 	}
1108cdf0e10cSrcweir 
1109cdf0e10cSrcweir 	// Konversion der Daten:
1110cdf0e10cSrcweir 	SbxValues aNew;
1111cdf0e10cSrcweir 	aNew.eType = eTo;
1112cdf0e10cSrcweir 	if( Get( aNew ) )
1113cdf0e10cSrcweir 	{
1114cdf0e10cSrcweir 		// Der Datentyp konnte konvertiert werden. Bei Fixed-Elementen
1115cdf0e10cSrcweir 		// ist hier Ende, da die Daten nicht uebernommen zu werden brauchen
1116cdf0e10cSrcweir 		if( !IsFixed() )
1117cdf0e10cSrcweir 		{
1118cdf0e10cSrcweir 			SetType( eTo );
1119cdf0e10cSrcweir 			Put( aNew );
1120cdf0e10cSrcweir 			SetModified( sal_True );
1121cdf0e10cSrcweir 		}
1122cdf0e10cSrcweir 		Broadcast( SBX_HINT_CONVERTED );
1123cdf0e10cSrcweir 		return sal_True;
1124cdf0e10cSrcweir 	}
1125cdf0e10cSrcweir 	else
1126cdf0e10cSrcweir 		return sal_False;
1127cdf0e10cSrcweir }
1128cdf0e10cSrcweir ////////////////////////////////// Rechnen /////////////////////////////////
1129cdf0e10cSrcweir 
Compute(SbxOperator eOp,const SbxValue & rOp)1130cdf0e10cSrcweir sal_Bool SbxValue::Compute( SbxOperator eOp, const SbxValue& rOp )
1131cdf0e10cSrcweir {
1132cdf0e10cSrcweir 	bool bVBAInterop =  SbiRuntime::isVBAEnabled();
1133cdf0e10cSrcweir 
1134cdf0e10cSrcweir 	SbxDataType eThisType = GetType();
1135cdf0e10cSrcweir 	SbxDataType eOpType = rOp.GetType();
1136cdf0e10cSrcweir 	SbxError eOld = GetError();
1137cdf0e10cSrcweir 	if( eOld != SbxERR_OK )
1138cdf0e10cSrcweir 		ResetError();
1139cdf0e10cSrcweir 	if( !CanWrite() )
1140cdf0e10cSrcweir 		SetError( SbxERR_PROP_READONLY );
1141cdf0e10cSrcweir 	else if( !rOp.CanRead() )
1142cdf0e10cSrcweir 		SetError( SbxERR_PROP_WRITEONLY );
1143cdf0e10cSrcweir 	// Sonderregel 1: Ist ein Operand Null, ist das Ergebnis Null
1144cdf0e10cSrcweir 	else if( eThisType == SbxNULL || eOpType == SbxNULL )
1145cdf0e10cSrcweir 		SetType( SbxNULL );
1146cdf0e10cSrcweir 	// Sonderregel 2: Ist ein Operand Empty, ist das Ergebnis der 2. Operand
1147cdf0e10cSrcweir 	else if( eThisType == SbxEMPTY
1148cdf0e10cSrcweir 	&& !bVBAInterop
1149cdf0e10cSrcweir 	)
1150cdf0e10cSrcweir 		*this = rOp;
1151cdf0e10cSrcweir 	// 13.2.96: Nicht schon vor Get auf SbxEMPTY pruefen
1152cdf0e10cSrcweir 	else
1153cdf0e10cSrcweir 	{
1154cdf0e10cSrcweir 		SbxValues aL, aR;
1155cdf0e10cSrcweir 		bool bDecimal = false;
1156cdf0e10cSrcweir 		if( bVBAInterop && ( ( eThisType == SbxSTRING && eOpType != SbxSTRING ) ||
1157cdf0e10cSrcweir 			 ( eThisType != SbxSTRING && eOpType == SbxSTRING ) ) &&
1158cdf0e10cSrcweir 			 ( eOp == SbxMUL || eOp == SbxDIV || eOp == SbxPLUS || eOp == SbxMINUS ) )
1159cdf0e10cSrcweir 		{
1160cdf0e10cSrcweir 			goto Lbl_OpIsDouble;
1161cdf0e10cSrcweir 		}
1162cdf0e10cSrcweir 		else if( eThisType == SbxSTRING || eOp == SbxCAT || ( bVBAInterop && ( eOpType == SbxSTRING ) && (  eOp == SbxPLUS ) ) )
1163cdf0e10cSrcweir 		{
1164cdf0e10cSrcweir 			if( eOp == SbxCAT || eOp == SbxPLUS )
1165cdf0e10cSrcweir 			{
1166cdf0e10cSrcweir 				// AB 5.11.1999, OUString beruecksichtigen
1167cdf0e10cSrcweir 				aL.eType = aR.eType = SbxSTRING;
1168cdf0e10cSrcweir 				rOp.Get( aR );
1169cdf0e10cSrcweir 				// AB 8.12.1999, #70399: Hier wieder GetType() rufen, Get() kann Typ aendern!
1170cdf0e10cSrcweir 				if( rOp.GetType() == SbxEMPTY )
1171cdf0e10cSrcweir 					goto Lbl_OpIsEmpty;
1172cdf0e10cSrcweir 				Get( aL );
1173cdf0e10cSrcweir 
1174cdf0e10cSrcweir 				// #30576: Erstmal testen, ob Wandlung geklappt hat
1175cdf0e10cSrcweir 				if( aL.pOUString != NULL && aR.pOUString != NULL )
1176cdf0e10cSrcweir 				{
1177cdf0e10cSrcweir 					*aL.pOUString += *aR.pOUString;
1178cdf0e10cSrcweir 				}
1179cdf0e10cSrcweir 				// Nicht einmal Left OK?
1180cdf0e10cSrcweir 				else if( aL.pOUString == NULL )
1181cdf0e10cSrcweir 				{
1182cdf0e10cSrcweir 					aL.pOUString = new ::rtl::OUString();
1183cdf0e10cSrcweir 				}
1184cdf0e10cSrcweir 				Put( aL );
1185cdf0e10cSrcweir 			}
1186cdf0e10cSrcweir 			else
1187cdf0e10cSrcweir 				SetError( SbxERR_CONVERSION );
1188cdf0e10cSrcweir 		}
1189cdf0e10cSrcweir 		else if( eOpType == SbxSTRING && rOp.IsFixed() )
1190cdf0e10cSrcweir 		{	// Numerisch: rechts darf kein String stehen
1191cdf0e10cSrcweir 			SetError( SbxERR_CONVERSION );
1192cdf0e10cSrcweir 		}
1193cdf0e10cSrcweir 		else if( ( eOp >= SbxIDIV && eOp <= SbxNOT ) || eOp == SbxMOD )
1194cdf0e10cSrcweir 		{
1195cdf0e10cSrcweir 			if( GetType() == eOpType )
1196cdf0e10cSrcweir 			{
1197cdf0e10cSrcweir 				if( GetType() == SbxULONG64
1198cdf0e10cSrcweir 					|| GetType() == SbxLONG64
1199cdf0e10cSrcweir 					|| GetType() == SbxCURRENCY
1200cdf0e10cSrcweir 					|| GetType() == SbxULONG )
1201cdf0e10cSrcweir 					aL.eType = aR.eType = GetType();
1202cdf0e10cSrcweir //				else if( GetType() == SbxDouble || GetType() == SbxSingle )
1203cdf0e10cSrcweir //					aL.eType = aR.eType = SbxLONG64;
1204cdf0e10cSrcweir 				else
1205cdf0e10cSrcweir 					aL.eType = aR.eType = SbxLONG;
1206cdf0e10cSrcweir 			}
1207cdf0e10cSrcweir 			else if( GetType() == SbxCURRENCY || eOpType == SbxCURRENCY
1208cdf0e10cSrcweir 					 || GetType() == SbxULONG64 || eOpType == SbxULONG64
1209cdf0e10cSrcweir 					 || GetType() == SbxLONG64 || eOpType == SbxLONG64 )
1210cdf0e10cSrcweir 				aL.eType = aR.eType = SbxLONG64;
1211cdf0e10cSrcweir //			else if( GetType() == SbxDouble || rOP.GetType() == SbxDouble
1212cdf0e10cSrcweir //			         || GetType() == SbxSingle || rOP.GetType() == SbxSingle )
1213cdf0e10cSrcweir //				aL.eType = aR.eType = SbxLONG64;
1214cdf0e10cSrcweir 			else
1215cdf0e10cSrcweir 				aL.eType = aR.eType = SbxLONG;
1216cdf0e10cSrcweir 
1217cdf0e10cSrcweir 			if( rOp.Get( aR ) )
1218cdf0e10cSrcweir 			{
1219cdf0e10cSrcweir 				if( rOp.GetType() == SbxEMPTY )
1220cdf0e10cSrcweir 				{
1221cdf0e10cSrcweir 					if ( !bVBAInterop || ( bVBAInterop && ( eOp != SbxNOT  ) ) )
1222cdf0e10cSrcweir 						goto Lbl_OpIsEmpty;
1223cdf0e10cSrcweir 				}
1224cdf0e10cSrcweir 				if( Get( aL ) ) switch( eOp )
1225cdf0e10cSrcweir 				{
1226cdf0e10cSrcweir 					case SbxIDIV:
1227cdf0e10cSrcweir 						if( aL.eType == SbxCURRENCY )
1228cdf0e10cSrcweir 							aL.eType = SbxLONG64;
1229cdf0e10cSrcweir 						if( aL.eType == SbxLONG64 )
1230cdf0e10cSrcweir 							if( !aR.nLong64 ) SetError( SbxERR_ZERODIV );
1231cdf0e10cSrcweir 							else aL.nLong64 /= aR.nLong64;
1232cdf0e10cSrcweir 						else if( aL.eType == SbxULONG64 )
1233cdf0e10cSrcweir 							if( !aR.nULong64 ) SetError( SbxERR_ZERODIV );
1234cdf0e10cSrcweir 							else aL.nULong64 /= aR.nULong64;
1235cdf0e10cSrcweir 						else if( aL.eType == SbxLONG )
1236cdf0e10cSrcweir 							if( !aR.nLong ) SetError( SbxERR_ZERODIV );
1237cdf0e10cSrcweir 							else aL.nLong /= aR.nLong;
1238cdf0e10cSrcweir 						else
1239cdf0e10cSrcweir 							if( !aR.nULong ) SetError( SbxERR_ZERODIV );
1240cdf0e10cSrcweir 							else aL.nULong /= aR.nULong;
1241cdf0e10cSrcweir 						break;
1242cdf0e10cSrcweir 					case SbxMOD:
1243cdf0e10cSrcweir 						if( aL.eType == SbxCURRENCY )
1244cdf0e10cSrcweir 							aL.eType = SbxLONG64;
1245cdf0e10cSrcweir 						if( aL.eType == SbxLONG64 )
1246cdf0e10cSrcweir 							if( !aR.nLong64 ) SetError( SbxERR_ZERODIV );
1247cdf0e10cSrcweir 							else aL.nLong64 %= aR.nLong64;
1248cdf0e10cSrcweir 						else if( aL.eType == SbxULONG64 )
1249cdf0e10cSrcweir 							if( !aR.nULong64 ) SetError( SbxERR_ZERODIV );
1250cdf0e10cSrcweir 							else aL.nULong64 %= aR.nULong64;
1251cdf0e10cSrcweir 						else if( aL.eType == SbxLONG )
1252cdf0e10cSrcweir 							if( !aR.nLong ) SetError( SbxERR_ZERODIV );
1253cdf0e10cSrcweir 							else aL.nLong %= aR.nLong;
1254cdf0e10cSrcweir 						else
1255cdf0e10cSrcweir 							if( !aR.nULong ) SetError( SbxERR_ZERODIV );
1256cdf0e10cSrcweir 							else aL.nULong %= aR.nULong;
1257cdf0e10cSrcweir 						break;
1258cdf0e10cSrcweir 					case SbxAND:
1259cdf0e10cSrcweir 						if( aL.eType != SbxLONG && aL.eType != SbxULONG )
1260cdf0e10cSrcweir 							aL.nLong64 &= aR.nLong64;
1261cdf0e10cSrcweir 						else
1262cdf0e10cSrcweir 							aL.nLong &= aR.nLong;
1263cdf0e10cSrcweir 						break;
1264cdf0e10cSrcweir 					case SbxOR:
1265cdf0e10cSrcweir 						if( aL.eType != SbxLONG && aL.eType != SbxULONG )
1266cdf0e10cSrcweir 							aL.nLong64 |= aR.nLong64;
1267cdf0e10cSrcweir 						else
1268cdf0e10cSrcweir 							aL.nLong |= aR.nLong;
1269cdf0e10cSrcweir 						break;
1270cdf0e10cSrcweir 					case SbxXOR:
1271cdf0e10cSrcweir 						if( aL.eType != SbxLONG && aL.eType != SbxULONG )
1272cdf0e10cSrcweir 							aL.nLong64 ^= aR.nLong64;
1273cdf0e10cSrcweir 						else
1274cdf0e10cSrcweir 							aL.nLong ^= aR.nLong;
1275cdf0e10cSrcweir 						break;
1276cdf0e10cSrcweir 					case SbxEQV:
1277cdf0e10cSrcweir 						if( aL.eType != SbxLONG && aL.eType != SbxULONG )
1278cdf0e10cSrcweir 							aL.nLong64 = (aL.nLong64 & aR.nLong64) | (~aL.nLong64 & ~aR.nLong64);
1279cdf0e10cSrcweir 						else
1280cdf0e10cSrcweir 							aL.nLong = (aL.nLong & aR.nLong) | (~aL.nLong & ~aR.nLong);
1281cdf0e10cSrcweir 						break;
1282cdf0e10cSrcweir 					case SbxIMP:
1283cdf0e10cSrcweir 						if( aL.eType != SbxLONG && aL.eType != SbxULONG )
1284cdf0e10cSrcweir 							aL.nLong64 = ~aL.nLong64 | aR.nLong64;
1285cdf0e10cSrcweir 						else
1286cdf0e10cSrcweir 							aL.nLong = ~aL.nLong | aR.nLong;
1287cdf0e10cSrcweir 						break;
1288cdf0e10cSrcweir 					case SbxNOT:
1289cdf0e10cSrcweir 						if( aL.eType != SbxLONG && aL.eType != SbxULONG )
1290cdf0e10cSrcweir 							aL.nLong64 = ~aL.nLong64;
1291cdf0e10cSrcweir 						else
1292cdf0e10cSrcweir 							aL.nLong = ~aL.nLong;
1293cdf0e10cSrcweir 						break;
1294cdf0e10cSrcweir 					default: break;
1295cdf0e10cSrcweir 				}
1296cdf0e10cSrcweir 			}
1297cdf0e10cSrcweir 		}
1298cdf0e10cSrcweir 		else if( ( GetType() == SbxDECIMAL || rOp.GetType() == SbxDECIMAL ) &&
1299cdf0e10cSrcweir 			     ( eOp == SbxMUL || eOp == SbxDIV || eOp == SbxPLUS || eOp == SbxMINUS || eOp == SbxNEG ) )
1300cdf0e10cSrcweir 		{
1301cdf0e10cSrcweir 			aL.eType = aR.eType = SbxDECIMAL;
1302cdf0e10cSrcweir 			bDecimal = true;
1303cdf0e10cSrcweir 			if( rOp.Get( aR ) )
1304cdf0e10cSrcweir 			{
1305cdf0e10cSrcweir 				if( rOp.GetType() == SbxEMPTY )
1306cdf0e10cSrcweir 				{
1307cdf0e10cSrcweir 					releaseDecimalPtr( aL.pDecimal );
1308cdf0e10cSrcweir 					goto Lbl_OpIsEmpty;
1309cdf0e10cSrcweir 				}
1310cdf0e10cSrcweir 				if( Get( aL ) )
1311cdf0e10cSrcweir 				{
1312cdf0e10cSrcweir 					if( aL.pDecimal && aR.pDecimal )
1313cdf0e10cSrcweir 					{
1314cdf0e10cSrcweir 						bool bOk = true;
1315cdf0e10cSrcweir 						switch( eOp )
1316cdf0e10cSrcweir 						{
1317cdf0e10cSrcweir 							case SbxMUL:
1318cdf0e10cSrcweir 								bOk = ( *(aL.pDecimal) *= *(aR.pDecimal) );
1319cdf0e10cSrcweir 								break;
1320cdf0e10cSrcweir 							case SbxDIV:
1321cdf0e10cSrcweir 								if( aR.pDecimal->isZero() )
1322cdf0e10cSrcweir 									SetError( SbxERR_ZERODIV );
1323cdf0e10cSrcweir 								else
1324cdf0e10cSrcweir 									bOk = ( *(aL.pDecimal) /= *(aR.pDecimal) );
1325cdf0e10cSrcweir 								break;
1326cdf0e10cSrcweir 							case SbxPLUS:
1327cdf0e10cSrcweir 								bOk = ( *(aL.pDecimal) += *(aR.pDecimal) );
1328cdf0e10cSrcweir 								break;
1329cdf0e10cSrcweir 							case SbxMINUS:
1330cdf0e10cSrcweir 								bOk = ( *(aL.pDecimal) -= *(aR.pDecimal) );
1331cdf0e10cSrcweir 								break;
1332cdf0e10cSrcweir 							case SbxNEG:
1333cdf0e10cSrcweir 								bOk = ( aL.pDecimal->neg() );
1334cdf0e10cSrcweir 								break;
1335cdf0e10cSrcweir 							default:
1336cdf0e10cSrcweir 								SetError( SbxERR_NOTIMP );
1337cdf0e10cSrcweir 						}
1338cdf0e10cSrcweir 						if( !bOk )
1339cdf0e10cSrcweir 							SetError( SbxERR_OVERFLOW );
1340cdf0e10cSrcweir 					}
1341cdf0e10cSrcweir 					else
1342cdf0e10cSrcweir 					{
1343cdf0e10cSrcweir 						SetError( SbxERR_CONVERSION );
1344cdf0e10cSrcweir 					}
1345cdf0e10cSrcweir 				}
1346cdf0e10cSrcweir 			}
1347cdf0e10cSrcweir 		}
1348cdf0e10cSrcweir 		else if( GetType() == SbxCURRENCY || rOp.GetType() == SbxCURRENCY )
1349cdf0e10cSrcweir 		{
1350cdf0e10cSrcweir 			aL.eType = SbxCURRENCY;
1351cdf0e10cSrcweir 			aR.eType = SbxCURRENCY;
1352cdf0e10cSrcweir 
1353cdf0e10cSrcweir 			if( rOp.Get( aR ) )
1354cdf0e10cSrcweir 			{
1355cdf0e10cSrcweir 				static BigInt n10K( 10000 );
1356cdf0e10cSrcweir 
1357cdf0e10cSrcweir 				if( rOp.GetType() == SbxEMPTY )
1358cdf0e10cSrcweir 					goto Lbl_OpIsEmpty;
1359cdf0e10cSrcweir 
1360cdf0e10cSrcweir 				if( Get( aL ) ) switch( eOp )
1361cdf0e10cSrcweir 				{
1362cdf0e10cSrcweir 					case SbxMUL:
1363cdf0e10cSrcweir 					{
1364cdf0e10cSrcweir 						// #i20704 Implement directly
1365cdf0e10cSrcweir 						BigInt b1( aL.nLong64 );
1366cdf0e10cSrcweir 						BigInt b2( aR.nLong64 );
1367cdf0e10cSrcweir 						b1 *= b2;
1368cdf0e10cSrcweir 						b1 /= n10K;
1369cdf0e10cSrcweir 						double d = double( b1 ) / 10000.0;
1370cdf0e10cSrcweir 						if( d > SbxMAXCURR || d < SbxMINCURR )
1371cdf0e10cSrcweir 							SetError( SbxERR_OVERFLOW );
1372cdf0e10cSrcweir 						else
1373cdf0e10cSrcweir 							b1.INT64( &aL.nLong64 );
1374cdf0e10cSrcweir 						break;
1375cdf0e10cSrcweir 					}
1376cdf0e10cSrcweir 					case SbxDIV:
1377cdf0e10cSrcweir 						if( !aR.nLong64 )
1378cdf0e10cSrcweir 						{
1379cdf0e10cSrcweir 							SetError( SbxERR_ZERODIV );
1380cdf0e10cSrcweir 						}
1381cdf0e10cSrcweir 						else
1382cdf0e10cSrcweir 						{
1383cdf0e10cSrcweir 							// #i20704 Implement directly
1384cdf0e10cSrcweir 							BigInt b1( aL.nLong64 );
1385cdf0e10cSrcweir 							BigInt b2( aR.nLong64 );
1386cdf0e10cSrcweir 							b1 *= n10K;
1387cdf0e10cSrcweir 							b1 /= b2;
1388cdf0e10cSrcweir 							double d = double( b1 ) / 10000.0;
1389cdf0e10cSrcweir 							if( d > SbxMAXCURR || d < SbxMINCURR )
1390cdf0e10cSrcweir 								SetError( SbxERR_OVERFLOW );
1391cdf0e10cSrcweir 							else
1392cdf0e10cSrcweir 								b1.INT64( &aL.nLong64 );
1393cdf0e10cSrcweir 						}
1394cdf0e10cSrcweir 						break;
1395cdf0e10cSrcweir 					case SbxPLUS:
1396cdf0e10cSrcweir 						aL.nLong64 += aR.nLong64; break;
1397cdf0e10cSrcweir 					case SbxMINUS:
1398cdf0e10cSrcweir 						aL.nLong64 -= aR.nLong64; break;
1399cdf0e10cSrcweir 					case SbxNEG:
1400cdf0e10cSrcweir 						aL.nLong64 = -aL.nLong64; break;
1401cdf0e10cSrcweir 					default:
1402cdf0e10cSrcweir 						SetError( SbxERR_NOTIMP );
1403cdf0e10cSrcweir 				}
1404cdf0e10cSrcweir 			}
1405cdf0e10cSrcweir 		}
1406cdf0e10cSrcweir 		else
1407cdf0e10cSrcweir Lbl_OpIsDouble:
1408cdf0e10cSrcweir 		{	// Andere Operatoren
1409cdf0e10cSrcweir 			aL.eType = aR.eType = SbxDOUBLE;
1410cdf0e10cSrcweir 			if( rOp.Get( aR ) )
1411cdf0e10cSrcweir 			{
1412cdf0e10cSrcweir 				if( rOp.GetType() == SbxEMPTY )
1413cdf0e10cSrcweir 				{
1414cdf0e10cSrcweir 					if ( !bVBAInterop || ( bVBAInterop && ( eOp != SbxNEG ) ) )
1415cdf0e10cSrcweir 						goto Lbl_OpIsEmpty;
1416cdf0e10cSrcweir 				}
1417cdf0e10cSrcweir 				if( Get( aL ) )
1418cdf0e10cSrcweir 				{
1419cdf0e10cSrcweir 					switch( eOp )
1420cdf0e10cSrcweir 					{
1421cdf0e10cSrcweir 						case SbxEXP:
1422cdf0e10cSrcweir 							aL.nDouble = pow( aL.nDouble, aR.nDouble );
1423cdf0e10cSrcweir 							break;
1424cdf0e10cSrcweir 						case SbxMUL:
1425cdf0e10cSrcweir 							aL.nDouble *= aR.nDouble; break;
1426cdf0e10cSrcweir 						case SbxDIV:
1427cdf0e10cSrcweir 							if( !aR.nDouble ) SetError( SbxERR_ZERODIV );
1428cdf0e10cSrcweir 							else aL.nDouble /= aR.nDouble; break;
1429cdf0e10cSrcweir 						case SbxPLUS:
1430cdf0e10cSrcweir 							aL.nDouble += aR.nDouble; break;
1431cdf0e10cSrcweir 						case SbxMINUS:
1432cdf0e10cSrcweir 							aL.nDouble -= aR.nDouble; break;
1433cdf0e10cSrcweir 						case SbxNEG:
1434cdf0e10cSrcweir 							aL.nDouble = -aL.nDouble; break;
1435cdf0e10cSrcweir 						default:
1436cdf0e10cSrcweir 							SetError( SbxERR_NOTIMP );
1437cdf0e10cSrcweir 					}
1438cdf0e10cSrcweir 
1439cdf0e10cSrcweir 					// #45465 Date braucht bei + eine Spezial-Behandlung
1440cdf0e10cSrcweir 					if( eOp == SbxPLUS && (GetType() == SbxDATE || rOp.GetType() == SbxDATE ) )
1441cdf0e10cSrcweir 						aL.eType = SbxDATE;
1442cdf0e10cSrcweir 				}
1443cdf0e10cSrcweir 			}
1444cdf0e10cSrcweir 
1445cdf0e10cSrcweir 		}
1446cdf0e10cSrcweir 		if( !IsError() )
1447cdf0e10cSrcweir 			Put( aL );
1448cdf0e10cSrcweir 		if( bDecimal )
1449cdf0e10cSrcweir 		{
1450cdf0e10cSrcweir 			releaseDecimalPtr( aL.pDecimal );
1451cdf0e10cSrcweir 			releaseDecimalPtr( aR.pDecimal );
1452cdf0e10cSrcweir 		}
1453cdf0e10cSrcweir 	}
1454cdf0e10cSrcweir Lbl_OpIsEmpty:
1455cdf0e10cSrcweir 
1456cdf0e10cSrcweir 	sal_Bool bRes = sal_Bool( !IsError() );
1457cdf0e10cSrcweir 	if( bRes && eOld != SbxERR_OK )
1458cdf0e10cSrcweir 		SetError( eOld );
1459cdf0e10cSrcweir 	return bRes;
1460cdf0e10cSrcweir }
1461cdf0e10cSrcweir 
1462cdf0e10cSrcweir // Die Vergleichs-Routine liefert sal_True oder sal_False.
1463cdf0e10cSrcweir 
Compare(SbxOperator eOp,const SbxValue & rOp) const1464cdf0e10cSrcweir sal_Bool SbxValue::Compare( SbxOperator eOp, const SbxValue& rOp ) const
1465cdf0e10cSrcweir {
1466cdf0e10cSrcweir 	bool bVBAInterop =  SbiRuntime::isVBAEnabled();
1467cdf0e10cSrcweir 
1468cdf0e10cSrcweir 	sal_Bool bRes = sal_False;
1469cdf0e10cSrcweir 	SbxError eOld = GetError();
1470cdf0e10cSrcweir 	if( eOld != SbxERR_OK )
1471cdf0e10cSrcweir 		ResetError();
1472cdf0e10cSrcweir 	if( !CanRead() || !rOp.CanRead() )
1473cdf0e10cSrcweir 		SetError( SbxERR_PROP_WRITEONLY );
1474cdf0e10cSrcweir 	else if( GetType() == SbxNULL && rOp.GetType() == SbxNULL && !bVBAInterop )
1475cdf0e10cSrcweir     {
1476cdf0e10cSrcweir 		bRes = sal_True;
1477cdf0e10cSrcweir     }
1478cdf0e10cSrcweir 	else if( GetType() == SbxEMPTY && rOp.GetType() == SbxEMPTY )
1479cdf0e10cSrcweir 		bRes = !bVBAInterop ? sal_True : ( eOp == SbxEQ ? sal_True : sal_False );
1480cdf0e10cSrcweir 	// Sonderregel 1: Ist ein Operand Null, ist das Ergebnis FALSE
1481cdf0e10cSrcweir 	else if( GetType() == SbxNULL || rOp.GetType() == SbxNULL )
1482cdf0e10cSrcweir 		bRes = sal_False;
1483cdf0e10cSrcweir 	// Sonderregel 2: Wenn beide Variant sind und einer ist numerisch,
1484cdf0e10cSrcweir 	// und der andere ein String, ist num < str
1485cdf0e10cSrcweir 	else if( !IsFixed() && !rOp.IsFixed()
1486cdf0e10cSrcweir 	 && ( rOp.GetType() == SbxSTRING && GetType() != SbxSTRING && IsNumeric() ) && !bVBAInterop
1487cdf0e10cSrcweir 	)
1488cdf0e10cSrcweir 		bRes = sal_Bool( eOp == SbxLT || eOp == SbxLE || eOp == SbxNE );
1489cdf0e10cSrcweir 	else if( !IsFixed() && !rOp.IsFixed()
1490cdf0e10cSrcweir 	 && ( GetType() == SbxSTRING && rOp.GetType() != SbxSTRING && rOp.IsNumeric() )
1491cdf0e10cSrcweir && !bVBAInterop
1492cdf0e10cSrcweir 	)
1493cdf0e10cSrcweir 		bRes = sal_Bool( eOp == SbxGT || eOp == SbxGE || eOp == SbxNE );
1494cdf0e10cSrcweir 	else
1495cdf0e10cSrcweir 	{
1496cdf0e10cSrcweir 		SbxValues aL, aR;
1497cdf0e10cSrcweir 		// Wenn einer der Operanden ein String ist,
1498cdf0e10cSrcweir 		// findet ein Stringvergleich statt
1499cdf0e10cSrcweir 		if( GetType() == SbxSTRING || rOp.GetType() == SbxSTRING )
1500cdf0e10cSrcweir 		{
1501cdf0e10cSrcweir 			aL.eType = aR.eType = SbxSTRING;
1502cdf0e10cSrcweir 			if( Get( aL ) && rOp.Get( aR ) ) switch( eOp )
1503cdf0e10cSrcweir 			{
1504cdf0e10cSrcweir 				case SbxEQ:
1505cdf0e10cSrcweir 					bRes = sal_Bool( *aL.pOUString == *aR.pOUString ); break;
1506cdf0e10cSrcweir 				case SbxNE:
1507cdf0e10cSrcweir 					bRes = sal_Bool( *aL.pOUString != *aR.pOUString ); break;
1508cdf0e10cSrcweir 				case SbxLT:
1509cdf0e10cSrcweir 					bRes = sal_Bool( *aL.pOUString <  *aR.pOUString ); break;
1510cdf0e10cSrcweir 				case SbxGT:
1511cdf0e10cSrcweir 					bRes = sal_Bool( *aL.pOUString >  *aR.pOUString ); break;
1512cdf0e10cSrcweir 				case SbxLE:
1513cdf0e10cSrcweir 					bRes = sal_Bool( *aL.pOUString <= *aR.pOUString ); break;
1514cdf0e10cSrcweir 				case SbxGE:
1515cdf0e10cSrcweir 					bRes = sal_Bool( *aL.pOUString >= *aR.pOUString ); break;
1516cdf0e10cSrcweir 				default:
1517cdf0e10cSrcweir 					SetError( SbxERR_NOTIMP );
1518cdf0e10cSrcweir 			}
1519cdf0e10cSrcweir 		}
1520cdf0e10cSrcweir 		// AB 19.12.95: Wenn SbxSINGLE beteiligt, auf SINGLE konvertieren,
1521cdf0e10cSrcweir 		//				sonst gibt es numerische Fehler
1522cdf0e10cSrcweir 		else if( GetType() == SbxSINGLE || rOp.GetType() == SbxSINGLE )
1523cdf0e10cSrcweir 		{
1524cdf0e10cSrcweir 			aL.eType = aR.eType = SbxSINGLE;
1525cdf0e10cSrcweir 			if( Get( aL ) && rOp.Get( aR ) )
1526cdf0e10cSrcweir 			  switch( eOp )
1527cdf0e10cSrcweir 			{
1528cdf0e10cSrcweir 				case SbxEQ:
1529cdf0e10cSrcweir 					bRes = sal_Bool( aL.nSingle == aR.nSingle ); break;
1530cdf0e10cSrcweir 				case SbxNE:
1531cdf0e10cSrcweir 					bRes = sal_Bool( aL.nSingle != aR.nSingle ); break;
1532cdf0e10cSrcweir 				case SbxLT:
1533cdf0e10cSrcweir 					bRes = sal_Bool( aL.nSingle <  aR.nSingle ); break;
1534cdf0e10cSrcweir 				case SbxGT:
1535cdf0e10cSrcweir 					bRes = sal_Bool( aL.nSingle >  aR.nSingle ); break;
1536cdf0e10cSrcweir 				case SbxLE:
1537cdf0e10cSrcweir 					bRes = sal_Bool( aL.nSingle <= aR.nSingle ); break;
1538cdf0e10cSrcweir 				case SbxGE:
1539cdf0e10cSrcweir 					bRes = sal_Bool( aL.nSingle >= aR.nSingle ); break;
1540cdf0e10cSrcweir 				default:
1541cdf0e10cSrcweir 					SetError( SbxERR_NOTIMP );
1542cdf0e10cSrcweir 			}
1543cdf0e10cSrcweir 		}
1544cdf0e10cSrcweir 		else if( GetType() == SbxDECIMAL && rOp.GetType() == SbxDECIMAL )
1545cdf0e10cSrcweir 		{
1546cdf0e10cSrcweir 			aL.eType = aR.eType = SbxDECIMAL;
1547cdf0e10cSrcweir 			Get( aL );
1548cdf0e10cSrcweir 			rOp.Get( aR );
1549cdf0e10cSrcweir 			if( aL.pDecimal && aR.pDecimal )
1550cdf0e10cSrcweir 			{
1551cdf0e10cSrcweir 				SbxDecimal::CmpResult eRes = compare( *aL.pDecimal, *aR.pDecimal );
1552cdf0e10cSrcweir 				switch( eOp )
1553cdf0e10cSrcweir 				{
1554cdf0e10cSrcweir 					case SbxEQ:
1555cdf0e10cSrcweir 						bRes = sal_Bool( eRes == SbxDecimal::EQ ); break;
1556cdf0e10cSrcweir 					case SbxNE:
1557cdf0e10cSrcweir 						bRes = sal_Bool( eRes != SbxDecimal::EQ ); break;
1558cdf0e10cSrcweir 					case SbxLT:
1559cdf0e10cSrcweir 						bRes = sal_Bool( eRes == SbxDecimal::LT ); break;
1560cdf0e10cSrcweir 					case SbxGT:
1561cdf0e10cSrcweir 						bRes = sal_Bool( eRes == SbxDecimal::GT ); break;
1562cdf0e10cSrcweir 					case SbxLE:
1563cdf0e10cSrcweir 						bRes = sal_Bool( eRes != SbxDecimal::GT ); break;
1564cdf0e10cSrcweir 					case SbxGE:
1565cdf0e10cSrcweir 						bRes = sal_Bool( eRes != SbxDecimal::LT ); break;
1566cdf0e10cSrcweir 					default:
1567cdf0e10cSrcweir 						SetError( SbxERR_NOTIMP );
1568cdf0e10cSrcweir 				}
1569cdf0e10cSrcweir 			}
1570cdf0e10cSrcweir 			else
1571cdf0e10cSrcweir 			{
1572cdf0e10cSrcweir 				SetError( SbxERR_CONVERSION );
1573cdf0e10cSrcweir 			}
1574cdf0e10cSrcweir 			releaseDecimalPtr( aL.pDecimal );
1575cdf0e10cSrcweir 			releaseDecimalPtr( aR.pDecimal );
1576cdf0e10cSrcweir 		}
1577cdf0e10cSrcweir 		// Alles andere auf SbxDOUBLE-Basis vergleichen
1578cdf0e10cSrcweir 		else
1579cdf0e10cSrcweir 		{
1580cdf0e10cSrcweir 			aL.eType = aR.eType = SbxDOUBLE;
1581cdf0e10cSrcweir 			//if( Get( aL ) && rOp.Get( aR ) )
1582cdf0e10cSrcweir 			bool bGetL = Get( aL );
1583cdf0e10cSrcweir 			bool bGetR = rOp.Get( aR );
1584cdf0e10cSrcweir 			if( bGetL && bGetR )
1585cdf0e10cSrcweir 			  switch( eOp )
1586cdf0e10cSrcweir 			{
1587cdf0e10cSrcweir 				case SbxEQ:
1588cdf0e10cSrcweir 					bRes = sal_Bool( aL.nDouble == aR.nDouble ); break;
1589cdf0e10cSrcweir 				case SbxNE:
1590cdf0e10cSrcweir 					bRes = sal_Bool( aL.nDouble != aR.nDouble ); break;
1591cdf0e10cSrcweir 				case SbxLT:
1592cdf0e10cSrcweir 					bRes = sal_Bool( aL.nDouble <  aR.nDouble ); break;
1593cdf0e10cSrcweir 				case SbxGT:
1594cdf0e10cSrcweir 					bRes = sal_Bool( aL.nDouble >  aR.nDouble ); break;
1595cdf0e10cSrcweir 				case SbxLE:
1596cdf0e10cSrcweir 					bRes = sal_Bool( aL.nDouble <= aR.nDouble ); break;
1597cdf0e10cSrcweir 				case SbxGE:
1598cdf0e10cSrcweir 					bRes = sal_Bool( aL.nDouble >= aR.nDouble ); break;
1599cdf0e10cSrcweir 				default:
1600cdf0e10cSrcweir 					SetError( SbxERR_NOTIMP );
1601cdf0e10cSrcweir 			}
1602cdf0e10cSrcweir 			// at least one value was got
1603cdf0e10cSrcweir 			// if this is VBA then a conversion error for one
1604cdf0e10cSrcweir 			// side will yield a false result of an equality test
1605cdf0e10cSrcweir 			else if ( bGetR || bGetL )
1606cdf0e10cSrcweir 			{
1607cdf0e10cSrcweir 				if ( bVBAInterop && eOp == SbxEQ && GetError() == SbxERR_CONVERSION )
1608cdf0e10cSrcweir 				{
1609cdf0e10cSrcweir 					ResetError();
1610cdf0e10cSrcweir 					bRes = sal_False;
1611cdf0e10cSrcweir 				}
1612cdf0e10cSrcweir 			}
1613cdf0e10cSrcweir 		}
1614cdf0e10cSrcweir 	}
1615cdf0e10cSrcweir 	if( eOld != SbxERR_OK )
1616cdf0e10cSrcweir 		SetError( eOld );
1617cdf0e10cSrcweir 	return bRes;
1618cdf0e10cSrcweir }
1619cdf0e10cSrcweir 
1620cdf0e10cSrcweir ///////////////////////////// Lesen/Schreiben ////////////////////////////
1621cdf0e10cSrcweir 
LoadData(SvStream & r,sal_uInt16)1622cdf0e10cSrcweir sal_Bool SbxValue::LoadData( SvStream& r, sal_uInt16 )
1623cdf0e10cSrcweir {
1624cdf0e10cSrcweir 	SbxValue::Clear();
1625cdf0e10cSrcweir 	sal_uInt16 nType;
1626cdf0e10cSrcweir 	r >> nType;
1627cdf0e10cSrcweir 	aData.eType = SbxDataType( nType );
1628cdf0e10cSrcweir 	switch( nType )
1629cdf0e10cSrcweir 	{
1630cdf0e10cSrcweir 		case SbxBOOL:
1631cdf0e10cSrcweir 		case SbxINTEGER:
1632cdf0e10cSrcweir 			r >> aData.nInteger; break;
1633cdf0e10cSrcweir 		case SbxLONG:
1634cdf0e10cSrcweir 			r >> aData.nLong; break;
1635cdf0e10cSrcweir 		case SbxSINGLE:
1636cdf0e10cSrcweir 		{
1637cdf0e10cSrcweir 			// Floats als ASCII
1638cdf0e10cSrcweir 			XubString aVal;
1639cdf0e10cSrcweir 			r.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US );
1640cdf0e10cSrcweir 			double d;
1641cdf0e10cSrcweir 			SbxDataType t;
1642cdf0e10cSrcweir 			if( ImpScan( aVal, d, t, NULL ) != SbxERR_OK || t == SbxDOUBLE )
1643cdf0e10cSrcweir 			{
1644cdf0e10cSrcweir 				aData.nSingle = 0.0F;
1645cdf0e10cSrcweir 				return sal_False;
1646cdf0e10cSrcweir 			}
1647cdf0e10cSrcweir 			aData.nSingle = (float) d;
1648cdf0e10cSrcweir 			break;
1649cdf0e10cSrcweir 		}
1650cdf0e10cSrcweir 		case SbxDATE:
1651cdf0e10cSrcweir 		case SbxDOUBLE:
1652cdf0e10cSrcweir 		{
1653cdf0e10cSrcweir 			// Floats als ASCII
1654cdf0e10cSrcweir 			XubString aVal;
1655cdf0e10cSrcweir 			r.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US );
1656cdf0e10cSrcweir 			SbxDataType t;
1657cdf0e10cSrcweir 			if( ImpScan( aVal, aData.nDouble, t, NULL ) != SbxERR_OK )
1658cdf0e10cSrcweir 			{
1659cdf0e10cSrcweir 				aData.nDouble = 0.0;
1660cdf0e10cSrcweir 				return sal_False;
1661cdf0e10cSrcweir 			}
1662cdf0e10cSrcweir 			break;
1663cdf0e10cSrcweir 		}
1664cdf0e10cSrcweir 		case SbxULONG64:
1665cdf0e10cSrcweir 		{
1666cdf0e10cSrcweir 			r >> aData.nULong64.nHigh >> aData.nULong64.nLow;
1667cdf0e10cSrcweir 			break;
1668cdf0e10cSrcweir 		}
1669cdf0e10cSrcweir 		case SbxLONG64:
1670cdf0e10cSrcweir 		case SbxCURRENCY:
1671cdf0e10cSrcweir 		{
1672cdf0e10cSrcweir 			r >> aData.nLong64.nHigh >> aData.nLong64.nLow;
1673cdf0e10cSrcweir 			break;
1674cdf0e10cSrcweir 		}
1675cdf0e10cSrcweir 		case SbxSTRING:
1676cdf0e10cSrcweir 		{
1677cdf0e10cSrcweir 			XubString aVal;
1678cdf0e10cSrcweir 			r.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US );
1679cdf0e10cSrcweir 			if( aVal.Len() )
1680cdf0e10cSrcweir 				aData.pOUString = new ::rtl::OUString( aVal );
1681cdf0e10cSrcweir 			else
1682cdf0e10cSrcweir 				aData.pOUString = NULL; // JSM 22.09.1995
1683cdf0e10cSrcweir 			break;
1684cdf0e10cSrcweir 		}
1685cdf0e10cSrcweir 		case SbxERROR:
1686cdf0e10cSrcweir 		case SbxUSHORT:
1687cdf0e10cSrcweir 			r >> aData.nUShort; break;
1688cdf0e10cSrcweir 		case SbxOBJECT:
1689cdf0e10cSrcweir 		{
1690cdf0e10cSrcweir 			sal_uInt8 nMode;
1691cdf0e10cSrcweir 			r >> nMode;
1692cdf0e10cSrcweir 			switch( nMode )
1693cdf0e10cSrcweir 			{
1694cdf0e10cSrcweir 				case 0:
1695cdf0e10cSrcweir 					aData.pObj = NULL;
1696cdf0e10cSrcweir 					break;
1697cdf0e10cSrcweir 				case 1:
1698cdf0e10cSrcweir 					aData.pObj = SbxBase::Load( r );
1699cdf0e10cSrcweir 					return sal_Bool( aData.pObj != NULL );
1700cdf0e10cSrcweir 				case 2:
1701cdf0e10cSrcweir 					aData.pObj = this;
1702cdf0e10cSrcweir 					break;
1703cdf0e10cSrcweir 			}
1704cdf0e10cSrcweir 			break;
1705cdf0e10cSrcweir 		}
1706cdf0e10cSrcweir 		case SbxCHAR:
1707cdf0e10cSrcweir 		{
1708cdf0e10cSrcweir 			char c;
1709cdf0e10cSrcweir 			r >> c;
1710cdf0e10cSrcweir 			aData.nChar = c;
1711cdf0e10cSrcweir 			break;
1712cdf0e10cSrcweir 		}
1713cdf0e10cSrcweir 		case SbxBYTE:
1714cdf0e10cSrcweir 			r >> aData.nByte; break;
1715cdf0e10cSrcweir 		case SbxULONG:
1716cdf0e10cSrcweir 			r >> aData.nULong; break;
1717cdf0e10cSrcweir 		case SbxINT:
1718cdf0e10cSrcweir 		{
1719cdf0e10cSrcweir 			sal_uInt8 n;
1720cdf0e10cSrcweir 			r >> n;
1721cdf0e10cSrcweir 			// Passt der Int auf diesem System?
1722cdf0e10cSrcweir 			if( n > SAL_TYPES_SIZEOFINT )
1723cdf0e10cSrcweir 				r >> aData.nLong, aData.eType = SbxLONG;
1724cdf0e10cSrcweir 			else
1725cdf0e10cSrcweir 				r >> aData.nInt;
1726cdf0e10cSrcweir 			break;
1727cdf0e10cSrcweir 		}
1728cdf0e10cSrcweir 		case SbxUINT:
1729cdf0e10cSrcweir 		{
1730cdf0e10cSrcweir 			sal_uInt8 n;
1731cdf0e10cSrcweir 			r >> n;
1732cdf0e10cSrcweir 			// Passt der UInt auf diesem System?
1733cdf0e10cSrcweir 			if( n > SAL_TYPES_SIZEOFINT )
1734cdf0e10cSrcweir 				r >> aData.nULong, aData.eType = SbxULONG;
1735cdf0e10cSrcweir 			else
1736cdf0e10cSrcweir 				r >> (sal_uInt32&)aData.nUInt;
1737cdf0e10cSrcweir 			break;
1738cdf0e10cSrcweir 		}
1739cdf0e10cSrcweir 		case SbxEMPTY:
1740cdf0e10cSrcweir 		case SbxNULL:
1741cdf0e10cSrcweir 		case SbxVOID:
1742cdf0e10cSrcweir 			break;
1743cdf0e10cSrcweir 		case SbxDATAOBJECT:
1744cdf0e10cSrcweir 			r >> aData.nLong;
1745cdf0e10cSrcweir 			break;
1746cdf0e10cSrcweir 		// #78919 For backwards compatibility
1747cdf0e10cSrcweir 		case SbxWSTRING:
1748cdf0e10cSrcweir 		case SbxWCHAR:
1749cdf0e10cSrcweir 			break;
1750cdf0e10cSrcweir 		default:
1751cdf0e10cSrcweir 			memset (&aData,0,sizeof(aData));
1752cdf0e10cSrcweir 			ResetFlag(SBX_FIXED);
1753cdf0e10cSrcweir 			aData.eType = SbxNULL;
1754*870262e3SDon Lewis 			DBG_ASSERT( sal_False, "Unsupported data type loaded" );
1755cdf0e10cSrcweir 			return sal_False;
1756cdf0e10cSrcweir 	}
1757cdf0e10cSrcweir 	return sal_True;
1758cdf0e10cSrcweir }
1759cdf0e10cSrcweir 
StoreData(SvStream & r) const1760cdf0e10cSrcweir sal_Bool SbxValue::StoreData( SvStream& r ) const
1761cdf0e10cSrcweir {
1762cdf0e10cSrcweir 	sal_uInt16 nType = sal::static_int_cast< sal_uInt16 >(aData.eType);
1763cdf0e10cSrcweir 	r << nType;
1764cdf0e10cSrcweir 	switch( nType & 0x0FFF )
1765cdf0e10cSrcweir 	{
1766cdf0e10cSrcweir 		case SbxBOOL:
1767cdf0e10cSrcweir 		case SbxINTEGER:
1768cdf0e10cSrcweir 			r << aData.nInteger; break;
1769cdf0e10cSrcweir 		case SbxLONG:
1770cdf0e10cSrcweir 			r << aData.nLong; break;
1771cdf0e10cSrcweir 		case SbxDATE:
1772cdf0e10cSrcweir 			// #49935: Als double speichern, sonst Fehler beim Einlesen
1773cdf0e10cSrcweir 			((SbxValue*)this)->aData.eType = (SbxDataType)( ( nType & 0xF000 ) | SbxDOUBLE );
1774cdf0e10cSrcweir 			r.WriteByteString( GetCoreString(), RTL_TEXTENCODING_ASCII_US );
1775cdf0e10cSrcweir 			((SbxValue*)this)->aData.eType = (SbxDataType)nType;
1776cdf0e10cSrcweir 			break;
1777cdf0e10cSrcweir 		case SbxSINGLE:
1778cdf0e10cSrcweir 		case SbxDOUBLE:
1779cdf0e10cSrcweir 			r.WriteByteString( GetCoreString(), RTL_TEXTENCODING_ASCII_US );
1780cdf0e10cSrcweir 			break;
1781cdf0e10cSrcweir 		case SbxULONG64:
1782cdf0e10cSrcweir 		{
1783cdf0e10cSrcweir 			r << aData.nULong64.nHigh << aData.nULong64.nLow;
1784cdf0e10cSrcweir 			break;
1785cdf0e10cSrcweir 		}
1786cdf0e10cSrcweir 		case SbxLONG64:
1787cdf0e10cSrcweir 		case SbxCURRENCY:
1788cdf0e10cSrcweir 		{
1789cdf0e10cSrcweir 			r << aData.nLong64.nHigh << aData.nLong64.nLow;
1790cdf0e10cSrcweir 			break;
1791cdf0e10cSrcweir 		}
1792cdf0e10cSrcweir 		case SbxSTRING:
1793cdf0e10cSrcweir 			if( aData.pOUString )
1794cdf0e10cSrcweir 			{
1795cdf0e10cSrcweir 				r.WriteByteString( *aData.pOUString, RTL_TEXTENCODING_ASCII_US );
1796cdf0e10cSrcweir 			}
1797cdf0e10cSrcweir 			else
1798cdf0e10cSrcweir 			{
1799cdf0e10cSrcweir 				String aEmpty;
1800cdf0e10cSrcweir 				r.WriteByteString( aEmpty, RTL_TEXTENCODING_ASCII_US );
1801cdf0e10cSrcweir 			}
1802cdf0e10cSrcweir 			break;
1803cdf0e10cSrcweir 		case SbxERROR:
1804cdf0e10cSrcweir 		case SbxUSHORT:
1805cdf0e10cSrcweir 			r << aData.nUShort; break;
1806cdf0e10cSrcweir 		case SbxOBJECT:
1807cdf0e10cSrcweir 			// sich selbst als Objektptr speichern geht nicht!
1808cdf0e10cSrcweir 			if( aData.pObj )
1809cdf0e10cSrcweir 			{
1810cdf0e10cSrcweir 				if( PTR_CAST(SbxValue,aData.pObj) != this )
1811cdf0e10cSrcweir 				{
1812cdf0e10cSrcweir 					r << (sal_uInt8) 1;
1813cdf0e10cSrcweir 					return aData.pObj->Store( r );
1814cdf0e10cSrcweir 				}
1815cdf0e10cSrcweir 				else
1816cdf0e10cSrcweir 					r << (sal_uInt8) 2;
1817cdf0e10cSrcweir 			}
1818cdf0e10cSrcweir 			else
1819cdf0e10cSrcweir 				r << (sal_uInt8) 0;
1820cdf0e10cSrcweir 			break;
1821cdf0e10cSrcweir 		case SbxCHAR:
1822cdf0e10cSrcweir 		{
1823cdf0e10cSrcweir 			char c = sal::static_int_cast< char >(aData.nChar);
1824cdf0e10cSrcweir 			r << c;
1825cdf0e10cSrcweir 			break;
1826cdf0e10cSrcweir 		}
1827cdf0e10cSrcweir 		case SbxBYTE:
1828cdf0e10cSrcweir 			r << aData.nByte; break;
1829cdf0e10cSrcweir 		case SbxULONG:
1830cdf0e10cSrcweir 			r << aData.nULong; break;
1831cdf0e10cSrcweir 		case SbxINT:
1832cdf0e10cSrcweir 		{
1833cdf0e10cSrcweir 			sal_uInt8 n = SAL_TYPES_SIZEOFINT;
1834cdf0e10cSrcweir 			r << n << (sal_Int32)aData.nInt;
1835cdf0e10cSrcweir 			break;
1836cdf0e10cSrcweir 		}
1837cdf0e10cSrcweir 		case SbxUINT:
1838cdf0e10cSrcweir 		{
1839cdf0e10cSrcweir 			sal_uInt8 n = SAL_TYPES_SIZEOFINT;
1840cdf0e10cSrcweir 			r << n << (sal_uInt32)aData.nUInt;
1841cdf0e10cSrcweir 			break;
1842cdf0e10cSrcweir 		}
1843cdf0e10cSrcweir 		case SbxEMPTY:
1844cdf0e10cSrcweir 		case SbxNULL:
1845cdf0e10cSrcweir 		case SbxVOID:
1846cdf0e10cSrcweir 			break;
1847cdf0e10cSrcweir 		case SbxDATAOBJECT:
1848cdf0e10cSrcweir 			r << aData.nLong;
1849cdf0e10cSrcweir 			break;
1850cdf0e10cSrcweir 		// #78919 For backwards compatibility
1851cdf0e10cSrcweir 		case SbxWSTRING:
1852cdf0e10cSrcweir 		case SbxWCHAR:
1853cdf0e10cSrcweir 			break;
1854cdf0e10cSrcweir 		default:
1855*870262e3SDon Lewis 			DBG_ASSERT( sal_False, "Save an unsupported data type" );
1856cdf0e10cSrcweir 			return sal_False;
1857cdf0e10cSrcweir 	}
1858cdf0e10cSrcweir 	return sal_True;
1859cdf0e10cSrcweir }
1860cdf0e10cSrcweir 
1861