Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <tools/errcode.hxx>
21 : #include <basic/sbx.hxx>
22 : #include "sbxconv.hxx"
23 :
24 2 : float ImpGetSingle( const SbxValues* p )
25 : {
26 2 : SbxValues aTmp;
27 : float nRes;
28 : start:
29 2 : switch( +p->eType )
30 : {
31 : case SbxNULL:
32 0 : SbxBase::SetError( SbxERR_CONVERSION );
33 : case SbxEMPTY:
34 0 : nRes = 0; break;
35 : case SbxCHAR:
36 0 : nRes = p->nChar; break;
37 : case SbxBYTE:
38 0 : nRes = p->nByte; break;
39 : case SbxINTEGER:
40 : case SbxBOOL:
41 2 : nRes = p->nInteger; break;
42 : case SbxERROR:
43 : case SbxUSHORT:
44 0 : nRes = p->nUShort; break;
45 : case SbxLONG:
46 0 : nRes = (float) p->nLong; break;
47 : case SbxULONG:
48 0 : nRes = (float) p->nULong; break;
49 : case SbxSINGLE:
50 0 : nRes = p->nSingle; break;
51 : case SbxDECIMAL:
52 : case SbxBYREF | SbxDECIMAL:
53 0 : if( p->pDecimal )
54 0 : p->pDecimal->getSingle( nRes );
55 : else
56 0 : nRes = 0.0;
57 0 : break;
58 : case SbxDATE:
59 : case SbxDOUBLE:
60 : case SbxCURRENCY:
61 : case SbxSALINT64:
62 : case SbxSALUINT64:
63 : {
64 : double dVal;
65 0 : if( p->eType == SbxCURRENCY )
66 0 : dVal = ImpCurrencyToDouble( p->nInt64 );
67 0 : else if( p->eType == SbxSALINT64 )
68 0 : dVal = (float) p->nInt64;
69 0 : else if( p->eType == SbxSALUINT64 )
70 0 : dVal = (float) p->uInt64;
71 : else
72 0 : dVal = p->nDouble;
73 :
74 0 : if( dVal > SbxMAXSNG )
75 : {
76 0 : SbxBase::SetError( SbxERR_OVERFLOW );
77 0 : nRes = static_cast< float >(SbxMAXSNG);
78 : }
79 0 : else if( dVal < SbxMINSNG )
80 : {
81 0 : SbxBase::SetError( SbxERR_OVERFLOW );
82 0 : nRes = static_cast< float >(SbxMINSNG);
83 : }
84 : // tests for underflow - storing value too small for precision of single
85 0 : else if( dVal > 0 && dVal < SbxMAXSNG2 )
86 : {
87 0 : SbxBase::SetError( SbxERR_OVERFLOW );
88 0 : nRes = static_cast< float >(SbxMAXSNG2);
89 : }
90 0 : else if( dVal < 0 && dVal > SbxMINSNG2 )
91 : {
92 0 : SbxBase::SetError( SbxERR_OVERFLOW );
93 0 : nRes = static_cast< float >(SbxMINSNG2);
94 : }
95 : else
96 0 : nRes = (float) dVal;
97 0 : break;
98 : }
99 : case SbxBYREF | SbxSTRING:
100 : case SbxSTRING:
101 : case SbxLPSTR:
102 0 : if( !p->pOUString )
103 0 : nRes = 0;
104 : else
105 : {
106 : double d;
107 : SbxDataType t;
108 0 : if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
109 0 : nRes = 0;
110 0 : else if( d > SbxMAXSNG )
111 : {
112 0 : SbxBase::SetError( SbxERR_OVERFLOW );
113 0 : nRes = static_cast< float >(SbxMAXSNG);
114 : }
115 0 : else if( d < SbxMINSNG )
116 : {
117 0 : SbxBase::SetError( SbxERR_OVERFLOW );
118 0 : nRes = static_cast< float >(SbxMINSNG);
119 : }
120 : else
121 0 : nRes = (float) d;
122 : }
123 0 : break;
124 : case SbxOBJECT:
125 : {
126 0 : SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
127 0 : if( pVal )
128 0 : nRes = pVal->GetSingle();
129 : else
130 : {
131 0 : SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
132 : }
133 0 : break;
134 : }
135 :
136 : case SbxBYREF | SbxCHAR:
137 0 : nRes = *p->pChar; break;
138 : case SbxBYREF | SbxBYTE:
139 0 : nRes = *p->pByte; break;
140 : case SbxBYREF | SbxINTEGER:
141 : case SbxBYREF | SbxBOOL:
142 0 : nRes = *p->pInteger; break;
143 : case SbxBYREF | SbxLONG:
144 0 : nRes = (float) *p->pLong; break;
145 : case SbxBYREF | SbxULONG:
146 0 : nRes = (float) *p->pULong; break;
147 : case SbxBYREF | SbxERROR:
148 : case SbxBYREF | SbxUSHORT:
149 0 : nRes = *p->pUShort; break;
150 : case SbxBYREF | SbxSINGLE:
151 0 : nRes = *p->pSingle; break;
152 : // from here had to be tested
153 : case SbxBYREF | SbxDATE:
154 : case SbxBYREF | SbxDOUBLE:
155 0 : aTmp.nDouble = *p->pDouble; goto ref;
156 : case SbxBYREF | SbxSALINT64:
157 : case SbxBYREF | SbxCURRENCY:
158 0 : aTmp.nInt64 = *p->pnInt64; goto ref;
159 : case SbxBYREF | SbxSALUINT64:
160 0 : aTmp.uInt64 = *p->puInt64; goto ref;
161 : ref:
162 0 : aTmp.eType = SbxDataType( p->eType & 0x0FFF );
163 0 : p = &aTmp; goto start;
164 :
165 : default:
166 0 : SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
167 : }
168 2 : return nRes;
169 : }
170 :
171 14 : void ImpPutSingle( SbxValues* p, float n )
172 : {
173 14 : SbxValues aTmp;
174 : start:
175 14 : switch( +p->eType )
176 : {
177 : case SbxCHAR:
178 0 : aTmp.pChar = &p->nChar; goto direct;
179 : case SbxBYTE:
180 0 : aTmp.pByte = &p->nByte; goto direct;
181 : case SbxINTEGER:
182 : case SbxBOOL:
183 0 : aTmp.pInteger = &p->nInteger; goto direct;
184 : case SbxLONG:
185 0 : aTmp.pLong = &p->nLong; goto direct;
186 : case SbxULONG:
187 0 : aTmp.pULong = &p->nULong; goto direct;
188 : case SbxERROR:
189 : case SbxUSHORT:
190 0 : aTmp.pUShort = &p->nUShort; goto direct;
191 : case SbxCURRENCY:
192 : case SbxSALINT64:
193 0 : aTmp.pnInt64 = &p->nInt64; goto direct;
194 : case SbxSALUINT64:
195 0 : aTmp.puInt64 = &p->uInt64; goto direct;
196 : case SbxDECIMAL:
197 : case SbxBYREF | SbxDECIMAL:
198 : {
199 0 : SbxDecimal* pDec = ImpCreateDecimal( p );
200 0 : if( !pDec->setSingle( n ) )
201 0 : SbxBase::SetError( SbxERR_OVERFLOW );
202 0 : break;
203 : }
204 : direct:
205 0 : aTmp.eType = SbxDataType( p->eType | SbxBYREF );
206 0 : p = &aTmp; goto start;
207 :
208 : // from here no tests
209 : case SbxSINGLE:
210 12 : p->nSingle = n; break;
211 : case SbxDATE:
212 : case SbxDOUBLE:
213 0 : p->nDouble = n; break;
214 :
215 : case SbxBYREF | SbxSTRING:
216 : case SbxSTRING:
217 : case SbxLPSTR:
218 : {
219 2 : if( !p->pOUString )
220 0 : p->pOUString = new OUString;
221 2 : ImpCvtNum( (double) n, 6, *p->pOUString );
222 2 : break;
223 : }
224 : case SbxOBJECT:
225 : {
226 0 : SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
227 0 : if( pVal )
228 0 : pVal->PutSingle( n );
229 : else
230 0 : SbxBase::SetError( SbxERR_NO_OBJECT );
231 0 : break;
232 : }
233 : case SbxBYREF | SbxCHAR:
234 0 : if( n > SbxMAXCHAR )
235 : {
236 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
237 : }
238 0 : else if( n < SbxMINCHAR )
239 : {
240 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
241 : }
242 0 : *p->pChar = (sal_Unicode) n; break;
243 : case SbxBYREF | SbxBYTE:
244 0 : if( n > SbxMAXBYTE )
245 : {
246 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
247 : }
248 0 : else if( n < 0 )
249 : {
250 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
251 : }
252 0 : *p->pByte = (sal_uInt8) n; break;
253 : case SbxBYREF | SbxINTEGER:
254 : case SbxBYREF | SbxBOOL:
255 0 : if( n > SbxMAXINT )
256 : {
257 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
258 : }
259 0 : else if( n < SbxMININT )
260 : {
261 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
262 : }
263 0 : *p->pInteger = (sal_Int16) n; break;
264 : case SbxBYREF | SbxERROR:
265 : case SbxBYREF | SbxUSHORT:
266 0 : if( n > SbxMAXUINT )
267 : {
268 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
269 : }
270 0 : else if( n < 0 )
271 : {
272 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
273 : }
274 0 : *p->pUShort = (sal_uInt16) n; break;
275 : case SbxBYREF | SbxLONG:
276 : {
277 : sal_Int32 i;
278 0 : if( n > SbxMAXLNG )
279 : {
280 0 : SbxBase::SetError( SbxERR_OVERFLOW ); i = SbxMAXLNG;
281 : }
282 0 : else if( n < SbxMINLNG )
283 : {
284 0 : SbxBase::SetError( SbxERR_OVERFLOW ); i = SbxMINLNG;
285 : }
286 : else
287 : {
288 0 : i = sal::static_int_cast< sal_Int32 >(n);
289 : }
290 0 : *p->pLong = i; break;
291 : }
292 : case SbxBYREF | SbxULONG:
293 : {
294 : sal_uInt32 i;
295 0 : if( n > SbxMAXULNG )
296 : {
297 0 : SbxBase::SetError( SbxERR_OVERFLOW ); i = SbxMAXULNG;
298 : }
299 0 : else if( n < 0 )
300 : {
301 0 : SbxBase::SetError( SbxERR_OVERFLOW ); i = 0;
302 : }
303 : else
304 : {
305 0 : i = sal::static_int_cast< sal_uInt32 >(n);
306 : }
307 0 : *p->pULong = i; break;
308 : }
309 : case SbxBYREF | SbxSINGLE:
310 0 : *p->pSingle = n; break;
311 : case SbxBYREF | SbxDATE:
312 : case SbxBYREF | SbxDOUBLE:
313 0 : *p->pDouble = (double) n; break;
314 : case SbxBYREF | SbxSALINT64:
315 0 : *p->pnInt64 = (sal_Int64)n; break;
316 : case SbxBYREF | SbxSALUINT64:
317 0 : *p->puInt64 = (sal_uInt64)n; break;
318 : case SbxBYREF | SbxCURRENCY:
319 : double d;
320 0 : if( n > SbxMAXCURR )
321 : {
322 0 : SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMAXCURR;
323 : }
324 0 : else if( n < SbxMINCURR )
325 : {
326 0 : SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMINCURR;
327 : }
328 : else
329 : {
330 0 : d = n;
331 : }
332 0 : *p->pnInt64 = ImpDoubleToCurrency( d ); break;
333 :
334 : default:
335 0 : SbxBase::SetError( SbxERR_CONVERSION );
336 : }
337 14 : }
338 :
339 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|