fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / basic / source / sbx / sbxdec.cxx
blob276b78857e56257551e42fadd38fdc1832cd214c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <tools/errcode.hxx>
22 #include <basic/sbx.hxx>
23 #include "sbxconv.hxx"
25 #include <com/sun/star/bridge/oleautomation/Decimal.hpp>
28 // Implementation SbxDecimal
29 SbxDecimal::SbxDecimal( void )
31 setInt( 0 );
32 mnRefCount = 0;
35 SbxDecimal::SbxDecimal( const SbxDecimal& rDec )
37 #ifdef WIN32
38 maDec = rDec.maDec;
39 #else
40 (void)rDec;
41 #endif
42 mnRefCount = 0;
45 SbxDecimal::SbxDecimal
46 ( const com::sun::star::bridge::oleautomation::Decimal& rAutomationDec )
48 #ifdef WIN32
49 maDec.scale = rAutomationDec.Scale;
50 maDec.sign = rAutomationDec.Sign;
51 maDec.Lo32 = rAutomationDec.LowValue;
52 maDec.Mid32 = rAutomationDec.MiddleValue;
53 maDec.Hi32 = rAutomationDec.HighValue;
54 #else
55 (void)rAutomationDec;
56 #endif
57 mnRefCount = 0;
60 void SbxDecimal::fillAutomationDecimal
61 ( com::sun::star::bridge::oleautomation::Decimal& rAutomationDec )
63 #ifdef WIN32
64 rAutomationDec.Scale = maDec.scale;
65 rAutomationDec.Sign = maDec.sign;
66 rAutomationDec.LowValue = maDec.Lo32;
67 rAutomationDec.MiddleValue = maDec.Mid32;
68 rAutomationDec.HighValue = maDec.Hi32;
69 #else
70 (void)rAutomationDec;
71 #endif
74 SbxDecimal::~SbxDecimal()
78 void releaseDecimalPtr( SbxDecimal*& rpDecimal )
80 if( rpDecimal )
82 rpDecimal->mnRefCount--;
83 if( rpDecimal->mnRefCount == 0 )
85 delete rpDecimal;
86 rpDecimal = NULL;
91 #ifdef WIN32
93 bool SbxDecimal::operator -= ( const SbxDecimal &r )
95 HRESULT hResult = VarDecSub( &maDec, (LPDECIMAL)&r.maDec, &maDec );
96 bool bRet = ( hResult == S_OK );
97 return bRet;
100 bool SbxDecimal::operator += ( const SbxDecimal &r )
102 HRESULT hResult = VarDecAdd( &maDec, (LPDECIMAL)&r.maDec, &maDec );
103 bool bRet = ( hResult == S_OK );
104 return bRet;
107 bool SbxDecimal::operator /= ( const SbxDecimal &r )
109 HRESULT hResult = VarDecDiv( &maDec, (LPDECIMAL)&r.maDec, &maDec );
110 bool bRet = ( hResult == S_OK );
111 return bRet;
114 bool SbxDecimal::operator *= ( const SbxDecimal &r )
116 HRESULT hResult = VarDecMul( &maDec, (LPDECIMAL)&r.maDec, &maDec );
117 bool bRet = ( hResult == S_OK );
118 return bRet;
121 bool SbxDecimal::neg( void )
123 HRESULT hResult = VarDecNeg( &maDec, &maDec );
124 bool bRet = ( hResult == S_OK );
125 return bRet;
128 bool SbxDecimal::isZero( void )
130 SbxDecimal aZeroDec;
131 aZeroDec.setLong( 0 );
132 bool bZero = ( EQ == compare( *this, aZeroDec ) );
133 return bZero;
136 SbxDecimal::CmpResult compare( const SbxDecimal &rLeft, const SbxDecimal &rRight )
138 HRESULT hResult = VarDecCmp( (LPDECIMAL)&rLeft.maDec, (LPDECIMAL)&rRight.maDec );
139 SbxDecimal::CmpResult eRes = (SbxDecimal::CmpResult)hResult;
140 return eRes;
143 void SbxDecimal::setChar( sal_Unicode val )
145 VarDecFromUI2( (sal_uInt16)val, &maDec );
148 void SbxDecimal::setByte( sal_uInt8 val )
150 VarDecFromUI1( (sal_uInt8)val, &maDec );
153 void SbxDecimal::setShort( sal_Int16 val )
155 VarDecFromI2( (short)val, &maDec );
158 void SbxDecimal::setLong( sal_Int32 val )
160 VarDecFromI4( (long)val, &maDec );
163 void SbxDecimal::setUShort( sal_uInt16 val )
165 VarDecFromUI2( (sal_uInt16)val, &maDec );
168 void SbxDecimal::setULong( sal_uInt32 val )
170 VarDecFromUI4( (sal_uIntPtr)val, &maDec );
173 bool SbxDecimal::setSingle( float val )
175 bool bRet = ( VarDecFromR4( val, &maDec ) == S_OK );
176 return bRet;
179 bool SbxDecimal::setDouble( double val )
181 bool bRet = ( VarDecFromR8( val, &maDec ) == S_OK );
182 return bRet;
185 void SbxDecimal::setInt( int val )
187 setLong( (sal_Int32)val );
190 void SbxDecimal::setUInt( unsigned int val )
192 setULong( (sal_uInt32)val );
195 bool SbxDecimal::setString( OUString* pOUString )
197 static LCID nLANGID = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US );
199 // Convert delimiter
200 sal_Unicode cDecimalSep;
201 sal_Unicode cThousandSep;
202 ImpGetIntntlSep( cDecimalSep, cThousandSep );
204 bool bRet = false;
205 HRESULT hResult;
206 if( cDecimalSep != '.' || cThousandSep != ',' )
208 int nLen = pOUString->getLength();
209 sal_Unicode* pBuffer = new sal_Unicode[nLen + 1];
210 pBuffer[nLen] = 0;
212 const sal_Unicode* pSrc = pOUString->getStr();
213 int i;
214 for( i = 0 ; i < nLen ; ++i )
215 pBuffer[i] = pSrc[i];
217 sal_Unicode c;
218 i = 0;
219 while( (c = pBuffer[i]) != 0 )
221 if( c == cDecimalSep )
222 pBuffer[i] = '.';
223 else if( c == cThousandSep )
224 pBuffer[i] = ',';
225 i++;
227 hResult = VarDecFromStr( (OLECHAR*)pBuffer, nLANGID, 0, &maDec );
228 delete [] pBuffer;
230 else
232 hResult = VarDecFromStr( (OLECHAR*)pOUString->getStr(), nLANGID, 0, &maDec );
234 bRet = ( hResult == S_OK );
235 return bRet;
239 bool SbxDecimal::getChar( sal_Unicode& rVal )
241 bool bRet = ( VarUI2FromDec( &maDec, &rVal ) == S_OK );
242 return bRet;
245 bool SbxDecimal::getShort( sal_Int16& rVal )
247 bool bRet = ( VarI2FromDec( &maDec, &rVal ) == S_OK );
248 return bRet;
251 bool SbxDecimal::getLong( sal_Int32& rVal )
253 bool bRet = ( VarI4FromDec( &maDec, &rVal ) == S_OK );
254 return bRet;
257 bool SbxDecimal::getUShort( sal_uInt16& rVal )
259 bool bRet = ( VarUI2FromDec( &maDec, &rVal ) == S_OK );
260 return bRet;
263 bool SbxDecimal::getULong( sal_uInt32& rVal )
265 bool bRet = ( VarUI4FromDec( &maDec, &rVal ) == S_OK );
266 return bRet;
269 bool SbxDecimal::getSingle( float& rVal )
271 bool bRet = ( VarR4FromDec( &maDec, &rVal ) == S_OK );
272 return bRet;
275 bool SbxDecimal::getDouble( double& rVal )
277 bool bRet = ( VarR8FromDec( &maDec, &rVal ) == S_OK );
278 return bRet;
281 #else
282 // !WIN32
284 bool SbxDecimal::operator -= ( const SbxDecimal &r )
286 (void)r;
287 return false;
290 bool SbxDecimal::operator += ( const SbxDecimal &r )
292 (void)r;
293 return false;
296 bool SbxDecimal::operator /= ( const SbxDecimal &r )
298 (void)r;
299 return false;
302 bool SbxDecimal::operator *= ( const SbxDecimal &r )
304 (void)r;
305 return false;
308 bool SbxDecimal::neg( void )
310 return false;
313 bool SbxDecimal::isZero( void )
315 return false;
318 SbxDecimal::CmpResult compare( const SbxDecimal &rLeft, const SbxDecimal &rRight )
320 (void)rLeft;
321 (void)rRight;
322 return (SbxDecimal::CmpResult)0;
325 void SbxDecimal::setChar( sal_Unicode val ) { (void)val; }
326 void SbxDecimal::setByte( sal_uInt8 val ) { (void)val; }
327 void SbxDecimal::setShort( sal_Int16 val ) { (void)val; }
328 void SbxDecimal::setLong( sal_Int32 val ) { (void)val; }
329 void SbxDecimal::setUShort( sal_uInt16 val ) { (void)val; }
330 void SbxDecimal::setULong( sal_uInt32 val ) { (void)val; }
331 bool SbxDecimal::setSingle( float val ) { (void)val; return false; }
332 bool SbxDecimal::setDouble( double val ) { (void)val; return false; }
333 void SbxDecimal::setInt( int val ) { (void)val; }
334 void SbxDecimal::setUInt( unsigned int val ) { (void)val; }
335 bool SbxDecimal::setString( OUString* pOUString ) { (void)pOUString; return false; }
337 bool SbxDecimal::getChar( sal_Unicode& rVal ) { (void)rVal; return false; }
338 bool SbxDecimal::getShort( sal_Int16& rVal ) { (void)rVal; return false; }
339 bool SbxDecimal::getLong( sal_Int32& rVal ) { (void)rVal; return false; }
340 bool SbxDecimal::getUShort( sal_uInt16& rVal ) { (void)rVal; return false; }
341 bool SbxDecimal::getULong( sal_uInt32& rVal ) { (void)rVal; return false; }
342 bool SbxDecimal::getSingle( float& rVal ) { (void)rVal; return false; }
343 bool SbxDecimal::getDouble( double& rVal ) { (void)rVal; return false; }
345 #endif
347 bool SbxDecimal::getString( OUString& rString )
349 #ifdef WIN32
350 static LCID nLANGID = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US );
352 bool bRet = false;
354 OLECHAR sz[100];
355 BSTR aBStr = SysAllocString( sz );
356 if( aBStr != NULL )
358 HRESULT hResult = VarBstrFromDec( &maDec, nLANGID, 0, &aBStr );
359 bRet = ( hResult == S_OK );
360 if( bRet )
362 // Convert delimiter
363 sal_Unicode cDecimalSep;
364 sal_Unicode cThousandSep;
365 ImpGetIntntlSep( cDecimalSep, cThousandSep );
367 if( cDecimalSep != '.' || cThousandSep != ',' )
369 sal_Unicode c;
370 int i = 0;
371 while( (c = aBStr[i]) != 0 )
373 if( c == '.' )
374 aBStr[i] = cDecimalSep;
375 else if( c == ',' )
376 aBStr[i] = cThousandSep;
377 i++;
380 rString = reinterpret_cast<const sal_Unicode*>(aBStr);
383 SysFreeString( aBStr );
385 return bRet;
386 #else
387 (void)rString;
388 return false;
389 #endif
392 SbxDecimal* ImpCreateDecimal( SbxValues* p )
394 if( !p )
395 return NULL;
397 SbxDecimal*& rpDecimal = p->pDecimal;
398 if( rpDecimal == NULL )
400 rpDecimal = new SbxDecimal();
401 rpDecimal->addRef();
403 return rpDecimal;
406 SbxDecimal* ImpGetDecimal( const SbxValues* p )
408 SbxValues aTmp;
409 SbxDecimal* pnDecRes;
411 SbxDataType eType = p->eType;
412 if( eType == SbxDECIMAL && p->pDecimal )
414 pnDecRes = new SbxDecimal( *p->pDecimal );
415 pnDecRes->addRef();
416 return pnDecRes;
418 pnDecRes = new SbxDecimal();
419 pnDecRes->addRef();
421 start:
422 switch( +eType )
424 case SbxNULL:
425 SbxBase::SetError( SbxERR_CONVERSION );
426 case SbxEMPTY:
427 pnDecRes->setShort( 0 ); break;
428 case SbxCHAR:
429 pnDecRes->setChar( p->nChar ); break;
430 case SbxBYTE:
431 pnDecRes->setByte( p->nByte ); break;
432 case SbxINTEGER:
433 case SbxBOOL:
434 pnDecRes->setInt( p->nInteger ); break;
435 case SbxERROR:
436 case SbxUSHORT:
437 pnDecRes->setUShort( p->nUShort ); break;
438 case SbxLONG:
439 pnDecRes->setLong( p->nLong ); break;
440 case SbxULONG:
441 pnDecRes->setULong( p->nULong ); break;
442 case SbxSINGLE:
443 if( !pnDecRes->setSingle( p->nSingle ) )
444 SbxBase::SetError( SbxERR_OVERFLOW );
445 break;
446 case SbxCURRENCY:
448 if( !pnDecRes->setDouble( ImpCurrencyToDouble( p->nInt64 ) ) )
449 SbxBase::SetError( SbxERR_OVERFLOW );
450 break;
452 case SbxSALINT64:
454 if( !pnDecRes->setDouble( (double)p->nInt64 ) )
455 SbxBase::SetError( SbxERR_OVERFLOW );
456 break;
458 case SbxSALUINT64:
460 if( !pnDecRes->setDouble( (double)p->uInt64 ) )
461 SbxBase::SetError( SbxERR_OVERFLOW );
462 break;
464 case SbxDATE:
465 case SbxDOUBLE:
467 double dVal = p->nDouble;
468 if( !pnDecRes->setDouble( dVal ) )
469 SbxBase::SetError( SbxERR_OVERFLOW );
470 break;
472 case SbxLPSTR:
473 case SbxSTRING:
474 case SbxBYREF | SbxSTRING:
475 pnDecRes->setString( p->pOUString ); break;
476 case SbxOBJECT:
478 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
479 if( pVal )
480 pnDecRes->setDecimal( pVal->GetDecimal() );
481 else
483 SbxBase::SetError( SbxERR_NO_OBJECT );
484 pnDecRes->setShort( 0 );
486 break;
489 case SbxBYREF | SbxCHAR:
490 pnDecRes->setChar( *p->pChar ); break;
491 case SbxBYREF | SbxBYTE:
492 pnDecRes->setByte( *p->pByte ); break;
493 case SbxBYREF | SbxINTEGER:
494 case SbxBYREF | SbxBOOL:
495 pnDecRes->setInt( *p->pInteger ); break;
496 case SbxBYREF | SbxLONG:
497 pnDecRes->setLong( *p->pLong ); break;
498 case SbxBYREF | SbxULONG:
499 pnDecRes->setULong( *p->pULong ); break;
500 case SbxBYREF | SbxERROR:
501 case SbxBYREF | SbxUSHORT:
502 pnDecRes->setUShort( *p->pUShort ); break;
504 // from here on had to be tested
505 case SbxBYREF | SbxSINGLE:
506 aTmp.nSingle = *p->pSingle; goto ref;
507 case SbxBYREF | SbxDATE:
508 case SbxBYREF | SbxDOUBLE:
509 aTmp.nDouble = *p->pDouble; goto ref;
510 case SbxBYREF | SbxCURRENCY:
511 case SbxBYREF | SbxSALINT64:
512 aTmp.nInt64 = *p->pnInt64; goto ref;
513 case SbxBYREF | SbxSALUINT64:
514 aTmp.uInt64 = *p->puInt64; goto ref;
515 ref:
516 aTmp.eType = SbxDataType( p->eType & 0x0FFF );
517 p = &aTmp; goto start;
519 default:
520 SbxBase::SetError( SbxERR_CONVERSION ); pnDecRes->setShort( 0 );
522 return pnDecRes;
525 void ImpPutDecimal( SbxValues* p, SbxDecimal* pDec )
527 if( !pDec )
528 return;
530 SbxValues aTmp;
531 start:
532 switch( +p->eType )
534 // here had to be tested
535 case SbxCHAR:
536 aTmp.pChar = &p->nChar; goto direct;
537 case SbxBYTE:
538 aTmp.pByte = &p->nByte; goto direct;
539 case SbxULONG:
540 aTmp.pULong = &p->nULong; goto direct;
541 case SbxERROR:
542 case SbxUSHORT:
543 aTmp.pUShort = &p->nUShort; goto direct;
544 case SbxINTEGER:
545 case SbxBOOL:
546 aTmp.pInteger = &p->nInteger; goto direct;
547 case SbxLONG:
548 aTmp.pLong = &p->nLong; goto direct;
549 case SbxCURRENCY:
550 case SbxSALINT64:
551 aTmp.pnInt64 = &p->nInt64; goto direct;
552 case SbxSALUINT64:
553 aTmp.puInt64 = &p->uInt64; goto direct;
555 direct:
556 aTmp.eType = SbxDataType( p->eType | SbxBYREF );
557 p = &aTmp; goto start;
559 // from here on no longer
560 case SbxDECIMAL:
561 case SbxBYREF | SbxDECIMAL:
563 if( pDec != p->pDecimal )
565 releaseDecimalPtr( p->pDecimal );
566 p->pDecimal = pDec;
567 if( pDec )
568 pDec->addRef();
570 break;
572 case SbxSINGLE:
574 float f(0.0);
575 pDec->getSingle( f );
576 p->nSingle = f;
577 break;
579 case SbxDATE:
580 case SbxDOUBLE:
582 double d(0.0);
583 pDec->getDouble( d );
584 p->nDouble = d;
585 break;
588 case SbxLPSTR:
589 case SbxSTRING:
590 case SbxBYREF | SbxSTRING:
591 if( !p->pOUString )
592 p->pOUString = new OUString;
593 pDec->getString( *p->pOUString );
594 break;
595 case SbxOBJECT:
597 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
598 if( pVal )
599 pVal->PutDecimal( pDec );
600 else
601 SbxBase::SetError( SbxERR_NO_OBJECT );
602 break;
605 case SbxBYREF | SbxCHAR:
606 if( !pDec->getChar( *p->pChar ) )
608 SbxBase::SetError( SbxERR_OVERFLOW );
609 *p->pChar = 0;
611 break;
612 case SbxBYREF | SbxBYTE:
613 if( !pDec->getChar( *p->pChar ) )
615 SbxBase::SetError( SbxERR_OVERFLOW );
616 *p->pByte = 0;
618 break;
619 case SbxBYREF | SbxINTEGER:
620 case SbxBYREF | SbxBOOL:
621 if( !pDec->getShort( *p->pInteger ) )
623 SbxBase::SetError( SbxERR_OVERFLOW );
624 *p->pInteger = 0;
626 break;
627 case SbxBYREF | SbxERROR:
628 case SbxBYREF | SbxUSHORT:
629 if( !pDec->getUShort( *p->pUShort ) )
631 SbxBase::SetError( SbxERR_OVERFLOW );
632 *p->pUShort = 0;
634 break;
635 case SbxBYREF | SbxLONG:
636 if( !pDec->getLong( *p->pLong ) )
638 SbxBase::SetError( SbxERR_OVERFLOW );
639 *p->pLong = 0;
641 break;
642 case SbxBYREF | SbxULONG:
643 if( !pDec->getULong( *p->pULong ) )
645 SbxBase::SetError( SbxERR_OVERFLOW );
646 *p->pULong = 0;
648 break;
649 case SbxBYREF | SbxCURRENCY:
651 double d(0.0);
652 if( !pDec->getDouble( d ) )
653 SbxBase::SetError( SbxERR_OVERFLOW );
654 *p->pnInt64 = ImpDoubleToCurrency( d );
656 break;
657 case SbxBYREF | SbxSALINT64:
659 double d(0.0);
660 if( !pDec->getDouble( d ) )
661 SbxBase::SetError( SbxERR_OVERFLOW );
662 else
663 *p->pnInt64 = ImpDoubleToSalInt64( d );
665 break;
666 case SbxBYREF | SbxSALUINT64:
668 double d(0.0);
669 if( !pDec->getDouble( d ) )
670 SbxBase::SetError( SbxERR_OVERFLOW );
671 else
672 *p->puInt64 = ImpDoubleToSalUInt64( d );
674 break;
675 case SbxBYREF | SbxSINGLE:
676 if( !pDec->getSingle( *p->pSingle ) )
678 SbxBase::SetError( SbxERR_OVERFLOW );
679 *p->pSingle = 0;
681 break;
682 case SbxBYREF | SbxDATE:
683 case SbxBYREF | SbxDOUBLE:
684 if( !pDec->getDouble( *p->pDouble ) )
686 SbxBase::SetError( SbxERR_OVERFLOW );
687 *p->pDouble = 0;
689 break;
690 default:
691 SbxBase::SetError( SbxERR_CONVERSION );
695 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */