Update ooo320-m1
[ooovba.git] / basic / source / sbx / sbxcurr.cxx
blobea906ccc011cfc6dccc5de4b73e92193ff7767fa
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sbxcurr.cxx,v $
10 * $Revision: 1.7 $
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 )
48 SbxValues aTmp;
49 SbxINT64 nRes;
50 start:
51 switch( +p->eType )
53 case SbxNULL:
54 SbxBase::SetError( SbxERR_CONVERSION );
55 case SbxEMPTY:
56 nRes.SetNull(); break;
57 case SbxCHAR:
58 nRes = ImpDoubleToCurrency( (double)p->nChar ); break;
59 case SbxBYTE:
60 nRes = ImpDoubleToCurrency( (double)p->nByte ); break;
61 case SbxINTEGER:
62 case SbxBOOL:
63 nRes = ImpDoubleToCurrency( (double)p->nInteger ); break;
64 case SbxERROR:
65 case SbxUSHORT:
66 nRes = ImpDoubleToCurrency( (double)p->nUShort ); break;
67 case SbxCURRENCY:
68 nRes = p->nLong64; break;
69 case SbxLONG:
70 nRes = ImpDoubleToCurrency( (double)p->nLong );
71 break;
72 case SbxULONG:
73 nRes = ImpDoubleToCurrency( (double)p->nULong );
74 break;
75 case SbxSALINT64:
76 nRes = ImpDoubleToCurrency( (double)p->nInt64 );
77 break;
78 case SbxSALUINT64:
79 nRes = ImpDoubleToCurrency( ImpSalUInt64ToDouble( p->uInt64 ) );
80 break;
81 case SbxSINGLE:
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();
90 else
91 nRes = ImpDoubleToCurrency( (double)p->nSingle );
92 break;
93 case SbxDATE:
94 case SbxDOUBLE:
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();
103 else
104 nRes = ImpDoubleToCurrency( p->nDouble );
105 break;
106 case SbxDECIMAL:
107 case SbxBYREF | SbxDECIMAL:
109 double d = 0.0;
110 if( p->pDecimal )
111 p->pDecimal->getDouble( d );
112 if( d > SbxMAXCURR )
114 SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMax();
116 else if( d < SbxMINCURR )
118 SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMin();
120 else
121 nRes = ImpDoubleToCurrency( d );
122 break;
124 case SbxBYREF | SbxSTRING:
125 case SbxSTRING:
126 case SbxLPSTR:
127 if( !p->pString )
128 nRes.SetNull();
129 else
130 nRes = ImpStringToCurrency( *p->pString );
131 break;
132 case SbxOBJECT:
134 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
135 if( pVal )
136 nRes = pVal->GetCurrency();
137 else
139 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes.SetNull();
141 break;
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;
171 ref:
172 aTmp.eType = SbxDataType( p->eType & 0x0FFF );
173 p = &aTmp; goto start;
175 default:
176 SbxBase::SetError( SbxERR_CONVERSION ); nRes.SetNull();
178 return nRes;
181 void ImpPutCurrency( SbxValues* p, const SbxINT64 &r )
183 double dVal = ImpCurrencyToDouble( r );
184 SbxValues aTmp;
185 start:
186 switch( +p->eType )
188 // Hier sind Tests notwendig
189 case SbxCHAR:
190 aTmp.pChar = &p->nChar; goto direct;
191 case SbxBYTE:
192 aTmp.pByte = &p->nByte; goto direct;
193 case SbxINTEGER:
194 case SbxBOOL:
195 aTmp.pInteger = &p->nInteger; goto direct;
196 case SbxLONG:
197 aTmp.pLong = &p->nLong; goto direct;
198 case SbxULONG:
199 aTmp.pULong = &p->nULong; goto direct;
200 case SbxERROR:
201 case SbxUSHORT:
202 aTmp.pUShort = &p->nUShort; goto direct;
203 direct:
204 aTmp.eType = SbxDataType( p->eType | SbxBYREF );
205 p = &aTmp; goto start;
207 // ab hier nicht mehr
208 case SbxSINGLE:
209 p->nSingle = (float)dVal; break;
210 case SbxDATE:
211 case SbxDOUBLE:
212 p->nDouble = dVal; break;
213 case SbxSALINT64:
214 p->nInt64 = ImpDoubleToSalInt64( dVal ); break;
215 case SbxSALUINT64:
216 p->uInt64 = ImpDoubleToSalUInt64( dVal ); break;
217 case SbxCURRENCY:
218 p->nLong64 = r; break;
219 case SbxDECIMAL:
220 case SbxBYREF | SbxDECIMAL:
222 SbxDecimal* pDec = ImpCreateDecimal( p );
223 if( !pDec->setDouble( dVal ) )
224 SbxBase::SetError( SbxERR_OVERFLOW );
225 break;
227 case SbxBYREF | SbxSTRING:
228 case SbxSTRING:
229 case SbxLPSTR:
230 if( !p->pString )
231 p->pString = new XubString;
233 *p->pString = ImpCurrencyToString( r );
234 break;
235 case SbxOBJECT:
237 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
238 if( pVal )
239 pVal->PutCurrency( r );
240 else
241 SbxBase::SetError( SbxERR_NO_OBJECT );
242 break;
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;
259 else if( dVal < 0 )
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;
281 else if( dVal < 0 )
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;
301 else if( dVal < 0 )
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;
318 default:
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 );
330 BigInt aInt( r );
331 aInt.Abs();
332 BigInt aFrac = aInt;
333 aInt /= a10000;
334 aFrac %= a10000;
335 aFrac += a10000;
337 String aString;
338 if( r.nHigh < 0 )
339 aString = '-';
340 aString += aInt.GetString();
341 aString += '.';
342 aString += aFrac.GetString().GetBuffer()+1;
343 return aString;
346 static SbxINT64 ImpStringToCurrency( const String &r )
348 int nDec = 4;
349 String aStr;
350 const sal_Unicode* p = r.GetBuffer();
352 if( *p == '-' )
353 aStr += *p++;
355 while( *p >= '0' && *p <= '9' ) {
356 aStr += *p++;
357 if( *p == ',' )
358 p++;
361 if( *p == '.' ) {
362 p++;
363 while( nDec && *p >= '0' && *p <= '9' ) {
364 aStr += *p++;
365 nDec--;
368 while( nDec ) {
369 aStr += '0';
370 nDec--;
373 BigInt aBig( aStr );
374 SbxINT64 nRes;
375 aBig.INT64( &nRes );
376 return nRes;
379 double ImpINT64ToDouble( const SbxINT64 &r )
380 { return (double)r.nHigh*(double)4294967296.0 + (double)r.nLow; }
382 SbxINT64 ImpDoubleToINT64( double d )
384 SbxINT64 nRes;
385 nRes.Set( d );
386 return nRes;
389 double ImpUINT64ToDouble( const SbxUINT64 &r )
390 { return (double)r.nHigh*(double)4294967296.0 + (double)r.nLow; }
392 SbxUINT64 ImpDoubleToUINT64( double d )
394 SbxUINT64 nRes;
395 nRes.Set( d );
396 return nRes;