Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / basic / source / sbx / sbxstr.cxx
blob65fdb906daf94de7cd390bcca7ec240fddebbe6f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
22 #include <basic/sbx.hxx>
23 #include "sbxconv.hxx"
24 #include "sbxres.hxx"
25 #include <runtime.hxx>
26 #include <rtl/ustrbuf.hxx>
27 #include <memory>
29 // The conversion of an item onto String was handled via the Put-Methods
30 // of the several data types to avoid duplicated code.
32 OUString ImpGetString( const SbxValues* p )
34 SbxValues aTmp;
35 OUString aRes;
36 aTmp.eType = SbxSTRING;
37 aTmp.pOUString = &aRes;
38 switch( +p->eType )
40 case SbxNULL:
41 SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
42 [[fallthrough]];
43 case SbxEMPTY:
44 break;
45 case SbxCHAR:
46 ImpPutChar( &aTmp, p->nChar ); break;
47 case SbxBYTE:
48 ImpPutByte( &aTmp, p->nByte ); break;
49 case SbxINTEGER:
50 ImpPutInteger( &aTmp, p->nInteger ); break;
51 case SbxBOOL:
52 ImpPutBool( &aTmp, p->nUShort ); break;
53 case SbxUSHORT:
54 ImpPutUShort( &aTmp, p->nUShort ); break;
55 case SbxLONG:
56 ImpPutLong( &aTmp, p->nLong ); break;
57 case SbxULONG:
58 ImpPutULong( &aTmp, p->nULong ); break;
59 case SbxSINGLE:
60 ImpPutSingle( &aTmp, p->nSingle ); break;
61 case SbxDOUBLE:
62 ImpPutDouble( &aTmp, p->nDouble ); break;
63 case SbxCURRENCY:
64 ImpPutCurrency( &aTmp, p->nInt64 ); break;
65 case SbxDECIMAL:
66 case SbxBYREF | SbxDECIMAL:
67 ImpPutDecimal( &aTmp, p->pDecimal ); break;
68 case SbxSALINT64:
69 ImpPutInt64( &aTmp, p->nInt64 ); break;
70 case SbxSALUINT64:
71 ImpPutUInt64( &aTmp, p->uInt64 ); break;
72 case SbxBYREF | SbxSTRING:
73 case SbxSTRING:
74 case SbxLPSTR:
75 if ( p->pOUString )
77 *aTmp.pOUString = *p->pOUString;
79 break;
80 case SbxOBJECT:
82 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
83 if( pVal )
85 aRes = pVal->GetOUString();
87 else if( p->pObj && p->pObj->IsFixed()
88 && (p->pObj->GetType() == (SbxARRAY | SbxBYTE )) )
90 // convert byte array to string
91 SbxArray* pArr = dynamic_cast<SbxArray*>( p->pObj );
92 if( pArr )
94 aRes = ByteArrayToString( pArr );
97 else
99 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
101 break;
103 case SbxERROR:
104 // Here the String "Error n" is generated
105 aRes = GetSbxRes( StringId::ErrorMsg ) + OUString::number(p->nUShort);
106 break;
107 case SbxDATE:
108 ImpPutDate( &aTmp, p->nDouble ); break;
110 case SbxBYREF | SbxCHAR:
111 ImpPutChar( &aTmp, *p->pChar ); break;
112 case SbxBYREF | SbxBYTE:
113 ImpPutByte( &aTmp, *p->pByte ); break;
114 case SbxBYREF | SbxINTEGER:
115 case SbxBYREF | SbxBOOL:
116 ImpPutInteger( &aTmp, *p->pInteger ); break;
117 case SbxBYREF | SbxLONG:
118 ImpPutLong( &aTmp, *p->pLong ); break;
119 case SbxBYREF | SbxULONG:
120 ImpPutULong( &aTmp, *p->pULong ); break;
121 case SbxBYREF | SbxERROR:
122 case SbxBYREF | SbxUSHORT:
123 ImpPutUShort( &aTmp, *p->pUShort ); break;
124 case SbxBYREF | SbxSINGLE:
125 ImpPutSingle( &aTmp, *p->pSingle ); break;
126 case SbxBYREF | SbxDATE:
127 case SbxBYREF | SbxDOUBLE:
128 ImpPutDouble( &aTmp, *p->pDouble ); break;
129 case SbxBYREF | SbxCURRENCY:
130 ImpPutCurrency( &aTmp, *p->pnInt64 ); break;
131 case SbxBYREF | SbxSALINT64:
132 ImpPutInt64( &aTmp, *p->pnInt64 ); break;
133 case SbxBYREF | SbxSALUINT64:
134 ImpPutUInt64( &aTmp, *p->puInt64 ); break;
135 default:
136 SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
138 return aRes;
141 // From 1997-04-10, new function for SbxValue::GetCoreString()
142 OUString ImpGetCoreString( const SbxValues* p )
144 // For now only for double
145 if( ( p->eType & (~SbxBYREF) ) == SbxDOUBLE )
147 SbxValues aTmp;
148 OUString aRes;
149 aTmp.eType = SbxSTRING;
150 aTmp.pOUString = &aRes;
151 if( p->eType == SbxDOUBLE )
152 ImpPutDouble( &aTmp, p->nDouble, true ); // true = bCoreString
153 else
154 ImpPutDouble( &aTmp, *p->pDouble, true ); // true = bCoreString
155 return aRes;
157 else
158 return ImpGetString( p );
161 void ImpPutString( SbxValues* p, const OUString* n )
163 SbxValues aTmp;
164 aTmp.eType = SbxSTRING;
165 std::unique_ptr<OUString> pTmp;
166 // as a precaution, if a NULL-Ptr appears
167 if( !n )
169 pTmp.reset(new OUString);
170 n = pTmp.get();
172 aTmp.pOUString = const_cast<OUString*>(n);
173 switch( +p->eType )
175 case SbxCHAR:
176 p->nChar = ImpGetChar( &aTmp ); break;
177 case SbxBYTE:
178 p->nByte = ImpGetByte( &aTmp ); break;
179 case SbxINTEGER:
180 case SbxBOOL:
181 p->nInteger = ImpGetInteger( &aTmp ); break;
182 case SbxLONG:
183 p->nLong = ImpGetLong( &aTmp ); break;
184 case SbxULONG:
185 p->nULong = ImpGetULong( &aTmp ); break;
186 case SbxERROR:
187 case SbxUSHORT:
188 p->nUShort = ImpGetUShort( &aTmp ); break;
189 case SbxSINGLE:
190 p->nSingle = ImpGetSingle( &aTmp ); break;
191 case SbxDATE:
192 p->nDouble = ImpGetDate( &aTmp ); break;
193 case SbxDOUBLE:
194 p->nDouble = ImpGetDouble( &aTmp ); break;
195 case SbxCURRENCY:
196 p->nInt64 = ImpGetCurrency( &aTmp ); break;
197 case SbxDECIMAL:
198 case SbxBYREF | SbxDECIMAL:
199 releaseDecimalPtr( p->pDecimal );
200 p->pDecimal = ImpGetDecimal( &aTmp ); break;
201 case SbxSALINT64:
202 p->nInt64 = ImpGetInt64( &aTmp ); break;
203 case SbxSALUINT64:
204 p->uInt64 = ImpGetUInt64( &aTmp ); break;
206 case SbxBYREF | SbxSTRING:
207 case SbxSTRING:
208 case SbxLPSTR:
209 if( !n->isEmpty() )
211 if( !p->pOUString )
212 p->pOUString = new OUString( *n );
213 else
214 *p->pOUString = *n;
216 else
218 delete p->pOUString;
219 p->pOUString = nullptr;
221 break;
222 case SbxOBJECT:
224 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
225 if( pVal )
226 pVal->PutString( *n );
227 else
228 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
229 break;
231 case SbxBYREF | SbxCHAR:
232 *p->pChar = ImpGetChar( p ); break;
233 case SbxBYREF | SbxBYTE:
234 *p->pByte = ImpGetByte( p ); break;
235 case SbxBYREF | SbxINTEGER:
236 *p->pInteger = ImpGetInteger( p ); break;
237 case SbxBYREF | SbxBOOL:
238 *p->pUShort = sal::static_int_cast< sal_uInt16 >( ImpGetBool( p ) );
239 break;
240 case SbxBYREF | SbxERROR:
241 case SbxBYREF | SbxUSHORT:
242 *p->pUShort = ImpGetUShort( p ); break;
243 case SbxBYREF | SbxLONG:
244 *p->pLong = ImpGetLong( p ); break;
245 case SbxBYREF | SbxULONG:
246 *p->pULong = ImpGetULong( p ); break;
247 case SbxBYREF | SbxSINGLE:
248 *p->pSingle = ImpGetSingle( p ); break;
249 case SbxBYREF | SbxDATE:
250 *p->pDouble = ImpGetDate( p ); break;
251 case SbxBYREF | SbxDOUBLE:
252 *p->pDouble = ImpGetDouble( p ); break;
253 case SbxBYREF | SbxCURRENCY:
254 *p->pnInt64 = ImpGetCurrency( p ); break;
255 case SbxBYREF | SbxSALINT64:
256 *p->pnInt64 = ImpGetInt64( p ); break;
257 case SbxBYREF | SbxSALUINT64:
258 *p->puInt64 = ImpGetUInt64( p ); break;
259 default:
260 SbxBase::SetError( ERRCODE_BASIC_CONVERSION );
265 // Convert string to an array of bytes, preserving unicode (2bytes per character)
266 SbxArray* StringToByteArray(const OUString& rStr)
268 sal_Int32 nArraySize = rStr.getLength() * 2;
269 const sal_Unicode* pSrc = rStr.getStr();
270 SbxDimArray* pArray = new SbxDimArray(SbxBYTE);
271 if( nArraySize )
273 #if !HAVE_FEATURE_SCRIPTING
274 bool bIncIndex = false;
275 #else
276 bool bIncIndex = ( IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
277 #endif
278 if( bIncIndex )
279 pArray->AddDim32( 1, nArraySize );
280 else
281 pArray->AddDim32( 0, nArraySize-1 );
283 else
285 pArray->unoAddDim( 0, -1 );
288 for( sal_Int32 i=0; i< nArraySize; i++)
290 SbxVariable* pNew = new SbxVariable( SbxBYTE );
291 sal_uInt8 aByte = static_cast< sal_uInt8 >( (i%2) ? ((*pSrc) >> 8) & 0xff : (*pSrc) & 0xff );
292 pNew->PutByte( aByte );
293 pNew->SetFlag( SbxFlagBits::Write );
294 pArray->Put( pNew, i );
295 if( i%2 )
296 pSrc++;
298 return pArray;
301 // Convert an array of bytes to string (2bytes per character)
302 OUString ByteArrayToString(SbxArray* pArr)
304 sal_uInt16 nCount = pArr->Count();
305 OUStringBuffer aStrBuf;
306 sal_Unicode aChar = 0;
307 for( sal_uInt16 i = 0 ; i < nCount ; i++ )
309 sal_Unicode aTempChar = pArr->Get(i)->GetByte();
310 if( i%2 )
312 aChar = (aTempChar << 8 ) | aChar;
313 aStrBuf.append(aChar);
314 aChar = 0;
316 else
318 aChar = aTempChar;
322 if( nCount%2 )
324 aStrBuf.append(aChar);
327 return aStrBuf.makeStringAndClear();
331 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */