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 3 : double ImpRound( double d )
25 : {
26 3 : return d + ( d < 0 ? -0.5 : 0.5 );
27 : }
28 :
29 26 : sal_Int16 ImpGetInteger( const SbxValues* p )
30 : {
31 26 : SbxValues aTmp;
32 : sal_Int16 nRes;
33 : start:
34 26 : switch( +p->eType )
35 : {
36 : case SbxNULL:
37 0 : SbxBase::SetError( SbxERR_CONVERSION );
38 : case SbxEMPTY:
39 0 : nRes = 0; break;
40 : case SbxCHAR:
41 0 : nRes = p->nChar; break;
42 : case SbxBYTE:
43 0 : nRes = p->nByte; break;
44 : case SbxINTEGER:
45 : case SbxBOOL:
46 23 : nRes = p->nInteger; break;
47 : case SbxERROR:
48 : case SbxUSHORT:
49 0 : if( p->nUShort > (sal_uInt16) SbxMAXINT )
50 : {
51 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
52 : }
53 : else
54 0 : nRes = (sal_Int16) p->nUShort;
55 0 : break;
56 : case SbxLONG:
57 0 : if( p->nLong > SbxMAXINT )
58 : {
59 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
60 : }
61 0 : else if( p->nLong < SbxMININT )
62 : {
63 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
64 : }
65 : else
66 0 : nRes = (sal_Int16) p->nLong;
67 0 : break;
68 : case SbxULONG:
69 0 : if( p->nULong > SbxMAXINT )
70 : {
71 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
72 : }
73 : else
74 0 : nRes = (sal_Int16) p->nULong;
75 0 : break;
76 : case SbxSINGLE:
77 0 : if( p->nSingle > SbxMAXINT )
78 : {
79 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
80 : }
81 0 : else if( p->nSingle < SbxMININT )
82 : {
83 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
84 : }
85 : else
86 0 : nRes = (sal_Int16) ImpRound( p->nSingle );
87 0 : break;
88 : case SbxCURRENCY:
89 : {
90 0 : sal_Int64 tstVal = (sal_Int64) p->nInt64 / (sal_Int64) CURRENCY_FACTOR;
91 :
92 0 : if( tstVal > SbxMAXINT )
93 : {
94 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
95 : }
96 0 : else if( tstVal < SbxMININT )
97 : {
98 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
99 : }
100 : else
101 0 : nRes = (sal_Int16) (tstVal);
102 0 : break;
103 : }
104 : case SbxSALINT64:
105 0 : if( p->nInt64 > SbxMAXINT )
106 : {
107 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
108 : }
109 0 : else if( p->nInt64 < SbxMININT )
110 : {
111 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
112 : }
113 : else
114 0 : nRes = (sal_Int16) p->nInt64;
115 0 : break;
116 : case SbxSALUINT64:
117 0 : if( p->uInt64 > SbxMAXINT )
118 : {
119 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
120 : }
121 : else
122 0 : nRes = (sal_Int16) p->uInt64;
123 0 : break;
124 : case SbxDATE:
125 : case SbxDOUBLE:
126 : case SbxDECIMAL:
127 : case SbxBYREF | SbxDECIMAL:
128 : {
129 3 : double dVal = 0.0;
130 3 : if( p->eType == SbxDECIMAL )
131 : {
132 0 : if( p->pDecimal )
133 0 : p->pDecimal->getDouble( dVal );
134 : }
135 : else
136 3 : dVal = p->nDouble;
137 :
138 3 : if( dVal > SbxMAXINT )
139 : {
140 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
141 : }
142 3 : else if( dVal < SbxMININT )
143 : {
144 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
145 : }
146 : else
147 3 : nRes = (sal_Int16) ImpRound( dVal );
148 : break;
149 : }
150 : case SbxLPSTR:
151 : case SbxSTRING:
152 : case SbxBYREF | SbxSTRING:
153 0 : if( !p->pOUString )
154 0 : nRes = 0;
155 : else
156 : {
157 : double d;
158 : SbxDataType t;
159 0 : if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
160 0 : nRes = 0;
161 0 : else if( d > SbxMAXINT )
162 : {
163 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
164 : }
165 0 : else if( d < SbxMININT )
166 : {
167 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
168 : }
169 : else
170 0 : nRes = (sal_Int16) ImpRound( d );
171 : }
172 0 : break;
173 : case SbxOBJECT:
174 : {
175 0 : SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
176 0 : if( pVal )
177 0 : nRes = pVal->GetInteger();
178 : else
179 : {
180 0 : SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
181 : }
182 0 : break;
183 : }
184 :
185 : case SbxBYREF | SbxCHAR:
186 0 : nRes = *p->pChar; break;
187 : case SbxBYREF | SbxBYTE:
188 0 : nRes = *p->pByte; break;
189 : case SbxBYREF | SbxINTEGER:
190 : case SbxBYREF | SbxBOOL:
191 0 : nRes = *p->pInteger; break;
192 :
193 : // from here had to be tested
194 : case SbxBYREF | SbxLONG:
195 0 : aTmp.nLong = *p->pLong; goto ref;
196 : case SbxBYREF | SbxULONG:
197 0 : aTmp.nULong = *p->pULong; goto ref;
198 : case SbxBYREF | SbxERROR:
199 : case SbxBYREF | SbxUSHORT:
200 0 : aTmp.nUShort = *p->pUShort; goto ref;
201 : case SbxBYREF | SbxSINGLE:
202 0 : aTmp.nSingle = *p->pSingle; goto ref;
203 : case SbxBYREF | SbxDATE:
204 : case SbxBYREF | SbxDOUBLE:
205 0 : aTmp.nDouble = *p->pDouble; goto ref;
206 : case SbxBYREF | SbxCURRENCY:
207 : case SbxBYREF | SbxSALINT64:
208 0 : aTmp.nInt64 = *p->pnInt64; goto ref;
209 : case SbxBYREF | SbxSALUINT64:
210 0 : aTmp.uInt64 = *p->puInt64; goto ref;
211 : ref:
212 0 : aTmp.eType = SbxDataType( p->eType & 0x0FFF );
213 0 : p = &aTmp; goto start;
214 :
215 : default:
216 0 : SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
217 : }
218 26 : return nRes;
219 : }
220 :
221 72 : void ImpPutInteger( SbxValues* p, sal_Int16 n )
222 : {
223 72 : SbxValues aTmp;
224 : start:
225 72 : switch( +p->eType )
226 : {
227 : // here had to be tested
228 : case SbxCHAR:
229 0 : aTmp.pChar = &p->nChar; goto direct;
230 : case SbxBYTE:
231 0 : aTmp.pByte = &p->nByte; goto direct;
232 : case SbxULONG:
233 0 : aTmp.pULong = &p->nULong; goto direct;
234 : case SbxERROR:
235 : case SbxUSHORT:
236 0 : aTmp.pUShort = &p->nUShort; goto direct;
237 : case SbxSALUINT64:
238 0 : aTmp.puInt64 = &p->uInt64; goto direct;
239 : direct:
240 0 : aTmp.eType = SbxDataType( p->eType | SbxBYREF );
241 0 : p = &aTmp; goto start;
242 :
243 : // from here no tests needed
244 : case SbxINTEGER:
245 : case SbxBOOL:
246 72 : p->nInteger = n; break;
247 : case SbxLONG:
248 0 : p->nLong = n; break;
249 : case SbxSINGLE:
250 0 : p->nSingle = n; break;
251 : case SbxDATE:
252 : case SbxDOUBLE:
253 0 : p->nDouble = n; break;
254 : case SbxCURRENCY:
255 0 : p->nInt64 = n * CURRENCY_FACTOR; break;
256 : case SbxSALINT64:
257 0 : p->nInt64 = n; break;
258 : case SbxDECIMAL:
259 : case SbxBYREF | SbxDECIMAL:
260 0 : ImpCreateDecimal( p )->setInt( n );
261 0 : break;
262 :
263 : case SbxLPSTR:
264 : case SbxSTRING:
265 : case SbxBYREF | SbxSTRING:
266 0 : if( !p->pOUString )
267 0 : p->pOUString = new ::rtl::OUString;
268 0 : ImpCvtNum( (double) n, 0, *p->pOUString );
269 0 : break;
270 : case SbxOBJECT:
271 : {
272 0 : SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
273 0 : if( pVal )
274 0 : pVal->PutInteger( n );
275 : else
276 0 : SbxBase::SetError( SbxERR_NO_OBJECT );
277 0 : break;
278 : }
279 : case SbxBYREF | SbxCHAR:
280 0 : if( n < SbxMINCHAR )
281 : {
282 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
283 : }
284 0 : *p->pChar = (char) n; break;
285 : case SbxBYREF | SbxBYTE:
286 0 : if( n > SbxMAXBYTE )
287 : {
288 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
289 : }
290 0 : else if( n < 0 )
291 : {
292 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
293 : }
294 0 : *p->pByte = (sal_uInt8) n; break;
295 : case SbxBYREF | SbxINTEGER:
296 : case SbxBYREF | SbxBOOL:
297 0 : *p->pInteger = n; break;
298 : case SbxBYREF | SbxERROR:
299 : case SbxBYREF | SbxUSHORT:
300 0 : if( n < 0 )
301 : {
302 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
303 : }
304 0 : *p->pUShort = (sal_uInt16) n; break;
305 : case SbxBYREF | SbxLONG:
306 0 : *p->pLong = (sal_Int32) n; break;
307 : case SbxBYREF | SbxULONG:
308 0 : if( n < 0 )
309 : {
310 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
311 : }
312 0 : *p->pULong = (sal_uInt32) n; break;
313 : case SbxBYREF | SbxCURRENCY:
314 0 : *p->pnInt64 = n * CURRENCY_FACTOR; break;
315 : case SbxBYREF | SbxSALINT64:
316 0 : *p->pnInt64 = n; break;
317 : case SbxBYREF | SbxSALUINT64:
318 0 : if( n < 0 )
319 : {
320 0 : SbxBase::SetError( SbxERR_OVERFLOW );
321 0 : *p->puInt64 = 0;
322 : }
323 : else
324 0 : *p->puInt64 = n;
325 0 : break;
326 : case SbxBYREF | SbxSINGLE:
327 0 : *p->pSingle = (float) n; break;
328 : case SbxBYREF | SbxDATE:
329 : case SbxBYREF | SbxDOUBLE:
330 0 : *p->pDouble = (double) n; break;
331 :
332 : default:
333 0 : SbxBase::SetError( SbxERR_CONVERSION );
334 : }
335 72 : }
336 :
337 :
338 : // sal_Int64 / hyper
339 :
340 0 : sal_Int64 ImpDoubleToSalInt64( double d )
341 : {
342 : sal_Int64 nRes;
343 0 : if( d > SbxMAXSALINT64 )
344 : {
345 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALINT64;
346 : }
347 0 : else if( d < SbxMINSALINT64 )
348 : {
349 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINSALINT64;
350 : }
351 : else
352 0 : nRes = (sal_Int64) ImpRound( d );
353 0 : return nRes;
354 : }
355 :
356 0 : sal_uInt64 ImpDoubleToSalUInt64( double d )
357 : {
358 : sal_uInt64 nRes;
359 0 : if( d > SbxMAXSALUINT64 )
360 : {
361 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALUINT64;
362 : }
363 0 : else if( d < 0.0 )
364 : {
365 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
366 : }
367 : else
368 0 : nRes = (sal_uInt64) ImpRound( d );
369 0 : return nRes;
370 : }
371 :
372 :
373 0 : double ImpSalUInt64ToDouble( sal_uInt64 n )
374 : {
375 0 : double d = 0.0;
376 0 : if( n > SbxMAXSALINT64 )
377 0 : SbxBase::SetError( SbxERR_CONVERSION );
378 : else
379 0 : d = (double)(sal_Int64) n;
380 0 : return d;
381 : }
382 :
383 :
384 0 : sal_Int64 ImpGetInt64( const SbxValues* p )
385 : {
386 0 : SbxValues aTmp;
387 : sal_Int64 nRes;
388 : start:
389 0 : switch( +p->eType )
390 : {
391 : case SbxNULL:
392 0 : SbxBase::SetError( SbxERR_CONVERSION );
393 : case SbxEMPTY:
394 0 : nRes = 0; break;
395 : case SbxCHAR:
396 0 : nRes = p->nChar; break;
397 : case SbxBYTE:
398 0 : nRes = p->nByte; break;
399 : case SbxINTEGER:
400 : case SbxBOOL:
401 0 : nRes = p->nInteger; break;
402 : case SbxERROR:
403 : case SbxUSHORT:
404 0 : nRes = (sal_Int64) p->nUShort; break;
405 : case SbxLONG:
406 0 : nRes = (sal_Int64) p->nLong; break;
407 : case SbxULONG:
408 0 : nRes = (sal_Int64) p->nULong; break;
409 : case SbxSINGLE:
410 0 : nRes = (sal_Int64) p->nSingle;
411 0 : break;
412 : case SbxDATE:
413 : case SbxDOUBLE:
414 0 : nRes = (sal_Int64) p->nDouble;
415 0 : break;
416 : case SbxCURRENCY:
417 0 : nRes = p->nInt64 / CURRENCY_FACTOR; break;
418 : case SbxSALINT64:
419 0 : nRes = p->nInt64; break;
420 : case SbxSALUINT64:
421 0 : if( p->uInt64 > SbxMAXSALINT64 )
422 : {
423 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALINT64;
424 : }
425 : else
426 0 : nRes = (sal_Int64) p->uInt64;
427 0 : break;
428 :
429 : case SbxBYREF | SbxSTRING:
430 : case SbxSTRING:
431 : case SbxLPSTR:
432 0 : if( !p->pOUString )
433 0 : nRes = 0;
434 : else
435 : {
436 : ::rtl::OString aOStr = ::rtl::OUStringToOString
437 0 : ( *p->pOUString, RTL_TEXTENCODING_ASCII_US );
438 0 : nRes = aOStr.toInt64();
439 0 : if( nRes == 0 )
440 : {
441 : // Check if really 0 or invalid conversion
442 : double d;
443 : SbxDataType t;
444 0 : if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
445 0 : nRes = 0;
446 : else
447 0 : nRes = (sal_Int64) d;
448 0 : }
449 : }
450 0 : break;
451 : case SbxOBJECT:
452 : {
453 0 : SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
454 0 : if( pVal )
455 0 : nRes = pVal->GetInt64();
456 : else
457 : {
458 0 : SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
459 : }
460 0 : break;
461 : }
462 :
463 : case SbxBYREF | SbxCHAR:
464 0 : nRes = *p->pChar; break;
465 : case SbxBYREF | SbxBYTE:
466 0 : nRes = *p->pByte; break;
467 : case SbxBYREF | SbxINTEGER:
468 : case SbxBYREF | SbxBOOL:
469 0 : nRes = *p->pInteger; break;
470 : case SbxBYREF | SbxLONG:
471 0 : nRes = *p->pLong; break;
472 : case SbxBYREF | SbxULONG:
473 0 : nRes = *p->pULong; break;
474 : case SbxBYREF | SbxCURRENCY:
475 0 : nRes = p->nInt64 / CURRENCY_FACTOR; break;
476 : case SbxBYREF | SbxSALINT64:
477 0 : nRes = *p->pnInt64; break;
478 :
479 : // from here the values has to be checked
480 : case SbxBYREF | SbxSALUINT64:
481 0 : aTmp.uInt64 = *p->puInt64; goto ref;
482 :
483 : case SbxBYREF | SbxERROR:
484 : case SbxBYREF | SbxUSHORT:
485 0 : aTmp.nUShort = *p->pUShort; goto ref;
486 : case SbxBYREF | SbxSINGLE:
487 0 : aTmp.nSingle = *p->pSingle; goto ref;
488 : case SbxBYREF | SbxDATE:
489 : case SbxBYREF | SbxDOUBLE:
490 0 : aTmp.nDouble = *p->pDouble; goto ref;
491 : ref:
492 0 : aTmp.eType = SbxDataType( p->eType & 0x0FFF );
493 0 : p = &aTmp; goto start;
494 :
495 : default:
496 0 : SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
497 : }
498 0 : return nRes;
499 : }
500 :
501 0 : void ImpPutInt64( SbxValues* p, sal_Int64 n )
502 : {
503 0 : SbxValues aTmp;
504 :
505 : start:
506 0 : switch( +p->eType )
507 : {
508 : // Check neccessary
509 : case SbxCHAR:
510 0 : aTmp.pChar = &p->nChar; goto direct;
511 : case SbxBYTE:
512 0 : aTmp.pByte = &p->nByte; goto direct;
513 : case SbxINTEGER:
514 : case SbxBOOL:
515 0 : aTmp.pInteger = &p->nInteger; goto direct;
516 : case SbxULONG:
517 0 : aTmp.pULong = &p->nULong; goto direct;
518 : case SbxERROR:
519 : case SbxUSHORT:
520 0 : aTmp.pUShort = &p->nUShort; goto direct;
521 : case SbxLONG:
522 0 : aTmp.pnInt64 = &p->nInt64; goto direct;
523 : case SbxCURRENCY:
524 : case SbxSALINT64:
525 0 : aTmp.pnInt64 = &p->nInt64; goto direct;
526 : case SbxSALUINT64:
527 0 : aTmp.puInt64 = &p->uInt64; goto direct;
528 :
529 : direct:
530 0 : aTmp.eType = SbxDataType( p->eType | SbxBYREF );
531 0 : p = &aTmp; goto start;
532 :
533 : case SbxSINGLE:
534 0 : p->nSingle = (float) n; break;
535 : case SbxDATE:
536 : case SbxDOUBLE:
537 0 : p->nDouble = (double) n; break;
538 :
539 : case SbxBYREF | SbxSTRING:
540 : case SbxSTRING:
541 : case SbxLPSTR:
542 : {
543 0 : if( !p->pOUString )
544 0 : p->pOUString = new ::rtl::OUString;
545 :
546 0 : ::rtl::OString aOStr = ::rtl::OString::valueOf( n );
547 : (*p->pOUString) = ::rtl::OStringToOUString
548 0 : ( aOStr, RTL_TEXTENCODING_ASCII_US );
549 0 : break;
550 : }
551 : case SbxOBJECT:
552 : {
553 0 : SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
554 0 : if( pVal )
555 0 : pVal->PutInt64( n );
556 : else
557 0 : SbxBase::SetError( SbxERR_NO_OBJECT );
558 0 : break;
559 : }
560 : case SbxBYREF | SbxCHAR:
561 0 : if( n > SbxMAXCHAR )
562 : {
563 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
564 : }
565 0 : else if( n < SbxMINCHAR )
566 : {
567 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
568 : }
569 0 : *p->pChar = (sal_Unicode) n; break;
570 : case SbxBYREF | SbxBYTE:
571 0 : if( n > SbxMAXBYTE )
572 : {
573 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
574 : }
575 0 : else if( n < 0 )
576 : {
577 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
578 : }
579 0 : *p->pByte = (sal_uInt8) n; break;
580 : case SbxBYREF | SbxINTEGER:
581 : case SbxBYREF | SbxBOOL:
582 0 : if( n > SbxMAXINT )
583 : {
584 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
585 : }
586 0 : else if( n < SbxMININT )
587 : {
588 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
589 : }
590 0 : *p->pInteger = (sal_Int16) n; break;
591 : case SbxBYREF | SbxERROR:
592 : case SbxBYREF | SbxUSHORT:
593 0 : if( n > SbxMAXUINT )
594 : {
595 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
596 : }
597 0 : else if( n < 0 )
598 : {
599 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
600 : }
601 0 : *p->pUShort = (sal_uInt16) n; break;
602 : case SbxBYREF | SbxLONG:
603 0 : if( n > SbxMAXLNG )
604 : {
605 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
606 : }
607 0 : else if( n < SbxMINLNG )
608 : {
609 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
610 : }
611 0 : *p->pLong = (sal_Int32) n; break;
612 : case SbxBYREF | SbxULONG:
613 0 : if( n > SbxMAXULNG )
614 : {
615 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
616 : }
617 0 : else if( n < 0 )
618 : {
619 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
620 : }
621 0 : *p->pULong = (sal_uInt32) n; break;
622 : case SbxBYREF | SbxSINGLE:
623 0 : *p->pSingle = (float) n; break;
624 : case SbxBYREF | SbxDATE:
625 : case SbxBYREF | SbxDOUBLE:
626 0 : *p->pDouble = (double) n; break;
627 : case SbxBYREF | SbxCURRENCY:
628 0 : *p->pnInt64 = n * CURRENCY_FACTOR; break;
629 : case SbxBYREF | SbxSALINT64:
630 0 : *p->pnInt64 = n; break;
631 : case SbxBYREF | SbxSALUINT64:
632 0 : if( n < 0 )
633 : {
634 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
635 : }
636 0 : *p->puInt64 = (sal_Int64) n; break;
637 :
638 : default:
639 0 : SbxBase::SetError( SbxERR_CONVERSION );
640 : }
641 0 : }
642 :
643 0 : sal_uInt64 ImpGetUInt64( const SbxValues* p )
644 : {
645 0 : SbxValues aTmp;
646 : sal_uInt64 nRes;
647 : start:
648 0 : switch( +p->eType )
649 : {
650 : case SbxNULL:
651 0 : SbxBase::SetError( SbxERR_CONVERSION );
652 : case SbxEMPTY:
653 0 : nRes = 0; break;
654 : case SbxCHAR:
655 0 : nRes = p->nChar; break;
656 : case SbxBYTE:
657 0 : nRes = p->nByte; break;
658 : case SbxINTEGER:
659 : case SbxBOOL:
660 0 : nRes = p->nInteger; break;
661 : case SbxERROR:
662 : case SbxUSHORT:
663 0 : nRes = p->nUShort; break;
664 : case SbxLONG:
665 0 : nRes = p->nLong; break;
666 : case SbxULONG:
667 0 : nRes = (sal_uInt64) p->nULong; break;
668 : case SbxSINGLE:
669 0 : nRes = (sal_uInt64) p->nSingle; break;
670 : case SbxDATE:
671 : case SbxDOUBLE:
672 : {
673 : //TODO overflow check
674 0 : nRes = (sal_uInt64) p->nDouble;
675 0 : break;
676 : }
677 : case SbxCURRENCY:
678 0 : nRes = p->nInt64 * CURRENCY_FACTOR; break;
679 : case SbxSALINT64:
680 0 : if( p->nInt64 < 0 )
681 : {
682 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
683 : }
684 : else
685 0 : nRes = (sal_uInt64) p->nInt64;
686 0 : break;
687 : case SbxSALUINT64:
688 0 : nRes = p->uInt64; break;
689 :
690 : case SbxBYREF | SbxSTRING:
691 : case SbxSTRING:
692 : case SbxLPSTR:
693 0 : if( !p->pOUString )
694 0 : nRes = 0;
695 : else
696 : {
697 : ::rtl::OString aOStr = ::rtl::OUStringToOString
698 0 : ( *p->pOUString, RTL_TEXTENCODING_ASCII_US );
699 0 : sal_Int64 n64 = aOStr.toInt64();
700 0 : if( n64 == 0 )
701 : {
702 : // Check if really 0 or invalid conversion
703 : double d;
704 : SbxDataType t;
705 0 : if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
706 0 : nRes = 0;
707 0 : else if( d > SbxMAXSALUINT64 )
708 : {
709 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALUINT64;
710 : }
711 0 : else if( d < 0.0 )
712 : {
713 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
714 : }
715 : else
716 0 : nRes = (sal_uInt64) ImpRound( d );
717 : }
718 0 : else if( n64 < 0 )
719 : {
720 0 : SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
721 : }
722 : else
723 : {
724 0 : nRes = n64;
725 0 : }
726 : }
727 0 : break;
728 : case SbxOBJECT:
729 : {
730 0 : SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
731 0 : if( pVal )
732 0 : nRes = pVal->GetUInt64();
733 : else
734 : {
735 0 : SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
736 : }
737 0 : break;
738 : }
739 :
740 : case SbxBYREF | SbxCHAR:
741 0 : nRes = *p->pChar; break;
742 : case SbxBYREF | SbxBYTE:
743 0 : nRes = *p->pByte; break;
744 : case SbxBYREF | SbxINTEGER:
745 : case SbxBYREF | SbxBOOL:
746 0 : nRes = *p->pInteger; break;
747 : case SbxBYREF | SbxLONG:
748 0 : nRes = *p->pLong; break;
749 : case SbxBYREF | SbxULONG:
750 0 : nRes = *p->pULong; break;
751 : case SbxBYREF | SbxSALUINT64:
752 0 : nRes = *p->puInt64; break;
753 :
754 : // from here on the value has to be checked
755 : case SbxBYREF | SbxERROR:
756 : case SbxBYREF | SbxUSHORT:
757 0 : aTmp.nUShort = *p->pUShort; goto ref;
758 : case SbxBYREF | SbxSINGLE:
759 0 : aTmp.nSingle = *p->pSingle; goto ref;
760 : case SbxBYREF | SbxDATE:
761 : case SbxBYREF | SbxDOUBLE:
762 0 : aTmp.nDouble = *p->pDouble; goto ref;
763 : case SbxBYREF | SbxCURRENCY:
764 : case SbxBYREF | SbxSALINT64:
765 0 : aTmp.nInt64 = *p->pnInt64; goto ref;
766 : ref:
767 0 : aTmp.eType = SbxDataType( p->eType & 0x0FFF );
768 0 : p = &aTmp; goto start;
769 :
770 : default:
771 0 : SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
772 : }
773 0 : return nRes;
774 : }
775 :
776 0 : void ImpPutUInt64( SbxValues* p, sal_uInt64 n )
777 : {
778 0 : SbxValues aTmp;
779 :
780 : start:
781 0 : switch( +p->eType )
782 : {
783 : // Check neccessary
784 : case SbxCHAR:
785 0 : aTmp.pChar = &p->nChar; goto direct;
786 : case SbxBYTE:
787 0 : aTmp.pByte = &p->nByte; goto direct;
788 : case SbxINTEGER:
789 : case SbxBOOL:
790 0 : aTmp.pInteger = &p->nInteger; goto direct;
791 : case SbxULONG:
792 0 : aTmp.pULong = &p->nULong; goto direct;
793 : case SbxERROR:
794 : case SbxUSHORT:
795 0 : aTmp.pUShort = &p->nUShort; goto direct;
796 : case SbxLONG:
797 0 : aTmp.pnInt64 = &p->nInt64; goto direct;
798 : case SbxCURRENCY:
799 : case SbxSALINT64:
800 0 : aTmp.pnInt64 = &p->nInt64; goto direct;
801 : case SbxSINGLE:
802 0 : aTmp.pSingle = &p->nSingle; goto direct;
803 : case SbxDATE:
804 : case SbxDOUBLE:
805 0 : aTmp.pDouble = &p->nDouble; goto direct;
806 :
807 : direct:
808 0 : aTmp.eType = SbxDataType( p->eType | SbxBYREF );
809 0 : p = &aTmp; goto start;
810 :
811 : // Check not neccessary
812 : case SbxSALUINT64:
813 0 : p->uInt64 = n; break;
814 :
815 : case SbxBYREF | SbxSTRING:
816 : case SbxSTRING:
817 : case SbxLPSTR:
818 0 : if( !p->pOUString )
819 0 : p->pOUString = new ::rtl::OUString;
820 0 : if( n > SbxMAXSALINT64 )
821 0 : SbxBase::SetError( SbxERR_CONVERSION );
822 : else
823 : {
824 0 : ::rtl::OString aOStr = ::rtl::OString::valueOf( (sal_Int64)n );
825 : (*p->pOUString) = ::rtl::OStringToOUString
826 0 : ( aOStr, RTL_TEXTENCODING_ASCII_US );
827 : }
828 0 : break;
829 : case SbxOBJECT:
830 : {
831 0 : SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
832 0 : if( pVal )
833 0 : pVal->PutUInt64( n );
834 : else
835 0 : SbxBase::SetError( SbxERR_NO_OBJECT );
836 0 : break;
837 : }
838 : case SbxBYREF | SbxCHAR:
839 0 : if( n > SbxMAXCHAR )
840 : {
841 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
842 : }
843 0 : *p->pChar = (sal_Unicode) n; break;
844 : case SbxBYREF | SbxBYTE:
845 0 : if( n > SbxMAXBYTE )
846 : {
847 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
848 : }
849 0 : *p->pByte = (sal_uInt8) n; break;
850 : case SbxBYREF | SbxINTEGER:
851 : case SbxBYREF | SbxBOOL:
852 0 : if( n > SbxMAXINT )
853 : {
854 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
855 : }
856 0 : *p->pInteger = (sal_Int16) n; break;
857 : case SbxBYREF | SbxERROR:
858 : case SbxBYREF | SbxUSHORT:
859 0 : if( n > SbxMAXUINT )
860 : {
861 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
862 : }
863 0 : *p->pUShort = (sal_uInt16) n; break;
864 : case SbxBYREF | SbxLONG:
865 0 : if( n > SbxMAXLNG )
866 : {
867 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
868 : }
869 0 : *p->pLong = (sal_Int32) n; break;
870 : case SbxBYREF | SbxULONG:
871 0 : if( n > SbxMAXULNG )
872 : {
873 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
874 : }
875 0 : *p->pULong = (sal_uInt32) n; break;
876 : case SbxBYREF | SbxSINGLE:
877 0 : *p->pDouble = (float)ImpSalUInt64ToDouble( n ); break;
878 : case SbxBYREF | SbxDATE:
879 : case SbxBYREF | SbxDOUBLE:
880 :
881 0 : *p->pDouble = ImpSalUInt64ToDouble( n ); break;
882 : case SbxBYREF | SbxCURRENCY:
883 0 : if ( n > ( SbxMAXSALINT64 / CURRENCY_FACTOR ) )
884 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSALINT64;
885 0 : *p->pnInt64 = ( sal_Int64) ( n * CURRENCY_FACTOR ); break;
886 : case SbxBYREF | SbxSALUINT64:
887 0 : *p->puInt64 = n; break;
888 : case SbxBYREF | SbxSALINT64:
889 0 : if( n > SbxMAXSALINT64 )
890 : {
891 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
892 : }
893 0 : *p->pnInt64 = (sal_Int64) n; break;
894 :
895 : default:
896 0 : SbxBase::SetError( SbxERR_CONVERSION );
897 : }
898 0 : }
899 :
900 :
901 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|