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