xref: /aoo41x/main/basic/source/sbx/sbxint.cxx (revision cdf0e10c)
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