1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sbxvalue.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basic.hxx"
34 #define _TLBIGINT_INT64
35 #include <tools/bigint.hxx>
36 #include <tools/stream.hxx>
38 #include <basic/sbx.hxx>
39 #include "sbxconv.hxx"
41 #include "runtime.hxx"
42 // AB 29.10.99 Unicode
43 #ifndef _USE_NO_NAMESPACE
48 TYPEINIT1(SbxValue
,SbxBase
)
50 /////////////////////////// SbxINT64 /////////////////////////////////////
51 SbxINT64
&SbxINT64::operator -= ( const SbxINT64
&r
)
58 SbxINT64
&SbxINT64::operator += ( const SbxINT64
&r
)
65 SbxINT64
&SbxINT64::operator *= ( const SbxINT64
&r
)
72 SbxINT64
&SbxINT64::operator %= ( const SbxINT64
&r
)
79 SbxINT64
&SbxINT64::operator /= ( const SbxINT64
&r
)
86 SbxINT64
&SbxINT64::operator &= ( const SbxINT64
&r
)
92 SbxINT64
&SbxINT64::operator |= ( const SbxINT64
&r
)
98 SbxINT64
&SbxINT64::operator ^= ( const SbxINT64
&r
)
105 SbxINT64
operator - ( const SbxINT64
&l
, const SbxINT64
&r
)
111 SbxINT64
operator + ( const SbxINT64
&l
, const SbxINT64
&r
)
117 SbxINT64
operator / ( const SbxINT64
&l
, const SbxINT64
&r
)
123 SbxINT64
operator % ( const SbxINT64
&l
, const SbxINT64
&r
)
129 SbxINT64
operator * ( const SbxINT64
&l
, const SbxINT64
&r
)
135 SbxINT64
operator & ( const SbxINT64
&l
, const SbxINT64
&r
)
138 a
.nHigh
= r
.nHigh
& l
.nHigh
;
139 a
.nLow
= r
.nLow
& l
.nLow
;
142 SbxINT64
operator | ( const SbxINT64
&l
, const SbxINT64
&r
)
145 a
.nHigh
= r
.nHigh
| l
.nHigh
;
146 a
.nLow
= r
.nLow
| l
.nLow
;
149 SbxINT64
operator ^ ( const SbxINT64
&r
, const SbxINT64
&l
)
152 a
.nHigh
= r
.nHigh
^ l
.nHigh
;
153 a
.nLow
= r
.nLow
^ l
.nLow
;
157 SbxINT64
operator - ( const SbxINT64
&r
)
163 SbxINT64
operator ~ ( const SbxINT64
&r
)
171 SbxUINT64
&SbxUINT64::operator %= ( const SbxUINT64
&r
)
178 SbxUINT64
&SbxUINT64::operator /= ( const SbxUINT64
&r
)
185 /////////////////////////// Fehlerbehandlung /////////////////////////////
190 // Das Default-Handling setzt nur den Fehlercode.
194 int matherr( struct exception
* p
)
196 int matherr( struct _exception
* p
)
202 case OVERFLOW
: SbxBase::SetError( SbxERR_OVERFLOW
); break;
204 case _OVERFLOW
: SbxBase::SetError( SbxERR_OVERFLOW
); break;
206 default: SbxBase::SetError( SbxERR_NOTIMP
); break;
215 ///////////////////////////// Konstruktoren //////////////////////////////
217 SbxValue::SbxValue() : SbxBase()
219 aData
.eType
= SbxEMPTY
;
222 SbxValue::SbxValue( SbxDataType t
, void* p
) : SbxBase()
227 if( n
== SbxVARIANT
)
230 SetFlag( SBX_FIXED
);
234 case SbxINTEGER
: n
|= SbxBYREF
; aData
.pInteger
= (INT16
*) p
; break;
235 case SbxULONG64
: n
|= SbxBYREF
; aData
.pULong64
= (SbxUINT64
*) p
; break;
237 case SbxCURRENCY
: n
|= SbxBYREF
; aData
.pLong64
= (SbxINT64
*) p
; break;
238 case SbxLONG
: n
|= SbxBYREF
; aData
.pLong
= (INT32
*) p
; break;
239 case SbxSINGLE
: n
|= SbxBYREF
; aData
.pSingle
= (float*) p
; break;
241 case SbxDOUBLE
: n
|= SbxBYREF
; aData
.pDouble
= (double*) p
; break;
242 case SbxSTRING
: n
|= SbxBYREF
; aData
.pString
= (XubString
*) p
; break;
245 case SbxBOOL
: n
|= SbxBYREF
; aData
.pUShort
= (UINT16
*) p
; break;
246 case SbxULONG
: n
|= SbxBYREF
; aData
.pULong
= (UINT32
*) p
; break;
247 case SbxCHAR
: n
|= SbxBYREF
; aData
.pChar
= (xub_Unicode
*) p
; break;
248 case SbxBYTE
: n
|= SbxBYREF
; aData
.pByte
= (BYTE
*) p
; break;
249 case SbxINT
: n
|= SbxBYREF
; aData
.pInt
= (int*) p
; break;
251 aData
.pObj
= (SbxBase
*) p
;
253 aData
.pObj
->AddRef();
256 aData
.pDecimal
= (SbxDecimal
*) p
;
258 aData
.pDecimal
->addRef();
261 DBG_ASSERT( !this, "Angabe eines Pointers unzulaessig" );
265 memset( &aData
, 0, sizeof( SbxValues
) );
266 aData
.eType
= SbxDataType( n
);
269 SbxValue::SbxValue( const SbxValue
& r
)
270 : SvRefBase( r
), SbxBase( r
)
274 SetError( SbxERR_PROP_WRITEONLY
);
276 aData
.eType
= SbxNULL
;
280 ((SbxValue
*) &r
)->Broadcast( SBX_HINT_DATAWANTED
);
282 // Pointer kopieren, Referenzen inkrementieren
283 switch( aData
.eType
)
287 aData
.pString
= new XubString( *aData
.pString
);
291 aData
.pObj
->AddRef();
295 aData
.pDecimal
->addRef();
302 SbxValue
& SbxValue::operator=( const SbxValue
& r
)
307 SetError( SbxERR_PROP_READONLY
);
310 // string -> byte array
311 if( IsFixed() && (aData
.eType
== SbxOBJECT
)
312 && aData
.pObj
&& ( aData
.pObj
->GetType() == (SbxARRAY
| SbxBYTE
) )
313 && (r
.aData
.eType
== SbxSTRING
) )
315 String aStr
= r
.GetString();
316 SbxArray
* pArr
= StringToByteArray(aStr
);
320 // byte array -> string
321 if( r
.IsFixed() && (r
.aData
.eType
== SbxOBJECT
)
322 && r
.aData
.pObj
&& ( r
.aData
.pObj
->GetType() == (SbxARRAY
| SbxBYTE
) )
323 && (aData
.eType
== SbxSTRING
) )
325 SbxBase
* pObj
= r
.GetObject();
326 SbxArray
* pArr
= PTR_CAST(SbxArray
, pObj
);
329 String aStr
= ByteArrayToString( pArr
);
334 // Den Inhalt der Variablen auslesen
337 // fest: dann muss der Typ stimmen
338 aNew
.eType
= aData
.eType
;
339 else if( r
.IsFixed() )
340 // Quelle fest: Typ uebernehmen
341 aNew
.eType
= SbxDataType( r
.aData
.eType
& 0x0FFF );
343 // beides Variant: dann isses egal
344 aNew
.eType
= SbxVARIANT
;
352 SbxValue::~SbxValue()
355 Broadcast( SBX_HINT_DYING
);
356 SetFlag( SBX_WRITE
);
359 // Provisorischer Fix fuer Solaris 5.0 Compiler Bug
360 // bei Nutzung virtueller Vererbung. Virtuelle Calls
361 // im Destruktor vermeiden. Statt Clear() zu rufen
362 // moegliche Objekt-Referenzen direkt freigeben.
363 if( aData
.eType
== SbxOBJECT
)
365 if( aData
.pObj
&& aData
.pObj
!= this )
367 HACK(nicht bei Parent
-Prop
- sonst CyclicRef
)
368 SbxVariable
*pThisVar
= PTR_CAST(SbxVariable
, this);
369 BOOL bParentProp
= pThisVar
&& 5345 ==
370 ( (INT16
) ( pThisVar
->GetUserData() & 0xFFFF ) );
372 aData
.pObj
->ReleaseRef();
375 else if( aData
.eType
== SbxDECIMAL
)
377 releaseDecimalPtr( aData
.pDecimal
);
382 void SbxValue::Clear()
384 switch( aData
.eType
)
391 delete aData
.pString
; aData
.pString
= NULL
;
396 if( aData
.pObj
!= this )
398 HACK(nicht bei Parent
-Prop
- sonst CyclicRef
)
399 SbxVariable
*pThisVar
= PTR_CAST(SbxVariable
, this);
400 BOOL bParentProp
= pThisVar
&& 5345 ==
401 ( (INT16
) ( pThisVar
->GetUserData() & 0xFFFF ) );
403 aData
.pObj
->ReleaseRef();
409 if( aData
.eType
== SbxDECIMAL
)
410 releaseDecimalPtr( aData
.pDecimal
);
413 aData
.pData
= NULL
; break;
417 memset( &aEmpty
, 0, sizeof( SbxValues
) );
418 aEmpty
.eType
= GetType();
426 void SbxValue::Broadcast( ULONG
)
429 //////////////////////////// Daten auslesen //////////////////////////////
431 // Ermitteln der "richtigen" Variablen. Falls es ein Objekt ist, wird
432 // entweder das Objekt selbst oder dessen Default-Property angesprochen.
433 // Falls die Variable eine Variable oder ein Objekt enthaelt, wird
434 // dieses angesprochen.
436 SbxValue
* SbxValue::TheRealValue() const
438 return TheRealValue( TRUE
);
441 // #55226 Zusaetzliche Info transportieren
442 SbxValue
* SbxValue::TheRealValue( BOOL bObjInObjError
) const
444 SbxValue
* p
= (SbxValue
*) this;
447 SbxDataType t
= SbxDataType( p
->aData
.eType
& 0x0FFF );
450 // Der Block enthaelt ein Objekt oder eine Variable
451 SbxObject
* pObj
= PTR_CAST(SbxObject
,p
->aData
.pObj
);
454 // Hat das Objekt eine Default-Property?
455 SbxVariable
* pDflt
= pObj
->GetDfltProperty();
457 // Falls dies ein Objekt ist und sich selbst enthaelt,
458 // koennen wir nicht darauf zugreifen
459 // #55226# Die alte Bedingung, um einen Fehler zu setzen,
460 // ist nicht richtig, da z.B. eine ganz normale Variant-
461 // Variable mit Objekt davon betroffen sein kann, wenn ein
462 // anderer Wert zugewiesen werden soll. Daher mit Flag.
463 if( bObjInObjError
&& !pDflt
&&
464 ((SbxValue
*) pObj
)->aData
.eType
== SbxOBJECT
&&
465 ((SbxValue
*) pObj
)->aData
.pObj
== pObj
)
467 SetError( SbxERR_BAD_PROP_VALUE
);
474 p = pDflt ? pDflt : (SbxVariable*) pObj;
478 // Haben wir ein Array?
479 SbxArray
* pArray
= PTR_CAST(SbxArray
,p
->aData
.pObj
);
482 // Ggf. Parameter holen
483 SbxArray
* pPar
= NULL
;
484 SbxVariable
* pVar
= PTR_CAST(SbxVariable
,p
);
486 pPar
= pVar
->GetParameters();
489 // Haben wir ein dimensioniertes Array?
490 SbxDimArray
* pDimArray
= PTR_CAST(SbxDimArray
,p
->aData
.pObj
);
492 p
= pDimArray
->Get( pPar
);
494 p
= pArray
->Get( pPar
->Get( 1 )->GetInteger() );
498 // Sonst einen SbxValue annehmen
499 SbxValue
* pVal
= PTR_CAST(SbxValue
,p
->aData
.pObj
);
511 BOOL
SbxValue::Get( SbxValues
& rRes
) const
514 SbxError eOld
= GetError();
515 if( eOld
!= SbxERR_OK
)
519 SetError( SbxERR_PROP_WRITEONLY
);
524 // Falls nach einem Objekt oder einem VARIANT gefragt wird, nicht
525 // die wahren Werte suchen
526 SbxValue
* p
= (SbxValue
*) this;
527 if( rRes
.eType
!= SbxOBJECT
&& rRes
.eType
!= SbxVARIANT
)
531 p
->Broadcast( SBX_HINT_DATAWANTED
);
537 case SbxVARIANT
: rRes
= p
->aData
; break;
538 case SbxINTEGER
: rRes
.nInteger
= ImpGetInteger( &p
->aData
); break;
539 case SbxLONG
: rRes
.nLong
= ImpGetLong( &p
->aData
); break;
540 case SbxSALINT64
: rRes
.nInt64
= ImpGetInt64( &p
->aData
); break;
541 case SbxSALUINT64
: rRes
.uInt64
= ImpGetUInt64( &p
->aData
); break;
542 case SbxSINGLE
: rRes
.nSingle
= ImpGetSingle( &p
->aData
); break;
543 case SbxDOUBLE
: rRes
.nDouble
= ImpGetDouble( &p
->aData
); break;
544 case SbxCURRENCY
:rRes
.nLong64
= ImpGetCurrency( &p
->aData
); break;
545 case SbxDECIMAL
: rRes
.pDecimal
= ImpGetDecimal( &p
->aData
); break;
546 case SbxDATE
: rRes
.nDouble
= ImpGetDate( &p
->aData
); break;
548 rRes
.nUShort
= sal::static_int_cast
< UINT16
>(
549 ImpGetBool( &p
->aData
) );
551 case SbxCHAR
: rRes
.nChar
= ImpGetChar( &p
->aData
); break;
552 case SbxBYTE
: rRes
.nByte
= ImpGetByte( &p
->aData
); break;
553 case SbxUSHORT
: rRes
.nUShort
= ImpGetUShort( &p
->aData
); break;
554 case SbxULONG
: rRes
.nULong
= ImpGetULong( &p
->aData
); break;
556 case SbxSTRING
: p
->aPic
= ImpGetString( &p
->aData
);
557 rRes
.pString
= &p
->aPic
; break;
558 case SbxCoreSTRING
: p
->aPic
= ImpGetCoreString( &p
->aData
);
559 rRes
.pString
= &p
->aPic
; break;
561 #if SAL_TYPES_SIZEOFINT == 2
562 rRes
.nInt
= (int) ImpGetInteger( &p
->aData
);
564 rRes
.nInt
= (int) ImpGetLong( &p
->aData
);
568 #if SAL_TYPES_SIZEOFINT == 2
569 rRes
.nUInt
= (int) ImpGetUShort( &p
->aData
);
571 rRes
.nUInt
= (int) ImpGetULong( &p
->aData
);
575 if( p
->aData
.eType
== SbxOBJECT
)
576 rRes
.pObj
= p
->aData
.pObj
;
579 SetError( SbxERR_NO_OBJECT
);
584 if( p
->aData
.eType
== rRes
.eType
)
588 SetError( SbxERR_CONVERSION
);
595 // Objekt enthielt sich selbst
596 SbxDataType eTemp
= rRes
.eType
;
597 memset( &rRes
, 0, sizeof( SbxValues
) );
604 if( eOld
!= SbxERR_OK
)
610 BOOL
SbxValue::GetNoBroadcast( SbxValues
& rRes
)
612 USHORT nFlags_
= GetFlags();
613 SetFlag( SBX_NO_BROADCAST
);
614 BOOL bRes
= Get( rRes
);
619 const XubString
& SbxValue::GetString() const
622 aRes
.eType
= SbxSTRING
;
624 // Geht in Ordnung, da Ptr eine Kopie ist
625 return *aRes
.pString
;
628 ((SbxValue
*) this)->aPic
.Erase();
633 const XubString
& SbxValue::GetCoreString() const
636 aRes
.eType
= SbxCoreSTRING
;
638 // Geht in Ordnung, da Ptr eine Kopie ist
639 return *aRes
.pString
;
642 ((SbxValue
*) this)->aPic
.Erase();
647 BOOL
SbxValue::HasObject() const
649 ErrCode eErr
= GetError();
651 aRes
.eType
= SbxOBJECT
;
654 return 0 != aRes
.pObj
;
657 BOOL
SbxValue::GetBool() const
660 aRes
.eType
= SbxBOOL
;
662 return BOOL( aRes
.nUShort
!= 0 );
665 #define GET( g, e, t, m ) \
666 t SbxValue::g() const { SbxValues aRes(e); Get( aRes ); return aRes.m; }
668 GET( GetByte
, SbxBYTE
, BYTE
, nByte
)
669 GET( GetChar
, SbxCHAR
, xub_Unicode
, nChar
)
670 GET( GetCurrency
, SbxCURRENCY
, SbxINT64
, nLong64
)
671 GET( GetDate
, SbxDATE
, double, nDouble
)
672 GET( GetData
, SbxDATAOBJECT
, void*, pData
)
673 GET( GetDouble
, SbxDOUBLE
, double, nDouble
)
674 GET( GetErr
, SbxERROR
, UINT16
, nUShort
)
675 GET( GetInt
, SbxINT
, int, nInt
)
676 GET( GetInteger
, SbxINTEGER
, INT16
, nInteger
)
677 GET( GetLong
, SbxLONG
, INT32
, nLong
)
678 GET( GetLong64
, SbxLONG64
, SbxINT64
, nLong64
)
679 GET( GetObject
, SbxOBJECT
, SbxBase
*, pObj
)
680 GET( GetSingle
, SbxSINGLE
, float, nSingle
)
681 GET( GetULong
, SbxULONG
, UINT32
, nULong
)
682 GET( GetULong64
, SbxULONG64
, SbxUINT64
, nULong64
)
683 GET( GetUShort
, SbxUSHORT
, UINT16
, nUShort
)
684 GET( GetInt64
, SbxSALINT64
, sal_Int64
, nInt64
)
685 GET( GetUInt64
, SbxSALUINT64
, sal_uInt64
, uInt64
)
686 GET( GetDecimal
, SbxDECIMAL
, SbxDecimal
*, pDecimal
)
689 //////////////////////////// Daten schreiben /////////////////////////////
691 BOOL
SbxValue::Put( const SbxValues
& rVal
)
694 SbxError eOld
= GetError();
695 if( eOld
!= SbxERR_OK
)
698 SetError( SbxERR_PROP_READONLY
);
699 else if( rVal
.eType
& 0xF000 )
700 SetError( SbxERR_NOTIMP
);
703 // Falls nach einem Objekt gefragt wird, nicht
704 // die wahren Werte suchen
706 if( rVal
.eType
!= SbxOBJECT
)
707 p
= TheRealValue( FALSE
); // #55226 Hier keinen Fehler erlauben
711 SetError( SbxERR_PROP_READONLY
);
712 else if( p
->IsFixed() || p
->SetType( (SbxDataType
) ( rVal
.eType
& 0x0FFF ) ) )
713 switch( rVal
.eType
& 0x0FFF )
718 case SbxINTEGER
: ImpPutInteger( &p
->aData
, rVal
.nInteger
); break;
719 case SbxLONG
: ImpPutLong( &p
->aData
, rVal
.nLong
); break;
720 case SbxSALINT64
: ImpPutInt64( &p
->aData
, rVal
.nInt64
); break;
721 case SbxSALUINT64
: ImpPutUInt64( &p
->aData
, rVal
.uInt64
); break;
722 case SbxSINGLE
: ImpPutSingle( &p
->aData
, rVal
.nSingle
); break;
723 case SbxDOUBLE
: ImpPutDouble( &p
->aData
, rVal
.nDouble
); break;
724 case SbxCURRENCY
: ImpPutCurrency( &p
->aData
, rVal
.nLong64
); break;
725 case SbxDECIMAL
: ImpPutDecimal( &p
->aData
, rVal
.pDecimal
); break;
726 case SbxDATE
: ImpPutDate( &p
->aData
, rVal
.nDouble
); break;
727 case SbxBOOL
: ImpPutBool( &p
->aData
, rVal
.nInteger
); break;
728 case SbxCHAR
: ImpPutChar( &p
->aData
, rVal
.nChar
); break;
729 case SbxBYTE
: ImpPutByte( &p
->aData
, rVal
.nByte
); break;
730 case SbxUSHORT
: ImpPutUShort( &p
->aData
, rVal
.nUShort
); break;
731 case SbxULONG
: ImpPutULong( &p
->aData
, rVal
.nULong
); break;
733 case SbxSTRING
: ImpPutString( &p
->aData
, rVal
.pString
); break;
735 #if SAL_TYPES_SIZEOFINT == 2
736 ImpPutInteger( &p
->aData
, (INT16
) rVal
.nInt
);
738 ImpPutLong( &p
->aData
, (INT32
) rVal
.nInt
);
742 #if SAL_TYPES_SIZEOFINT == 2
743 ImpPutUShort( &p
->aData
, (UINT16
) rVal
.nUInt
);
745 ImpPutULong( &p
->aData
, (UINT32
) rVal
.nUInt
);
749 if( !p
->IsFixed() || p
->aData
.eType
== SbxOBJECT
)
752 if( p
->aData
.eType
== SbxOBJECT
&& p
->aData
.pObj
== rVal
.pObj
)
755 // Nur den Werteteil loeschen!
756 p
->SbxValue::Clear();
758 // eingentliche Zuweisung
759 p
->aData
.pObj
= rVal
.pObj
;
761 // ggf. Ref-Count mitzaehlen
762 if( p
->aData
.pObj
&& p
->aData
.pObj
!= p
)
766 DBG_ERROR( "TheRealValue" );
768 HACK(nicht bei Parent
-Prop
- sonst CyclicRef
)
769 SbxVariable
*pThisVar
= PTR_CAST(SbxVariable
, this);
770 BOOL bParentProp
= pThisVar
&& 5345 ==
771 ( (INT16
) ( pThisVar
->GetUserData() & 0xFFFF ) );
773 p
->aData
.pObj
->AddRef();
777 SetError( SbxERR_CONVERSION
);
780 if( p
->aData
.eType
== rVal
.eType
)
784 SetError( SbxERR_CONVERSION
);
786 p
->aData
.eType
= SbxNULL
;
791 p
->SetModified( TRUE
);
792 p
->Broadcast( SBX_HINT_DATACHANGED
);
793 if( eOld
!= SbxERR_OK
)
803 // Methode, um bei speziellen Typen eine Vorbehandlung des Strings
804 // durchzufuehren. Insbesondere erforderlich fuer BASIC-IDE, damit
805 // die Ausgaben im Watch-Fenster mit PutStringExt zurueckgeschrieben
806 // werden koennen, wenn Floats mit ',' als Dezimaltrenner oder BOOLs
807 // explizit mit "TRUE" oder "FALSE" angegeben werden.
808 // Implementierung in ImpConvStringExt (SBXSCAN.CXX)
809 BOOL
SbxValue::PutStringExt( const XubString
& r
)
811 // Kopieren, bei Unicode gleich konvertieren
814 // Eigenen Typ bestimmen (nicht wie in Put() mit TheRealValue(),
815 // Objekte werden sowieso nicht behandelt)
816 SbxDataType eTargetType
= SbxDataType( aData
.eType
& 0x0FFF );
818 // Source-Value basteln
820 aRes
.eType
= SbxSTRING
;
822 // Nur, wenn wirklich was konvertiert wurde, Kopie nehmen,
823 // sonst Original (Unicode bleibt erhalten)
825 if( ImpConvStringExt( aStr
, eTargetType
) )
826 aRes
.pString
= (XubString
*)&aStr
;
828 aRes
.pString
= (XubString
*)&r
;
830 // #34939: Bei Strings. die eine Zahl enthalten und wenn this einen
831 // Num-Typ hat, Fixed-Flag setzen, damit der Typ nicht veraendert wird
832 USHORT nFlags_
= GetFlags();
833 if( ( eTargetType
>= SbxINTEGER
&& eTargetType
<= SbxCURRENCY
) ||
834 ( eTargetType
>= SbxCHAR
&& eTargetType
<= SbxUINT
) ||
835 eTargetType
== SbxBOOL
)
839 if( aVal
.IsNumeric() )
840 SetFlag( SBX_FIXED
);
844 bRet
= BOOL( !IsError() );
846 // Falls das mit dem FIXED einen Error gegeben hat, zuruecksetzen
847 // (UI-Aktion sollte keinen Error ergeben, sondern nur scheitern)
855 BOOL
SbxValue::PutString( const xub_Unicode
* p
)
859 aRes
.eType
= SbxSTRING
;
860 aRes
.pString
= &aVal
;
862 return BOOL( !IsError() );
865 BOOL
SbxValue::PutBool( BOOL b
)
868 aRes
.eType
= SbxBOOL
;
869 aRes
.nUShort
= sal::static_int_cast
< UINT16
>(b
? SbxTRUE
: SbxFALSE
);
871 return BOOL( !IsError() );
874 BOOL
SbxValue::PutEmpty()
876 BOOL bRet
= SetType( SbxEMPTY
);
881 BOOL
SbxValue::PutNull()
883 BOOL bRet
= SetType( SbxNULL
);
890 // Special decimal methods
891 BOOL
SbxValue::PutDecimal( com::sun::star::bridge::oleautomation::Decimal
& rAutomationDec
)
894 aData
.pDecimal
= new SbxDecimal( rAutomationDec
);
895 aData
.pDecimal
->addRef();
896 aData
.eType
= SbxDECIMAL
;
900 BOOL
SbxValue::fillAutomationDecimal
901 ( com::sun::star::bridge::oleautomation::Decimal
& rAutomationDec
)
903 SbxDecimal
* pDecimal
= GetDecimal();
904 if( pDecimal
!= NULL
)
906 pDecimal
->fillAutomationDecimal( rAutomationDec
);
913 BOOL
SbxValue::PutpChar( const xub_Unicode
* p
)
917 aRes
.eType
= SbxLPSTR
;
918 aRes
.pString
= &aVal
;
920 return BOOL( !IsError() );
923 BOOL
SbxValue::PutString( const XubString
& r
)
926 aRes
.eType
= SbxSTRING
;
927 aRes
.pString
= (XubString
*) &r
;
929 return BOOL( !IsError() );
933 #define PUT( p, e, t, m ) \
934 BOOL SbxValue::p( t n ) \
935 { SbxValues aRes(e); aRes.m = n; Put( aRes ); return BOOL( !IsError() ); }
937 PUT( PutByte
, SbxBYTE
, BYTE
, nByte
)
938 PUT( PutChar
, SbxCHAR
, xub_Unicode
, nChar
)
939 PUT( PutCurrency
, SbxCURRENCY
, const SbxINT64
&, nLong64
)
940 PUT( PutDate
, SbxDATE
, double, nDouble
)
941 PUT( PutData
, SbxDATAOBJECT
, void*, pData
)
942 PUT( PutDouble
, SbxDOUBLE
, double, nDouble
)
943 PUT( PutErr
, SbxERROR
, UINT16
, nUShort
)
944 PUT( PutInt
, SbxINT
, int, nInt
)
945 PUT( PutInteger
, SbxINTEGER
, INT16
, nInteger
)
946 PUT( PutLong
, SbxLONG
, INT32
, nLong
)
947 PUT( PutLong64
, SbxLONG64
, const SbxINT64
&, nLong64
)
948 PUT( PutObject
, SbxOBJECT
, SbxBase
*, pObj
)
949 PUT( PutSingle
, SbxSINGLE
, float, nSingle
)
950 PUT( PutULong
, SbxULONG
, UINT32
, nULong
)
951 PUT( PutULong64
, SbxULONG64
, const SbxUINT64
&, nULong64
)
952 PUT( PutUShort
, SbxUSHORT
, UINT16
, nUShort
)
953 PUT( PutInt64
, SbxSALINT64
, sal_Int64
, nInt64
)
954 PUT( PutUInt64
, SbxSALUINT64
, sal_uInt64
, uInt64
)
955 PUT( PutDecimal
, SbxDECIMAL
, SbxDecimal
*, pDecimal
)
958 ////////////////////////// Setzen des Datentyps ///////////////////////////
960 BOOL
SbxValue::IsFixed() const
962 return ( (GetFlags() & SBX_FIXED
) | (aData
.eType
& SbxBYREF
) ) != 0;
965 // Eine Variable ist numerisch, wenn sie EMPTY oder wirklich numerisch ist
966 // oder einen vollstaendig konvertierbaren String enthaelt
968 // #41692, fuer RTL und Basic-Core getrennt implementieren
969 BOOL
SbxValue::IsNumeric() const
971 return ImpIsNumeric( /*bOnlyIntntl*/FALSE
);
974 BOOL
SbxValue::IsNumericRTL() const
976 return ImpIsNumeric( /*bOnlyIntntl*/TRUE
);
979 BOOL
SbxValue::ImpIsNumeric( BOOL bOnlyIntntl
) const
984 SetError( SbxERR_PROP_WRITEONLY
); return FALSE
;
986 // Downcast pruefen!!!
987 if( this->ISA(SbxVariable
) )
988 ((SbxVariable
*)this)->Broadcast( SBX_HINT_DATAWANTED
);
989 SbxDataType t
= GetType();
994 XubString
s( *aData
.pString
);
998 if( ImpScan( s
, n
, t2
, &nLen
, /*bAllowIntntl*/FALSE
, bOnlyIntntl
) == SbxERR_OK
)
999 return BOOL( nLen
== s
.Len() );
1004 return BOOL( t
== SbxEMPTY
1005 || ( t
>= SbxINTEGER
&& t
<= SbxCURRENCY
)
1006 || ( t
>= SbxCHAR
&& t
<= SbxUINT
) );
1009 SbxClassType
SbxValue::GetClass() const
1011 return SbxCLASS_VALUE
;
1014 SbxDataType
SbxValue::GetType() const
1016 return SbxDataType( aData
.eType
& 0x0FFF );
1019 SbxDataType
SbxValue::GetFullType() const
1024 BOOL
SbxValue::SetType( SbxDataType t
)
1026 DBG_ASSERT( !( t
& 0xF000 ), "Setzen von BYREF|ARRAY verboten!" );
1027 if( ( t
== SbxEMPTY
&& aData
.eType
== SbxVOID
)
1028 || ( aData
.eType
== SbxEMPTY
&& t
== SbxVOID
) )
1030 if( ( t
& 0x0FFF ) == SbxVARIANT
)
1032 // Versuch, den Datentyp auf Variant zu setzen
1033 ResetFlag( SBX_FIXED
);
1036 SetError( SbxERR_CONVERSION
); return FALSE
;
1040 if( ( t
& 0x0FFF ) != ( aData
.eType
& 0x0FFF ) )
1042 if( !CanWrite() || IsFixed() )
1044 SetError( SbxERR_CONVERSION
); return FALSE
;
1048 // Eventuelle Objekte freigeben
1049 switch( aData
.eType
)
1052 delete aData
.pString
;
1055 if( aData
.pObj
&& aData
.pObj
!= this )
1057 HACK(nicht bei Parent
-Prop
- sonst CyclicRef
)
1058 SbxVariable
*pThisVar
= PTR_CAST(SbxVariable
, this);
1059 UINT16 nSlotId
= pThisVar
1060 ? ( (INT16
) ( pThisVar
->GetUserData() & 0xFFFF ) )
1062 DBG_ASSERT( nSlotId
!= 5345 || pThisVar
->GetName() == UniString::CreateFromAscii( "Parent" ),
1063 "SID_PARENTOBJECT heisst nicht 'Parent'" );
1064 BOOL bParentProp
= 5345 == nSlotId
;
1066 aData
.pObj
->ReleaseRef();
1071 // Das klappt immer, da auch die Float-Repraesentationen 0 sind.
1072 memset( &aData
, 0, sizeof( SbxValues
) );
1079 BOOL
SbxValue::Convert( SbxDataType eTo
)
1081 eTo
= SbxDataType( eTo
& 0x0FFF );
1082 if( ( aData
.eType
& 0x0FFF ) == eTo
)
1086 if( eTo
== SbxVARIANT
)
1088 // Versuch, den Datentyp auf Variant zu setzen
1089 ResetFlag( SBX_FIXED
);
1092 SetError( SbxERR_CONVERSION
); return FALSE
;
1097 // Convert from Null geht niemals. Einmal Null, immer Null!
1098 if( aData
.eType
== SbxNULL
)
1100 SetError( SbxERR_CONVERSION
); return FALSE
;
1103 // Konversion der Daten:
1108 // Der Datentyp konnte konvertiert werden. Bei Fixed-Elementen
1109 // ist hier Ende, da die Daten nicht uebernommen zu werden brauchen
1114 SetModified( TRUE
);
1116 Broadcast( SBX_HINT_CONVERTED
);
1122 ////////////////////////////////// Rechnen /////////////////////////////////
1124 BOOL
SbxValue::Compute( SbxOperator eOp
, const SbxValue
& rOp
)
1126 bool bVBAInterop
= SbiRuntime::isVBAEnabled();
1128 SbxDataType eThisType
= GetType();
1129 SbxDataType eOpType
= rOp
.GetType();
1130 SbxError eOld
= GetError();
1131 if( eOld
!= SbxERR_OK
)
1134 SetError( SbxERR_PROP_READONLY
);
1135 else if( !rOp
.CanRead() )
1136 SetError( SbxERR_PROP_WRITEONLY
);
1137 // Sonderregel 1: Ist ein Operand Null, ist das Ergebnis Null
1138 else if( eThisType
== SbxNULL
|| eOpType
== SbxNULL
)
1140 // Sonderregel 2: Ist ein Operand Empty, ist das Ergebnis der 2. Operand
1141 else if( eThisType
== SbxEMPTY
1145 // 13.2.96: Nicht schon vor Get auf SbxEMPTY pruefen
1149 bool bDecimal
= false;
1150 if( bVBAInterop
&& ( ( eThisType
== SbxSTRING
&& eOpType
!= SbxSTRING
&& eOpType
!= SbxEMPTY
) ||
1151 ( eThisType
!= SbxSTRING
&& eThisType
!= SbxEMPTY
&& eOpType
== SbxSTRING
) ) &&
1152 ( eOp
== SbxMUL
|| eOp
== SbxDIV
|| eOp
== SbxPLUS
|| eOp
== SbxMINUS
) )
1154 goto Lbl_OpIsDouble
;
1156 else if( eThisType
== SbxSTRING
|| eOp
== SbxCAT
|| ( bVBAInterop
&& ( eOpType
== SbxSTRING
) && ( eOp
== SbxPLUS
) ) )
1158 if( eOp
== SbxCAT
|| eOp
== SbxPLUS
)
1160 // AB 5.11.1999, OUString beruecksichtigen
1161 aL
.eType
= aR
.eType
= SbxSTRING
;
1163 // AB 8.12.1999, #70399: Hier wieder GetType() rufen, Get() kann Typ aendern!
1164 if( rOp
.GetType() == SbxEMPTY
)
1168 // #30576: Erstmal testen, ob Wandlung geklappt hat
1169 if( aL
.pString
!= NULL
&& aR
.pString
!= NULL
)
1171 *aL
.pString
+= *aR
.pString
;
1173 // Nicht einmal Left OK?
1174 else if( aL
.pString
== NULL
)
1176 aL
.pString
= new String();
1181 SetError( SbxERR_CONVERSION
);
1183 else if( eOpType
== SbxSTRING
&& rOp
.IsFixed() )
1184 { // Numerisch: rechts darf kein String stehen
1185 SetError( SbxERR_CONVERSION
);
1187 else if( ( eOp
>= SbxIDIV
&& eOp
<= SbxNOT
) || eOp
== SbxMOD
)
1189 if( GetType() == eOpType
)
1191 if( GetType() == SbxULONG64
1192 || GetType() == SbxLONG64
1193 || GetType() == SbxCURRENCY
1194 || GetType() == SbxULONG
)
1195 aL
.eType
= aR
.eType
= GetType();
1196 // else if( GetType() == SbxDouble || GetType() == SbxSingle )
1197 // aL.eType = aR.eType = SbxLONG64;
1198 else if ( bVBAInterop
&& eOpType
== SbxBOOL
)
1199 aL
.eType
= aR
.eType
= SbxBOOL
;
1201 aL
.eType
= aR
.eType
= SbxLONG
;
1203 else if( GetType() == SbxCURRENCY
|| eOpType
== SbxCURRENCY
1204 || GetType() == SbxULONG64
|| eOpType
== SbxULONG64
1205 || GetType() == SbxLONG64
|| eOpType
== SbxLONG64
)
1206 aL
.eType
= aR
.eType
= SbxLONG64
;
1207 // else if( GetType() == SbxDouble || rOP.GetType() == SbxDouble
1208 // || GetType() == SbxSingle || rOP.GetType() == SbxSingle )
1209 // aL.eType = aR.eType = SbxLONG64;
1211 aL
.eType
= aR
.eType
= SbxLONG
;
1215 if( rOp
.GetType() == SbxEMPTY
)
1217 if ( !bVBAInterop
|| ( bVBAInterop
&& ( eOp
!= SbxNOT
) ) )
1220 if( Get( aL
) ) switch( eOp
)
1223 if( aL
.eType
== SbxCURRENCY
)
1224 aL
.eType
= SbxLONG64
;
1225 if( aL
.eType
== SbxLONG64
)
1226 if( !aR
.nLong64
) SetError( SbxERR_ZERODIV
);
1227 else aL
.nLong64
/= aR
.nLong64
;
1228 else if( aL
.eType
== SbxULONG64
)
1229 if( !aR
.nULong64
) SetError( SbxERR_ZERODIV
);
1230 else aL
.nULong64
/= aR
.nULong64
;
1231 else if( aL
.eType
== SbxLONG
)
1232 if( !aR
.nLong
) SetError( SbxERR_ZERODIV
);
1233 else aL
.nLong
/= aR
.nLong
;
1235 if( !aR
.nULong
) SetError( SbxERR_ZERODIV
);
1236 else aL
.nULong
/= aR
.nULong
;
1239 if( aL
.eType
== SbxCURRENCY
)
1240 aL
.eType
= SbxLONG64
;
1241 if( aL
.eType
== SbxLONG64
)
1242 if( !aR
.nLong64
) SetError( SbxERR_ZERODIV
);
1243 else aL
.nLong64
%= aR
.nLong64
;
1244 else if( aL
.eType
== SbxULONG64
)
1245 if( !aR
.nULong64
) SetError( SbxERR_ZERODIV
);
1246 else aL
.nULong64
%= aR
.nULong64
;
1247 else if( aL
.eType
== SbxLONG
)
1248 if( !aR
.nLong
) SetError( SbxERR_ZERODIV
);
1249 else aL
.nLong
%= aR
.nLong
;
1251 if( !aR
.nULong
) SetError( SbxERR_ZERODIV
);
1252 else aL
.nULong
%= aR
.nULong
;
1255 if( aL
.eType
!= SbxLONG
&& aL
.eType
!= SbxULONG
)
1256 aL
.nLong64
&= aR
.nLong64
;
1258 aL
.nLong
&= aR
.nLong
;
1261 if( aL
.eType
!= SbxLONG
&& aL
.eType
!= SbxULONG
)
1262 aL
.nLong64
|= aR
.nLong64
;
1264 aL
.nLong
|= aR
.nLong
;
1267 if( aL
.eType
!= SbxLONG
&& aL
.eType
!= SbxULONG
)
1268 aL
.nLong64
^= aR
.nLong64
;
1270 aL
.nLong
^= aR
.nLong
;
1273 if( aL
.eType
!= SbxLONG
&& aL
.eType
!= SbxULONG
)
1274 aL
.nLong64
= (aL
.nLong64
& aR
.nLong64
) | (~aL
.nLong64
& ~aR
.nLong64
);
1276 aL
.nLong
= (aL
.nLong
& aR
.nLong
) | (~aL
.nLong
& ~aR
.nLong
);
1279 if( aL
.eType
!= SbxLONG
&& aL
.eType
!= SbxULONG
)
1280 aL
.nLong64
= ~aL
.nLong64
| aR
.nLong64
;
1282 aL
.nLong
= ~aL
.nLong
| aR
.nLong
;
1285 if( aL
.eType
!= SbxLONG
&& aL
.eType
!= SbxULONG
)
1287 if ( aL
.eType
!= SbxBOOL
)
1288 aL
.nLong64
= ~aL
.nLong64
;
1290 aL
.nLong
= ~aL
.nLong
;
1293 aL
.nLong
= ~aL
.nLong
;
1299 else if( ( GetType() == SbxDECIMAL
|| rOp
.GetType() == SbxDECIMAL
) &&
1300 ( eOp
== SbxMUL
|| eOp
== SbxDIV
|| eOp
== SbxPLUS
|| eOp
== SbxMINUS
|| eOp
== SbxNEG
) )
1302 aL
.eType
= aR
.eType
= SbxDECIMAL
;
1306 if( rOp
.GetType() == SbxEMPTY
)
1308 releaseDecimalPtr( aL
.pDecimal
);
1313 if( aL
.pDecimal
&& aR
.pDecimal
)
1319 bOk
= ( *(aL
.pDecimal
) *= *(aR
.pDecimal
) );
1322 if( aR
.pDecimal
->isZero() )
1323 SetError( SbxERR_ZERODIV
);
1325 bOk
= ( *(aL
.pDecimal
) /= *(aR
.pDecimal
) );
1328 bOk
= ( *(aL
.pDecimal
) += *(aR
.pDecimal
) );
1331 bOk
= ( *(aL
.pDecimal
) -= *(aR
.pDecimal
) );
1334 bOk
= ( aL
.pDecimal
->neg() );
1337 SetError( SbxERR_NOTIMP
);
1340 SetError( SbxERR_OVERFLOW
);
1344 SetError( SbxERR_CONVERSION
);
1349 else if( GetType() == SbxCURRENCY
|| rOp
.GetType() == SbxCURRENCY
)
1351 aL
.eType
= SbxCURRENCY
;
1352 aR
.eType
= SbxCURRENCY
;
1356 static BigInt
n10K( 10000 );
1358 if( rOp
.GetType() == SbxEMPTY
)
1361 if( Get( aL
) ) switch( eOp
)
1365 // #i20704 Implement directly
1366 BigInt
b1( aL
.nLong64
);
1367 BigInt
b2( aR
.nLong64
);
1370 double d
= double( b1
) / 10000.0;
1371 if( d
> SbxMAXCURR
|| d
< SbxMINCURR
)
1372 SetError( SbxERR_OVERFLOW
);
1374 b1
.INT64( &aL
.nLong64
);
1380 SetError( SbxERR_ZERODIV
);
1384 // #i20704 Implement directly
1385 BigInt
b1( aL
.nLong64
);
1386 BigInt
b2( aR
.nLong64
);
1389 double d
= double( b1
) / 10000.0;
1390 if( d
> SbxMAXCURR
|| d
< SbxMINCURR
)
1391 SetError( SbxERR_OVERFLOW
);
1393 b1
.INT64( &aL
.nLong64
);
1397 aL
.nLong64
+= aR
.nLong64
; break;
1399 aL
.nLong64
-= aR
.nLong64
; break;
1401 aL
.nLong64
= -aL
.nLong64
; break;
1403 SetError( SbxERR_NOTIMP
);
1409 { // Andere Operatoren
1410 aL
.eType
= aR
.eType
= SbxDOUBLE
;
1413 if( rOp
.GetType() == SbxEMPTY
)
1415 if ( !bVBAInterop
|| ( bVBAInterop
&& ( eOp
!= SbxNEG
) ) )
1423 aL
.nDouble
= pow( aL
.nDouble
, aR
.nDouble
);
1426 aL
.nDouble
*= aR
.nDouble
; break;
1428 if( !aR
.nDouble
) SetError( SbxERR_ZERODIV
);
1429 else aL
.nDouble
/= aR
.nDouble
; break;
1431 aL
.nDouble
+= aR
.nDouble
; break;
1433 aL
.nDouble
-= aR
.nDouble
; break;
1435 aL
.nDouble
= -aL
.nDouble
; break;
1437 SetError( SbxERR_NOTIMP
);
1440 // #45465 Date braucht bei + eine Spezial-Behandlung
1441 if( eOp
== SbxPLUS
&& (GetType() == SbxDATE
|| rOp
.GetType() == SbxDATE
) )
1451 releaseDecimalPtr( aL
.pDecimal
);
1452 releaseDecimalPtr( aR
.pDecimal
);
1457 BOOL bRes
= BOOL( !IsError() );
1458 if( bRes
&& eOld
!= SbxERR_OK
)
1463 // Die Vergleichs-Routine liefert TRUE oder FALSE.
1465 BOOL
SbxValue::Compare( SbxOperator eOp
, const SbxValue
& rOp
) const
1467 bool bVBAInterop
= SbiRuntime::isVBAEnabled();
1470 SbxError eOld
= GetError();
1471 if( eOld
!= SbxERR_OK
)
1473 if( !CanRead() || !rOp
.CanRead() )
1474 SetError( SbxERR_PROP_WRITEONLY
);
1475 else if( GetType() == SbxNULL
&& rOp
.GetType() == SbxNULL
&& !bVBAInterop
)
1479 else if( GetType() == SbxEMPTY
&& rOp
.GetType() == SbxEMPTY
)
1480 bRes
= !bVBAInterop
? TRUE
: ( eOp
== SbxEQ
? TRUE
: FALSE
);
1481 // Sonderregel 1: Ist ein Operand Null, ist das Ergebnis FALSE
1482 else if( GetType() == SbxNULL
|| rOp
.GetType() == SbxNULL
)
1484 // Sonderregel 2: Wenn beide Variant sind und einer ist numerisch,
1485 // und der andere ein String, ist num < str
1486 else if( !IsFixed() && !rOp
.IsFixed()
1487 && ( rOp
.GetType() == SbxSTRING
&& GetType() != SbxSTRING
&& IsNumeric() ) && !bVBAInterop
1489 bRes
= BOOL( eOp
== SbxLT
|| eOp
== SbxLE
|| eOp
== SbxNE
);
1490 else if( !IsFixed() && !rOp
.IsFixed()
1491 && ( GetType() == SbxSTRING
&& rOp
.GetType() != SbxSTRING
&& rOp
.IsNumeric() )
1494 bRes
= BOOL( eOp
== SbxGT
|| eOp
== SbxGE
|| eOp
== SbxNE
);
1498 // Wenn einer der Operanden ein String ist,
1499 // findet ein Stringvergleich statt
1500 if( GetType() == SbxSTRING
|| rOp
.GetType() == SbxSTRING
)
1502 aL
.eType
= aR
.eType
= SbxSTRING
;
1503 if( Get( aL
) && rOp
.Get( aR
) ) switch( eOp
)
1506 bRes
= BOOL( *aL
.pString
== *aR
.pString
); break;
1508 bRes
= BOOL( *aL
.pString
!= *aR
.pString
); break;
1510 bRes
= BOOL( *aL
.pString
< *aR
.pString
); break;
1512 bRes
= BOOL( *aL
.pString
> *aR
.pString
); break;
1514 bRes
= BOOL( *aL
.pString
<= *aR
.pString
); break;
1516 bRes
= BOOL( *aL
.pString
>= *aR
.pString
); break;
1518 SetError( SbxERR_NOTIMP
);
1521 // AB 19.12.95: Wenn SbxSINGLE beteiligt, auf SINGLE konvertieren,
1522 // sonst gibt es numerische Fehler
1523 else if( GetType() == SbxSINGLE
|| rOp
.GetType() == SbxSINGLE
)
1525 aL
.eType
= aR
.eType
= SbxSINGLE
;
1526 if( Get( aL
) && rOp
.Get( aR
) )
1530 bRes
= BOOL( aL
.nSingle
== aR
.nSingle
); break;
1532 bRes
= BOOL( aL
.nSingle
!= aR
.nSingle
); break;
1534 bRes
= BOOL( aL
.nSingle
< aR
.nSingle
); break;
1536 bRes
= BOOL( aL
.nSingle
> aR
.nSingle
); break;
1538 bRes
= BOOL( aL
.nSingle
<= aR
.nSingle
); break;
1540 bRes
= BOOL( aL
.nSingle
>= aR
.nSingle
); break;
1542 SetError( SbxERR_NOTIMP
);
1545 else if( GetType() == SbxDECIMAL
&& rOp
.GetType() == SbxDECIMAL
)
1547 aL
.eType
= aR
.eType
= SbxDECIMAL
;
1550 if( aL
.pDecimal
&& aR
.pDecimal
)
1552 SbxDecimal::CmpResult eRes
= compare( *aL
.pDecimal
, *aR
.pDecimal
);
1556 bRes
= BOOL( eRes
== SbxDecimal::EQ
); break;
1558 bRes
= BOOL( eRes
!= SbxDecimal::EQ
); break;
1560 bRes
= BOOL( eRes
== SbxDecimal::LT
); break;
1562 bRes
= BOOL( eRes
== SbxDecimal::GT
); break;
1564 bRes
= BOOL( eRes
!= SbxDecimal::GT
); break;
1566 bRes
= BOOL( eRes
!= SbxDecimal::LT
); break;
1568 SetError( SbxERR_NOTIMP
);
1573 SetError( SbxERR_CONVERSION
);
1575 releaseDecimalPtr( aL
.pDecimal
);
1576 releaseDecimalPtr( aR
.pDecimal
);
1578 // Alles andere auf SbxDOUBLE-Basis vergleichen
1581 aL
.eType
= aR
.eType
= SbxDOUBLE
;
1582 //if( Get( aL ) && rOp.Get( aR ) )
1583 bool bGetL
= Get( aL
);
1584 bool bGetR
= rOp
.Get( aR
);
1585 if( bGetL
&& bGetR
)
1589 bRes
= BOOL( aL
.nDouble
== aR
.nDouble
); break;
1591 bRes
= BOOL( aL
.nDouble
!= aR
.nDouble
); break;
1593 bRes
= BOOL( aL
.nDouble
< aR
.nDouble
); break;
1595 bRes
= BOOL( aL
.nDouble
> aR
.nDouble
); break;
1597 bRes
= BOOL( aL
.nDouble
<= aR
.nDouble
); break;
1599 bRes
= BOOL( aL
.nDouble
>= aR
.nDouble
); break;
1601 SetError( SbxERR_NOTIMP
);
1603 // at least one value was got
1604 // if this is VBA then a conversion error for one
1605 // side will yield a false result of an equality test
1606 else if ( bGetR
|| bGetL
)
1608 if ( bVBAInterop
&& eOp
== SbxEQ
&& GetError() == SbxERR_CONVERSION
)
1616 if( eOld
!= SbxERR_OK
)
1621 ///////////////////////////// Lesen/Schreiben ////////////////////////////
1623 BOOL
SbxValue::LoadData( SvStream
& r
, USHORT
)
1628 aData
.eType
= SbxDataType( nType
);
1633 r
>> aData
.nInteger
; break;
1635 r
>> aData
.nLong
; break;
1640 r
.ReadByteString( aVal
, RTL_TEXTENCODING_ASCII_US
);
1643 if( ImpScan( aVal
, d
, t
, NULL
) != SbxERR_OK
|| t
== SbxDOUBLE
)
1645 aData
.nSingle
= 0.0F
;
1648 aData
.nSingle
= (float) d
;
1656 r
.ReadByteString( aVal
, RTL_TEXTENCODING_ASCII_US
);
1658 if( ImpScan( aVal
, aData
.nDouble
, t
, NULL
) != SbxERR_OK
)
1660 aData
.nDouble
= 0.0;
1667 r
>> aData
.nULong64
.nHigh
>> aData
.nULong64
.nLow
;
1673 r
>> aData
.nLong64
.nHigh
>> aData
.nLong64
.nLow
;
1679 r
.ReadByteString( aVal
, RTL_TEXTENCODING_ASCII_US
);
1681 aData
.pString
= new XubString( aVal
);
1683 aData
.pString
= NULL
; // JSM 22.09.1995
1688 r
>> aData
.nUShort
; break;
1699 aData
.pObj
= SbxBase::Load( r
);
1700 return BOOL( aData
.pObj
!= NULL
);
1715 r
>> aData
.nByte
; break;
1717 r
>> aData
.nULong
; break;
1722 // Passt der Int auf diesem System?
1723 if( n
> SAL_TYPES_SIZEOFINT
)
1724 r
>> aData
.nLong
, aData
.eType
= SbxLONG
;
1733 // Passt der UInt auf diesem System?
1734 if( n
> SAL_TYPES_SIZEOFINT
)
1735 r
>> aData
.nULong
, aData
.eType
= SbxULONG
;
1737 r
>> (sal_uInt32
&)aData
.nUInt
;
1747 // #78919 For backwards compatibility
1752 memset (&aData
,0,sizeof(aData
));
1753 ResetFlag(SBX_FIXED
);
1754 aData
.eType
= SbxNULL
;
1755 DBG_ASSERT( !this, "Nicht unterstuetzer Datentyp geladen" );
1761 BOOL
SbxValue::StoreData( SvStream
& r
) const
1763 UINT16 nType
= sal::static_int_cast
< UINT16
>(aData
.eType
);
1765 switch( nType
& 0x0FFF )
1769 r
<< aData
.nInteger
; break;
1771 r
<< aData
.nLong
; break;
1773 // #49935: Als double speichern, sonst Fehler beim Einlesen
1774 ((SbxValue
*)this)->aData
.eType
= (SbxDataType
)( ( nType
& 0xF000 ) | SbxDOUBLE
);
1775 r
.WriteByteString( GetCoreString(), RTL_TEXTENCODING_ASCII_US
);
1776 ((SbxValue
*)this)->aData
.eType
= (SbxDataType
)nType
;
1780 r
.WriteByteString( GetCoreString(), RTL_TEXTENCODING_ASCII_US
);
1784 r
<< aData
.nULong64
.nHigh
<< aData
.nULong64
.nLow
;
1790 r
<< aData
.nLong64
.nHigh
<< aData
.nLong64
.nLow
;
1796 r
.WriteByteString( *aData
.pString
, RTL_TEXTENCODING_ASCII_US
);
1801 r
.WriteByteString( aEmpty
, RTL_TEXTENCODING_ASCII_US
);
1806 r
<< aData
.nUShort
; break;
1808 // sich selbst als Objektptr speichern geht nicht!
1811 if( PTR_CAST(SbxValue
,aData
.pObj
) != this )
1814 return aData
.pObj
->Store( r
);
1824 char c
= sal::static_int_cast
< char >(aData
.nChar
);
1829 r
<< aData
.nByte
; break;
1831 r
<< aData
.nULong
; break;
1834 BYTE n
= SAL_TYPES_SIZEOFINT
;
1835 r
<< n
<< (sal_Int32
)aData
.nInt
;
1840 BYTE n
= SAL_TYPES_SIZEOFINT
;
1841 r
<< n
<< (sal_uInt32
)aData
.nUInt
;
1851 // #78919 For backwards compatibility
1856 DBG_ASSERT( !this, "Speichern eines nicht unterstuetzten Datentyps" );