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