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