xref: /trunk/main/basic/source/sbx/sbxint.cxx (revision e1f63238)
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 
30 double ImpRound( double d )
31 {
32 	return d + ( d < 0 ? -0.5 : 0.5 );
33 }
34 
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 
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 
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 
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 
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 
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 
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 
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 
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