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 "sbxres.hxx" 30 #include "runtime.hxx" 31 #ifndef _RTL_USTRBUF_HXX_ 32 #include <rtl/ustrbuf.hxx> 33 #endif 34 // AB 29.10.99 Unicode 35 #ifndef _USE_NO_NAMESPACE 36 using namespace rtl; 37 #endif 38 39 40 // Die Konversion eines Items auf String wird ueber die Put-Methoden 41 // der einzelnen Datentypen abgewickelt, um doppelten Code zu vermeiden. 42 43 ::rtl::OUString ImpGetString( const SbxValues* p ) 44 { 45 SbxValues aTmp; 46 ::rtl::OUString aRes; 47 aTmp.eType = SbxSTRING; 48 aTmp.pOUString = &aRes; 49 switch( +p->eType ) 50 { 51 case SbxNULL: 52 SbxBase::SetError( SbxERR_CONVERSION ); 53 case SbxEMPTY: 54 break; 55 case SbxCHAR: 56 ImpPutChar( &aTmp, p->nChar ); break; 57 case SbxBYTE: 58 ImpPutByte( &aTmp, p->nByte ); break; 59 case SbxINTEGER: 60 ImpPutInteger( &aTmp, p->nInteger ); break; 61 case SbxBOOL: 62 ImpPutBool( &aTmp, p->nUShort ); break; 63 case SbxUSHORT: 64 ImpPutUShort( &aTmp, p->nUShort ); break; 65 case SbxLONG: 66 ImpPutLong( &aTmp, p->nLong ); break; 67 case SbxULONG: 68 ImpPutULong( &aTmp, p->nULong ); break; 69 case SbxSINGLE: 70 ImpPutSingle( &aTmp, p->nSingle ); break; 71 case SbxDOUBLE: 72 ImpPutDouble( &aTmp, p->nDouble ); break; 73 case SbxCURRENCY: 74 ImpPutCurrency( &aTmp, p->nLong64 ); break; 75 case SbxDECIMAL: 76 case SbxBYREF | SbxDECIMAL: 77 ImpPutDecimal( &aTmp, p->pDecimal ); break; 78 case SbxSALINT64: 79 ImpPutInt64( &aTmp, p->nInt64 ); break; 80 case SbxSALUINT64: 81 ImpPutUInt64( &aTmp, p->uInt64 ); break; 82 case SbxBYREF | SbxSTRING: 83 case SbxSTRING: 84 case SbxLPSTR: 85 if ( p->pOUString ) 86 *aTmp.pOUString = *p->pOUString; 87 break; 88 case SbxOBJECT: 89 { 90 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj); 91 if( pVal ) 92 aRes = pVal->GetString(); 93 else if( p->pObj && p->pObj->IsFixed() 94 && (p->pObj->GetType() == (SbxARRAY | SbxBYTE )) ) 95 { 96 // convert byte array to string 97 SbxArray* pArr = PTR_CAST(SbxArray, p->pObj); 98 if( pArr ) 99 aRes = ByteArrayToString( pArr ); 100 } 101 else 102 SbxBase::SetError( SbxERR_NO_OBJECT ); 103 break; 104 } 105 case SbxERROR: 106 // Hier wird der String "Error n" erzeugt 107 aRes = SbxRes( STRING_ERRORMSG ); 108 aRes += ::rtl::OUString( p->nUShort ); break; 109 case SbxDATE: 110 ImpPutDate( &aTmp, p->nDouble ); break; 111 112 case SbxBYREF | SbxCHAR: 113 ImpPutChar( &aTmp, *p->pChar ); break; 114 case SbxBYREF | SbxBYTE: 115 ImpPutByte( &aTmp, *p->pByte ); break; 116 case SbxBYREF | SbxINTEGER: 117 case SbxBYREF | SbxBOOL: 118 ImpPutInteger( &aTmp, *p->pInteger ); break; 119 case SbxBYREF | SbxLONG: 120 ImpPutLong( &aTmp, *p->pLong ); break; 121 case SbxBYREF | SbxULONG: 122 ImpPutULong( &aTmp, *p->pULong ); break; 123 case SbxBYREF | SbxERROR: 124 case SbxBYREF | SbxUSHORT: 125 ImpPutUShort( &aTmp, *p->pUShort ); break; 126 case SbxBYREF | SbxSINGLE: 127 ImpPutSingle( &aTmp, *p->pSingle ); break; 128 case SbxBYREF | SbxDATE: 129 case SbxBYREF | SbxDOUBLE: 130 ImpPutDouble( &aTmp, *p->pDouble ); break; 131 case SbxBYREF | SbxCURRENCY: 132 ImpPutCurrency( &aTmp, *p->pLong64 ); break; 133 case SbxBYREF | SbxSALINT64: 134 ImpPutInt64( &aTmp, *p->pnInt64 ); break; 135 case SbxBYREF | SbxSALUINT64: 136 ImpPutUInt64( &aTmp, *p->puInt64 ); break; 137 default: 138 SbxBase::SetError( SbxERR_CONVERSION ); 139 } 140 return aRes; 141 } 142 143 // AB 10.4.97, neue Funktion fuer SbxValue::GetCoreString() 144 ::rtl::OUString ImpGetCoreString( const SbxValues* p ) 145 { 146 // Vorerst nur fuer double 147 if( ( p->eType & (~SbxBYREF) ) == SbxDOUBLE ) 148 { 149 SbxValues aTmp; 150 XubString aRes; 151 aTmp.eType = SbxSTRING; 152 if( p->eType == SbxDOUBLE ) 153 ImpPutDouble( &aTmp, p->nDouble, /*bCoreString=*/sal_True ); 154 else 155 ImpPutDouble( &aTmp, *p->pDouble, /*bCoreString=*/sal_True ); 156 return aRes; 157 } 158 else 159 return ImpGetString( p ); 160 } 161 162 void ImpPutString( SbxValues* p, const ::rtl::OUString* n ) 163 { 164 SbxValues aTmp; 165 aTmp.eType = SbxSTRING; 166 ::rtl::OUString* pTmp = NULL; 167 // Sicherheitshalber, falls ein NULL-Ptr kommt 168 if( !n ) 169 n = pTmp = new ::rtl::OUString; 170 aTmp.pOUString = (::rtl::OUString*)n; 171 switch( +p->eType ) 172 { 173 case SbxCHAR: 174 p->nChar = ImpGetChar( &aTmp ); break; 175 case SbxBYTE: 176 p->nByte = ImpGetByte( &aTmp ); break; 177 case SbxINTEGER: 178 case SbxBOOL: 179 p->nInteger = ImpGetInteger( &aTmp ); break; 180 case SbxLONG: 181 p->nLong = ImpGetLong( &aTmp ); break; 182 case SbxULONG: 183 p->nULong = ImpGetULong( &aTmp ); break; 184 case SbxERROR: 185 case SbxUSHORT: 186 p->nUShort = ImpGetUShort( &aTmp ); break; 187 case SbxSINGLE: 188 p->nSingle = ImpGetSingle( &aTmp ); break; 189 case SbxDATE: 190 p->nDouble = ImpGetDate( &aTmp ); break; 191 case SbxDOUBLE: 192 p->nDouble = ImpGetDouble( &aTmp ); break; 193 case SbxULONG64: 194 p->nLong64 = ImpGetCurrency( &aTmp ); break; 195 case SbxDECIMAL: 196 case SbxBYREF | SbxDECIMAL: 197 releaseDecimalPtr( p->pDecimal ); 198 p->pDecimal = ImpGetDecimal( &aTmp ); break; 199 case SbxSALINT64: 200 p->nInt64 = ImpGetInt64( &aTmp ); break; 201 case SbxSALUINT64: 202 p->uInt64 = ImpGetUInt64( &aTmp ); break; 203 204 case SbxBYREF | SbxSTRING: 205 case SbxSTRING: 206 case SbxLPSTR: 207 if( n->getLength() ) 208 { 209 if( !p->pOUString ) 210 p->pOUString = new ::rtl::OUString( *n ); 211 else 212 *p->pOUString = *n; 213 } 214 else 215 delete p->pOUString, p->pOUString = NULL; 216 break; 217 case SbxOBJECT: 218 { 219 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj); 220 if( pVal ) 221 pVal->PutString( *n ); 222 else 223 SbxBase::SetError( SbxERR_NO_OBJECT ); 224 break; 225 } 226 case SbxBYREF | SbxCHAR: 227 *p->pChar = ImpGetChar( p ); break; 228 case SbxBYREF | SbxBYTE: 229 *p->pByte = ImpGetByte( p ); break; 230 case SbxBYREF | SbxINTEGER: 231 *p->pInteger = ImpGetInteger( p ); break; 232 case SbxBYREF | SbxBOOL: 233 *p->pUShort = sal::static_int_cast< sal_uInt16 >( ImpGetBool( p ) ); 234 break; 235 case SbxBYREF | SbxERROR: 236 case SbxBYREF | SbxUSHORT: 237 *p->pUShort = ImpGetUShort( p ); break; 238 case SbxBYREF | SbxLONG: 239 *p->pLong = ImpGetLong( p ); break; 240 case SbxBYREF | SbxULONG: 241 *p->pULong = ImpGetULong( p ); break; 242 case SbxBYREF | SbxSINGLE: 243 *p->pSingle = ImpGetSingle( p ); break; 244 case SbxBYREF | SbxDATE: 245 *p->pDouble = ImpGetDate( p ); break; 246 case SbxBYREF | SbxDOUBLE: 247 *p->pDouble = ImpGetDouble( p ); break; 248 case SbxBYREF | SbxCURRENCY: 249 *p->pLong64 = ImpGetCurrency( p ); break; 250 default: 251 SbxBase::SetError( SbxERR_CONVERSION ); 252 } 253 delete pTmp; 254 } 255 256 // Convert string to an array of bytes, preserving unicode (2bytes per character) 257 SbxArray* StringToByteArray(const ::rtl::OUString& rStr) 258 { 259 sal_Int32 nArraySize = rStr.getLength() * 2; 260 const sal_Unicode* pSrc = rStr.getStr(); 261 SbxDimArray* pArray = new SbxDimArray(SbxBYTE); 262 bool bIncIndex = ( IsBaseIndexOne() && SbiRuntime::isVBAEnabled() ); 263 if( nArraySize ) 264 { 265 if( bIncIndex ) 266 pArray->AddDim32( 1, nArraySize ); 267 else 268 pArray->AddDim32( 0, nArraySize-1 ); 269 } 270 else 271 { 272 pArray->unoAddDim( 0, -1 ); 273 } 274 275 for( sal_uInt16 i=0; i< nArraySize; i++) 276 { 277 SbxVariable* pNew = new SbxVariable( SbxBYTE ); 278 sal_uInt8 aByte = static_cast< sal_uInt8 >( i%2 ? ((*pSrc) >> 8) & 0xff : (*pSrc) & 0xff ); 279 pNew->PutByte( aByte ); 280 pNew->SetFlag( SBX_WRITE ); 281 pArray->Put( pNew, i ); 282 if( i%2 ) 283 pSrc++; 284 } 285 return pArray; 286 } 287 288 // Convert an array of bytes to string (2bytes per character) 289 ::rtl::OUString ByteArrayToString(SbxArray* pArr) 290 { 291 sal_uInt16 nCount = pArr->Count(); 292 OUStringBuffer aStrBuf; 293 sal_Unicode aChar = 0; 294 for( sal_uInt16 i = 0 ; i < nCount ; i++ ) 295 { 296 sal_Unicode aTempChar = pArr->Get(i)->GetByte(); 297 if( i%2 ) 298 { 299 aChar = (aTempChar << 8 ) | aChar; 300 aStrBuf.append(aChar); 301 aChar = 0; 302 } 303 else 304 { 305 aChar = aTempChar; 306 } 307 } 308 309 if( nCount%2 ) 310 { 311 aStrBuf.append(aChar); 312 } 313 314 return aStrBuf.makeStringAndClear(); 315 } 316