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