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