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