LibreOffice Module basic (master) 1
sbxstr.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <config_features.h>
21
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>
28
29// The conversion of an item onto String was handled via the Put-Methods
30// of the several data types to avoid duplicated code.
31
32OUString ImpGetString( const SbxValues* p )
33{
34 SbxValues aTmp;
35 OUString aRes;
36 aTmp.eType = SbxSTRING;
37 aTmp.pOUString = &aRes;
38 switch( +p->eType )
39 {
40 case SbxNULL:
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 )
76 {
77 *aTmp.pOUString = *p->pOUString;
78 }
79 break;
80 case SbxOBJECT:
81 {
82 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
83 if( pVal )
84 {
85 aRes = pVal->GetOUString();
86 }
87 else if( p->pObj && p->pObj->IsFixed()
88 && (p->pObj->GetType() == (SbxARRAY | SbxBYTE )) )
89 {
90 // convert byte array to string
91 SbxArray* pArr = dynamic_cast<SbxArray*>( p->pObj );
92 if( pArr )
93 {
94 aRes = ByteArrayToString( pArr );
95 }
96 }
97 else
98 {
100 }
101 break;
102 }
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;
109
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:
137 }
138 return aRes;
139}
140
141// From 1997-04-10, new function for SbxValue::GetCoreString()
142OUString ImpGetCoreString( const SbxValues* p )
143{
144 // For now only for double
145 if( ( p->eType & (~SbxBYREF) ) == SbxDOUBLE )
146 {
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;
156 }
157 else
158 return ImpGetString( p );
159}
160
161void ImpPutString( SbxValues* p, const OUString* n )
162{
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 )
168 {
169 pTmp.reset(new OUString);
170 n = pTmp.get();
171 }
172 aTmp.pOUString = const_cast<OUString*>(n);
173 switch( +p->eType )
174 {
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;
205
206 case SbxBYREF | SbxSTRING:
207 case SbxSTRING:
208 case SbxLPSTR:
209 if( !n->isEmpty() )
210 {
211 if( !p->pOUString )
212 p->pOUString = new OUString( *n );
213 else
214 *p->pOUString = *n;
215 }
216 else
217 {
218 delete p->pOUString;
219 p->pOUString = nullptr;
220 }
221 break;
222 case SbxOBJECT:
223 {
224 SbxValue* pVal = dynamic_cast<SbxValue*>( p->pObj );
225 if( pVal )
226 pVal->PutString( *n );
227 else
229 break;
230 }
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:
261 }
262}
263
264
265// Convert string to an array of bytes, preserving unicode (2bytes per character)
266SbxArray* StringToByteArray(const OUString& rStr)
267{
268 sal_Int32 nArraySize = rStr.getLength() * 2;
269 const sal_Unicode* pSrc = rStr.getStr();
270 SbxDimArray* pArray = new SbxDimArray(SbxBYTE);
271 if( nArraySize )
272 {
273#if !HAVE_FEATURE_SCRIPTING
274 bool bIncIndex = false;
275#else
276 bool bIncIndex = IsBaseIndexOne();
277#endif
278 if( bIncIndex )
279 pArray->AddDim(1, nArraySize);
280 else
281 pArray->AddDim(0, nArraySize - 1);
282 }
283 else
284 {
285 pArray->unoAddDim(0, -1);
286 }
287
288 for( sal_Int32 i=0; i< nArraySize; i++)
289 {
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 );
294 pArray->Put(pNew, i);
295 if( i%2 )
296 pSrc++;
297 }
298 return pArray;
299}
300
301// Convert an array of bytes to string (2bytes per character)
303{
304 sal_uInt32 nCount = pArr->Count();
305 OUStringBuffer aStrBuf((nCount + 1) / 2);
306 sal_Unicode aChar = 0;
307 for( sal_uInt32 i = 0 ; i < nCount ; i++ )
308 {
309 sal_Unicode aTempChar = pArr->Get(i)->GetByte();
310 if( i%2 )
311 {
312 aChar = (aTempChar << 8 ) | aChar;
313 aStrBuf.append(aChar);
314 aChar = 0;
315 }
316 else
317 {
318 aChar = aTempChar;
319 }
320 }
321
322 if( nCount%2 )
323 {
324 aStrBuf.append(aChar);
325 }
326
327 return aStrBuf.makeStringAndClear();
328}
329
330
331/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Definition: sbx.hxx:95
sal_uInt32 Count() const
Definition: sbxarray.cxx:87
SbxVariable * Get(sal_uInt32)
Definition: sbxarray.cxx:108
static void SetError(ErrCode)
Definition: sbxbase.cxx:116
void SetFlag(SbxFlagBits n)
Definition: sbxcore.hxx:108
void AddDim(sal_Int32, sal_Int32)
Definition: sbxarray.cxx:445
void unoAddDim(sal_Int32, sal_Int32)
Definition: sbxarray.cxx:450
void Put(SbxVariable *, const sal_Int32 *)
Definition: sbxarray.cxx:499
OUString GetOUString() const
Definition: sbxvalue.cxx:380
bool PutString(const OUString &)
Definition: sbxvalue.cxx:585
bool PutByte(sal_uInt8)
sal_uInt8 GetByte() const
Definition: sbxvar.hxx:158
int nCount
void * p
sal_Int64 n
int i
bool IsBaseIndexOne()
#define ERRCODE_BASIC_NO_OBJECT
Definition: sberrors.hxx:34
#define ERRCODE_BASIC_CONVERSION
Definition: sberrors.hxx:30
enum SbxBOOL ImpGetBool(const SbxValues *p)
Definition: sbxbool.cxx:26
void ImpPutBool(SbxValues *p, sal_Int16 n)
Definition: sbxbool.cxx:140
void ImpPutByte(SbxValues *p, sal_uInt8 n)
Definition: sbxbyte.cxx:231
sal_uInt8 ImpGetByte(const SbxValues *p)
Definition: sbxbyte.cxx:31
sal_Unicode ImpGetChar(const SbxValues *p)
Definition: sbxchar.cxx:27
void ImpPutChar(SbxValues *p, sal_Unicode n)
Definition: sbxchar.cxx:212
void ImpPutDecimal(SbxValues *p, SbxDecimal *pDec)
Definition: sbxdec.cxx:512
void ImpPutLong(SbxValues *, sal_Int32)
Definition: sbxlng.cxx:161
void ImpPutInt64(SbxValues *, sal_Int64)
Definition: sbxint.cxx:443
sal_Int16 ImpGetInteger(const SbxValues *)
Definition: sbxint.cxx:30
void ImpPutUInt64(SbxValues *, sal_uInt64)
Definition: sbxint.cxx:696
void ImpPutCurrency(SbxValues *, const sal_Int64)
Definition: sbxcurr.cxx:324
sal_Int64 ImpGetInt64(const SbxValues *)
Definition: sbxint.cxx:327
double ImpGetDouble(const SbxValues *)
Definition: sbxdbl.cxx:27
sal_uInt32 ImpGetULong(const SbxValues *)
Definition: sbxulng.cxx:27
void ImpPutSingle(SbxValues *, float)
Definition: sbxsng.cxx:173
void ImpPutDouble(SbxValues *, double, bool bCoreString=false)
Definition: sbxdbl.cxx:138
sal_uInt64 ImpGetUInt64(const SbxValues *)
Definition: sbxint.cxx:583
void ImpPutInteger(SbxValues *, sal_Int16)
Definition: sbxint.cxx:197
void ImpPutULong(SbxValues *, sal_uInt32)
Definition: sbxulng.cxx:160
sal_uInt16 ImpGetUShort(const SbxValues *)
Definition: sbxuint.cxx:27
double ImpGetDate(const SbxValues *)
Definition: sbxdate.cxx:36
sal_Int32 ImpGetLong(const SbxValues *)
Definition: sbxlng.cxx:29
float ImpGetSingle(const SbxValues *)
Definition: sbxsng.cxx:27
sal_Int64 ImpGetCurrency(const SbxValues *)
Definition: sbxcurr.cxx:159
void ImpPutDate(SbxValues *, double)
Definition: sbxdate.cxx:214
void ImpPutUShort(SbxValues *, sal_uInt16)
Definition: sbxuint.cxx:193
SbxDecimal * ImpGetDecimal(const SbxValues *p)
Definition: sbxdec.cxx:390
void releaseDecimalPtr(SbxDecimal *&rpDecimal)
Definition: sbxdec.cxx:77
SbxBOOL
Definition: sbxdef.hxx:215
@ SbxOBJECT
Definition: sbxdef.hxx:47
@ SbxSALINT64
Definition: sbxdef.hxx:75
@ SbxLONG
Definition: sbxdef.hxx:41
@ SbxARRAY
Definition: sbxdef.hxx:80
@ SbxSALUINT64
Definition: sbxdef.hxx:76
@ SbxNULL
Definition: sbxdef.hxx:39
@ SbxBYTE
Definition: sbxdef.hxx:55
@ SbxEMPTY
Definition: sbxdef.hxx:38
@ SbxDECIMAL
Definition: sbxdef.hxx:77
@ SbxULONG
Definition: sbxdef.hxx:57
@ SbxUSHORT
Definition: sbxdef.hxx:56
@ SbxERROR
Definition: sbxdef.hxx:48
@ SbxDATE
Definition: sbxdef.hxx:45
@ SbxCURRENCY
Definition: sbxdef.hxx:44
@ SbxLPSTR
Definition: sbxdef.hxx:68
@ SbxSINGLE
Definition: sbxdef.hxx:42
@ SbxBYREF
Definition: sbxdef.hxx:81
@ SbxCHAR
Definition: sbxdef.hxx:54
@ SbxSTRING
Definition: sbxdef.hxx:46
@ SbxINTEGER
Definition: sbxdef.hxx:40
@ SbxDOUBLE
Definition: sbxdef.hxx:43
OUString GetSbxRes(StringId nId)
Definition: sbxres.cxx:75
OUString ImpGetCoreString(const SbxValues *p)
Definition: sbxstr.cxx:142
void ImpPutString(SbxValues *p, const OUString *n)
Definition: sbxstr.cxx:161
SbxArray * StringToByteArray(const OUString &rStr)
Definition: sbxstr.cxx:266
OUString ImpGetString(const SbxValues *p)
Definition: sbxstr.cxx:32
OUString ByteArrayToString(SbxArray *pArr)
Definition: sbxstr.cxx:302
OUString * pOUString
Definition: sbxvar.hxx:58
SbxDataType eType
Definition: sbxvar.hxx:77
unsigned char sal_uInt8
sal_uInt16 sal_Unicode