bump product version to 5.0.4.1
[LibreOffice.git] / basic / source / sbx / sbxstr.cxx
blobd6b9f30e663f3547037c354cfec17514054a8941
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 <tools/errcode.hxx>
23 #include <basic/sbx.hxx>
24 #include "sbxconv.hxx"
25 #include "sbxres.hxx"
26 #include "runtime.hxx"
27 #include <rtl/ustrbuf.hxx>
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( SbxERR_CONVERSION );
42 case SbxEMPTY:
43 break;
44 case SbxCHAR:
45 ImpPutChar( &aTmp, p->nChar ); break;
46 case SbxBYTE:
47 ImpPutByte( &aTmp, p->nByte ); break;
48 case SbxINTEGER:
49 ImpPutInteger( &aTmp, p->nInteger ); break;
50 case SbxBOOL:
51 ImpPutBool( &aTmp, p->nUShort ); break;
52 case SbxUSHORT:
53 ImpPutUShort( &aTmp, p->nUShort ); break;
54 case SbxLONG:
55 ImpPutLong( &aTmp, p->nLong ); break;
56 case SbxULONG:
57 ImpPutULong( &aTmp, p->nULong ); break;
58 case SbxSINGLE:
59 ImpPutSingle( &aTmp, p->nSingle ); break;
60 case SbxDOUBLE:
61 ImpPutDouble( &aTmp, p->nDouble ); break;
62 case SbxCURRENCY:
63 ImpPutCurrency( &aTmp, p->nInt64 ); break;
64 case SbxDECIMAL:
65 case SbxBYREF | SbxDECIMAL:
66 ImpPutDecimal( &aTmp, p->pDecimal ); break;
67 case SbxSALINT64:
68 ImpPutInt64( &aTmp, p->nInt64 ); break;
69 case SbxSALUINT64:
70 ImpPutUInt64( &aTmp, p->uInt64 ); break;
71 case SbxBYREF | SbxSTRING:
72 case SbxSTRING:
73 case SbxLPSTR:
74 if ( p->pOUString )
76 *aTmp.pOUString = *p->pOUString;
78 break;
79 case SbxOBJECT:
81 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
82 if( pVal )
84 aRes = pVal->GetOUString();
86 else if( p->pObj && p->pObj->IsFixed()
87 && (p->pObj->GetType() == (SbxARRAY | SbxBYTE )) )
89 // convert byte array to string
90 SbxArray* pArr = PTR_CAST(SbxArray, p->pObj);
91 if( pArr )
93 aRes = ByteArrayToString( pArr );
96 else
98 SbxBase::SetError( SbxERR_NO_OBJECT );
100 break;
102 case SbxERROR:
103 // Here the String "Error n" is generated
104 aRes = SbxRes( STRING_ERRORMSG );
105 aRes += OUString::number(p->nUShort); break;
106 case SbxDATE:
107 ImpPutDate( &aTmp, p->nDouble ); break;
109 case SbxBYREF | SbxCHAR:
110 ImpPutChar( &aTmp, *p->pChar ); break;
111 case SbxBYREF | SbxBYTE:
112 ImpPutByte( &aTmp, *p->pByte ); break;
113 case SbxBYREF | SbxINTEGER:
114 case SbxBYREF | SbxBOOL:
115 ImpPutInteger( &aTmp, *p->pInteger ); break;
116 case SbxBYREF | SbxLONG:
117 ImpPutLong( &aTmp, *p->pLong ); break;
118 case SbxBYREF | SbxULONG:
119 ImpPutULong( &aTmp, *p->pULong ); break;
120 case SbxBYREF | SbxERROR:
121 case SbxBYREF | SbxUSHORT:
122 ImpPutUShort( &aTmp, *p->pUShort ); break;
123 case SbxBYREF | SbxSINGLE:
124 ImpPutSingle( &aTmp, *p->pSingle ); break;
125 case SbxBYREF | SbxDATE:
126 case SbxBYREF | SbxDOUBLE:
127 ImpPutDouble( &aTmp, *p->pDouble ); break;
128 case SbxBYREF | SbxCURRENCY:
129 ImpPutCurrency( &aTmp, *p->pnInt64 ); break;
130 case SbxBYREF | SbxSALINT64:
131 ImpPutInt64( &aTmp, *p->pnInt64 ); break;
132 case SbxBYREF | SbxSALUINT64:
133 ImpPutUInt64( &aTmp, *p->puInt64 ); break;
134 default:
135 SbxBase::SetError( SbxERR_CONVERSION );
137 return aRes;
140 // From 1997-04-10, new function for SbxValue::GetCoreString()
141 OUString ImpGetCoreString( const SbxValues* p )
143 // For now only for double
144 if( ( p->eType & (~SbxBYREF) ) == SbxDOUBLE )
146 SbxValues aTmp;
147 OUString aRes;
148 aTmp.eType = SbxSTRING;
149 aTmp.pOUString = &aRes;
150 if( p->eType == SbxDOUBLE )
151 ImpPutDouble( &aTmp, p->nDouble, true ); // true = bCoreString
152 else
153 ImpPutDouble( &aTmp, *p->pDouble, true ); // true = bCoreString
154 return aRes;
156 else
157 return ImpGetString( p );
160 void ImpPutString( SbxValues* p, const OUString* n )
162 SbxValues aTmp;
163 aTmp.eType = SbxSTRING;
164 OUString* pTmp = NULL;
165 // as a precaution, if a NULL-Ptr appears
166 if( !n )
167 n = pTmp = new OUString;
168 aTmp.pOUString = const_cast<OUString*>(n);
169 switch( +p->eType )
171 case SbxCHAR:
172 p->nChar = ImpGetChar( &aTmp ); break;
173 case SbxBYTE:
174 p->nByte = ImpGetByte( &aTmp ); break;
175 case SbxINTEGER:
176 case SbxBOOL:
177 p->nInteger = ImpGetInteger( &aTmp ); break;
178 case SbxLONG:
179 p->nLong = ImpGetLong( &aTmp ); break;
180 case SbxULONG:
181 p->nULong = ImpGetULong( &aTmp ); break;
182 case SbxERROR:
183 case SbxUSHORT:
184 p->nUShort = ImpGetUShort( &aTmp ); break;
185 case SbxSINGLE:
186 p->nSingle = ImpGetSingle( &aTmp ); break;
187 case SbxDATE:
188 p->nDouble = ImpGetDate( &aTmp ); break;
189 case SbxDOUBLE:
190 p->nDouble = ImpGetDouble( &aTmp ); break;
191 case SbxCURRENCY:
192 p->nInt64 = ImpGetCurrency( &aTmp ); break;
193 case SbxDECIMAL:
194 case SbxBYREF | SbxDECIMAL:
195 releaseDecimalPtr( p->pDecimal );
196 p->pDecimal = ImpGetDecimal( &aTmp ); break;
197 case SbxSALINT64:
198 p->nInt64 = ImpGetInt64( &aTmp ); break;
199 case SbxSALUINT64:
200 p->uInt64 = ImpGetUInt64( &aTmp ); break;
202 case SbxBYREF | SbxSTRING:
203 case SbxSTRING:
204 case SbxLPSTR:
205 if( !n->isEmpty() )
207 if( !p->pOUString )
208 p->pOUString = new OUString( *n );
209 else
210 *p->pOUString = *n;
212 else
213 delete p->pOUString, p->pOUString = NULL;
214 break;
215 case SbxOBJECT:
217 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
218 if( pVal )
219 pVal->PutString( *n );
220 else
221 SbxBase::SetError( SbxERR_NO_OBJECT );
222 break;
224 case SbxBYREF | SbxCHAR:
225 *p->pChar = ImpGetChar( p ); break;
226 case SbxBYREF | SbxBYTE:
227 *p->pByte = ImpGetByte( p ); break;
228 case SbxBYREF | SbxINTEGER:
229 *p->pInteger = ImpGetInteger( p ); break;
230 case SbxBYREF | SbxBOOL:
231 *p->pUShort = sal::static_int_cast< sal_uInt16 >( ImpGetBool( p ) );
232 break;
233 case SbxBYREF | SbxERROR:
234 case SbxBYREF | SbxUSHORT:
235 *p->pUShort = ImpGetUShort( p ); break;
236 case SbxBYREF | SbxLONG:
237 *p->pLong = ImpGetLong( p ); break;
238 case SbxBYREF | SbxULONG:
239 *p->pULong = ImpGetULong( p ); break;
240 case SbxBYREF | SbxSINGLE:
241 *p->pSingle = ImpGetSingle( p ); break;
242 case SbxBYREF | SbxDATE:
243 *p->pDouble = ImpGetDate( p ); break;
244 case SbxBYREF | SbxDOUBLE:
245 *p->pDouble = ImpGetDouble( p ); break;
246 case SbxBYREF | SbxCURRENCY:
247 *p->pnInt64 = ImpGetCurrency( p ); break;
248 case SbxBYREF | SbxSALINT64:
249 *p->pnInt64 = ImpGetInt64( p ); break;
250 case SbxBYREF | SbxSALUINT64:
251 *p->puInt64 = ImpGetUInt64( p ); break;
252 default:
253 SbxBase::SetError( SbxERR_CONVERSION );
255 delete pTmp;
259 // Convert string to an array of bytes, preserving unicode (2bytes per character)
260 SbxArray* StringToByteArray(const OUString& rStr)
262 sal_Int32 nArraySize = rStr.getLength() * 2;
263 const sal_Unicode* pSrc = rStr.getStr();
264 SbxDimArray* pArray = new SbxDimArray(SbxBYTE);
265 if( nArraySize )
267 #if !HAVE_FEATURE_SCRIPTING
268 bool bIncIndex = false;
269 #else
270 bool bIncIndex = ( IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
271 #endif
272 if( bIncIndex )
273 pArray->AddDim32( 1, nArraySize );
274 else
275 pArray->AddDim32( 0, nArraySize-1 );
277 else
279 pArray->unoAddDim( 0, -1 );
282 for( sal_uInt16 i=0; i< nArraySize; i++)
284 SbxVariable* pNew = new SbxVariable( SbxBYTE );
285 sal_uInt8 aByte = static_cast< sal_uInt8 >( (i%2) ? ((*pSrc) >> 8) & 0xff : (*pSrc) & 0xff );
286 pNew->PutByte( aByte );
287 pNew->SetFlag( SBX_WRITE );
288 pArray->Put( pNew, i );
289 if( i%2 )
290 pSrc++;
292 return pArray;
295 // Convert an array of bytes to string (2bytes per character)
296 OUString ByteArrayToString(SbxArray* pArr)
298 sal_uInt16 nCount = pArr->Count();
299 OUStringBuffer aStrBuf;
300 sal_Unicode aChar = 0;
301 for( sal_uInt16 i = 0 ; i < nCount ; i++ )
303 sal_Unicode aTempChar = pArr->Get(i)->GetByte();
304 if( i%2 )
306 aChar = (aTempChar << 8 ) | aChar;
307 aStrBuf.append(aChar);
308 aChar = 0;
310 else
312 aChar = aTempChar;
316 if( nCount%2 )
318 aStrBuf.append(aChar);
321 return aStrBuf.makeStringAndClear();
325 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */