xref: /trunk/main/basic/source/sbx/sbxsng.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 
34 float ImpGetSingle( const SbxValues* p )
35 {
36     SbxValues aTmp;
37     float nRes;
38 start:
39     switch( +p->eType )
40     {
41         case SbxNULL:
42             SbxBase::SetError( SbxERR_CONVERSION );
43         case SbxEMPTY:
44             nRes = 0; break;
45         case SbxCHAR:
46             nRes = p->nChar; break;
47         case SbxBYTE:
48             nRes = p->nByte; break;
49         case SbxINTEGER:
50         case SbxBOOL:
51             nRes = p->nInteger; break;
52         case SbxERROR:
53         case SbxUSHORT:
54             nRes = p->nUShort; break;
55         case SbxLONG:
56             nRes = (float) p->nLong; break;
57         case SbxULONG:
58             nRes = (float) p->nULong; break;
59         case SbxSINGLE:
60             nRes = p->nSingle; break;
61         case SbxSALINT64:
62             nRes = (float) p->nInt64; break;
63         case SbxSALUINT64:
64             nRes = (float) ImpSalUInt64ToDouble( p->uInt64 ); break;
65         case SbxDECIMAL:
66         case SbxBYREF | SbxDECIMAL:
67             if( p->pDecimal )
68                 p->pDecimal->getSingle( nRes );
69             else
70                 nRes = 0.0;
71             break;
72         case SbxDATE:
73         case SbxDOUBLE:
74         case SbxLONG64:
75         case SbxULONG64:
76         case SbxCURRENCY:
77             {
78             double dVal;
79             if( p->eType == SbxCURRENCY )
80                 dVal = ImpCurrencyToDouble( p->nLong64 );
81             else if( p->eType == SbxLONG64 )
82                 dVal = ImpINT64ToDouble( p->nLong64 );
83             else if( p->eType == SbxULONG64 )
84                 dVal = ImpUINT64ToDouble( p->nULong64 );
85             else
86                 dVal = p->nDouble;
87 
88             if( dVal > SbxMAXSNG )
89             {
90                 SbxBase::SetError( SbxERR_OVERFLOW );
91                 nRes = static_cast< float >(SbxMAXSNG);
92             }
93             else if( dVal < SbxMINSNG )
94             {
95                 SbxBase::SetError( SbxERR_OVERFLOW );
96                 nRes = static_cast< float >(SbxMINSNG);
97             }
98             else if( dVal > 0 && dVal < SbxMAXSNG2 )
99             {
100                 SbxBase::SetError( SbxERR_OVERFLOW );
101                 nRes = static_cast< float >(SbxMAXSNG2);
102             }
103             else if( dVal < 0 && dVal > SbxMINSNG2 )
104             {
105                 SbxBase::SetError( SbxERR_OVERFLOW );
106                 nRes = static_cast< float >(SbxMINSNG2);
107             }
108             else
109                 nRes = (float) dVal;
110             break;
111             }
112         case SbxBYREF | SbxSTRING:
113         case SbxSTRING:
114         case SbxLPSTR:
115             if( !p->pOUString )
116                 nRes = 0;
117             else
118             {
119                 double d;
120                 SbxDataType t;
121                 if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
122                     nRes = 0;
123                 else if( d > SbxMAXSNG )
124                 {
125                     SbxBase::SetError( SbxERR_OVERFLOW );
126                     nRes = static_cast< float >(SbxMAXSNG);
127                 }
128                 else if( d < SbxMINSNG )
129                 {
130                     SbxBase::SetError( SbxERR_OVERFLOW );
131                     nRes = static_cast< float >(SbxMINSNG);
132                 }
133                 else
134                     nRes = (float) d;
135             }
136             break;
137         case SbxOBJECT:
138         {
139             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
140             if( pVal )
141                 nRes = pVal->GetSingle();
142             else
143             {
144                 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
145             }
146             break;
147         }
148 
149         case SbxBYREF | SbxCHAR:
150             nRes = *p->pChar; break;
151         case SbxBYREF | SbxBYTE:
152             nRes = *p->pByte; break;
153         case SbxBYREF | SbxINTEGER:
154         case SbxBYREF | SbxBOOL:
155             nRes = *p->pInteger; break;
156         case SbxBYREF | SbxLONG:
157             nRes = (float) *p->pLong; break;
158         case SbxBYREF | SbxULONG:
159             nRes = (float) *p->pULong; break;
160         case SbxBYREF | SbxERROR:
161         case SbxBYREF | SbxUSHORT:
162             nRes = *p->pUShort; break;
163         case SbxBYREF | SbxSINGLE:
164             nRes = *p->pSingle; break;
165         // ab hier muss getestet werden
166         case SbxBYREF | SbxDATE:
167         case SbxBYREF | SbxDOUBLE:
168             aTmp.nDouble = *p->pDouble; goto ref;
169         case SbxBYREF | SbxULONG64:
170             aTmp.nULong64 = *p->pULong64; goto ref;
171         case SbxBYREF | SbxLONG64:
172         case SbxBYREF | SbxSALINT64:
173             nRes = (float) *p->pnInt64; break;
174         case SbxBYREF | SbxSALUINT64:
175             nRes = (float) ImpSalUInt64ToDouble( *p->puInt64 ); break;
176         case SbxBYREF | SbxCURRENCY:
177             aTmp.nLong64 = *p->pLong64; goto ref;
178         ref:
179             aTmp.eType = SbxDataType( p->eType & 0x0FFF );
180             p = &aTmp; goto start;
181 
182         default:
183             SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
184     }
185     return nRes;
186 }
187 
188 void ImpPutSingle( SbxValues* p, float n )
189 {
190     SbxValues aTmp;
191 start:
192     switch( +p->eType )
193     {
194         case SbxCHAR:
195             aTmp.pChar = &p->nChar; goto direct;
196         case SbxBYTE:
197             aTmp.pByte = &p->nByte; goto direct;
198         case SbxINTEGER:
199         case SbxBOOL:
200             aTmp.pInteger = &p->nInteger; goto direct;
201         case SbxLONG:
202             aTmp.pLong = &p->nLong; goto direct;
203         case SbxULONG:
204             aTmp.pULong = &p->nULong; goto direct;
205         case SbxERROR:
206         case SbxUSHORT:
207             aTmp.pUShort = &p->nUShort; goto direct;
208         case SbxULONG64:
209             aTmp.pULong64 = &p->nULong64; goto direct;
210         case SbxLONG64:
211         case SbxCURRENCY:
212             aTmp.pLong64 = &p->nLong64; goto direct;
213         case SbxSALINT64:
214             aTmp.pnInt64 = &p->nInt64; goto direct;
215         case SbxSALUINT64:
216             aTmp.puInt64 = &p->uInt64; goto direct;
217         case SbxDECIMAL:
218         case SbxBYREF | SbxDECIMAL:
219             {
220             SbxDecimal* pDec = ImpCreateDecimal( p );
221             if( !pDec->setSingle( n ) )
222                 SbxBase::SetError( SbxERR_OVERFLOW );
223             break;
224             }
225         direct:
226             aTmp.eType = SbxDataType( p->eType | SbxBYREF );
227             p = &aTmp; goto start;
228 
229         // keine Tests ab hier
230         case SbxSINGLE:
231             p->nSingle = n; break;
232         case SbxDATE:
233         case SbxDOUBLE:
234             p->nDouble = n; break;
235 
236         case SbxBYREF | SbxSTRING:
237         case SbxSTRING:
238         case SbxLPSTR:
239         {
240             if( !p->pOUString )
241                 p->pOUString = new ::rtl::OUString;
242             ImpCvtNum( (double) n, 6, *p->pOUString );
243             break;
244         }
245         case SbxOBJECT:
246         {
247             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
248             if( pVal )
249                 pVal->PutSingle( n );
250             else
251                 SbxBase::SetError( SbxERR_NO_OBJECT );
252             break;
253         }
254         case SbxBYREF | SbxCHAR:
255             if( n > SbxMAXCHAR )
256             {
257                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
258             }
259             else if( n < SbxMINCHAR )
260             {
261                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
262             }
263             *p->pChar = (xub_Unicode) n; break;
264         case SbxBYREF | SbxBYTE:
265             if( n > SbxMAXBYTE )
266             {
267                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
268             }
269             else if( n < 0 )
270             {
271                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
272             }
273             *p->pByte = (sal_uInt8) n; break;
274         case SbxBYREF | SbxINTEGER:
275         case SbxBYREF | SbxBOOL:
276             if( n > SbxMAXINT )
277             {
278                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
279             }
280             else if( n < SbxMININT )
281             {
282                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
283             }
284             *p->pInteger = (sal_Int16) n; break;
285         case SbxBYREF | SbxERROR:
286         case SbxBYREF | SbxUSHORT:
287             if( n > SbxMAXUINT )
288             {
289                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
290             }
291             else if( n < 0 )
292             {
293                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
294             }
295             *p->pUShort = (sal_uInt16) n; break;
296         case SbxBYREF | SbxLONG:
297         {
298             sal_Int32 i;
299             if( n > SbxMAXLNG )
300             {
301                 SbxBase::SetError( SbxERR_OVERFLOW ); i = SbxMAXLNG;
302             }
303             else if( n < SbxMINLNG )
304             {
305                 SbxBase::SetError( SbxERR_OVERFLOW ); i = SbxMINLNG;
306             }
307             else
308             {
309                 i = sal::static_int_cast< sal_Int32 >(n);
310             }
311             *p->pLong = i; break;
312         }
313         case SbxBYREF | SbxULONG:
314         {
315             sal_uInt32 i;
316             if( n > SbxMAXULNG )
317             {
318                 SbxBase::SetError( SbxERR_OVERFLOW ); i = SbxMAXULNG;
319             }
320             else if( n < 0 )
321             {
322                 SbxBase::SetError( SbxERR_OVERFLOW ); i = 0;
323             }
324             else
325             {
326                 i = sal::static_int_cast< sal_uInt32 >(n);
327             }
328             *p->pULong = i; break;
329         }
330         case SbxBYREF | SbxSINGLE:
331             *p->pSingle = n; break;
332         case SbxBYREF | SbxDATE:
333         case SbxBYREF | SbxDOUBLE:
334             *p->pDouble = (double) n; break;
335         case SbxBYREF | SbxSALINT64:
336             *p->pnInt64 = ImpDoubleToSalInt64( (double) n ); break;
337         case SbxBYREF | SbxSALUINT64:
338             *p->puInt64 = ImpDoubleToSalUInt64( (double) n ); break;
339         case SbxBYREF | SbxCURRENCY:
340             double d;
341             if( n > SbxMAXCURR )
342             {
343                 SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMAXCURR;
344             }
345             else if( n < SbxMINCURR )
346             {
347                 SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMINCURR;
348             }
349             else
350             {
351                 d = n;
352             }
353             *p->pLong64 = ImpDoubleToCurrency( n ); break;
354 
355         default:
356             SbxBase::SetError( SbxERR_CONVERSION );
357     }
358 }
359 
360