xref: /trunk/main/basic/source/sbx/sbxdbl.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basic.hxx"
30 #include <tools/errcode.hxx>
31 #include <basic/sbx.hxx>
32 #include "sbxconv.hxx"
33 #include "runtime.hxx"
34 
35 double ImpGetDouble( const SbxValues* p )
36 {
37     double nRes;
38     switch( +p->eType )
39     {
40         case SbxNULL:
41             SbxBase::SetError( SbxERR_CONVERSION );
42         case SbxEMPTY:
43             nRes = 0; break;
44         case SbxCHAR:
45             nRes = p->nChar; break;
46         case SbxBYTE:
47             nRes = p->nByte; break;
48         case SbxINTEGER:
49         case SbxBOOL:
50             nRes = p->nInteger; break;
51         case SbxERROR:
52         case SbxUSHORT:
53             nRes = p->nUShort; break;
54         case SbxLONG:
55             nRes = p->nLong; break;
56         case SbxULONG:
57             nRes = p->nULong; break;
58         case SbxSINGLE:
59             nRes = p->nSingle; break;
60         case SbxDATE:
61         case SbxDOUBLE:
62             nRes = p->nDouble; break;
63         case SbxCURRENCY:
64             nRes = ImpCurrencyToDouble( p->nLong64 ); break;
65         case SbxSALINT64:
66             nRes = static_cast< double >(p->nInt64); break;
67         case SbxSALUINT64:
68             nRes = ImpSalUInt64ToDouble( p->uInt64 ); break;
69         case SbxDECIMAL:
70         case SbxBYREF | SbxDECIMAL:
71             if( p->pDecimal )
72                 p->pDecimal->getDouble( nRes );
73             else
74                 nRes = 0.0;
75             break;
76         case SbxBYREF | SbxSTRING:
77         case SbxSTRING:
78         case SbxLPSTR:
79             if( !p->pOUString )
80             {
81                 nRes = 0;
82                 if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour
83                     SbxBase::SetError( SbxERR_CONVERSION );
84             }
85             else
86             {
87                 double d;
88                 SbxDataType t;
89                 if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
90                 {
91                     nRes = 0;
92                     if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour
93                         SbxBase::SetError( SbxERR_CONVERSION );
94                 }
95                 else
96                     nRes = d;
97             }
98             break;
99         case SbxOBJECT:
100         {
101             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
102             if( pVal )
103                 nRes = pVal->GetDouble();
104             else
105             {
106                 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
107             }
108             break;
109         }
110 
111         case SbxBYREF | SbxCHAR:
112             nRes = *p->pChar; break;
113         case SbxBYREF | SbxBYTE:
114             nRes = *p->pByte; break;
115         case SbxBYREF | SbxINTEGER:
116         case SbxBYREF | SbxBOOL:
117             nRes = *p->pInteger; break;
118         case SbxBYREF | SbxLONG:
119             nRes = *p->pLong; break;
120         case SbxBYREF | SbxULONG:
121             nRes = *p->pULong; break;
122         case SbxBYREF | SbxERROR:
123         case SbxBYREF | SbxUSHORT:
124             nRes = *p->pUShort; break;
125         case SbxBYREF | SbxSINGLE:
126             nRes = *p->pSingle; break;
127         case SbxBYREF | SbxDATE:
128         case SbxBYREF | SbxDOUBLE:
129             nRes = *p->pDouble; break;
130         case SbxBYREF | SbxCURRENCY:
131             nRes = ImpCurrencyToDouble( *p->pLong64 ); break;
132         case SbxBYREF | SbxSALINT64:
133             nRes = static_cast< double >(*p->pnInt64); break;
134         case SbxBYREF | SbxSALUINT64:
135             nRes = ImpSalUInt64ToDouble( *p->puInt64 ); break;
136 
137         default:
138             SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
139     }
140     return nRes;
141 }
142 
143 void ImpPutDouble( SbxValues* p, double n, sal_Bool bCoreString )
144 {
145     SbxValues aTmp;
146 start:
147     switch( +p->eType )
148     {
149         // Hier sind Tests notwendig
150         case SbxCHAR:
151             aTmp.pChar = &p->nChar; goto direct;
152         case SbxBYTE:
153             aTmp.pByte = &p->nByte; goto direct;
154         case SbxINTEGER:
155         case SbxBOOL:
156             aTmp.pInteger = &p->nInteger; goto direct;
157         case SbxLONG:
158         case SbxCURRENCY:
159             aTmp.pLong = &p->nLong; goto direct;
160         case SbxULONG:
161             aTmp.pULong = &p->nULong; goto direct;
162         case SbxERROR:
163         case SbxUSHORT:
164             aTmp.pUShort = &p->nUShort; goto direct;
165         case SbxSINGLE:
166             aTmp.pSingle = &p->nSingle; goto direct;
167         case SbxDECIMAL:
168         case SbxBYREF | SbxDECIMAL:
169             {
170             SbxDecimal* pDec = ImpCreateDecimal( p );
171             if( !pDec->setDouble( n ) )
172                 SbxBase::SetError( SbxERR_OVERFLOW );
173             break;
174             }
175         direct:
176             aTmp.eType = SbxDataType( p->eType | SbxBYREF );
177             p = &aTmp; goto start;
178 
179             // ab hier nicht mehr
180         case SbxSALINT64:
181             p->nInt64 = ImpDoubleToSalInt64( n ); break;
182         case SbxSALUINT64:
183             p->uInt64 = ImpDoubleToSalUInt64( n ); break;
184         case SbxDATE:
185         case SbxDOUBLE:
186             p->nDouble = n; break;
187 
188         case SbxBYREF | SbxSTRING:
189         case SbxSTRING:
190         case SbxLPSTR:
191             if( !p->pOUString )
192                 p->pOUString = new ::rtl::OUString;
193             ImpCvtNum( (double) n, 14, *p->pOUString, bCoreString );
194             break;
195         case SbxOBJECT:
196         {
197             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
198             if( pVal )
199                 pVal->PutDouble( n );
200             else
201                 SbxBase::SetError( SbxERR_NO_OBJECT );
202             break;
203         }
204         case SbxBYREF | SbxCHAR:
205             if( n > SbxMAXCHAR )
206             {
207                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
208             }
209             else if( n < SbxMINCHAR )
210             {
211                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
212             }
213             *p->pChar = (xub_Unicode) n; break;
214         case SbxBYREF | SbxBYTE:
215             if( n > SbxMAXBYTE )
216             {
217                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
218             }
219             else if( n < 0 )
220             {
221                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
222             }
223             *p->pByte = (sal_uInt8) n; break;
224         case SbxBYREF | SbxINTEGER:
225         case SbxBYREF | SbxBOOL:
226             if( n > SbxMAXINT )
227             {
228                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
229             }
230             else if( n < SbxMININT )
231             {
232                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
233             }
234             *p->pInteger = (sal_Int16) n; break;
235         case SbxBYREF | SbxERROR:
236         case SbxBYREF | SbxUSHORT:
237             if( n > SbxMAXUINT )
238             {
239                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
240             }
241             else if( n < 0 )
242             {
243                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
244             }
245             *p->pUShort = (sal_uInt16) n; break;
246         case SbxBYREF | SbxLONG:
247             if( n > SbxMAXLNG )
248             {
249                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
250             }
251             else if( n < SbxMINLNG )
252             {
253                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
254             }
255             *p->pLong = (sal_Int32) n; break;
256         case SbxBYREF | SbxULONG:
257             if( n > SbxMAXULNG )
258             {
259                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
260             }
261             else if( n < 0 )
262             {
263                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
264             }
265             *p->pULong = (sal_uInt32) n; break;
266         case SbxBYREF | SbxSINGLE:
267             if( n > SbxMAXSNG )
268             {
269                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG;
270             }
271             else if( n < SbxMINSNG )
272             {
273                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG;
274             }
275             else if( n > 0 && n < SbxMAXSNG2 )
276             {
277                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG2;
278             }
279             else if( n < 0 && n > SbxMINSNG2 )
280             {
281                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG2;
282             }
283             *p->pSingle = (float) n; break;
284         case SbxBYREF | SbxSALINT64:
285             *p->pnInt64 = ImpDoubleToSalInt64( n ); break;
286         case SbxBYREF | SbxSALUINT64:
287             *p->puInt64 = ImpDoubleToSalUInt64( n ); break;
288         case SbxBYREF | SbxDATE:
289         case SbxBYREF | SbxDOUBLE:
290             *p->pDouble = (double) n; break;
291         case SbxBYREF | SbxCURRENCY:
292             if( n > SbxMAXCURR )
293             {
294                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCURR;
295             }
296             else if( n < SbxMINCURR )
297             {
298                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCURR;
299             }
300             *p->pLong64 = ImpDoubleToCurrency( n ); break;
301 
302         default:
303             SbxBase::SetError( SbxERR_CONVERSION );
304     }
305 }
306 
307