xref: /aoo41x/main/basic/source/sbx/sbxdbl.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 #include "runtime.hxx"
34 
35 double ImpGetDouble( const SbxValues* p )
36 {
37 	double nRes;
38 	switch( +p->eType )
39 	{
40 		case SbxNULL:
41 			SbxBase::SetError( SbxERR_CONVERSION );
42 		case SbxEMPTY:
43 			nRes = 0; break;
44 		case SbxCHAR:
45 			nRes = p->nChar; break;
46 		case SbxBYTE:
47 			nRes = p->nByte; break;
48 		case SbxINTEGER:
49 		case SbxBOOL:
50 			nRes = p->nInteger; break;
51 		case SbxERROR:
52 		case SbxUSHORT:
53 			nRes = p->nUShort; break;
54 		case SbxLONG:
55 			nRes = p->nLong; break;
56 		case SbxULONG:
57 			nRes = p->nULong; break;
58 		case SbxSINGLE:
59 			nRes = p->nSingle; break;
60 		case SbxDATE:
61 		case SbxDOUBLE:
62 			nRes = p->nDouble; break;
63 		case SbxCURRENCY:
64 			nRes = ImpCurrencyToDouble( p->nLong64 ); break;
65 		case SbxSALINT64:
66             nRes = static_cast< double >(p->nInt64); break;
67 		case SbxSALUINT64:
68             nRes = ImpSalUInt64ToDouble( p->uInt64 ); break;
69 		case SbxDECIMAL:
70 		case SbxBYREF | SbxDECIMAL:
71 			if( p->pDecimal )
72 				p->pDecimal->getDouble( nRes );
73 			else
74 				nRes = 0.0;
75 			break;
76 		case SbxBYREF | SbxSTRING:
77 		case SbxSTRING:
78 		case SbxLPSTR:
79 			if( !p->pOUString )
80 			{
81 				nRes = 0;
82 				if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour
83 					SbxBase::SetError( SbxERR_CONVERSION );
84 			}
85 			else
86 			{
87 				double d;
88 				SbxDataType t;
89 				if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
90 				{
91 					nRes = 0;
92 					if ( SbiRuntime::isVBAEnabled() )// VBA only behaviour
93 						SbxBase::SetError( SbxERR_CONVERSION );
94 				}
95 				else
96 					nRes = d;
97 			}
98 			break;
99 		case SbxOBJECT:
100 		{
101 			SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
102 			if( pVal )
103 				nRes = pVal->GetDouble();
104 			else
105 			{
106 				SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
107 			}
108 			break;
109 		}
110 
111 		case SbxBYREF | SbxCHAR:
112 			nRes = *p->pChar; break;
113 		case SbxBYREF | SbxBYTE:
114 			nRes = *p->pByte; break;
115 		case SbxBYREF | SbxINTEGER:
116 		case SbxBYREF | SbxBOOL:
117 			nRes = *p->pInteger; break;
118 		case SbxBYREF | SbxLONG:
119 			nRes = *p->pLong; break;
120 		case SbxBYREF | SbxULONG:
121 			nRes = *p->pULong; break;
122 		case SbxBYREF | SbxERROR:
123 		case SbxBYREF | SbxUSHORT:
124 			nRes = *p->pUShort; break;
125 		case SbxBYREF | SbxSINGLE:
126 			nRes = *p->pSingle; break;
127 		case SbxBYREF | SbxDATE:
128 		case SbxBYREF | SbxDOUBLE:
129 			nRes = *p->pDouble; break;
130 		case SbxBYREF | SbxCURRENCY:
131 			nRes = ImpCurrencyToDouble( *p->pLong64 ); break;
132 		case SbxBYREF | SbxSALINT64:
133             nRes = static_cast< double >(*p->pnInt64); break;
134 		case SbxBYREF | SbxSALUINT64:
135             nRes = ImpSalUInt64ToDouble( *p->puInt64 ); break;
136 
137 		default:
138 			SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
139 	}
140 	return nRes;
141 }
142 
143 void ImpPutDouble( SbxValues* p, double n, sal_Bool bCoreString )
144 {
145 	SbxValues aTmp;
146 start:
147 	switch( +p->eType )
148 	{
149 		// Hier sind Tests notwendig
150 		case SbxCHAR:
151 			aTmp.pChar = &p->nChar; goto direct;
152 		case SbxBYTE:
153 			aTmp.pByte = &p->nByte; goto direct;
154 		case SbxINTEGER:
155 		case SbxBOOL:
156 			aTmp.pInteger = &p->nInteger; goto direct;
157 		case SbxLONG:
158 		case SbxCURRENCY:
159 			aTmp.pLong = &p->nLong; goto direct;
160 		case SbxULONG:
161 			aTmp.pULong = &p->nULong; goto direct;
162 		case SbxERROR:
163 		case SbxUSHORT:
164 			aTmp.pUShort = &p->nUShort; goto direct;
165 		case SbxSINGLE:
166 			aTmp.pSingle = &p->nSingle; goto direct;
167 		case SbxDECIMAL:
168 		case SbxBYREF | SbxDECIMAL:
169 			{
170 			SbxDecimal* pDec = ImpCreateDecimal( p );
171 			if( !pDec->setDouble( n ) )
172 				SbxBase::SetError( SbxERR_OVERFLOW );
173 			break;
174 			}
175 		direct:
176 			aTmp.eType = SbxDataType( p->eType | SbxBYREF );
177 			p = &aTmp; goto start;
178 
179 			// ab hier nicht mehr
180 		case SbxSALINT64:
181             p->nInt64 = ImpDoubleToSalInt64( n ); break;
182 		case SbxSALUINT64:
183 			p->uInt64 = ImpDoubleToSalUInt64( n ); break;
184 		case SbxDATE:
185 		case SbxDOUBLE:
186 			p->nDouble = n; break;
187 
188 		case SbxBYREF | SbxSTRING:
189 		case SbxSTRING:
190 		case SbxLPSTR:
191 			if( !p->pOUString )
192 				p->pOUString = new ::rtl::OUString;
193 			ImpCvtNum( (double) n, 14, *p->pOUString, bCoreString );
194 			break;
195 		case SbxOBJECT:
196 		{
197 			SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
198 			if( pVal )
199 				pVal->PutDouble( n );
200 			else
201 				SbxBase::SetError( SbxERR_NO_OBJECT );
202 			break;
203 		}
204 		case SbxBYREF | SbxCHAR:
205 			if( n > SbxMAXCHAR )
206 			{
207 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
208 			}
209 			else if( n < SbxMINCHAR )
210 			{
211 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
212 			}
213 			*p->pChar = (xub_Unicode) n; break;
214 		case SbxBYREF | SbxBYTE:
215 			if( n > SbxMAXBYTE )
216 			{
217 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
218 			}
219 			else if( n < 0 )
220 			{
221 				SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
222 			}
223 			*p->pByte = (sal_uInt8) n; break;
224 		case SbxBYREF | SbxINTEGER:
225 		case SbxBYREF | SbxBOOL:
226 			if( n > SbxMAXINT )
227 			{
228 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
229 			}
230 			else if( n < SbxMININT )
231 			{
232 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
233 			}
234 			*p->pInteger = (sal_Int16) n; break;
235 		case SbxBYREF | SbxERROR:
236 		case SbxBYREF | SbxUSHORT:
237 			if( n > SbxMAXUINT )
238 			{
239 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
240 			}
241 			else if( n < 0 )
242 			{
243 				SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
244 			}
245 			*p->pUShort = (sal_uInt16) n; break;
246 		case SbxBYREF | SbxLONG:
247 			if( n > SbxMAXLNG )
248 			{
249 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
250 			}
251 			else if( n < SbxMINLNG )
252 			{
253 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
254 			}
255 			*p->pLong = (sal_Int32) n; break;
256 		case SbxBYREF | SbxULONG:
257 			if( n > SbxMAXULNG )
258 			{
259 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
260 			}
261 			else if( n < 0 )
262 			{
263 				SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
264 			}
265 			*p->pULong = (sal_uInt32) n; break;
266 		case SbxBYREF | SbxSINGLE:
267 			if( n > SbxMAXSNG )
268 			{
269 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG;
270 			}
271 			else if( n < SbxMINSNG )
272 			{
273 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG;
274 			}
275 			else if( n > 0 && n < SbxMAXSNG2 )
276 			{
277 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG2;
278 			}
279 			else if( n < 0 && n > SbxMINSNG2 )
280 			{
281 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG2;
282 			}
283 			*p->pSingle = (float) n; break;
284 		case SbxBYREF | SbxSALINT64:
285             *p->pnInt64 = ImpDoubleToSalInt64( n ); break;
286 		case SbxBYREF | SbxSALUINT64:
287 			*p->puInt64 = ImpDoubleToSalUInt64( n ); break;
288 		case SbxBYREF | SbxDATE:
289 		case SbxBYREF | SbxDOUBLE:
290 			*p->pDouble = (double) n; break;
291 		case SbxBYREF | SbxCURRENCY:
292 			if( n > SbxMAXCURR )
293 			{
294 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCURR;
295 			}
296 			else if( n < SbxMINCURR )
297 			{
298 				SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCURR;
299 			}
300 			*p->pLong64 = ImpDoubleToCurrency( n ); break;
301 
302 		default:
303 			SbxBase::SetError( SbxERR_CONVERSION );
304 	}
305 }
306 
307