xref: /AOO41X/main/basic/source/sbx/sbxint.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 
ImpRound(double d)30 double ImpRound( double d )
31 {
32     return d + ( d < 0 ? -0.5 : 0.5 );
33 }
34 
ImpGetInteger(const SbxValues * p)35 sal_Int16 ImpGetInteger( const SbxValues* p )
36 {
37     SbxValues aTmp;
38     sal_Int16 nRes;
39 start:
40     switch( +p->eType )
41     {
42         case SbxNULL:
43             SbxBase::SetError( SbxERR_CONVERSION );
44         case SbxEMPTY:
45             nRes = 0; break;
46         case SbxCHAR:
47             nRes = p->nChar; break;
48         case SbxBYTE:
49             nRes = p->nByte; break;
50         case SbxINTEGER:
51         case SbxBOOL:
52             nRes = p->nInteger; break;
53         case SbxERROR:
54         case SbxUSHORT:
55             if( p->nUShort > (sal_uInt16) SbxMAXINT )
56             {
57                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
58             }
59             else
60                 nRes = (sal_Int16) p->nUShort;
61             break;
62         case SbxLONG:
63             if( p->nLong > SbxMAXINT )
64             {
65                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
66             }
67             else if( p->nLong < SbxMININT )
68             {
69                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
70             }
71             else
72                 nRes = (sal_Int16) p->nLong;
73             break;
74         case SbxULONG:
75             if( p->nULong > SbxMAXINT )
76             {
77                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
78             }
79             else
80                 nRes = (sal_Int16) p->nULong;
81             break;
82         case SbxSINGLE:
83             if( p->nSingle > SbxMAXINT )
84             {
85                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
86             }
87             else if( p->nSingle < SbxMININT )
88             {
89                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
90             }
91             else
92                 nRes = (sal_Int16) ImpRound( p->nSingle );
93             break;
94         case SbxSALINT64:
95             if( p->nInt64 > SbxMAXINT )
96             {
97                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
98             }
99             else if( p->nInt64 < SbxMININT )
100             {
101                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
102             }
103             else
104                 nRes = (sal_Int16) p->nInt64;
105             break;
106         case SbxSALUINT64:
107             if( p->uInt64 > SbxMAXINT )
108             {
109                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
110             }
111             else
112                 nRes = (sal_Int16) p->uInt64;
113             break;
114         case SbxDATE:
115         case SbxDOUBLE:
116         case SbxLONG64:
117         case SbxULONG64:
118         case SbxCURRENCY:
119         case SbxDECIMAL:
120         case SbxBYREF | SbxDECIMAL:
121             {
122             double dVal;
123             if( p->eType == SbxCURRENCY )
124                 dVal = ImpCurrencyToDouble( p->nLong64 );
125             else if( p->eType == SbxLONG64 )
126                 dVal = ImpINT64ToDouble( p->nLong64 );
127             else if( p->eType == SbxULONG64 )
128                 dVal = ImpUINT64ToDouble( p->nULong64 );
129             else if( p->eType == SbxDECIMAL )
130             {
131                 dVal = 0.0;
132                 if( p->pDecimal )
133                     p->pDecimal->getDouble( dVal );
134             }
135             else
136                 dVal = p->nDouble;
137 
138             if( dVal > SbxMAXINT )
139             {
140                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
141             }
142             else if( dVal < SbxMININT )
143             {
144                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
145             }
146             else
147                 nRes = (sal_Int16) ImpRound( dVal );
148             break;
149             }
150         case SbxLPSTR:
151         case SbxSTRING:
152         case SbxBYREF | SbxSTRING:
153             if( !p->pOUString )
154                 nRes = 0;
155             else
156             {
157                 double d;
158                 SbxDataType t;
159                 if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
160                     nRes = 0;
161                 else if( d > SbxMAXINT )
162                 {
163                     SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
164                 }
165                 else if( d < SbxMININT )
166                 {
167                     SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
168                 }
169                 else
170                     nRes = (sal_Int16) ImpRound( d );
171             }
172             break;
173         case SbxOBJECT:
174         {
175             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
176             if( pVal )
177                 nRes = pVal->GetInteger();
178             else
179             {
180                 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
181             }
182             break;
183         }
184 
185         case SbxBYREF | SbxCHAR:
186             nRes = *p->pChar; break;
187         case SbxBYREF | SbxBYTE:
188             nRes = *p->pByte; break;
189         case SbxBYREF | SbxINTEGER:
190         case SbxBYREF | SbxBOOL:
191             nRes = *p->pInteger; break;
192 
193         // ab hier muss getestet werden
194         case SbxBYREF | SbxLONG:
195             aTmp.nLong = *p->pLong; goto ref;
196         case SbxBYREF | SbxULONG:
197             aTmp.nULong = *p->pULong; goto ref;
198         case SbxBYREF | SbxERROR:
199         case SbxBYREF | SbxUSHORT:
200             aTmp.nUShort = *p->pUShort; goto ref;
201         case SbxBYREF | SbxSINGLE:
202             aTmp.nSingle = *p->pSingle; goto ref;
203         case SbxBYREF | SbxDATE:
204         case SbxBYREF | SbxDOUBLE:
205             aTmp.nDouble = *p->pDouble; goto ref;
206         case SbxBYREF | SbxULONG64:
207             aTmp.nULong64 = *p->pULong64; goto ref;
208         case SbxBYREF | SbxLONG64:
209         case SbxBYREF | SbxCURRENCY:
210             aTmp.nLong64 = *p->pLong64; goto ref;
211         case SbxBYREF | SbxSALINT64:
212             aTmp.nInt64 = *p->pnInt64; goto ref;
213         case SbxBYREF | SbxSALUINT64:
214             aTmp.uInt64 = *p->puInt64; goto ref;
215         ref:
216             aTmp.eType = SbxDataType( p->eType & 0x0FFF );
217             p = &aTmp; goto start;
218 
219         default:
220             SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
221     }
222     return nRes;
223 }
224 
ImpPutInteger(SbxValues * p,sal_Int16 n)225 void ImpPutInteger( SbxValues* p, sal_Int16 n )
226 {
227     SbxValues aTmp;
228 start:
229     switch( +p->eType )
230     {
231         // hier muss getestet werden
232         case SbxCHAR:
233             aTmp.pChar = &p->nChar; goto direct;
234         case SbxBYTE:
235             aTmp.pByte = &p->nByte; goto direct;
236         case SbxULONG:
237             aTmp.pULong = &p->nULong; goto direct;
238         case SbxERROR:
239         case SbxUSHORT:
240             aTmp.pUShort = &p->nUShort; goto direct;
241         case SbxSALUINT64:
242             aTmp.puInt64 = &p->uInt64; goto direct;
243         direct:
244             aTmp.eType = SbxDataType( p->eType | SbxBYREF );
245             p = &aTmp; goto start;
246 
247         // ab hier nicht mehr
248         case SbxINTEGER:
249         case SbxBOOL:
250             p->nInteger = n; break;
251         case SbxLONG:
252             p->nLong = n; break;
253         case SbxSINGLE:
254             p->nSingle = n; break;
255         case SbxDATE:
256         case SbxDOUBLE:
257             p->nDouble = n; break;
258         case SbxSALINT64:
259             p->nInt64 = n; break;
260         case SbxULONG64:
261             p->nULong64 = ImpDoubleToUINT64( (double)n ); break;
262         case SbxLONG64:
263             p->nLong64 = ImpDoubleToINT64( (double)n ); break;
264         case SbxCURRENCY:
265             p->nLong64 = ImpDoubleToCurrency( (double)n ); break;
266         case SbxDECIMAL:
267         case SbxBYREF | SbxDECIMAL:
268             ImpCreateDecimal( p )->setInt( n );
269             break;
270 
271         case SbxLPSTR:
272         case SbxSTRING:
273         case SbxBYREF | SbxSTRING:
274             if( !p->pOUString )
275                 p->pOUString = new ::rtl::OUString;
276             ImpCvtNum( (double) n, 0, *p->pOUString );
277             break;
278         case SbxOBJECT:
279         {
280             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
281             if( pVal )
282                 pVal->PutInteger( n );
283             else
284                 SbxBase::SetError( SbxERR_NO_OBJECT );
285             break;
286         }
287         case SbxBYREF | SbxCHAR:
288             if( n < SbxMINCHAR )
289             {
290                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
291             }
292             *p->pChar = (char) n; break;
293         case SbxBYREF | SbxBYTE:
294             if( n > SbxMAXBYTE )
295             {
296                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
297             }
298             else if( n < 0 )
299             {
300                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
301             }
302             *p->pByte = (sal_uInt8) n; break;
303         case SbxBYREF | SbxINTEGER:
304         case SbxBYREF | SbxBOOL:
305             *p->pInteger = n; break;
306         case SbxBYREF | SbxERROR:
307         case SbxBYREF | SbxUSHORT:
308             if( n < 0 )
309             {
310                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
311             }
312             *p->pUShort = (sal_uInt16) n; break;
313         case SbxBYREF | SbxLONG:
314             *p->pLong = (sal_Int32) n; break;
315         case SbxBYREF | SbxULONG:
316             if( n < 0 )
317             {
318                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
319             }
320             *p->pULong = (sal_uInt32) n; break;
321         case SbxBYREF | SbxSALINT64:
322             *p->pnInt64 = n; break;
323         case SbxBYREF | SbxSALUINT64:
324             if( n < 0 )
325             {
326                 SbxBase::SetError( SbxERR_OVERFLOW ); *p->puInt64 = 0;
327             }
328             else
329                 *p->puInt64 = n;
330             break;
331         case SbxBYREF | SbxSINGLE:
332             *p->pSingle = (float) n; break;
333         case SbxBYREF | SbxDATE:
334         case SbxBYREF | SbxDOUBLE:
335             *p->pDouble = (double) n; break;
336         case SbxBYREF | SbxULONG64:
337             *p->pULong64 = ImpDoubleToUINT64( (double)n ); break;
338         case SbxBYREF | SbxLONG64:
339             *p->pLong64 = ImpDoubleToINT64( (double)n ); break;
340         case SbxBYREF | SbxCURRENCY:
341             *p->pLong64 = ImpDoubleToCurrency( (double)n ); break;
342 
343         default:
344             SbxBase::SetError( SbxERR_CONVERSION );
345     }
346 }
347 
348 
349 // sal_Int64 / hyper
350 
ImpDoubleToSalInt64(double d)351 sal_Int64 ImpDoubleToSalInt64( double d )
352 {
353     sal_Int64 nRes;
354     if( d > SbxMAXSALINT64 )
355     {
356         SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALINT64;
357     }
358     else if( d < SbxMINSALINT64 )
359     {
360         SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINSALINT64;
361     }
362     else
363         nRes = (sal_Int64) ImpRound( d );
364     return nRes;
365 }
366 
ImpDoubleToSalUInt64(double d)367 sal_uInt64 ImpDoubleToSalUInt64( double d )
368 {
369     sal_uInt64 nRes;
370     if( d > SbxMAXSALUINT64 )
371     {
372         SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALUINT64;
373     }
374     else if( d < 0.0 )
375     {
376         SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
377     }
378     else
379         nRes = (sal_uInt64) ImpRound( d );
380     return nRes;
381 }
382 
ImpSalUInt64ToDouble(sal_uInt64 n)383 double ImpSalUInt64ToDouble( sal_uInt64 n )
384 {
385     double d = 0.0;
386     if( n > SbxMAXSALINT64 )
387         SbxBase::SetError( SbxERR_CONVERSION );
388     else
389         d = (double)(sal_Int64) n;
390     return d;
391 }
392 
393 
ImpGetInt64(const SbxValues * p)394 sal_Int64 ImpGetInt64( const SbxValues* p )
395 {
396     SbxValues aTmp;
397     sal_Int64 nRes;
398 start:
399     switch( +p->eType )
400     {
401         case SbxNULL:
402             SbxBase::SetError( SbxERR_CONVERSION );
403         case SbxEMPTY:
404             nRes = 0; break;
405         case SbxCHAR:
406             nRes = p->nChar; break;
407         case SbxBYTE:
408             nRes = p->nByte; break;
409         case SbxINTEGER:
410         case SbxBOOL:
411             nRes = p->nInteger; break;
412         case SbxERROR:
413         case SbxUSHORT:
414             nRes = p->nUShort; break;
415         case SbxLONG:
416             nRes = p->nLong; break;
417         case SbxULONG:
418             nRes = (sal_Int64) p->nULong; break;
419         case SbxSINGLE:
420             nRes = ImpDoubleToSalInt64( (double)p->nSingle );
421             break;
422         case SbxDATE:
423         case SbxDOUBLE:
424         case SbxLONG64:
425         case SbxULONG64:
426         case SbxCURRENCY:
427             {
428             double dVal;
429             if( p->eType == SbxCURRENCY )
430                 dVal = ImpCurrencyToDouble( p->nLong64 );
431             else if( p->eType == SbxLONG64 )
432                 dVal = ImpINT64ToDouble( p->nLong64 );
433             else if( p->eType == SbxULONG64 )
434                 dVal = ImpUINT64ToDouble( p->nULong64 );
435             else
436                 dVal = p->nDouble;
437 
438             nRes = ImpDoubleToSalInt64( dVal );
439             break;
440             }
441         case SbxSALINT64:
442             nRes = p->nInt64; break;
443         case SbxSALUINT64:
444             if( p->uInt64 > SbxMAXSALINT64 )
445             {
446                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALINT64;
447             }
448             else
449                 nRes = (sal_Int64) p->uInt64;
450             break;
451 
452         case SbxBYREF | SbxSTRING:
453         case SbxSTRING:
454         case SbxLPSTR:
455             if( !p->pOUString )
456                 nRes = 0;
457             else
458             {
459                 ::rtl::OString aOStr = ::rtl::OUStringToOString
460                     ( *p->pOUString, RTL_TEXTENCODING_ASCII_US );
461                 nRes = aOStr.toInt64();
462                 if( nRes == 0 )
463                 {
464                     // Check if really 0 or invalid conversion
465                     double d;
466                     SbxDataType t;
467                     if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
468                         nRes = 0;
469                     else
470                         nRes = ImpDoubleToSalInt64( d );
471                 }
472             }
473             break;
474         case SbxOBJECT:
475         {
476             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
477             if( pVal )
478                 nRes = pVal->GetInt64();
479             else
480             {
481                 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
482             }
483             break;
484         }
485 
486         case SbxBYREF | SbxCHAR:
487             nRes = *p->pChar; break;
488         case SbxBYREF | SbxBYTE:
489             nRes = *p->pByte; break;
490         case SbxBYREF | SbxINTEGER:
491         case SbxBYREF | SbxBOOL:
492             nRes = *p->pInteger; break;
493         case SbxBYREF | SbxLONG:
494             nRes = *p->pLong; break;
495         case SbxBYREF | SbxULONG:
496             nRes = *p->pULong; break;
497         case SbxBYREF | SbxSALINT64:
498             nRes = *p->pnInt64; break;
499 
500         // from here the values has to be checked
501         case SbxBYREF | SbxERROR:
502         case SbxBYREF | SbxUSHORT:
503             aTmp.nUShort = *p->pUShort; goto ref;
504         case SbxBYREF | SbxSINGLE:
505             aTmp.nSingle = *p->pSingle; goto ref;
506         case SbxBYREF | SbxDATE:
507         case SbxBYREF | SbxDOUBLE:
508             aTmp.nDouble = *p->pDouble; goto ref;
509         case SbxBYREF | SbxULONG64:
510             aTmp.nULong64 = *p->pULong64; goto ref;
511         case SbxBYREF | SbxLONG64:
512         case SbxBYREF | SbxCURRENCY:
513             aTmp.nLong64 = *p->pLong64; goto ref;
514         case SbxBYREF | SbxSALUINT64:
515             aTmp.uInt64 = *p->puInt64; goto ref;
516         ref:
517             aTmp.eType = SbxDataType( p->eType & 0x0FFF );
518             p = &aTmp; goto start;
519 
520         default:
521             SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
522     }
523     return nRes;
524 }
525 
ImpPutInt64(SbxValues * p,sal_Int64 n)526 void ImpPutInt64( SbxValues* p, sal_Int64 n )
527 {
528     SbxValues aTmp;
529 
530 start:
531     switch( +p->eType )
532     {
533         // Check neccessary
534         case SbxCHAR:
535             aTmp.pChar = &p->nChar; goto direct;
536         case SbxBYTE:
537             aTmp.pByte = &p->nByte; goto direct;
538         case SbxINTEGER:
539         case SbxBOOL:
540             aTmp.pInteger = &p->nInteger; goto direct;
541         case SbxULONG64:
542             aTmp.pULong64 = &p->nULong64; goto direct;
543         case SbxLONG64:
544         case SbxCURRENCY:
545             aTmp.pLong64 = &p->nLong64; goto direct;
546         case SbxULONG:
547             aTmp.pULong = &p->nULong; goto direct;
548         case SbxERROR:
549         case SbxUSHORT:
550             aTmp.pUShort = &p->nUShort; goto direct;
551         case SbxLONG:
552             aTmp.pnInt64 = &p->nInt64; goto direct;
553         case SbxSALUINT64:
554             aTmp.puInt64 = &p->uInt64; goto direct;
555 
556         direct:
557             aTmp.eType = SbxDataType( p->eType | SbxBYREF );
558             p = &aTmp; goto start;
559 
560         // Check not neccessary
561         case SbxSALINT64:
562             p->nInt64 = n; break;
563         case SbxSINGLE:
564             p->nSingle = (float) n; break;
565         case SbxDATE:
566         case SbxDOUBLE:
567             p->nDouble = (double) n; break;
568 
569         case SbxBYREF | SbxSTRING:
570         case SbxSTRING:
571         case SbxLPSTR:
572         {
573             if( !p->pOUString )
574                 p->pOUString = new ::rtl::OUString;
575 
576             ::rtl::OString  aOStr  = ::rtl::OString::valueOf( n );
577             (*p->pOUString) = ::rtl::OStringToOUString
578                 ( aOStr, RTL_TEXTENCODING_ASCII_US );
579             break;
580         }
581         case SbxOBJECT:
582         {
583             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
584             if( pVal )
585                 pVal->PutInt64( n );
586             else
587                 SbxBase::SetError( SbxERR_NO_OBJECT );
588             break;
589         }
590         case SbxBYREF | SbxCHAR:
591             if( n > SbxMAXCHAR )
592             {
593                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
594             }
595             else if( n < SbxMINCHAR )
596             {
597                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
598             }
599             *p->pChar = (xub_Unicode) n; break;
600         case SbxBYREF | SbxBYTE:
601             if( n > SbxMAXBYTE )
602             {
603                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
604             }
605             else if( n < 0 )
606             {
607                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
608             }
609             *p->pByte = (sal_uInt8) n; break;
610         case SbxBYREF | SbxINTEGER:
611         case SbxBYREF | SbxBOOL:
612             if( n > SbxMAXINT )
613             {
614                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
615             }
616             else if( n < SbxMININT )
617             {
618                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
619             }
620             *p->pInteger = (sal_Int16) n; break;
621         case SbxBYREF | SbxERROR:
622         case SbxBYREF | SbxUSHORT:
623             if( n > SbxMAXUINT )
624             {
625                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
626             }
627             else if( n < 0 )
628             {
629                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
630             }
631             *p->pUShort = (sal_uInt16) n; break;
632         case SbxBYREF | SbxLONG:
633             if( n > SbxMAXLNG )
634             {
635                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
636             }
637             else if( n < SbxMINLNG )
638             {
639                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
640             }
641             *p->pLong = (sal_Int32) n; break;
642         case SbxBYREF | SbxULONG:
643             if( n > SbxMAXULNG )
644             {
645                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
646             }
647             else if( n < 0 )
648             {
649                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
650             }
651             *p->pULong = (sal_uInt32) n; break;
652         case SbxBYREF | SbxSINGLE:
653             *p->pSingle = (float) n; break;
654         case SbxBYREF | SbxDATE:
655         case SbxBYREF | SbxDOUBLE:
656             *p->pDouble = (double) n; break;
657         case SbxBYREF | SbxCURRENCY:
658             if( n > SbxMAXCURR )
659             {
660                 SbxBase::SetError( SbxERR_OVERFLOW ); n = (sal_Int64) SbxMAXCURR;
661             }
662             else if( n < SbxMINCURR )
663             {
664                 SbxBase::SetError( SbxERR_OVERFLOW ); n = (sal_Int64) SbxMINCURR;
665             }
666             *p->pLong64 = ImpDoubleToCurrency( (double)n ); break;
667 
668         case SbxBYREF | SbxSALINT64:
669             *p->pnInt64 = n; break;
670         case SbxBYREF | SbxSALUINT64:
671             if( n < 0 )
672             {
673                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
674             }
675             *p->puInt64 = (sal_Int64) n; break;
676 
677         default:
678             SbxBase::SetError( SbxERR_CONVERSION );
679     }
680 }
681 
ImpGetUInt64(const SbxValues * p)682 sal_uInt64 ImpGetUInt64( const SbxValues* p )
683 {
684     SbxValues aTmp;
685     sal_uInt64 nRes;
686 start:
687     switch( +p->eType )
688     {
689         case SbxNULL:
690             SbxBase::SetError( SbxERR_CONVERSION );
691         case SbxEMPTY:
692             nRes = 0; break;
693         case SbxCHAR:
694             nRes = p->nChar; break;
695         case SbxBYTE:
696             nRes = p->nByte; break;
697         case SbxINTEGER:
698         case SbxBOOL:
699             nRes = p->nInteger; break;
700         case SbxERROR:
701         case SbxUSHORT:
702             nRes = p->nUShort; break;
703         case SbxLONG:
704             nRes = p->nLong; break;
705         case SbxULONG:
706             nRes = (sal_uInt64) p->nULong; break;
707         case SbxSINGLE:
708             nRes = ImpDoubleToSalUInt64( (double)p->nSingle );
709             break;
710         case SbxDATE:
711         case SbxDOUBLE:
712         case SbxLONG64:
713         case SbxULONG64:
714         case SbxCURRENCY:
715             {
716             double dVal;
717             if( p->eType == SbxCURRENCY )
718                 dVal = ImpCurrencyToDouble( p->nLong64 );
719             else if( p->eType == SbxLONG64 )
720                 dVal = ImpINT64ToDouble( p->nLong64 );
721             else if( p->eType == SbxULONG64 )
722                 dVal = ImpUINT64ToDouble( p->nULong64 );
723             else
724                 dVal = p->nDouble;
725 
726             nRes = ImpDoubleToSalUInt64( dVal );
727             break;
728             }
729         case SbxSALINT64:
730             if( p->nInt64 < 0 )
731             {
732                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
733             }
734             else
735                 nRes = (sal_uInt64) p->nInt64;
736         case SbxSALUINT64:
737             nRes = p->uInt64; break;
738 
739         case SbxBYREF | SbxSTRING:
740         case SbxSTRING:
741         case SbxLPSTR:
742             if( !p->pOUString )
743                 nRes = 0;
744             else
745             {
746                 ::rtl::OString aOStr = ::rtl::OUStringToOString
747                     ( *p->pOUString, RTL_TEXTENCODING_ASCII_US );
748                 sal_Int64 n64 = aOStr.toInt64();
749                 if( n64 == 0 )
750                 {
751                     // Check if really 0 or invalid conversion
752                     double d;
753                     SbxDataType t;
754                     if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
755                         nRes = 0;
756                     else if( d > SbxMAXSALUINT64 )
757                     {
758                         SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALUINT64;
759                     }
760                     else if( d < 0.0 )
761                     {
762                         SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
763                     }
764                     else
765                         nRes = (sal_uInt64) ImpRound( d );
766                 }
767                 else if( n64 < 0 )
768                 {
769                     SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
770                 }
771                 else
772                 {
773                     nRes = n64;
774                 }
775             }
776             break;
777         case SbxOBJECT:
778         {
779             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
780             if( pVal )
781                 nRes = pVal->GetUInt64();
782             else
783             {
784                 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
785             }
786             break;
787         }
788 
789         case SbxBYREF | SbxCHAR:
790             nRes = *p->pChar; break;
791         case SbxBYREF | SbxBYTE:
792             nRes = *p->pByte; break;
793         case SbxBYREF | SbxINTEGER:
794         case SbxBYREF | SbxBOOL:
795             nRes = *p->pInteger; break;
796         case SbxBYREF | SbxLONG:
797             nRes = *p->pLong; break;
798         case SbxBYREF | SbxULONG:
799             nRes = *p->pULong; break;
800         case SbxBYREF | SbxSALUINT64:
801             nRes = *p->puInt64; break;
802 
803         // from here the values has to be checked
804         case SbxBYREF | SbxERROR:
805         case SbxBYREF | SbxUSHORT:
806             aTmp.nUShort = *p->pUShort; goto ref;
807         case SbxBYREF | SbxSINGLE:
808             aTmp.nSingle = *p->pSingle; goto ref;
809         case SbxBYREF | SbxDATE:
810         case SbxBYREF | SbxDOUBLE:
811             aTmp.nDouble = *p->pDouble; goto ref;
812         case SbxBYREF | SbxULONG64:
813             aTmp.nULong64 = *p->pULong64; goto ref;
814         case SbxBYREF | SbxLONG64:
815         case SbxBYREF | SbxCURRENCY:
816             aTmp.nLong64 = *p->pLong64; goto ref;
817         case SbxBYREF | SbxSALINT64:
818             aTmp.nInt64 = *p->pnInt64; goto ref;
819         ref:
820             aTmp.eType = SbxDataType( p->eType & 0x0FFF );
821             p = &aTmp; goto start;
822 
823         default:
824             SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
825     }
826     return nRes;
827 }
828 
ImpPutUInt64(SbxValues * p,sal_uInt64 n)829 void ImpPutUInt64( SbxValues* p, sal_uInt64 n )
830 {
831     SbxValues aTmp;
832 
833 start:
834     switch( +p->eType )
835     {
836         // Check neccessary
837         case SbxCHAR:
838             aTmp.pChar = &p->nChar; goto direct;
839         case SbxBYTE:
840             aTmp.pByte = &p->nByte; goto direct;
841         case SbxINTEGER:
842         case SbxBOOL:
843             aTmp.pInteger = &p->nInteger; goto direct;
844         case SbxULONG64:
845             aTmp.pULong64 = &p->nULong64; goto direct;
846         case SbxLONG64:
847         case SbxCURRENCY:
848             aTmp.pLong64 = &p->nLong64; goto direct;
849         case SbxULONG:
850             aTmp.pULong = &p->nULong; goto direct;
851         case SbxERROR:
852         case SbxUSHORT:
853             aTmp.pUShort = &p->nUShort; goto direct;
854         case SbxLONG:
855             aTmp.pnInt64 = &p->nInt64; goto direct;
856         case SbxSALINT64:
857             aTmp.pnInt64 = &p->nInt64; goto direct;
858         case SbxSINGLE:
859             aTmp.pSingle = &p->nSingle; goto direct;
860         case SbxDATE:
861         case SbxDOUBLE:
862             aTmp.pDouble = &p->nDouble; goto direct;
863 
864         direct:
865             aTmp.eType = SbxDataType( p->eType | SbxBYREF );
866             p = &aTmp; goto start;
867 
868         // Check not neccessary
869         case SbxSALUINT64:
870             p->uInt64 = n; break;
871 
872         case SbxBYREF | SbxSTRING:
873         case SbxSTRING:
874         case SbxLPSTR:
875             if( !p->pOUString )
876                 p->pOUString = new ::rtl::OUString;
877             if( n > SbxMAXSALINT64 )
878                 SbxBase::SetError( SbxERR_CONVERSION );
879             else
880             {
881                 ::rtl::OString  aOStr  = ::rtl::OString::valueOf( (sal_Int64)n );
882                 (*p->pOUString) = ::rtl::OStringToOUString
883                     ( aOStr, RTL_TEXTENCODING_ASCII_US );
884             }
885             break;
886         case SbxOBJECT:
887         {
888             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
889             if( pVal )
890                 pVal->PutUInt64( n );
891             else
892                 SbxBase::SetError( SbxERR_NO_OBJECT );
893             break;
894         }
895         case SbxBYREF | SbxCHAR:
896             if( n > SbxMAXCHAR )
897             {
898                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
899             }
900             *p->pChar = (xub_Unicode) n; break;
901         case SbxBYREF | SbxBYTE:
902             if( n > SbxMAXBYTE )
903             {
904                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
905             }
906             *p->pByte = (sal_uInt8) n; break;
907         case SbxBYREF | SbxINTEGER:
908         case SbxBYREF | SbxBOOL:
909             if( n > SbxMAXINT )
910             {
911                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
912             }
913             *p->pInteger = (sal_Int16) n; break;
914         case SbxBYREF | SbxERROR:
915         case SbxBYREF | SbxUSHORT:
916             if( n > SbxMAXUINT )
917             {
918                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
919             }
920             *p->pUShort = (sal_uInt16) n; break;
921         case SbxBYREF | SbxLONG:
922             if( n > SbxMAXLNG )
923             {
924                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
925             }
926             *p->pLong = (sal_Int32) n; break;
927         case SbxBYREF | SbxULONG:
928             if( n > SbxMAXULNG )
929             {
930                 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
931             }
932             *p->pULong = (sal_uInt32) n; break;
933         case SbxBYREF | SbxSINGLE:
934             *p->pDouble = (float)ImpSalUInt64ToDouble( n ); break;
935         case SbxBYREF | SbxDATE:
936         case SbxBYREF | SbxDOUBLE:
937             *p->pDouble = ImpSalUInt64ToDouble( n ); break;
938         case SbxBYREF | SbxCURRENCY:
939             if( n > SbxMAXSALINT64 || (sal_Int64)n > SbxMAXCURR )
940             {
941                 SbxBase::SetError( SbxERR_OVERFLOW ); n = (sal_Int64) SbxMAXCURR;
942             }
943             *p->pLong64 = ImpDoubleToCurrency( (double)(sal_Int64) n ); break;
944 
945         case SbxBYREF | SbxSALUINT64:
946             *p->puInt64 = n; break;
947         case SbxBYREF | SbxSALINT64:
948             if( n > SbxMAXSALINT64 )
949             {
950                 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
951             }
952             *p->pnInt64 = (sal_Int64) n; break;
953 
954         default:
955             SbxBase::SetError( SbxERR_CONVERSION );
956     }
957 }
958 
959 
960