1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sbxstr.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basic.hxx"
33 #include <tools/errcode.hxx>
34 #include <basic/sbx.hxx>
35 #include "sbxconv.hxx"
37 #include "runtime.hxx"
38 #ifndef _RTL_USTRBUF_HXX_
39 #include <rtl/ustrbuf.hxx>
41 // AB 29.10.99 Unicode
42 #ifndef _USE_NO_NAMESPACE
47 // Die Konversion eines Items auf String wird ueber die Put-Methoden
48 // der einzelnen Datentypen abgewickelt, um doppelten Code zu vermeiden.
50 XubString
ImpGetString( const SbxValues
* p
)
54 aTmp
.eType
= SbxSTRING
;
59 SbxBase::SetError( SbxERR_CONVERSION
);
63 ImpPutChar( &aTmp
, p
->nChar
); break;
65 ImpPutByte( &aTmp
, p
->nByte
); break;
67 ImpPutInteger( &aTmp
, p
->nInteger
); break;
69 ImpPutBool( &aTmp
, p
->nUShort
); break;
71 ImpPutUShort( &aTmp
, p
->nUShort
); break;
73 ImpPutLong( &aTmp
, p
->nLong
); break;
75 ImpPutULong( &aTmp
, p
->nULong
); break;
77 ImpPutSingle( &aTmp
, p
->nSingle
); break;
79 ImpPutDouble( &aTmp
, p
->nDouble
); break;
81 ImpPutCurrency( &aTmp
, p
->nLong64
); break;
83 case SbxBYREF
| SbxDECIMAL
:
84 ImpPutDecimal( &aTmp
, p
->pDecimal
); break;
86 ImpPutInt64( &aTmp
, p
->nInt64
); break;
88 ImpPutUInt64( &aTmp
, p
->uInt64
); break;
89 case SbxBYREF
| SbxSTRING
:
97 SbxValue
* pVal
= PTR_CAST(SbxValue
,p
->pObj
);
99 aRes
= pVal
->GetString();
100 else if( p
->pObj
&& p
->pObj
->IsFixed()
101 && (p
->pObj
->GetType() == (SbxARRAY
| SbxBYTE
)) )
103 // convert byte array to string
104 SbxArray
* pArr
= PTR_CAST(SbxArray
, p
->pObj
);
106 aRes
= ByteArrayToString( pArr
);
109 SbxBase::SetError( SbxERR_NO_OBJECT
);
113 // Hier wird der String "Error n" erzeugt
114 aRes
= SbxRes( STRING_ERRORMSG
);
115 aRes
+= p
->nUShort
; break;
117 ImpPutDate( &aTmp
, p
->nDouble
); break;
119 case SbxBYREF
| SbxCHAR
:
120 ImpPutChar( &aTmp
, *p
->pChar
); break;
121 case SbxBYREF
| SbxBYTE
:
122 ImpPutByte( &aTmp
, *p
->pByte
); break;
123 case SbxBYREF
| SbxINTEGER
:
124 case SbxBYREF
| SbxBOOL
:
125 ImpPutInteger( &aTmp
, *p
->pInteger
); break;
126 case SbxBYREF
| SbxLONG
:
127 ImpPutLong( &aTmp
, *p
->pLong
); break;
128 case SbxBYREF
| SbxULONG
:
129 ImpPutULong( &aTmp
, *p
->pULong
); break;
130 case SbxBYREF
| SbxERROR
:
131 case SbxBYREF
| SbxUSHORT
:
132 ImpPutUShort( &aTmp
, *p
->pUShort
); break;
133 case SbxBYREF
| SbxSINGLE
:
134 ImpPutSingle( &aTmp
, *p
->pSingle
); break;
135 case SbxBYREF
| SbxDATE
:
136 case SbxBYREF
| SbxDOUBLE
:
137 ImpPutDouble( &aTmp
, *p
->pDouble
); break;
138 case SbxBYREF
| SbxCURRENCY
:
139 ImpPutCurrency( &aTmp
, *p
->pLong64
); break;
140 case SbxBYREF
| SbxSALINT64
:
141 ImpPutInt64( &aTmp
, *p
->pnInt64
); break;
142 case SbxBYREF
| SbxSALUINT64
:
143 ImpPutUInt64( &aTmp
, *p
->puInt64
); break;
145 SbxBase::SetError( SbxERR_CONVERSION
);
150 // AB 10.4.97, neue Funktion fuer SbxValue::GetCoreString()
151 XubString
ImpGetCoreString( const SbxValues
* p
)
153 // Vorerst nur fuer double
154 if( ( p
->eType
& (~SbxBYREF
) ) == SbxDOUBLE
)
158 aTmp
.eType
= SbxSTRING
;
159 aTmp
.pString
= &aRes
;
160 if( p
->eType
== SbxDOUBLE
)
161 ImpPutDouble( &aTmp
, p
->nDouble
, /*bCoreString=*/TRUE
);
163 ImpPutDouble( &aTmp
, *p
->pDouble
, /*bCoreString=*/TRUE
);
167 return ImpGetString( p
);
170 void ImpPutString( SbxValues
* p
, const XubString
* n
)
173 aTmp
.eType
= SbxSTRING
;
174 XubString
* pTmp
= NULL
;
175 // Sicherheitshalber, falls ein NULL-Ptr kommt
177 n
= pTmp
= new XubString
;
178 aTmp
.pString
= (XubString
*) n
;
182 p
->nChar
= ImpGetChar( &aTmp
); break;
184 p
->nByte
= ImpGetByte( &aTmp
); break;
187 p
->nInteger
= ImpGetInteger( &aTmp
); break;
189 p
->nLong
= ImpGetLong( &aTmp
); break;
191 p
->nULong
= ImpGetULong( &aTmp
); break;
194 p
->nUShort
= ImpGetUShort( &aTmp
); break;
196 p
->nSingle
= ImpGetSingle( &aTmp
); break;
198 p
->nDouble
= ImpGetDate( &aTmp
); break;
200 p
->nDouble
= ImpGetDouble( &aTmp
); break;
202 p
->nLong64
= ImpGetCurrency( &aTmp
); break;
204 case SbxBYREF
| SbxDECIMAL
:
205 releaseDecimalPtr( p
->pDecimal
);
206 p
->pDecimal
= ImpGetDecimal( &aTmp
); break;
208 p
->nInt64
= ImpGetInt64( &aTmp
); break;
210 p
->uInt64
= ImpGetUInt64( &aTmp
); break;
212 case SbxBYREF
| SbxSTRING
:
218 p
->pString
= new XubString
;
222 delete p
->pString
, p
->pString
= NULL
;
226 SbxValue
* pVal
= PTR_CAST(SbxValue
,p
->pObj
);
228 pVal
->PutString( *n
);
230 SbxBase::SetError( SbxERR_NO_OBJECT
);
233 case SbxBYREF
| SbxCHAR
:
234 *p
->pChar
= ImpGetChar( p
); break;
235 case SbxBYREF
| SbxBYTE
:
236 *p
->pByte
= ImpGetByte( p
); break;
237 case SbxBYREF
| SbxINTEGER
:
238 *p
->pInteger
= ImpGetInteger( p
); break;
239 case SbxBYREF
| SbxBOOL
:
240 *p
->pUShort
= sal::static_int_cast
< UINT16
>( ImpGetBool( p
) );
242 case SbxBYREF
| SbxERROR
:
243 case SbxBYREF
| SbxUSHORT
:
244 *p
->pUShort
= ImpGetUShort( p
); break;
245 case SbxBYREF
| SbxLONG
:
246 *p
->pLong
= ImpGetLong( p
); break;
247 case SbxBYREF
| SbxULONG
:
248 *p
->pULong
= ImpGetULong( p
); break;
249 case SbxBYREF
| SbxSINGLE
:
250 *p
->pSingle
= ImpGetSingle( p
); break;
251 case SbxBYREF
| SbxDATE
:
252 *p
->pDouble
= ImpGetDate( p
); break;
253 case SbxBYREF
| SbxDOUBLE
:
254 *p
->pDouble
= ImpGetDouble( p
); break;
255 case SbxBYREF
| SbxCURRENCY
:
256 *p
->pLong64
= ImpGetCurrency( p
); break;
258 SbxBase::SetError( SbxERR_CONVERSION
);
263 // Convert string to an array of bytes, preserving unicode (2bytes per character)
264 SbxArray
* StringToByteArray(const String
& rStr
)
266 USHORT nArraySize
= rStr
.Len() * 2;
267 const sal_Unicode
* pSrc
= rStr
.GetBuffer();
268 SbxDimArray
* pArray
= new SbxDimArray(SbxBYTE
);
269 bool bIncIndex
= ( IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
273 pArray
->AddDim( 1, nArraySize
);
275 pArray
->AddDim( 0, nArraySize
-1 );
279 pArray
->unoAddDim( 0, -1 );
282 for( USHORT i
=0; i
< nArraySize
; i
++)
284 SbxVariable
* pNew
= new SbxVariable( SbxBYTE
);
285 BYTE aByte
= static_cast< BYTE
>( i
%2 ? ((*pSrc
) >> 8) & 0xff : (*pSrc
) & 0xff );
286 pNew
->PutByte( aByte
);
287 pNew
->SetFlag( SBX_WRITE
);
288 pArray
->Put( pNew
, i
);
295 // Convert an array of bytes to string (2bytes per character)
296 String
ByteArrayToString(SbxArray
* pArr
)
298 USHORT nCount
= pArr
->Count();
299 OUStringBuffer aStrBuf
;
300 sal_Unicode aChar
= 0;
301 for( USHORT i
= 0 ; i
< nCount
; i
++ )
303 sal_Unicode aTempChar
= pArr
->Get(i
)->GetByte();
306 aChar
= (aTempChar
<< 8 ) | aChar
;
307 aStrBuf
.append(aChar
);
318 aStrBuf
.append(aChar
);
321 String
aStr(aStrBuf
.makeStringAndClear());