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 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 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