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