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