1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
25 #include <runtime.hxx>
26 #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
)
36 aTmp
.eType
= SbxSTRING
;
37 aTmp
.pOUString
= &aRes
;
41 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
);
46 ImpPutChar( &aTmp
, p
->nChar
); break;
48 ImpPutByte( &aTmp
, p
->nByte
); break;
50 ImpPutInteger( &aTmp
, p
->nInteger
); break;
52 ImpPutBool( &aTmp
, p
->nUShort
); break;
54 ImpPutUShort( &aTmp
, p
->nUShort
); break;
56 ImpPutLong( &aTmp
, p
->nLong
); break;
58 ImpPutULong( &aTmp
, p
->nULong
); break;
60 ImpPutSingle( &aTmp
, p
->nSingle
); break;
62 ImpPutDouble( &aTmp
, p
->nDouble
); break;
64 ImpPutCurrency( &aTmp
, p
->nInt64
); break;
66 case SbxBYREF
| SbxDECIMAL
:
67 ImpPutDecimal( &aTmp
, p
->pDecimal
); break;
69 ImpPutInt64( &aTmp
, p
->nInt64
); break;
71 ImpPutUInt64( &aTmp
, p
->uInt64
); break;
72 case SbxBYREF
| SbxSTRING
:
77 *aTmp
.pOUString
= *p
->pOUString
;
82 SbxValue
* pVal
= dynamic_cast<SbxValue
*>( p
->pObj
);
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
);
94 aRes
= ByteArrayToString( pArr
);
99 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT
);
104 // Here the String "Error n" is generated
105 aRes
= GetSbxRes( StringId::ErrorMsg
) + OUString::number(p
->nUShort
);
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;
136 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
);
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
)
149 aTmp
.eType
= SbxSTRING
;
150 aTmp
.pOUString
= &aRes
;
151 if( p
->eType
== SbxDOUBLE
)
152 ImpPutDouble( &aTmp
, p
->nDouble
, true ); // true = bCoreString
154 ImpPutDouble( &aTmp
, *p
->pDouble
, true ); // true = bCoreString
158 return ImpGetString( p
);
161 void ImpPutString( SbxValues
* p
, const OUString
* n
)
164 aTmp
.eType
= SbxSTRING
;
165 std::unique_ptr
<OUString
> pTmp
;
166 // as a precaution, if a NULL-Ptr appears
169 pTmp
.reset(new OUString
);
172 aTmp
.pOUString
= const_cast<OUString
*>(n
);
176 p
->nChar
= ImpGetChar( &aTmp
); break;
178 p
->nByte
= ImpGetByte( &aTmp
); break;
181 p
->nInteger
= ImpGetInteger( &aTmp
); break;
183 p
->nLong
= ImpGetLong( &aTmp
); break;
185 p
->nULong
= ImpGetULong( &aTmp
); break;
188 p
->nUShort
= ImpGetUShort( &aTmp
); break;
190 p
->nSingle
= ImpGetSingle( &aTmp
); break;
192 p
->nDouble
= ImpGetDate( &aTmp
); break;
194 p
->nDouble
= ImpGetDouble( &aTmp
); break;
196 p
->nInt64
= ImpGetCurrency( &aTmp
); break;
198 case SbxBYREF
| SbxDECIMAL
:
199 releaseDecimalPtr( p
->pDecimal
);
200 p
->pDecimal
= ImpGetDecimal( &aTmp
); break;
202 p
->nInt64
= ImpGetInt64( &aTmp
); break;
204 p
->uInt64
= ImpGetUInt64( &aTmp
); break;
206 case SbxBYREF
| SbxSTRING
:
212 p
->pOUString
= new OUString( *n
);
219 p
->pOUString
= nullptr;
224 SbxValue
* pVal
= dynamic_cast<SbxValue
*>( p
->pObj
);
226 pVal
->PutString( *n
);
228 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT
);
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
) );
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;
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
);
273 #if !HAVE_FEATURE_SCRIPTING
274 bool bIncIndex
= false;
276 bool bIncIndex
= ( IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
279 pArray
->AddDim32( 1, nArraySize
);
281 pArray
->AddDim32( 0, nArraySize
-1 );
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
);
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();
312 aChar
= (aTempChar
<< 8 ) | aChar
;
313 aStrBuf
.append(aChar
);
324 aStrBuf
.append(aChar
);
327 return aStrBuf
.makeStringAndClear();
331 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */