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