xref: /aoo42x/main/basic/source/sbx/sbxdec.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 
32 #include <basic/sbx.hxx>
33 #include "sbxconv.hxx"
34 
35 #include <com/sun/star/bridge/oleautomation/Decimal.hpp>
36 
37 
38 // int GnDecCounter = 0;
39 
40 // Implementation SbxDecimal
41 SbxDecimal::SbxDecimal( void )
42 {
43 	setInt( 0 );
44 	mnRefCount = 0;
45 	// GnDecCounter++;
46 }
47 
48 SbxDecimal::SbxDecimal( const SbxDecimal& rDec )
49 {
50 #ifdef WIN32
51 	maDec = rDec.maDec;
52 #else
53     (void)rDec;
54 #endif
55 	mnRefCount = 0;
56 	// GnDecCounter++;
57 }
58 
59 SbxDecimal::SbxDecimal
60 	( const com::sun::star::bridge::oleautomation::Decimal& rAutomationDec )
61 {
62 #ifdef WIN32
63 	maDec.scale = rAutomationDec.Scale;
64 	maDec.sign  = rAutomationDec.Sign;
65 	maDec.Lo32 = rAutomationDec.LowValue;
66 	maDec.Mid32 = rAutomationDec.MiddleValue;
67 	maDec.Hi32 = rAutomationDec.HighValue;
68 #else
69     (void)rAutomationDec;
70 #endif
71 	mnRefCount = 0;
72 	// GnDecCounter++;
73 }
74 
75 void SbxDecimal::fillAutomationDecimal
76 	( com::sun::star::bridge::oleautomation::Decimal& rAutomationDec )
77 {
78 #ifdef WIN32
79 	rAutomationDec.Scale = maDec.scale;
80 	rAutomationDec.Sign = maDec.sign;
81 	rAutomationDec.LowValue = maDec.Lo32;
82 	rAutomationDec.MiddleValue = maDec.Mid32;
83 	rAutomationDec.HighValue = maDec.Hi32;
84 #else
85     (void)rAutomationDec;
86 #endif
87 }
88 
89 SbxDecimal::~SbxDecimal()
90 {
91 	// GnDecCounter--;
92 }
93 
94 void releaseDecimalPtr( SbxDecimal*& rpDecimal )
95 {
96 	if( rpDecimal )
97 	{
98 		rpDecimal->mnRefCount--;
99 		if( rpDecimal->mnRefCount == 0 )
100 		{
101 			delete rpDecimal;
102 			rpDecimal = NULL;
103 		}
104 	}
105 }
106 
107 #ifdef WIN32
108 
109 bool SbxDecimal::operator -= ( const SbxDecimal &r )
110 {
111 	HRESULT hResult = VarDecSub( &maDec, (LPDECIMAL)&r.maDec, &maDec );
112 	bool bRet = ( hResult == S_OK );
113 	return bRet;
114 }
115 
116 bool SbxDecimal::operator += ( const SbxDecimal &r )
117 {
118 	HRESULT hResult = VarDecAdd( &maDec, (LPDECIMAL)&r.maDec, &maDec );
119 	bool bRet = ( hResult == S_OK );
120 	return bRet;
121 }
122 
123 bool SbxDecimal::operator /= ( const SbxDecimal &r )
124 {
125 	HRESULT hResult = VarDecDiv( &maDec, (LPDECIMAL)&r.maDec, &maDec );
126 	bool bRet = ( hResult == S_OK );
127 	return bRet;
128 }
129 
130 bool SbxDecimal::operator *= ( const SbxDecimal &r )
131 {
132 	HRESULT hResult = VarDecMul( &maDec, (LPDECIMAL)&r.maDec, &maDec );
133 	bool bRet = ( hResult == S_OK );
134 	return bRet;
135 }
136 
137 bool SbxDecimal::neg( void )
138 {
139 	HRESULT hResult = VarDecNeg( &maDec, &maDec );
140 	bool bRet = ( hResult == S_OK );
141 	return bRet;
142 }
143 
144 bool SbxDecimal::isZero( void )
145 {
146 	SbxDecimal aZeroDec;
147 	aZeroDec.setLong( 0 );
148 	bool bZero = ( EQ == compare( *this, aZeroDec ) );
149 	return bZero;
150 }
151 
152 SbxDecimal::CmpResult compare( const SbxDecimal &rLeft, const SbxDecimal &rRight )
153 {
154 	HRESULT hResult = VarDecCmp( (LPDECIMAL)&rLeft.maDec, (LPDECIMAL)&rRight.maDec );
155 	SbxDecimal::CmpResult eRes = (SbxDecimal::CmpResult)hResult;
156 	return eRes;
157 }
158 
159 void SbxDecimal::setChar( sal_Unicode val )
160 {
161 	VarDecFromUI2( (sal_uInt16)val, &maDec );
162 }
163 
164 void SbxDecimal::setByte( sal_uInt8 val )
165 {
166 	VarDecFromUI1( (sal_uInt8)val, &maDec );
167 }
168 
169 void SbxDecimal::setShort( sal_Int16 val )
170 {
171 	VarDecFromI2( (short)val, &maDec );
172 }
173 
174 void SbxDecimal::setLong( sal_Int32 val )
175 {
176 	VarDecFromI4( (long)val, &maDec );
177 }
178 
179 void SbxDecimal::setUShort( sal_uInt16 val )
180 {
181 	VarDecFromUI2( (sal_uInt16)val, &maDec );
182 }
183 
184 void SbxDecimal::setULong( sal_uInt32 val )
185 {
186 	VarDecFromUI4( (sal_uIntPtr)val, &maDec );
187 }
188 
189 bool SbxDecimal::setSingle( float val )
190 {
191 	bool bRet = ( VarDecFromR4( val, &maDec ) == S_OK );
192 	return bRet;
193 }
194 
195 bool SbxDecimal::setDouble( double val )
196 {
197 	bool bRet = ( VarDecFromR8( val, &maDec ) == S_OK );
198 	return bRet;
199 }
200 
201 void SbxDecimal::setInt( int val )
202 {
203 	setLong( (sal_Int32)val );
204 }
205 
206 void SbxDecimal::setUInt( unsigned int val )
207 {
208 	setULong( (sal_uInt32)val );
209 }
210 
211 // sbxscan.cxx
212 void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, sal_Unicode& rcThousandSep );
213 
214 bool SbxDecimal::setString( ::rtl::OUString* pOUString )
215 {
216 	static LCID nLANGID = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US );
217 
218 	// Convert delimiter
219 	sal_Unicode cDecimalSep;
220 	sal_Unicode cThousandSep;
221 	ImpGetIntntlSep( cDecimalSep, cThousandSep );
222 
223 	bool bRet = false;
224 	HRESULT hResult;
225 	if( cDecimalSep != '.' || cThousandSep != ',' )
226 	{
227 		int nLen = pOUString->getLength();
228 		sal_Unicode* pBuffer = new sal_Unicode[nLen +  1];
229 		pBuffer[nLen] = 0;
230 
231 		const sal_Unicode* pSrc = pOUString->getStr();
232 		int i;
233 		for( i = 0 ; i < nLen ; ++i )
234 			pBuffer[i] = pSrc[i];
235 
236 		sal_Unicode c;
237 		i = 0;
238 		while( (c = pBuffer[i]) != 0 )
239 		{
240 			if( c == cDecimalSep )
241 				pBuffer[i] = '.';
242 			else if( c == cThousandSep )
243 				pBuffer[i] = ',';
244 			i++;
245 		}
246 		hResult = VarDecFromStr( (OLECHAR*)pBuffer, nLANGID, 0, &maDec );
247 		delete pBuffer;
248 	}
249 	else
250 	{
251 		hResult = VarDecFromStr( (OLECHAR*)pOUString->getStr(), nLANGID, 0, &maDec );
252 	}
253 	bRet = ( hResult == S_OK );
254 	return bRet;
255 }
256 
257 
258 bool SbxDecimal::getChar( sal_Unicode& rVal )
259 {
260 	bool bRet = ( VarUI2FromDec( &maDec, &rVal ) == S_OK );
261 	return bRet;
262 }
263 
264 bool SbxDecimal::getByte( sal_uInt8& rVal )
265 {
266 	bool bRet = ( VarUI1FromDec( &maDec, &rVal ) == S_OK );
267 	return bRet;
268 }
269 
270 bool SbxDecimal::getShort( sal_Int16& rVal )
271 {
272 	bool bRet = ( VarI2FromDec( &maDec, &rVal ) == S_OK );
273 	return bRet;
274 }
275 
276 bool SbxDecimal::getLong( sal_Int32& rVal )
277 {
278 	bool bRet = ( VarI4FromDec( &maDec, &rVal ) == S_OK );
279 	return bRet;
280 }
281 
282 bool SbxDecimal::getUShort( sal_uInt16& rVal )
283 {
284 	bool bRet = ( VarUI2FromDec( &maDec, &rVal ) == S_OK );
285 	return bRet;
286 }
287 
288 bool SbxDecimal::getULong( sal_uInt32& rVal )
289 {
290 	bool bRet = ( VarUI4FromDec( &maDec, &rVal ) == S_OK );
291 	return bRet;
292 }
293 
294 bool SbxDecimal::getSingle( float& rVal )
295 {
296 	bool bRet = ( VarR4FromDec( &maDec, &rVal ) == S_OK );
297 	return bRet;
298 }
299 
300 bool SbxDecimal::getDouble( double& rVal )
301 {
302 	bool bRet = ( VarR8FromDec( &maDec, &rVal ) == S_OK );
303 	return bRet;
304 }
305 
306 bool SbxDecimal::getInt( int& rVal )
307 {
308 	sal_Int32 TmpVal;
309 	bool bRet = getLong( TmpVal );
310 	rVal = TmpVal;
311 	return bRet;
312 }
313 
314 bool SbxDecimal::getUInt( unsigned int& rVal )
315 {
316 	sal_uInt32 TmpVal;
317 	bool bRet = getULong( TmpVal );
318 	rVal = TmpVal;
319 	return bRet;
320 }
321 
322 #else
323 // !WIN32
324 
325 bool SbxDecimal::operator -= ( const SbxDecimal &r )
326 {
327     (void)r;
328 	return false;
329 }
330 
331 bool SbxDecimal::operator += ( const SbxDecimal &r )
332 {
333     (void)r;
334 	return false;
335 }
336 
337 bool SbxDecimal::operator /= ( const SbxDecimal &r )
338 {
339     (void)r;
340 	return false;
341 }
342 
343 bool SbxDecimal::operator *= ( const SbxDecimal &r )
344 {
345     (void)r;
346 	return false;
347 }
348 
349 bool SbxDecimal::neg( void )
350 {
351 	return false;
352 }
353 
354 bool SbxDecimal::isZero( void )
355 {
356 	return false;
357 }
358 
359 SbxDecimal::CmpResult compare( const SbxDecimal &rLeft, const SbxDecimal &rRight )
360 {
361     (void)rLeft;
362     (void)rRight;
363 	return (SbxDecimal::CmpResult)0;
364 }
365 
366 void SbxDecimal::setChar( sal_Unicode val )		{ (void)val; }
367 void SbxDecimal::setByte( sal_uInt8 val )			{ (void)val; }
368 void SbxDecimal::setShort( sal_Int16 val )			{ (void)val; }
369 void SbxDecimal::setLong( sal_Int32 val )			{ (void)val; }
370 void SbxDecimal::setUShort( sal_uInt16 val )		{ (void)val; }
371 void SbxDecimal::setULong( sal_uInt32 val )			{ (void)val; }
372 bool SbxDecimal::setSingle( float val )			{ (void)val; return false; }
373 bool SbxDecimal::setDouble( double val )		{ (void)val; return false; }
374 void SbxDecimal::setInt( int val )				{ (void)val; }
375 void SbxDecimal::setUInt( unsigned int val )	{ (void)val; }
376 bool SbxDecimal::setString( ::rtl::OUString* pOUString )	{ (void)pOUString;  return false; }
377 
378 bool SbxDecimal::getChar( sal_Unicode& rVal )	{ (void)rVal; return false; }
379 bool SbxDecimal::getByte( sal_uInt8& rVal )			{ (void)rVal; return false; }
380 bool SbxDecimal::getShort( sal_Int16& rVal )		{ (void)rVal; return false; }
381 bool SbxDecimal::getLong( sal_Int32& rVal )			{ (void)rVal; return false; }
382 bool SbxDecimal::getUShort( sal_uInt16& rVal )		{ (void)rVal; return false; }
383 bool SbxDecimal::getULong( sal_uInt32& rVal )		{ (void)rVal; return false; }
384 bool SbxDecimal::getSingle( float& rVal )		{ (void)rVal; return false; }
385 bool SbxDecimal::getDouble( double& rVal )		{ (void)rVal; return false; }
386 bool SbxDecimal::getInt( int& rVal )			{ (void)rVal; return false; }
387 bool SbxDecimal::getUInt( unsigned int& rVal )	{ (void)rVal; return false; }
388 
389 #endif
390 
391 bool SbxDecimal::getString( ::rtl::OUString& rString )
392 {
393 #ifdef WIN32
394 	static LCID nLANGID = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US );
395 
396 	bool bRet = false;
397 
398 	OLECHAR sz[100];
399 	BSTR aBStr = SysAllocString( sz );
400 	if( aBStr != NULL )
401 	{
402 		HRESULT hResult = VarBstrFromDec( &maDec, nLANGID, 0, &aBStr );
403 		bRet = ( hResult == S_OK );
404 		if( bRet )
405 		{
406 			// Convert delimiter
407 			sal_Unicode cDecimalSep;
408 			sal_Unicode cThousandSep;
409 			ImpGetIntntlSep( cDecimalSep, cThousandSep );
410 
411 			if( cDecimalSep != '.' || cThousandSep != ',' )
412 			{
413 				sal_Unicode c;
414 				int i = 0;
415 				while( (c = aBStr[i]) != 0 )
416 				{
417 					if( c == '.' )
418 						aBStr[i] = cDecimalSep;
419 					else if( c == ',' )
420 						aBStr[i] = cThousandSep;
421 					i++;
422 				}
423 			}
424 			rString = reinterpret_cast<const sal_Unicode*>(aBStr);
425 		}
426 
427 		SysFreeString( aBStr );
428 	}
429 	return bRet;
430 #else
431     (void)rString;
432 	return false;
433 #endif
434 }
435 
436 SbxDecimal* ImpCreateDecimal( SbxValues* p )
437 {
438 #ifdef WIN32
439 	if( !p )
440 		return NULL;
441 
442 	SbxDecimal*& rpDecimal = p->pDecimal;
443 	if( rpDecimal == NULL )
444 	{
445 		rpDecimal = new SbxDecimal();
446 		rpDecimal->addRef();
447 	}
448 	return rpDecimal;
449 #else
450     (void)p;
451 	return NULL;
452 #endif
453 }
454 
455 SbxDecimal* ImpGetDecimal( const SbxValues* p )
456 {
457 #ifdef WIN32
458 	SbxValues aTmp;
459 	SbxDecimal* pnDecRes;
460 
461 	SbxDataType eType = p->eType;
462 	if( eType == SbxDECIMAL && p->pDecimal )
463 	{
464 		pnDecRes = new SbxDecimal( *p->pDecimal );
465 		pnDecRes->addRef();
466 		return pnDecRes;
467 	}
468 	pnDecRes = new SbxDecimal();
469 	pnDecRes->addRef();
470 
471 start:
472 	switch( +eType )
473 	{
474 		case SbxNULL:
475 			SbxBase::SetError( SbxERR_CONVERSION );
476 		case SbxEMPTY:
477 			pnDecRes->setShort( 0 ); break;
478 		case SbxCHAR:
479 			pnDecRes->setChar( p->nChar ); break;
480 		case SbxBYTE:
481 			pnDecRes->setByte( p->nByte ); break;
482 		case SbxINTEGER:
483 		case SbxBOOL:
484 			pnDecRes->setInt( p->nInteger ); break;
485 		case SbxERROR:
486 		case SbxUSHORT:
487 			pnDecRes->setUShort( p->nUShort ); break;
488 		case SbxLONG:
489 			pnDecRes->setLong( p->nLong ); break;
490 		case SbxULONG:
491 			pnDecRes->setULong( p->nULong ); break;
492 		case SbxSINGLE:
493 			if( !pnDecRes->setSingle( p->nSingle ) )
494 				SbxBase::SetError( SbxERR_OVERFLOW );
495 			break;
496 		case SbxSALINT64:
497 			{
498 				double d = (double)p->nInt64;
499 				pnDecRes->setDouble( d );
500 				break;
501 			}
502 		case SbxSALUINT64:
503 			{
504 				double d = ImpSalUInt64ToDouble( p->uInt64 );
505 				pnDecRes->setDouble( d );
506 				break;
507 			}
508 		case SbxDATE:
509 		case SbxDOUBLE:
510 		case SbxLONG64:
511 		case SbxULONG64:
512 		case SbxCURRENCY:
513 			{
514 			double dVal;
515 			if( p->eType ==	SbxCURRENCY )
516 				dVal = ImpCurrencyToDouble( p->nLong64 );
517 			else if( p->eType == SbxLONG64 )
518 				dVal = ImpINT64ToDouble( p->nLong64 );
519 			else if( p->eType == SbxULONG64 )
520 				dVal = ImpUINT64ToDouble( p->nULong64 );
521 			else
522 				dVal = p->nDouble;
523 
524 			if( !pnDecRes->setDouble( dVal ) )
525 				SbxBase::SetError( SbxERR_OVERFLOW );
526 			break;
527 			}
528 		case SbxLPSTR:
529 		case SbxSTRING:
530 		case SbxBYREF | SbxSTRING:
531 			pnDecRes->setString( p->pOUString ); break;
532 		case SbxOBJECT:
533 		{
534 			SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
535 			if( pVal )
536 				pnDecRes->setDecimal( pVal->GetDecimal() );
537 			else
538 			{
539 				SbxBase::SetError( SbxERR_NO_OBJECT );
540 				pnDecRes->setShort( 0 );
541 			}
542 			break;
543 		}
544 
545 		case SbxBYREF | SbxCHAR:
546 			pnDecRes->setChar( *p->pChar ); break;
547 		case SbxBYREF | SbxBYTE:
548 			pnDecRes->setByte( *p->pByte ); break;
549 		case SbxBYREF | SbxINTEGER:
550 		case SbxBYREF | SbxBOOL:
551 			pnDecRes->setInt( *p->pInteger ); break;
552 		case SbxBYREF | SbxLONG:
553 			pnDecRes->setLong( *p->pLong ); break;
554 		case SbxBYREF | SbxULONG:
555 			pnDecRes->setULong( *p->pULong ); break;
556 		case SbxBYREF | SbxERROR:
557 		case SbxBYREF | SbxUSHORT:
558 			pnDecRes->setUShort( *p->pUShort ); break;
559 
560 		// ab hier muss getestet werden
561 		case SbxBYREF | SbxSINGLE:
562 			aTmp.nSingle = *p->pSingle; goto ref;
563 		case SbxBYREF | SbxDATE:
564 		case SbxBYREF | SbxDOUBLE:
565 			aTmp.nDouble = *p->pDouble; goto ref;
566 		case SbxBYREF | SbxULONG64:
567 			aTmp.nULong64 = *p->pULong64; goto ref;
568 		case SbxBYREF | SbxLONG64:
569 		case SbxBYREF | SbxCURRENCY:
570 			aTmp.nLong64 = *p->pLong64; goto ref;
571 		case SbxBYREF | SbxSALINT64:
572 			aTmp.nInt64 = *p->pnInt64; goto ref;
573 		case SbxBYREF | SbxSALUINT64:
574 			aTmp.uInt64 = *p->puInt64; goto ref;
575 		ref:
576 			aTmp.eType = SbxDataType( p->eType & 0x0FFF );
577 			p = &aTmp; goto start;
578 
579 		default:
580 			SbxBase::SetError( SbxERR_CONVERSION ); pnDecRes->setShort( 0 );
581 	}
582 	return pnDecRes;
583 #else
584     (void)p;
585     return NULL;
586 #endif
587 }
588 
589 
590 void ImpPutDecimal( SbxValues* p, SbxDecimal* pDec )
591 {
592 #ifdef WIN32
593 	if( !pDec )
594 		return;
595 
596 	SbxValues aTmp;
597 start:
598 	switch( +p->eType )
599 	{
600 		// hier muss getestet werden
601 		case SbxCHAR:
602 			aTmp.pChar = &p->nChar; goto direct;
603 		case SbxBYTE:
604 			aTmp.pByte = &p->nByte; goto direct;
605 		case SbxULONG:
606 			aTmp.pULong = &p->nULong; goto direct;
607 		case SbxERROR:
608 		case SbxUSHORT:
609 			aTmp.pUShort = &p->nUShort; goto direct;
610 		case SbxSALUINT64:
611 			aTmp.puInt64 = &p->uInt64; goto direct;
612 		case SbxINTEGER:
613 		case SbxBOOL:
614 			aTmp.pInteger = &p->nInteger; goto direct;
615 		case SbxLONG:
616 			aTmp.pLong = &p->nLong; goto direct;
617 		case SbxSALINT64:
618 			aTmp.pnInt64 = &p->nInt64; goto direct;
619 		case SbxCURRENCY:
620 			aTmp.pLong64 = &p->nLong64; goto direct;
621 		direct:
622 			aTmp.eType = SbxDataType( p->eType | SbxBYREF );
623 			p = &aTmp; goto start;
624 
625 		// ab hier nicht mehr
626 		case SbxDECIMAL:
627 		case SbxBYREF | SbxDECIMAL:
628 		{
629 			if( pDec != p->pDecimal )
630 			{
631 				releaseDecimalPtr( p->pDecimal );
632 				// if( p->pDecimal )
633 					// p->pDecimal->ReleaseRef();
634 				p->pDecimal = pDec;
635 				if( pDec )
636 					pDec->addRef();
637 			}
638 			break;
639 		}
640 		case SbxSINGLE:
641 		{
642 			float f;
643 			pDec->getSingle( f );
644 			p->nSingle = f;
645 			break;
646 		}
647 		case SbxDATE:
648 		case SbxDOUBLE:
649 		{
650 			double d;
651 			pDec->getDouble( d );
652 			p->nDouble = d;
653 			break;
654 		}
655 		case SbxULONG64:
656 		{
657 			double d;
658 			pDec->getDouble( d );
659 			p->nULong64 = ImpDoubleToUINT64( d );
660 			break;
661 		}
662 		case SbxLONG64:
663 		{
664 			double d;
665 			pDec->getDouble( d );
666 			p->nLong64 = ImpDoubleToINT64( d );
667 			break;
668 		}
669 
670 		case SbxLPSTR:
671 		case SbxSTRING:
672 		case SbxBYREF | SbxSTRING:
673 			if( !p->pOUString )
674 				p->pOUString = new ::rtl::OUString;
675 			// ImpCvtNum( (double) n, 0, *p->pString );
676 			pDec->getString( *p->pOUString );
677 			break;
678 		case SbxOBJECT:
679 		{
680 			SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
681 			if( pVal )
682 				pVal->PutDecimal( pDec );
683 			else
684 				SbxBase::SetError( SbxERR_NO_OBJECT );
685 			break;
686 		}
687 
688 		case SbxBYREF | SbxCHAR:
689 			if( !pDec->getChar( *p->pChar ) )
690 			{
691 				SbxBase::SetError( SbxERR_OVERFLOW );
692 				*p->pChar = 0;
693 			}
694 			break;
695 		case SbxBYREF | SbxBYTE:
696 			if( !pDec->getChar( *p->pChar ) )
697 			{
698 				SbxBase::SetError( SbxERR_OVERFLOW );
699 				*p->pByte = 0;
700 			}
701 			break;
702 		case SbxBYREF | SbxINTEGER:
703 		case SbxBYREF | SbxBOOL:
704 			if( !pDec->getShort( *p->pInteger ) )
705 			{
706 				SbxBase::SetError( SbxERR_OVERFLOW );
707 				*p->pInteger = 0;
708 			}
709 			break;
710 			// *p->pInteger = n; break;
711 		case SbxBYREF | SbxERROR:
712 		case SbxBYREF | SbxUSHORT:
713 			if( !pDec->getUShort( *p->pUShort ) )
714 			{
715 				SbxBase::SetError( SbxERR_OVERFLOW );
716 				*p->pUShort = 0;
717 			}
718 			break;
719 		case SbxBYREF | SbxLONG:
720 			if( !pDec->getLong( *p->pLong ) )
721 			{
722 				SbxBase::SetError( SbxERR_OVERFLOW );
723 				*p->pLong = 0;
724 			}
725 			break;
726 		case SbxBYREF | SbxULONG:
727 			if( !pDec->getULong( *p->pULong ) )
728 			{
729 				SbxBase::SetError( SbxERR_OVERFLOW );
730 				*p->pULong = 0;
731 			}
732 			break;
733 		case SbxBYREF | SbxSALINT64:
734 			{
735 			double d;
736 			if( !pDec->getDouble( d ) )
737 				SbxBase::SetError( SbxERR_OVERFLOW );
738 			else
739 				*p->pnInt64 = ImpDoubleToSalInt64( d );
740 			break;
741 			}
742 		case SbxBYREF | SbxSALUINT64:
743 			{
744 			double d;
745 			if( !pDec->getDouble( d ) )
746 				SbxBase::SetError( SbxERR_OVERFLOW );
747 			else
748 				*p->puInt64 = ImpDoubleToSalUInt64( d );
749 			break;
750 			}
751 		case SbxBYREF | SbxSINGLE:
752 			if( !pDec->getSingle( *p->pSingle ) )
753 			{
754 				SbxBase::SetError( SbxERR_OVERFLOW );
755 				*p->pSingle = 0;
756 			}
757 			break;
758 			// *p->pSingle = (float) n; break;
759 		case SbxBYREF | SbxDATE:
760 		case SbxBYREF | SbxDOUBLE:
761 			if( !pDec->getDouble( *p->pDouble ) )
762 			{
763 				SbxBase::SetError( SbxERR_OVERFLOW );
764 				*p->pDouble = 0;
765 			}
766 			break;
767 		case SbxBYREF | SbxULONG64:
768 		{
769 			double d;
770 			pDec->getDouble( d );
771 			*p->pULong64 = ImpDoubleToUINT64( d );
772 			break;
773 		}
774 		case SbxBYREF | SbxLONG64:
775 		{
776 			double d;
777 			pDec->getDouble( d );
778 			*p->pLong64 = ImpDoubleToINT64( d );
779 			break;
780 		}
781 		case SbxBYREF | SbxCURRENCY:
782 		{
783 			double d;
784 			pDec->getDouble( d );
785 			*p->pLong64 = ImpDoubleToCurrency( d );
786 			break;
787 		}
788 
789 		default:
790 			SbxBase::SetError( SbxERR_CONVERSION );
791 	}
792 #else
793     (void)p;
794     (void)pDec;
795 #endif
796 }
797 
798