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