1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <tools/stream.hxx>
24 #include <basic/sbx.hxx>
25 #include "sbxconv.hxx"
26 #include "runtime.hxx"
28 TYPEINIT1(SbxValue
,SbxBase
)
30 ///////////////////////////// constructors //////////////////////////////
32 SbxValue::SbxValue() : SbxBase()
34 aData
.eType
= SbxEMPTY
;
37 SbxValue::SbxValue( SbxDataType t
, void* p
) : SbxBase()
50 case SbxINTEGER
: n
|= SbxBYREF
; aData
.pInteger
= (sal_Int16
*) p
; break;
51 case SbxSALUINT64
: n
|= SbxBYREF
; aData
.puInt64
= (sal_uInt64
*) p
; break;
53 case SbxCURRENCY
: n
|= SbxBYREF
; aData
.pnInt64
= (sal_Int64
*) p
; break;
54 case SbxLONG
: n
|= SbxBYREF
; aData
.pLong
= (sal_Int32
*) p
; break;
55 case SbxSINGLE
: n
|= SbxBYREF
; aData
.pSingle
= (float*) p
; break;
57 case SbxDOUBLE
: n
|= SbxBYREF
; aData
.pDouble
= (double*) p
; break;
58 case SbxSTRING
: n
|= SbxBYREF
; aData
.pOUString
= (OUString
*) p
; break;
61 case SbxBOOL
: n
|= SbxBYREF
; aData
.pUShort
= (sal_uInt16
*) p
; break;
62 case SbxULONG
: n
|= SbxBYREF
; aData
.pULong
= (sal_uInt32
*) p
; break;
63 case SbxCHAR
: n
|= SbxBYREF
; aData
.pChar
= (sal_Unicode
*) p
; break;
64 case SbxBYTE
: n
|= SbxBYREF
; aData
.pByte
= (sal_uInt8
*) p
; break;
65 case SbxINT
: n
|= SbxBYREF
; aData
.pInt
= (int*) p
; break;
67 aData
.pObj
= (SbxBase
*) p
;
72 aData
.pDecimal
= (SbxDecimal
*) p
;
74 aData
.pDecimal
->addRef();
77 DBG_ASSERT( !this, "Improper pointer argument" );
82 memset( &aData
, 0, sizeof( SbxValues
) );
83 aData
.eType
= SbxDataType( n
);
86 SbxValue::SbxValue( const SbxValue
& r
)
87 : SvRefBase( r
), SbxBase( r
)
91 SetError( SbxERR_PROP_WRITEONLY
);
93 aData
.eType
= SbxNULL
;
97 ((SbxValue
*) &r
)->Broadcast( SBX_HINT_DATAWANTED
);
99 // Copy pointer, increment references
100 switch( aData
.eType
)
103 if( aData
.pOUString
)
104 aData
.pOUString
= new OUString( *aData
.pOUString
);
108 aData
.pObj
->AddRef();
112 aData
.pDecimal
->addRef();
119 SbxValue
& SbxValue::operator=( const SbxValue
& r
)
124 SetError( SbxERR_PROP_READONLY
);
127 // string -> byte array
128 if( IsFixed() && (aData
.eType
== SbxOBJECT
)
129 && aData
.pObj
&& ( aData
.pObj
->GetType() == (SbxARRAY
| SbxBYTE
) )
130 && (r
.aData
.eType
== SbxSTRING
) )
132 OUString aStr
= r
.GetOUString();
133 SbxArray
* pArr
= StringToByteArray(aStr
);
137 // byte array -> string
138 if( r
.IsFixed() && (r
.aData
.eType
== SbxOBJECT
)
139 && r
.aData
.pObj
&& ( r
.aData
.pObj
->GetType() == (SbxARRAY
| SbxBYTE
) )
140 && (aData
.eType
== SbxSTRING
) )
142 SbxBase
* pObj
= r
.GetObject();
143 SbxArray
* pArr
= PTR_CAST(SbxArray
, pObj
);
146 OUString aStr
= ByteArrayToString( pArr
);
151 // Readout the content of the variables
154 // firm: then the type had to match
155 aNew
.eType
= aData
.eType
;
156 else if( r
.IsFixed() )
157 // Source firm: take over the type
158 aNew
.eType
= SbxDataType( r
.aData
.eType
& 0x0FFF );
160 // both variant: then it is equal
161 aNew
.eType
= SbxVARIANT
;
169 SbxValue::~SbxValue()
171 Broadcast( SBX_HINT_DYING
);
172 SetFlag( SBX_WRITE
);
176 void SbxValue::Clear()
178 switch( aData
.eType
)
185 delete aData
.pOUString
; aData
.pOUString
= NULL
;
190 if( aData
.pObj
!= this )
192 SAL_WARN("basic.sbx", "Not at Parent-Prop - otherwise CyclicRef");
193 SbxVariable
*pThisVar
= PTR_CAST(SbxVariable
, this);
194 sal_Bool bParentProp
= pThisVar
&& 5345 ==
195 ( (sal_Int16
) ( pThisVar
->GetUserData() & 0xFFFF ) );
197 aData
.pObj
->ReleaseRef();
203 if( aData
.eType
== SbxDECIMAL
)
204 releaseDecimalPtr( aData
.pDecimal
);
207 aData
.pData
= NULL
; break;
211 memset( &aEmpty
, 0, sizeof( SbxValues
) );
212 aEmpty
.eType
= GetType();
220 void SbxValue::Broadcast( sal_uIntPtr
)
223 //////////////////////////// Readout data //////////////////////////////
225 // Detect the "right" variables. If it is an object, will be addressed either
226 // the object itself or its default property.
227 // If the variable contain a variable or an object, this will be
230 SbxValue
* SbxValue::TheRealValue() const
232 return TheRealValue( sal_True
);
235 // #55226 ship additional information
236 bool handleToStringForCOMObjects( SbxObject
* pObj
, SbxValue
* pVal
); // sbunoobj.cxx
238 SbxValue
* SbxValue::TheRealValue( sal_Bool bObjInObjError
) const
240 SbxValue
* p
= (SbxValue
*) this;
243 SbxDataType t
= SbxDataType( p
->aData
.eType
& 0x0FFF );
246 // The block contains an object or a variable
247 SbxObject
* pObj
= PTR_CAST(SbxObject
,p
->aData
.pObj
);
250 // Has the object a default property?
251 SbxVariable
* pDflt
= pObj
->GetDfltProperty();
253 // If this is an object and contains itself,
254 // we cannot access on it
255 // The old condition to set an error
256 // is not correct, because e.g. a regular variant variable with an object
257 // could be affected thereof, if another value should be assigned.
258 // Therefore with flag.
259 if( bObjInObjError
&& !pDflt
&&
260 ((SbxValue
*) pObj
)->aData
.eType
== SbxOBJECT
&&
261 ((SbxValue
*) pObj
)->aData
.pObj
== pObj
)
263 #ifdef DISABLE_SCRIPTING // No sbunoobj
264 const bool bSuccess
= false;
266 bool bSuccess
= handleToStringForCOMObjects( pObj
, p
);
270 SetError( SbxERR_BAD_PROP_VALUE
);
278 // Did we have an array?
279 SbxArray
* pArray
= PTR_CAST(SbxArray
,p
->aData
.pObj
);
282 // When indicated get the parameter
283 SbxArray
* pPar
= NULL
;
284 SbxVariable
* pVar
= PTR_CAST(SbxVariable
,p
);
286 pPar
= pVar
->GetParameters();
289 // Did we have a dimensioned array?
290 SbxDimArray
* pDimArray
= PTR_CAST(SbxDimArray
,p
->aData
.pObj
);
292 p
= pDimArray
->Get( pPar
);
294 p
= pArray
->Get( pPar
->Get( 1 )->GetInteger() );
298 // Elsewise guess a SbxValue
299 SbxValue
* pVal
= PTR_CAST(SbxValue
,p
->aData
.pObj
);
311 sal_Bool
SbxValue::Get( SbxValues
& rRes
) const
313 sal_Bool bRes
= sal_False
;
314 SbxError eOld
= GetError();
315 if( eOld
!= SbxERR_OK
)
319 SetError( SbxERR_PROP_WRITEONLY
);
324 // If there was asked for an object or a VARIANT, don't search
326 SbxValue
* p
= (SbxValue
*) this;
327 if( rRes
.eType
!= SbxOBJECT
&& rRes
.eType
!= SbxVARIANT
)
331 p
->Broadcast( SBX_HINT_DATAWANTED
);
337 case SbxVARIANT
: rRes
= p
->aData
; break;
338 case SbxINTEGER
: rRes
.nInteger
= ImpGetInteger( &p
->aData
); break;
339 case SbxLONG
: rRes
.nLong
= ImpGetLong( &p
->aData
); break;
340 case SbxSALINT64
: rRes
.nInt64
= ImpGetInt64( &p
->aData
); break;
341 case SbxSALUINT64
: rRes
.uInt64
= ImpGetUInt64( &p
->aData
); break;
342 case SbxSINGLE
: rRes
.nSingle
= ImpGetSingle( &p
->aData
); break;
343 case SbxDOUBLE
: rRes
.nDouble
= ImpGetDouble( &p
->aData
); break;
344 case SbxCURRENCY
:rRes
.nInt64
= ImpGetCurrency( &p
->aData
); break;
345 case SbxDECIMAL
: rRes
.pDecimal
= ImpGetDecimal( &p
->aData
); break;
346 case SbxDATE
: rRes
.nDouble
= ImpGetDate( &p
->aData
); break;
348 rRes
.nUShort
= sal::static_int_cast
< sal_uInt16
>(
349 ImpGetBool( &p
->aData
) );
351 case SbxCHAR
: rRes
.nChar
= ImpGetChar( &p
->aData
); break;
352 case SbxBYTE
: rRes
.nByte
= ImpGetByte( &p
->aData
); break;
353 case SbxUSHORT
: rRes
.nUShort
= ImpGetUShort( &p
->aData
); break;
354 case SbxULONG
: rRes
.nULong
= ImpGetULong( &p
->aData
); break;
356 case SbxSTRING
: p
->aPic
= ImpGetString( &p
->aData
);
357 rRes
.pOUString
= &p
->aPic
; break;
358 case SbxCoreSTRING
: p
->aPic
= ImpGetCoreString( &p
->aData
);
359 rRes
.pOUString
= &p
->aPic
; break;
361 #if SAL_TYPES_SIZEOFINT == 2
362 rRes
.nInt
= (int) ImpGetInteger( &p
->aData
);
364 rRes
.nInt
= (int) ImpGetLong( &p
->aData
);
368 #if SAL_TYPES_SIZEOFINT == 2
369 rRes
.nUInt
= (int) ImpGetUShort( &p
->aData
);
371 rRes
.nUInt
= (int) ImpGetULong( &p
->aData
);
375 if( p
->aData
.eType
== SbxOBJECT
)
376 rRes
.pObj
= p
->aData
.pObj
;
379 SetError( SbxERR_NO_OBJECT
);
384 if( p
->aData
.eType
== rRes
.eType
)
388 SetError( SbxERR_CONVERSION
);
395 // Object contained itself
396 SbxDataType eTemp
= rRes
.eType
;
397 memset( &rRes
, 0, sizeof( SbxValues
) );
404 if( eOld
!= SbxERR_OK
)
410 const OUString
& SbxValue::GetCoreString() const
413 aRes
.eType
= SbxCoreSTRING
;
416 ((SbxValue
*) this)->aToolString
= *aRes
.pOUString
;
420 ((SbxValue
*) this)->aToolString
= "";
425 OUString
SbxValue::GetOUString() const
429 aRes
.eType
= SbxSTRING
;
432 aResult
= *aRes
.pOUString
;
437 sal_Bool
SbxValue::GetBool() const
440 aRes
.eType
= SbxBOOL
;
442 return sal_Bool( aRes
.nUShort
!= 0 );
445 #define GET( g, e, t, m ) \
446 t SbxValue::g() const { SbxValues aRes(e); Get( aRes ); return aRes.m; }
448 GET( GetByte
, SbxBYTE
, sal_uInt8
, nByte
)
449 GET( GetChar
, SbxCHAR
, sal_Unicode
, nChar
)
450 GET( GetCurrency
, SbxCURRENCY
, sal_Int64
, nInt64
)
451 GET( GetDate
, SbxDATE
, double, nDouble
)
452 GET( GetDouble
, SbxDOUBLE
, double, nDouble
)
453 GET( GetInteger
, SbxINTEGER
, sal_Int16
, nInteger
)
454 GET( GetLong
, SbxLONG
, sal_Int32
, nLong
)
455 GET( GetObject
, SbxOBJECT
, SbxBase
*, pObj
)
456 GET( GetSingle
, SbxSINGLE
, float, nSingle
)
457 GET( GetULong
, SbxULONG
, sal_uInt32
, nULong
)
458 GET( GetUShort
, SbxUSHORT
, sal_uInt16
, nUShort
)
459 GET( GetInt64
, SbxSALINT64
, sal_Int64
, nInt64
)
460 GET( GetUInt64
, SbxSALUINT64
, sal_uInt64
, uInt64
)
461 GET( GetDecimal
, SbxDECIMAL
, SbxDecimal
*, pDecimal
)
464 //////////////////////////// Write data /////////////////////////////
466 sal_Bool
SbxValue::Put( const SbxValues
& rVal
)
468 sal_Bool bRes
= sal_False
;
469 SbxError eOld
= GetError();
470 if( eOld
!= SbxERR_OK
)
473 SetError( SbxERR_PROP_READONLY
);
474 else if( rVal
.eType
& 0xF000 )
475 SetError( SbxERR_NOTIMP
);
478 // If there was asked for an object, don't search
481 if( rVal
.eType
!= SbxOBJECT
)
482 p
= TheRealValue( sal_False
); // Don't allow an error here
486 SetError( SbxERR_PROP_READONLY
);
487 else if( p
->IsFixed() || p
->SetType( (SbxDataType
) ( rVal
.eType
& 0x0FFF ) ) )
488 switch( rVal
.eType
& 0x0FFF )
493 case SbxINTEGER
: ImpPutInteger( &p
->aData
, rVal
.nInteger
); break;
494 case SbxLONG
: ImpPutLong( &p
->aData
, rVal
.nLong
); break;
495 case SbxSALINT64
: ImpPutInt64( &p
->aData
, rVal
.nInt64
); break;
496 case SbxSALUINT64
: ImpPutUInt64( &p
->aData
, rVal
.uInt64
); break;
497 case SbxSINGLE
: ImpPutSingle( &p
->aData
, rVal
.nSingle
); break;
498 case SbxDOUBLE
: ImpPutDouble( &p
->aData
, rVal
.nDouble
); break;
499 case SbxCURRENCY
: ImpPutCurrency( &p
->aData
, rVal
.nInt64
); break;
500 case SbxDECIMAL
: ImpPutDecimal( &p
->aData
, rVal
.pDecimal
); break;
501 case SbxDATE
: ImpPutDate( &p
->aData
, rVal
.nDouble
); break;
502 case SbxBOOL
: ImpPutBool( &p
->aData
, rVal
.nInteger
); break;
503 case SbxCHAR
: ImpPutChar( &p
->aData
, rVal
.nChar
); break;
504 case SbxBYTE
: ImpPutByte( &p
->aData
, rVal
.nByte
); break;
505 case SbxUSHORT
: ImpPutUShort( &p
->aData
, rVal
.nUShort
); break;
506 case SbxULONG
: ImpPutULong( &p
->aData
, rVal
.nULong
); break;
508 case SbxSTRING
: ImpPutString( &p
->aData
, rVal
.pOUString
); break;
510 #if SAL_TYPES_SIZEOFINT == 2
511 ImpPutInteger( &p
->aData
, (sal_Int16
) rVal
.nInt
);
513 ImpPutLong( &p
->aData
, (sal_Int32
) rVal
.nInt
);
517 #if SAL_TYPES_SIZEOFINT == 2
518 ImpPutUShort( &p
->aData
, (sal_uInt16
) rVal
.nUInt
);
520 ImpPutULong( &p
->aData
, (sal_uInt32
) rVal
.nUInt
);
524 if( !p
->IsFixed() || p
->aData
.eType
== SbxOBJECT
)
527 if( p
->aData
.eType
== SbxOBJECT
&& p
->aData
.pObj
== rVal
.pObj
)
530 // Delete only the value part!
531 p
->SbxValue::Clear();
534 p
->aData
.pObj
= rVal
.pObj
;
536 // if necessary cont in Ref-Count
537 if( p
->aData
.pObj
&& p
->aData
.pObj
!= p
)
541 OSL_FAIL( "TheRealValue" );
543 SAL_WARN("basic.sbx", "Not at Parent-Prop - otherwise CyclicRef");
544 SbxVariable
*pThisVar
= PTR_CAST(SbxVariable
, this);
545 sal_Bool bParentProp
= pThisVar
&& 5345 ==
546 ( (sal_Int16
) ( pThisVar
->GetUserData() & 0xFFFF ) );
548 p
->aData
.pObj
->AddRef();
552 SetError( SbxERR_CONVERSION
);
555 if( p
->aData
.eType
== rVal
.eType
)
559 SetError( SbxERR_CONVERSION
);
561 p
->aData
.eType
= SbxNULL
;
566 p
->SetModified( sal_True
);
567 p
->Broadcast( SBX_HINT_DATACHANGED
);
568 if( eOld
!= SbxERR_OK
)
578 // Method to execute a pretreatment of the strings at special types.
579 // In particular necessary for BASIC-IDE, so that
580 // the output in the Watch-Window can be writen back with PutStringExt,
581 // if Float were declared with ',' as the decimal separator or BOOl
582 // explicit with "TRUE" or "FALSE".
583 // Implementation in ImpConvStringExt (SBXSCAN.CXX)
584 sal_Bool
SbxValue::PutStringExt( const OUString
& r
)
586 // Copy; if it is Unicode convert it immediately
589 // Identify the own type (not as in Put() with TheRealValue(),
590 // Objects are not handled anyway)
591 SbxDataType eTargetType
= SbxDataType( aData
.eType
& 0x0FFF );
593 // tinker a Source-Value
595 aRes
.eType
= SbxSTRING
;
597 // Only if really something was converted, take the copy,
598 // elsewise take the original (Unicode remain)
600 if( ImpConvStringExt( aStr
, eTargetType
) )
601 aRes
.pOUString
= (OUString
*)&aStr
;
603 aRes
.pOUString
= (OUString
*)&r
;
605 // #34939: Set a Fixed-Flag at Strings. which contain a number, and
606 // if this has a Num-Type, so that the type will not be changed
607 sal_uInt16 nFlags_
= GetFlags();
608 if( ( eTargetType
>= SbxINTEGER
&& eTargetType
<= SbxCURRENCY
) ||
609 ( eTargetType
>= SbxCHAR
&& eTargetType
<= SbxUINT
) ||
610 eTargetType
== SbxBOOL
)
614 if( aVal
.IsNumeric() )
615 SetFlag( SBX_FIXED
);
619 bRet
= sal_Bool( !IsError() );
621 // If it throwed an error with FIXED, set it back
622 // (UI-Action should not cast an error, but only fail)
630 sal_Bool
SbxValue::PutBool( sal_Bool b
)
633 aRes
.eType
= SbxBOOL
;
634 aRes
.nUShort
= sal::static_int_cast
< sal_uInt16
>(b
? SbxTRUE
: SbxFALSE
);
636 return sal_Bool( !IsError() );
639 sal_Bool
SbxValue::PutEmpty()
641 sal_Bool bRet
= SetType( SbxEMPTY
);
642 SetModified( sal_True
);
646 sal_Bool
SbxValue::PutNull()
648 sal_Bool bRet
= SetType( SbxNULL
);
650 SetModified( sal_True
);
655 // Special decimal methods
656 sal_Bool
SbxValue::PutDecimal( com::sun::star::bridge::oleautomation::Decimal
& rAutomationDec
)
659 aData
.pDecimal
= new SbxDecimal( rAutomationDec
);
660 aData
.pDecimal
->addRef();
661 aData
.eType
= SbxDECIMAL
;
665 sal_Bool
SbxValue::fillAutomationDecimal
666 ( com::sun::star::bridge::oleautomation::Decimal
& rAutomationDec
) const
668 SbxDecimal
* pDecimal
= GetDecimal();
669 if( pDecimal
!= NULL
)
671 pDecimal
->fillAutomationDecimal( rAutomationDec
);
678 sal_Bool
SbxValue::PutString( const OUString
& r
)
681 aRes
.eType
= SbxSTRING
;
682 aRes
.pOUString
= (OUString
*) &r
;
684 return sal_Bool( !IsError() );
688 #define PUT( p, e, t, m ) \
689 sal_Bool SbxValue::p( t n ) \
690 { SbxValues aRes(e); aRes.m = n; Put( aRes ); return sal_Bool( !IsError() ); }
692 PUT( PutByte
, SbxBYTE
, sal_uInt8
, nByte
)
693 PUT( PutChar
, SbxCHAR
, sal_Unicode
, nChar
)
694 PUT( PutCurrency
, SbxCURRENCY
, const sal_Int64
&, nInt64
)
695 PUT( PutDate
, SbxDATE
, double, nDouble
)
696 PUT( PutDouble
, SbxDOUBLE
, double, nDouble
)
697 PUT( PutErr
, SbxERROR
, sal_uInt16
, nUShort
)
698 PUT( PutInteger
, SbxINTEGER
, sal_Int16
, nInteger
)
699 PUT( PutLong
, SbxLONG
, sal_Int32
, nLong
)
700 PUT( PutObject
, SbxOBJECT
, SbxBase
*, pObj
)
701 PUT( PutSingle
, SbxSINGLE
, float, nSingle
)
702 PUT( PutULong
, SbxULONG
, sal_uInt32
, nULong
)
703 PUT( PutUShort
, SbxUSHORT
, sal_uInt16
, nUShort
)
704 PUT( PutInt64
, SbxSALINT64
, sal_Int64
, nInt64
)
705 PUT( PutUInt64
, SbxSALUINT64
, sal_uInt64
, uInt64
)
706 PUT( PutDecimal
, SbxDECIMAL
, SbxDecimal
*, pDecimal
)
708 ////////////////////////// Setting of the data type ///////////////////////////
710 sal_Bool
SbxValue::IsFixed() const
712 return ( (GetFlags() & SBX_FIXED
) | (aData
.eType
& SbxBYREF
) ) != 0;
715 // A variable is numeric, if it is EMPTY or realy numeric
716 // or if it contains a complete convertible String
718 // #41692, implement it for RTL and Basic-Core separately
719 sal_Bool
SbxValue::IsNumeric() const
721 return ImpIsNumeric( /*bOnlyIntntl*/false );
724 sal_Bool
SbxValue::IsNumericRTL() const
726 return ImpIsNumeric( /*bOnlyIntntl*/true );
729 sal_Bool
SbxValue::ImpIsNumeric( bool bOnlyIntntl
) const
734 SetError( SbxERR_PROP_WRITEONLY
); return sal_False
;
737 if( this->ISA(SbxVariable
) )
738 ((SbxVariable
*)this)->Broadcast( SBX_HINT_DATAWANTED
);
739 SbxDataType t
= GetType();
742 if( aData
.pOUString
)
744 OUString
s( *aData
.pOUString
);
748 if( ImpScan( s
, n
, t2
, &nLen
, /*bAllowIntntl*/false, bOnlyIntntl
) == SbxERR_OK
)
749 return sal_Bool( nLen
== s
.getLength() );
754 return sal_Bool( t
== SbxEMPTY
755 || ( t
>= SbxINTEGER
&& t
<= SbxCURRENCY
)
756 || ( t
>= SbxCHAR
&& t
<= SbxUINT
) );
759 SbxClassType
SbxValue::GetClass() const
761 return SbxCLASS_VALUE
;
764 SbxDataType
SbxValue::GetType() const
766 return SbxDataType( aData
.eType
& 0x0FFF );
769 SbxDataType
SbxValue::GetFullType() const
774 sal_Bool
SbxValue::SetType( SbxDataType t
)
776 DBG_ASSERT( !( t
& 0xF000 ), "SetType of BYREF|ARRAY is forbidden!" );
777 if( ( t
== SbxEMPTY
&& aData
.eType
== SbxVOID
)
778 || ( aData
.eType
== SbxEMPTY
&& t
== SbxVOID
) )
780 if( ( t
& 0x0FFF ) == SbxVARIANT
)
782 // Trial to set the data type to Variant
783 ResetFlag( SBX_FIXED
);
786 SetError( SbxERR_CONVERSION
); return sal_False
;
790 if( ( t
& 0x0FFF ) != ( aData
.eType
& 0x0FFF ) )
792 if( !CanWrite() || IsFixed() )
794 SetError( SbxERR_CONVERSION
); return sal_False
;
798 // De-allocate potential objects
799 switch( aData
.eType
)
802 delete aData
.pOUString
;
805 if( aData
.pObj
&& aData
.pObj
!= this )
807 SAL_WARN("basic.sbx", "Not at Parent-Prop - otherwise CyclicRef");
808 SbxVariable
*pThisVar
= PTR_CAST(SbxVariable
, this);
809 sal_uInt16 nSlotId
= pThisVar
810 ? ( (sal_Int16
) ( pThisVar
->GetUserData() & 0xFFFF ) )
812 DBG_ASSERT( nSlotId
!= 5345 || pThisVar
->GetName().equalsAscii("Parent"),
813 "SID_PARENTOBJECT is not named 'Parent'" );
814 sal_Bool bParentProp
= 5345 == nSlotId
;
816 aData
.pObj
->ReleaseRef();
821 // This works always, because the Float representations are 0 as well.
822 memset( &aData
, 0, sizeof( SbxValues
) );
829 sal_Bool
SbxValue::Convert( SbxDataType eTo
)
831 eTo
= SbxDataType( eTo
& 0x0FFF );
832 if( ( aData
.eType
& 0x0FFF ) == eTo
)
836 if( eTo
== SbxVARIANT
)
838 // Trial to set the data type to Variant
839 ResetFlag( SBX_FIXED
);
842 SetError( SbxERR_CONVERSION
); return sal_False
;
847 // Converting from zero doesn't work. Once zero, always zero!
848 if( aData
.eType
== SbxNULL
)
850 SetError( SbxERR_CONVERSION
); return sal_False
;
853 // Conversion of the data:
858 // The data type could be converted. It ends here with fixed elements,
859 // because the data had not to be taken over
864 SetModified( sal_True
);
866 Broadcast( SBX_HINT_CONVERTED
);
872 ////////////////////////////////// Calculating /////////////////////////////////
874 sal_Bool
SbxValue::Compute( SbxOperator eOp
, const SbxValue
& rOp
)
876 #ifdef DISABLE_SCRIPTING
877 bool bVBAInterop
= false;
879 bool bVBAInterop
= SbiRuntime::isVBAEnabled();
881 SbxDataType eThisType
= GetType();
882 SbxDataType eOpType
= rOp
.GetType();
883 SbxError eOld
= GetError();
884 if( eOld
!= SbxERR_OK
)
887 SetError( SbxERR_PROP_READONLY
);
888 else if( !rOp
.CanRead() )
889 SetError( SbxERR_PROP_WRITEONLY
);
890 // Special rule 1: If one operand is zero, the result is zero
891 else if( eThisType
== SbxNULL
|| eOpType
== SbxNULL
)
893 // Special rule 2: If the operand is Empty, the result is the 2. operand
894 else if( eThisType
== SbxEMPTY
898 // 1996-2-13: Don't test already before Get upon SbxEMPTY
902 bool bDecimal
= false;
903 if( bVBAInterop
&& ( ( eThisType
== SbxSTRING
&& eOpType
!= SbxSTRING
&& eOpType
!= SbxEMPTY
) ||
904 ( eThisType
!= SbxSTRING
&& eThisType
!= SbxEMPTY
&& eOpType
== SbxSTRING
) ) &&
905 ( eOp
== SbxMUL
|| eOp
== SbxDIV
|| eOp
== SbxPLUS
|| eOp
== SbxMINUS
) )
909 else if( eThisType
== SbxSTRING
|| eOp
== SbxCAT
|| ( bVBAInterop
&& ( eOpType
== SbxSTRING
) && ( eOp
== SbxPLUS
) ) )
911 if( eOp
== SbxCAT
|| eOp
== SbxPLUS
)
913 // From 1999-11-5, keep OUString in mind
914 aL
.eType
= aR
.eType
= SbxSTRING
;
916 // From 1999-12-8, #70399: Here call GetType() again, Get() can change the type!
917 if( rOp
.GetType() == SbxEMPTY
)
921 // #30576: To begin with test, if the conversion worked
922 if( aL
.pOUString
!= NULL
&& aR
.pOUString
!= NULL
)
924 *aL
.pOUString
+= *aR
.pOUString
;
927 else if( aL
.pOUString
== NULL
)
929 aL
.pOUString
= new OUString();
934 SetError( SbxERR_CONVERSION
);
936 else if( eOpType
== SbxSTRING
&& rOp
.IsFixed() )
937 { // Numeric: there is no String allowed on the right side
938 SetError( SbxERR_CONVERSION
);
939 // falls all the way out
941 else if( ( eOp
>= SbxIDIV
&& eOp
<= SbxNOT
) || eOp
== SbxMOD
)
943 if( GetType() == eOpType
)
945 if( GetType() == SbxSALUINT64
|| GetType() == SbxSALINT64
946 || GetType() == SbxCURRENCY
|| GetType() == SbxULONG
)
947 aL
.eType
= aR
.eType
= GetType();
948 else if ( bVBAInterop
&& eOpType
== SbxBOOL
)
949 aL
.eType
= aR
.eType
= SbxBOOL
;
951 aL
.eType
= aR
.eType
= SbxLONG
;
954 aL
.eType
= aR
.eType
= SbxLONG
;
956 if( rOp
.Get( aR
) ) // re-do Get after type assigns above
958 if( rOp
.GetType() == SbxEMPTY
)
960 if ( !bVBAInterop
|| ( bVBAInterop
&& ( eOp
!= SbxNOT
) ) )
963 if( Get( aL
) ) switch( eOp
)
966 if( aL
.eType
== SbxCURRENCY
)
967 if( !aR
.nInt64
) SetError( SbxERR_ZERODIV
);
969 aL
.nInt64
/= aR
.nInt64
;
970 aL
.nInt64
*= CURRENCY_FACTOR
;
972 else if( aL
.eType
== SbxSALUINT64
)
973 if( !aR
.uInt64
) SetError( SbxERR_ZERODIV
);
974 else aL
.uInt64
/= aR
.uInt64
;
975 else if( aL
.eType
== SbxSALINT64
)
976 if( !aR
.nInt64
) SetError( SbxERR_ZERODIV
);
977 else aL
.nInt64
/= aR
.nInt64
;
978 else if( aL
.eType
== SbxLONG
)
979 if( !aR
.nLong
) SetError( SbxERR_ZERODIV
);
980 else aL
.nLong
/= aR
.nLong
;
982 if( !aR
.nULong
) SetError( SbxERR_ZERODIV
);
983 else aL
.nULong
/= aR
.nULong
;
986 if( aL
.eType
== SbxCURRENCY
|| aL
.eType
== SbxSALINT64
)
987 if( !aR
.nInt64
) SetError( SbxERR_ZERODIV
);
988 else aL
.nInt64
%= aR
.nInt64
;
989 else if( aL
.eType
== SbxSALUINT64
)
990 if( !aR
.uInt64
) SetError( SbxERR_ZERODIV
);
991 else aL
.uInt64
%= aR
.uInt64
;
992 else if( aL
.eType
== SbxLONG
)
993 if( !aR
.nLong
) SetError( SbxERR_ZERODIV
);
994 else aL
.nLong
%= aR
.nLong
;
996 if( !aR
.nULong
) SetError( SbxERR_ZERODIV
);
997 else aL
.nULong
%= aR
.nULong
;
1000 if( aL
.eType
!= SbxLONG
&& aL
.eType
!= SbxULONG
)
1001 aL
.nInt64
&= aR
.nInt64
;
1003 aL
.nLong
&= aR
.nLong
;
1006 if( aL
.eType
!= SbxLONG
&& aL
.eType
!= SbxULONG
)
1007 aL
.nInt64
|= aR
.nInt64
;
1009 aL
.nLong
|= aR
.nLong
;
1012 if( aL
.eType
!= SbxLONG
&& aL
.eType
!= SbxULONG
)
1013 aL
.nInt64
^= aR
.nInt64
;
1015 aL
.nLong
^= aR
.nLong
;
1018 if( aL
.eType
!= SbxLONG
&& aL
.eType
!= SbxULONG
)
1019 aL
.nInt64
= (aL
.nInt64
& aR
.nInt64
) | (~aL
.nInt64
& ~aR
.nInt64
);
1021 aL
.nLong
= (aL
.nLong
& aR
.nLong
) | (~aL
.nLong
& ~aR
.nLong
);
1024 if( aL
.eType
!= SbxLONG
&& aL
.eType
!= SbxULONG
)
1025 aL
.nInt64
= ~aL
.nInt64
| aR
.nInt64
;
1027 aL
.nLong
= ~aL
.nLong
| aR
.nLong
;
1030 if( aL
.eType
!= SbxLONG
&& aL
.eType
!= SbxULONG
)
1032 if ( aL
.eType
!= SbxBOOL
)
1033 aL
.nInt64
= ~aL
.nInt64
;
1035 aL
.nLong
= ~aL
.nLong
;
1038 aL
.nLong
= ~aL
.nLong
;
1044 else if( ( GetType() == SbxDECIMAL
|| rOp
.GetType() == SbxDECIMAL
)
1045 && ( eOp
== SbxMUL
|| eOp
== SbxDIV
|| eOp
== SbxPLUS
|| eOp
== SbxMINUS
|| eOp
== SbxNEG
) )
1047 aL
.eType
= aR
.eType
= SbxDECIMAL
;
1051 if( rOp
.GetType() == SbxEMPTY
)
1053 releaseDecimalPtr( aL
.pDecimal
);
1058 if( aL
.pDecimal
&& aR
.pDecimal
)
1064 bOk
= ( *(aL
.pDecimal
) *= *(aR
.pDecimal
) );
1067 if( aR
.pDecimal
->isZero() )
1068 SetError( SbxERR_ZERODIV
);
1070 bOk
= ( *(aL
.pDecimal
) /= *(aR
.pDecimal
) );
1073 bOk
= ( *(aL
.pDecimal
) += *(aR
.pDecimal
) );
1076 bOk
= ( *(aL
.pDecimal
) -= *(aR
.pDecimal
) );
1079 bOk
= ( aL
.pDecimal
->neg() );
1082 SetError( SbxERR_NOTIMP
);
1085 SetError( SbxERR_OVERFLOW
);
1089 SetError( SbxERR_CONVERSION
);
1094 else if( GetType() == SbxCURRENCY
|| rOp
.GetType() == SbxCURRENCY
)
1096 aL
.eType
= SbxCURRENCY
;
1097 aR
.eType
= SbxCURRENCY
;
1101 if( rOp
.GetType() == SbxEMPTY
)
1104 if( Get( aL
) ) switch( eOp
)
1108 // first overflow check: see if product will fit - test real value of product (hence 2 curr factors)
1109 dTest
= (double)aL
.nInt64
* (double)aR
.nInt64
/ (double)CURRENCY_FACTOR_SQUARE
;
1110 if( dTest
< SbxMINCURR
|| SbxMAXCURR
< dTest
)
1112 aL
.nInt64
= SAL_MAX_INT64
;
1113 if( dTest
< SbxMINCURR
) aL
.nInt64
= SAL_MIN_INT64
;
1114 SetError( SbxERR_OVERFLOW
);
1117 // second overflow check: see if unscaled product overflows - if so use doubles
1118 dTest
= (double)aL
.nInt64
* (double)aR
.nInt64
;
1119 if( dTest
< SAL_MIN_INT64
|| SAL_MAX_INT64
< dTest
)
1121 aL
.nInt64
= (sal_Int64
)( dTest
/ (double)CURRENCY_FACTOR
);
1124 // precise calc: multiply then scale back (move decimal pt)
1125 aL
.nInt64
*= aR
.nInt64
;
1126 aL
.nInt64
/= CURRENCY_FACTOR
;
1132 SetError( SbxERR_ZERODIV
);
1135 // first overflow check: see if quotient will fit - calc real value of quotient (curr factors cancel)
1136 dTest
= (double)aL
.nInt64
/ (double)aR
.nInt64
;
1137 if( dTest
< SbxMINCURR
|| SbxMAXCURR
< dTest
)
1139 SetError( SbxERR_OVERFLOW
);
1142 // second overflow check: see if scaled dividend overflows - if so use doubles
1143 dTest
= (double)aL
.nInt64
* (double)CURRENCY_FACTOR
;
1144 if( dTest
< SAL_MIN_INT64
|| SAL_MAX_INT64
< dTest
)
1146 aL
.nInt64
= (sal_Int64
)(dTest
/ (double)aR
.nInt64
);
1149 // precise calc: scale (move decimal pt) then divide
1150 aL
.nInt64
*= CURRENCY_FACTOR
;
1151 aL
.nInt64
/= aR
.nInt64
;
1155 dTest
= ( (double)aL
.nInt64
+ (double)aR
.nInt64
) / (double)CURRENCY_FACTOR
;
1156 if( dTest
< SbxMINCURR
|| SbxMAXCURR
< dTest
)
1158 SetError( SbxERR_OVERFLOW
);
1161 aL
.nInt64
+= aR
.nInt64
;
1165 dTest
= ( (double)aL
.nInt64
- (double)aR
.nInt64
) / (double)CURRENCY_FACTOR
;
1166 if( dTest
< SbxMINCURR
|| SbxMAXCURR
< dTest
)
1168 SetError( SbxERR_OVERFLOW
);
1171 aL
.nInt64
-= aR
.nInt64
;
1174 aL
.nInt64
= -aL
.nInt64
;
1177 SetError( SbxERR_NOTIMP
);
1183 { // other types and operators including Date, Double and Single
1184 aL
.eType
= aR
.eType
= SbxDOUBLE
;
1187 if( rOp
.GetType() == SbxEMPTY
)
1189 if ( !bVBAInterop
|| ( bVBAInterop
&& ( eOp
!= SbxNEG
) ) )
1197 aL
.nDouble
= pow( aL
.nDouble
, aR
.nDouble
);
1200 aL
.nDouble
*= aR
.nDouble
; break;
1202 if( !aR
.nDouble
) SetError( SbxERR_ZERODIV
);
1203 else aL
.nDouble
/= aR
.nDouble
; break;
1205 aL
.nDouble
+= aR
.nDouble
; break;
1207 aL
.nDouble
-= aR
.nDouble
; break;
1209 aL
.nDouble
= -aL
.nDouble
; break;
1211 SetError( SbxERR_NOTIMP
);
1213 // Date with "+" or "-" needs special handling that
1214 // forces the Date type. If the operation is '+' the
1215 // result is always a Date, if '-' the result is only
1216 // a Date if one of lhs or rhs ( but not both ) is already
1218 if( ( GetType() == SbxDATE
|| rOp
.GetType() == SbxDATE
) )
1220 if( eOp
== SbxPLUS
|| ( ( eOp
== SbxMINUS
) && ( GetType() != rOp
.GetType() ) ) )
1232 releaseDecimalPtr( aL
.pDecimal
);
1233 releaseDecimalPtr( aR
.pDecimal
);
1238 sal_Bool bRes
= sal_Bool( !IsError() );
1239 if( bRes
&& eOld
!= SbxERR_OK
)
1244 // The comparison routine deliver TRUE or FALSE.
1246 sal_Bool
SbxValue::Compare( SbxOperator eOp
, const SbxValue
& rOp
) const
1248 #ifdef DISABLE_SCRIPTING
1249 bool bVBAInterop
= false;
1251 bool bVBAInterop
= SbiRuntime::isVBAEnabled();
1254 sal_Bool bRes
= sal_False
;
1255 SbxError eOld
= GetError();
1256 if( eOld
!= SbxERR_OK
)
1258 if( !CanRead() || !rOp
.CanRead() )
1259 SetError( SbxERR_PROP_WRITEONLY
);
1260 else if( GetType() == SbxNULL
&& rOp
.GetType() == SbxNULL
&& !bVBAInterop
)
1264 else if( GetType() == SbxEMPTY
&& rOp
.GetType() == SbxEMPTY
)
1265 bRes
= !bVBAInterop
? sal_True
: ( eOp
== SbxEQ
? sal_True
: sal_False
);
1266 // Special rule 1: If an operand is zero, the result is FALSE
1267 else if( GetType() == SbxNULL
|| rOp
.GetType() == SbxNULL
)
1269 // Special rule 2: If both are variant and one is numeric
1270 // and the other is a String, num is < str
1271 else if( !IsFixed() && !rOp
.IsFixed()
1272 && ( rOp
.GetType() == SbxSTRING
&& GetType() != SbxSTRING
&& IsNumeric() ) && !bVBAInterop
1274 bRes
= sal_Bool( eOp
== SbxLT
|| eOp
== SbxLE
|| eOp
== SbxNE
);
1275 else if( !IsFixed() && !rOp
.IsFixed()
1276 && ( GetType() == SbxSTRING
&& rOp
.GetType() != SbxSTRING
&& rOp
.IsNumeric() )
1279 bRes
= sal_Bool( eOp
== SbxGT
|| eOp
== SbxGE
|| eOp
== SbxNE
);
1283 // If one of the operands is a String,
1284 // a String comparing take place
1285 if( GetType() == SbxSTRING
|| rOp
.GetType() == SbxSTRING
)
1287 aL
.eType
= aR
.eType
= SbxSTRING
;
1288 if( Get( aL
) && rOp
.Get( aR
) ) switch( eOp
)
1291 bRes
= sal_Bool( *aL
.pOUString
== *aR
.pOUString
); break;
1293 bRes
= sal_Bool( *aL
.pOUString
!= *aR
.pOUString
); break;
1295 bRes
= sal_Bool( *aL
.pOUString
< *aR
.pOUString
); break;
1297 bRes
= sal_Bool( *aL
.pOUString
> *aR
.pOUString
); break;
1299 bRes
= sal_Bool( *aL
.pOUString
<= *aR
.pOUString
); break;
1301 bRes
= sal_Bool( *aL
.pOUString
>= *aR
.pOUString
); break;
1303 SetError( SbxERR_NOTIMP
);
1306 // From 1995-12-19: If SbxSINGLE participate, then convert to SINGLE,
1307 // elsewise it shows a numeric error
1308 else if( GetType() == SbxSINGLE
|| rOp
.GetType() == SbxSINGLE
)
1310 aL
.eType
= aR
.eType
= SbxSINGLE
;
1311 if( Get( aL
) && rOp
.Get( aR
) )
1315 bRes
= sal_Bool( aL
.nSingle
== aR
.nSingle
); break;
1317 bRes
= sal_Bool( aL
.nSingle
!= aR
.nSingle
); break;
1319 bRes
= sal_Bool( aL
.nSingle
< aR
.nSingle
); break;
1321 bRes
= sal_Bool( aL
.nSingle
> aR
.nSingle
); break;
1323 bRes
= sal_Bool( aL
.nSingle
<= aR
.nSingle
); break;
1325 bRes
= sal_Bool( aL
.nSingle
>= aR
.nSingle
); break;
1327 SetError( SbxERR_NOTIMP
);
1330 else if( GetType() == SbxDECIMAL
&& rOp
.GetType() == SbxDECIMAL
)
1332 aL
.eType
= aR
.eType
= SbxDECIMAL
;
1335 if( aL
.pDecimal
&& aR
.pDecimal
)
1337 SbxDecimal::CmpResult eRes
= compare( *aL
.pDecimal
, *aR
.pDecimal
);
1341 bRes
= sal_Bool( eRes
== SbxDecimal::EQ
); break;
1343 bRes
= sal_Bool( eRes
!= SbxDecimal::EQ
); break;
1345 bRes
= sal_Bool( eRes
== SbxDecimal::LT
); break;
1347 bRes
= sal_Bool( eRes
== SbxDecimal::GT
); break;
1349 bRes
= sal_Bool( eRes
!= SbxDecimal::GT
); break;
1351 bRes
= sal_Bool( eRes
!= SbxDecimal::LT
); break;
1353 SetError( SbxERR_NOTIMP
);
1358 SetError( SbxERR_CONVERSION
);
1360 releaseDecimalPtr( aL
.pDecimal
);
1361 releaseDecimalPtr( aR
.pDecimal
);
1363 // Everything else comparing on a SbxDOUBLE-Basis
1366 aL
.eType
= aR
.eType
= SbxDOUBLE
;
1367 bool bGetL
= Get( aL
);
1368 bool bGetR
= rOp
.Get( aR
);
1369 if( bGetL
&& bGetR
)
1373 bRes
= sal_Bool( aL
.nDouble
== aR
.nDouble
); break;
1375 bRes
= sal_Bool( aL
.nDouble
!= aR
.nDouble
); break;
1377 bRes
= sal_Bool( aL
.nDouble
< aR
.nDouble
); break;
1379 bRes
= sal_Bool( aL
.nDouble
> aR
.nDouble
); break;
1381 bRes
= sal_Bool( aL
.nDouble
<= aR
.nDouble
); break;
1383 bRes
= sal_Bool( aL
.nDouble
>= aR
.nDouble
); break;
1385 SetError( SbxERR_NOTIMP
);
1387 // at least one value was got
1388 // if this is VBA then a conversion error for one
1389 // side will yield a false result of an equality test
1390 else if ( bGetR
|| bGetL
)
1392 if ( bVBAInterop
&& eOp
== SbxEQ
&& GetError() == SbxERR_CONVERSION
)
1400 if( eOld
!= SbxERR_OK
)
1405 ///////////////////////////// Reading/Writing ////////////////////////////
1407 sal_Bool
SbxValue::LoadData( SvStream
& r
, sal_uInt16
)
1409 // #TODO see if these types are really dumped to any stream
1410 // more than likely this is functionality used in the binfilter alone
1414 aData
.eType
= SbxDataType( nType
);
1419 r
>> aData
.nInteger
; break;
1421 r
>> aData
.nLong
; break;
1425 OUString aVal
= read_lenPrefixed_uInt8s_ToOUString
<sal_uInt16
>(r
,
1426 RTL_TEXTENCODING_ASCII_US
);
1429 if( ImpScan( aVal
, d
, t
, NULL
) != SbxERR_OK
|| t
== SbxDOUBLE
)
1431 aData
.nSingle
= 0.0F
;
1434 aData
.nSingle
= (float) d
;
1441 OUString aVal
= read_lenPrefixed_uInt8s_ToOUString
<sal_uInt16
>(r
,
1442 RTL_TEXTENCODING_ASCII_US
);
1444 if( ImpScan( aVal
, aData
.nDouble
, t
, NULL
) != SbxERR_OK
)
1446 aData
.nDouble
= 0.0;
1451 //#fdo39428 SvStream no longer supports operator>>(long&)
1453 r
.ReadInt64(aData
.nInt64
);
1460 sal_uInt32 tmpHi
= 0;
1461 sal_uInt32 tmpLo
= 0;
1462 r
>> tmpHi
>> tmpLo
;
1463 aData
.nInt64
= ((sal_Int64
)tmpHi
<< 32);
1464 aData
.nInt64
|= (sal_Int64
)tmpLo
;
1469 OUString aVal
= read_lenPrefixed_uInt8s_ToOUString
<sal_uInt16
>(r
,
1470 RTL_TEXTENCODING_ASCII_US
);
1471 if( !aVal
.isEmpty() )
1472 aData
.pOUString
= new OUString( aVal
);
1474 aData
.pOUString
= NULL
; // JSM 1995-09-22
1479 r
>> aData
.nUShort
; break;
1490 aData
.pObj
= SbxBase::Load( r
);
1491 return sal_Bool( aData
.pObj
!= NULL
);
1506 r
>> aData
.nByte
; break;
1508 r
>> aData
.nULong
; break;
1513 // Match the Int on this system?
1514 if( n
> SAL_TYPES_SIZEOFINT
)
1515 r
>> aData
.nLong
, aData
.eType
= SbxLONG
;
1527 // Match the UInt on this system?
1528 if( n
> SAL_TYPES_SIZEOFINT
)
1529 r
>> aData
.nULong
, aData
.eType
= SbxULONG
;
1533 aData
.nUInt
= nUInt
;
1544 // #78919 For backwards compatibility
1549 memset (&aData
,0,sizeof(aData
));
1550 ResetFlag(SBX_FIXED
);
1551 aData
.eType
= SbxNULL
;
1552 DBG_ASSERT( !this, "Loaded a non-supported data type" );
1559 sal_Bool
SbxValue::StoreData( SvStream
& r
) const
1561 sal_uInt16 nType
= sal::static_int_cast
< sal_uInt16
>(aData
.eType
);
1563 switch( nType
& 0x0FFF )
1567 r
<< aData
.nInteger
; break;
1569 r
<< aData
.nLong
; break;
1571 // #49935: Save as double, elsewise an error during the read in
1572 ((SbxValue
*)this)->aData
.eType
= (SbxDataType
)( ( nType
& 0xF000 ) | SbxDOUBLE
);
1573 write_lenPrefixed_uInt8s_FromOUString
<sal_uInt16
>(r
, GetCoreString(), RTL_TEXTENCODING_ASCII_US
);
1574 ((SbxValue
*)this)->aData
.eType
= (SbxDataType
)nType
;
1578 write_lenPrefixed_uInt8s_FromOUString
<sal_uInt16
>(r
, GetCoreString(), RTL_TEXTENCODING_ASCII_US
);
1582 // see comment in SbxValue::StoreData
1587 sal_Int32 tmpHi
= ( (aData
.nInt64
>> 32) & 0xFFFFFFFF );
1588 sal_Int32 tmpLo
= ( sal_Int32
)aData
.nInt64
;
1589 r
<< tmpHi
<< tmpLo
;
1593 if( aData
.pOUString
)
1595 write_lenPrefixed_uInt8s_FromOUString
<sal_uInt16
>(r
, *aData
.pOUString
, RTL_TEXTENCODING_ASCII_US
);
1599 write_lenPrefixed_uInt8s_FromOUString
<sal_uInt16
>(r
, OUString(), RTL_TEXTENCODING_ASCII_US
);
1604 r
<< aData
.nUShort
; break;
1606 // to save itself as Objectptr does not work!
1609 if( PTR_CAST(SbxValue
,aData
.pObj
) != this )
1612 return aData
.pObj
->Store( r
);
1622 char c
= sal::static_int_cast
< char >(aData
.nChar
);
1627 r
<< aData
.nByte
; break;
1629 r
<< aData
.nULong
; break;
1632 sal_uInt8 n
= SAL_TYPES_SIZEOFINT
;
1633 r
<< n
<< (sal_Int32
)aData
.nInt
;
1638 sal_uInt8 n
= SAL_TYPES_SIZEOFINT
;
1639 r
<< n
<< (sal_uInt32
)aData
.nUInt
;
1649 // #78919 For backwards compatibility
1654 DBG_ASSERT( !this, "Saving a non-supported data type" );
1660 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */