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: sbxcurr.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 #include <basic/sbx.hxx>
35 #include <tools/errcode.hxx>
37 #define _TLBIGINT_INT64
38 #include <tools/bigint.hxx>
40 #include <basic/sbxvar.hxx>
41 #include "sbxconv.hxx"
43 static String
ImpCurrencyToString( const SbxINT64
& );
44 static SbxINT64
ImpStringToCurrency( const String
& );
46 SbxINT64
ImpGetCurrency( const SbxValues
* p
)
54 SbxBase::SetError( SbxERR_CONVERSION
);
56 nRes
.SetNull(); break;
58 nRes
= ImpDoubleToCurrency( (double)p
->nChar
); break;
60 nRes
= ImpDoubleToCurrency( (double)p
->nByte
); break;
63 nRes
= ImpDoubleToCurrency( (double)p
->nInteger
); break;
66 nRes
= ImpDoubleToCurrency( (double)p
->nUShort
); break;
68 nRes
= p
->nLong64
; break;
70 nRes
= ImpDoubleToCurrency( (double)p
->nLong
);
73 nRes
= ImpDoubleToCurrency( (double)p
->nULong
);
76 nRes
= ImpDoubleToCurrency( (double)p
->nInt64
);
79 nRes
= ImpDoubleToCurrency( ImpSalUInt64ToDouble( p
->uInt64
) );
82 if( p
->nSingle
> SbxMAXCURR
)
84 SbxBase::SetError( SbxERR_OVERFLOW
); nRes
.SetMax();
86 else if( p
->nSingle
< SbxMINCURR
)
88 SbxBase::SetError( SbxERR_OVERFLOW
); nRes
.SetMin();
91 nRes
= ImpDoubleToCurrency( (double)p
->nSingle
);
95 if( p
->nDouble
> SbxMAXCURR
)
97 SbxBase::SetError( SbxERR_OVERFLOW
); nRes
.SetMax();
99 else if( p
->nDouble
< SbxMINCURR
)
101 SbxBase::SetError( SbxERR_OVERFLOW
); nRes
.SetMin();
104 nRes
= ImpDoubleToCurrency( p
->nDouble
);
107 case SbxBYREF
| SbxDECIMAL
:
111 p
->pDecimal
->getDouble( d
);
114 SbxBase::SetError( SbxERR_OVERFLOW
); nRes
.SetMax();
116 else if( d
< SbxMINCURR
)
118 SbxBase::SetError( SbxERR_OVERFLOW
); nRes
.SetMin();
121 nRes
= ImpDoubleToCurrency( d
);
124 case SbxBYREF
| SbxSTRING
:
130 nRes
= ImpStringToCurrency( *p
->pString
);
134 SbxValue
* pVal
= PTR_CAST(SbxValue
,p
->pObj
);
136 nRes
= pVal
->GetCurrency();
139 SbxBase::SetError( SbxERR_NO_OBJECT
); nRes
.SetNull();
144 case SbxBYREF
| SbxCHAR
:
145 nRes
= ImpDoubleToCurrency( (double)*p
->pChar
); break;
146 case SbxBYREF
| SbxBYTE
:
147 nRes
= ImpDoubleToCurrency( (double)*p
->pByte
); break;
148 case SbxBYREF
| SbxINTEGER
:
149 case SbxBYREF
| SbxBOOL
:
150 nRes
= ImpDoubleToCurrency( (double)*p
->pInteger
); break;
151 case SbxBYREF
| SbxERROR
:
152 case SbxBYREF
| SbxUSHORT
:
153 nRes
= ImpDoubleToCurrency( (double)*p
->pUShort
); break;
154 case SbxBYREF
| SbxCURRENCY
:
155 nRes
= *p
->pLong64
; break;
157 // ab hier muss getestet werden
158 case SbxBYREF
| SbxLONG
:
159 aTmp
.nLong
= *p
->pLong
; goto ref
;
160 case SbxBYREF
| SbxULONG
:
161 aTmp
.nULong
= *p
->pULong
; goto ref
;
162 case SbxBYREF
| SbxSINGLE
:
163 aTmp
.nSingle
= *p
->pSingle
; goto ref
;
164 case SbxBYREF
| SbxDATE
:
165 case SbxBYREF
| SbxDOUBLE
:
166 aTmp
.nDouble
= *p
->pDouble
; goto ref
;
167 case SbxBYREF
| SbxSALINT64
:
168 aTmp
.nInt64
= *p
->pnInt64
; goto ref
;
169 case SbxBYREF
| SbxSALUINT64
:
170 aTmp
.uInt64
= *p
->puInt64
; goto ref
;
172 aTmp
.eType
= SbxDataType( p
->eType
& 0x0FFF );
173 p
= &aTmp
; goto start
;
176 SbxBase::SetError( SbxERR_CONVERSION
); nRes
.SetNull();
181 void ImpPutCurrency( SbxValues
* p
, const SbxINT64
&r
)
183 double dVal
= ImpCurrencyToDouble( r
);
188 // Hier sind Tests notwendig
190 aTmp
.pChar
= &p
->nChar
; goto direct
;
192 aTmp
.pByte
= &p
->nByte
; goto direct
;
195 aTmp
.pInteger
= &p
->nInteger
; goto direct
;
197 aTmp
.pLong
= &p
->nLong
; goto direct
;
199 aTmp
.pULong
= &p
->nULong
; goto direct
;
202 aTmp
.pUShort
= &p
->nUShort
; goto direct
;
204 aTmp
.eType
= SbxDataType( p
->eType
| SbxBYREF
);
205 p
= &aTmp
; goto start
;
207 // ab hier nicht mehr
209 p
->nSingle
= (float)dVal
; break;
212 p
->nDouble
= dVal
; break;
214 p
->nInt64
= ImpDoubleToSalInt64( dVal
); break;
216 p
->uInt64
= ImpDoubleToSalUInt64( dVal
); break;
218 p
->nLong64
= r
; break;
220 case SbxBYREF
| SbxDECIMAL
:
222 SbxDecimal
* pDec
= ImpCreateDecimal( p
);
223 if( !pDec
->setDouble( dVal
) )
224 SbxBase::SetError( SbxERR_OVERFLOW
);
227 case SbxBYREF
| SbxSTRING
:
231 p
->pString
= new XubString
;
233 *p
->pString
= ImpCurrencyToString( r
);
237 SbxValue
* pVal
= PTR_CAST(SbxValue
,p
->pObj
);
239 pVal
->PutCurrency( r
);
241 SbxBase::SetError( SbxERR_NO_OBJECT
);
244 case SbxBYREF
| SbxCHAR
:
245 if( dVal
> SbxMAXCHAR
)
247 SbxBase::SetError( SbxERR_OVERFLOW
); dVal
= SbxMAXCHAR
;
249 else if( dVal
< SbxMINCHAR
)
251 SbxBase::SetError( SbxERR_OVERFLOW
); dVal
= SbxMINCHAR
;
253 *p
->pChar
= (xub_Unicode
) dVal
; break;
254 case SbxBYREF
| SbxBYTE
:
255 if( dVal
> SbxMAXBYTE
)
257 SbxBase::SetError( SbxERR_OVERFLOW
); dVal
= SbxMAXBYTE
;
261 SbxBase::SetError( SbxERR_OVERFLOW
); dVal
= 0;
263 *p
->pByte
= (BYTE
) dVal
; break;
264 case SbxBYREF
| SbxINTEGER
:
265 case SbxBYREF
| SbxBOOL
:
266 if( dVal
> SbxMAXINT
)
268 SbxBase::SetError( SbxERR_OVERFLOW
); dVal
= SbxMAXINT
;
270 else if( dVal
< SbxMININT
)
272 SbxBase::SetError( SbxERR_OVERFLOW
); dVal
= SbxMININT
;
274 *p
->pInteger
= (INT16
) dVal
; break;
275 case SbxBYREF
| SbxERROR
:
276 case SbxBYREF
| SbxUSHORT
:
277 if( dVal
> SbxMAXUINT
)
279 SbxBase::SetError( SbxERR_OVERFLOW
); dVal
= SbxMAXUINT
;
283 SbxBase::SetError( SbxERR_OVERFLOW
); dVal
= 0;
285 *p
->pUShort
= (UINT16
) dVal
; break;
286 case SbxBYREF
| SbxLONG
:
287 if( dVal
> SbxMAXLNG
)
289 SbxBase::SetError( SbxERR_OVERFLOW
); dVal
= SbxMAXLNG
;
291 else if( dVal
< SbxMINLNG
)
293 SbxBase::SetError( SbxERR_OVERFLOW
); dVal
= SbxMINLNG
;
295 *p
->pLong
= (INT32
) dVal
; break;
296 case SbxBYREF
| SbxULONG
:
297 if( dVal
> SbxMAXULNG
)
299 SbxBase::SetError( SbxERR_OVERFLOW
); dVal
= SbxMAXULNG
;
303 SbxBase::SetError( SbxERR_OVERFLOW
); dVal
= 0;
305 *p
->pULong
= (UINT32
) dVal
; break;
306 case SbxBYREF
| SbxSALINT64
:
307 *p
->pnInt64
= ImpDoubleToSalInt64( dVal
); break;
308 case SbxBYREF
| SbxSALUINT64
:
309 *p
->puInt64
= ImpDoubleToSalUInt64( dVal
); break;
310 case SbxBYREF
| SbxSINGLE
:
311 *p
->pSingle
= (float) dVal
; break;
312 case SbxBYREF
| SbxDATE
:
313 case SbxBYREF
| SbxDOUBLE
:
314 *p
->pDouble
= (double) dVal
; break;
315 case SbxBYREF
| SbxCURRENCY
:
316 *p
->pLong64
= r
; break;
319 SbxBase::SetError( SbxERR_CONVERSION
);
323 // Hilfs-Funktionen zur Wandlung
325 static String
ImpCurrencyToString( const SbxINT64
&r
)
327 BigInt a10000
= 10000;
329 //return GetpApp()->GetAppInternational().GetCurr( BigInt( r ), 4 );
340 aString
+= aInt
.GetString();
342 aString
+= aFrac
.GetString().GetBuffer()+1;
346 static SbxINT64
ImpStringToCurrency( const String
&r
)
350 const sal_Unicode
* p
= r
.GetBuffer();
355 while( *p
>= '0' && *p
<= '9' ) {
363 while( nDec
&& *p
>= '0' && *p
<= '9' ) {
379 double ImpINT64ToDouble( const SbxINT64
&r
)
380 { return (double)r
.nHigh
*(double)4294967296.0 + (double)r
.nLow
; }
382 SbxINT64
ImpDoubleToINT64( double d
)
389 double ImpUINT64ToDouble( const SbxUINT64
&r
)
390 { return (double)r
.nHigh
*(double)4294967296.0 + (double)r
.nLow
; }
392 SbxUINT64
ImpDoubleToUINT64( double d
)