xref: /aoo41x/main/basic/source/sbx/sbxstr.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basic.hxx"
30 #include <tools/errcode.hxx>
31 #include <basic/sbx.hxx>
32 #include "sbxconv.hxx"
33 #include "sbxres.hxx"
34 #include "runtime.hxx"
35 #ifndef _RTL_USTRBUF_HXX_
36 #include <rtl/ustrbuf.hxx>
37 #endif
38 // AB 29.10.99 Unicode
39 #ifndef _USE_NO_NAMESPACE
40 using namespace rtl;
41 #endif
42 
43 
44 // Die Konversion eines Items auf String wird ueber die Put-Methoden
45 // der einzelnen Datentypen abgewickelt, um doppelten Code zu vermeiden.
46 
47 ::rtl::OUString ImpGetString( const SbxValues* p )
48 {
49 	SbxValues aTmp;
50     ::rtl::OUString aRes;
51 	aTmp.eType = SbxSTRING;
52     aTmp.pOUString = &aRes;
53 	switch( +p->eType )
54 	{
55 		case SbxNULL:
56 			SbxBase::SetError( SbxERR_CONVERSION );
57 		case SbxEMPTY:
58 			break;
59 		case SbxCHAR:
60 			ImpPutChar( &aTmp, p->nChar ); break;
61 		case SbxBYTE:
62 			ImpPutByte( &aTmp, p->nByte ); break;
63 		case SbxINTEGER:
64 			ImpPutInteger( &aTmp, p->nInteger ); break;
65 		case SbxBOOL:
66 			ImpPutBool( &aTmp, p->nUShort ); break;
67 		case SbxUSHORT:
68 			ImpPutUShort( &aTmp, p->nUShort ); break;
69 		case SbxLONG:
70 			ImpPutLong( &aTmp, p->nLong ); break;
71 		case SbxULONG:
72 			ImpPutULong( &aTmp, p->nULong ); break;
73 		case SbxSINGLE:
74 			ImpPutSingle( &aTmp, p->nSingle ); break;
75 		case SbxDOUBLE:
76 			ImpPutDouble( &aTmp, p->nDouble ); break;
77 		case SbxCURRENCY:
78 			ImpPutCurrency( &aTmp, p->nLong64 ); break;
79 		case SbxDECIMAL:
80 		case SbxBYREF | SbxDECIMAL:
81 			ImpPutDecimal( &aTmp, p->pDecimal ); break;
82 		case SbxSALINT64:
83 			ImpPutInt64( &aTmp, p->nInt64 ); break;
84 		case SbxSALUINT64:
85 			ImpPutUInt64( &aTmp, p->uInt64 ); break;
86 		case SbxBYREF | SbxSTRING:
87 		case SbxSTRING:
88 		case SbxLPSTR:
89             if ( p->pOUString )
90                 *aTmp.pOUString = *p->pOUString;
91 			break;
92 		case SbxOBJECT:
93 		{
94 			SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
95 			if( pVal )
96 				aRes = pVal->GetString();
97 			else if( p->pObj && p->pObj->IsFixed()
98 					&& (p->pObj->GetType() == (SbxARRAY | SbxBYTE )) )
99 			{
100 				// convert byte array to string
101 				SbxArray* pArr = PTR_CAST(SbxArray, p->pObj);
102 				if( pArr )
103 					aRes = ByteArrayToString( pArr );
104 			}
105 			else
106 				SbxBase::SetError( SbxERR_NO_OBJECT );
107 			break;
108 		}
109 		case SbxERROR:
110 			// Hier wird der String "Error n" erzeugt
111 			aRes = SbxRes( STRING_ERRORMSG );
112 			aRes += ::rtl::OUString( p->nUShort ); break;
113 		case SbxDATE:
114 			ImpPutDate( &aTmp, p->nDouble ); break;
115 
116 		case SbxBYREF | SbxCHAR:
117 			ImpPutChar( &aTmp, *p->pChar ); break;
118 		case SbxBYREF | SbxBYTE:
119 			ImpPutByte( &aTmp, *p->pByte ); break;
120 		case SbxBYREF | SbxINTEGER:
121 		case SbxBYREF | SbxBOOL:
122 			ImpPutInteger( &aTmp, *p->pInteger ); break;
123 		case SbxBYREF | SbxLONG:
124 			ImpPutLong( &aTmp, *p->pLong ); break;
125 		case SbxBYREF | SbxULONG:
126 			ImpPutULong( &aTmp, *p->pULong ); break;
127 		case SbxBYREF | SbxERROR:
128 		case SbxBYREF | SbxUSHORT:
129 			ImpPutUShort( &aTmp, *p->pUShort ); break;
130 		case SbxBYREF | SbxSINGLE:
131 			ImpPutSingle( &aTmp, *p->pSingle ); break;
132 		case SbxBYREF | SbxDATE:
133 		case SbxBYREF | SbxDOUBLE:
134 			ImpPutDouble( &aTmp, *p->pDouble ); break;
135 		case SbxBYREF | SbxCURRENCY:
136 			ImpPutCurrency( &aTmp, *p->pLong64 ); break;
137 		case SbxBYREF | SbxSALINT64:
138 			ImpPutInt64( &aTmp, *p->pnInt64 ); break;
139 		case SbxBYREF | SbxSALUINT64:
140 			ImpPutUInt64( &aTmp, *p->puInt64 ); break;
141 		default:
142 			SbxBase::SetError( SbxERR_CONVERSION );
143 	}
144 	return aRes;
145 }
146 
147 // AB 10.4.97, neue Funktion fuer SbxValue::GetCoreString()
148 ::rtl::OUString ImpGetCoreString( const SbxValues* p )
149 {
150 	// Vorerst nur fuer double
151 	if( ( p->eType & (~SbxBYREF) ) == SbxDOUBLE )
152 	{
153 		SbxValues aTmp;
154 		XubString aRes;
155 		aTmp.eType = SbxSTRING;
156 		if( p->eType == SbxDOUBLE )
157 			ImpPutDouble( &aTmp, p->nDouble, /*bCoreString=*/sal_True );
158 		else
159 			ImpPutDouble( &aTmp, *p->pDouble, /*bCoreString=*/sal_True );
160 		return aRes;
161 	}
162 	else
163 		return ImpGetString( p );
164 }
165 
166 void ImpPutString( SbxValues* p, const ::rtl::OUString* n )
167 {
168 	SbxValues aTmp;
169 	aTmp.eType = SbxSTRING;
170 	::rtl::OUString* pTmp = NULL;
171 	// Sicherheitshalber, falls ein NULL-Ptr kommt
172 	if( !n )
173 		n = pTmp = new ::rtl::OUString;
174 	aTmp.pOUString = (::rtl::OUString*)n;
175 	switch( +p->eType )
176 	{
177 		case SbxCHAR:
178 			p->nChar = ImpGetChar( &aTmp ); break;
179 		case SbxBYTE:
180 			p->nByte = ImpGetByte( &aTmp ); break;
181 		case SbxINTEGER:
182 		case SbxBOOL:
183 			p->nInteger = ImpGetInteger( &aTmp ); break;
184 		case SbxLONG:
185 			p->nLong = ImpGetLong( &aTmp ); break;
186 		case SbxULONG:
187 			p->nULong = ImpGetULong( &aTmp ); break;
188 		case SbxERROR:
189 		case SbxUSHORT:
190 			p->nUShort = ImpGetUShort( &aTmp ); break;
191 		case SbxSINGLE:
192 			p->nSingle = ImpGetSingle( &aTmp ); break;
193 		case SbxDATE:
194 			p->nDouble = ImpGetDate( &aTmp ); break;
195 		case SbxDOUBLE:
196 			p->nDouble = ImpGetDouble( &aTmp ); break;
197 		case SbxULONG64:
198 			p->nLong64 = ImpGetCurrency( &aTmp ); break;
199 		case SbxDECIMAL:
200 		case SbxBYREF | SbxDECIMAL:
201 			releaseDecimalPtr( p->pDecimal );
202 			p->pDecimal = ImpGetDecimal( &aTmp ); break;
203 		case SbxSALINT64:
204 			p->nInt64 = ImpGetInt64( &aTmp ); break;
205 		case SbxSALUINT64:
206 			p->uInt64 = ImpGetUInt64( &aTmp ); break;
207 
208 		case SbxBYREF | SbxSTRING:
209 		case SbxSTRING:
210 		case SbxLPSTR:
211 			if( n->getLength() )
212 			{
213 				if( !p->pOUString )
214 					p->pOUString = new ::rtl::OUString( *n );
215                 else
216                     *p->pOUString = *n;
217 			}
218 			else
219 				delete p->pOUString, p->pOUString = NULL;
220 			break;
221 		case SbxOBJECT:
222 		{
223 			SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
224 			if( pVal )
225 				pVal->PutString( *n );
226 			else
227 				SbxBase::SetError( SbxERR_NO_OBJECT );
228 			break;
229 		}
230 		case SbxBYREF | SbxCHAR:
231 			*p->pChar = ImpGetChar( p ); break;
232 		case SbxBYREF | SbxBYTE:
233 			*p->pByte = ImpGetByte( p ); break;
234 		case SbxBYREF | SbxINTEGER:
235 			*p->pInteger = ImpGetInteger( p ); break;
236 		case SbxBYREF | SbxBOOL:
237 			*p->pUShort = sal::static_int_cast< sal_uInt16 >( ImpGetBool( p ) );
238             break;
239 		case SbxBYREF | SbxERROR:
240 		case SbxBYREF | SbxUSHORT:
241 			*p->pUShort = ImpGetUShort( p ); break;
242 		case SbxBYREF | SbxLONG:
243 			*p->pLong = ImpGetLong( p ); break;
244 		case SbxBYREF | SbxULONG:
245 			*p->pULong = ImpGetULong( p ); break;
246 		case SbxBYREF | SbxSINGLE:
247 			*p->pSingle = ImpGetSingle( p ); break;
248 		case SbxBYREF | SbxDATE:
249 			*p->pDouble = ImpGetDate( p ); break;
250 		case SbxBYREF | SbxDOUBLE:
251 			*p->pDouble = ImpGetDouble( p ); break;
252 		case SbxBYREF | SbxCURRENCY:
253 			*p->pLong64 = ImpGetCurrency( p ); break;
254 		default:
255 			SbxBase::SetError( SbxERR_CONVERSION );
256 	}
257 	delete pTmp;
258 }
259 
260 // Convert string to an array of bytes, preserving unicode (2bytes per character)
261 SbxArray* StringToByteArray(const ::rtl::OUString& rStr)
262 {
263 	sal_Int32 nArraySize = rStr.getLength() * 2;
264 	const sal_Unicode* pSrc = rStr.getStr();
265 	SbxDimArray* pArray = new SbxDimArray(SbxBYTE);
266 	bool bIncIndex = ( IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
267 	if( nArraySize )
268 	{
269 		if( bIncIndex )
270 			pArray->AddDim32( 1, nArraySize );
271 		else
272 			pArray->AddDim32( 0, nArraySize-1 );
273 	}
274 	else
275 	{
276 		pArray->unoAddDim( 0, -1 );
277 	}
278 
279 	for( sal_uInt16	i=0; i< nArraySize; i++)
280 	{
281 		SbxVariable* pNew = new SbxVariable( SbxBYTE );
282 		sal_uInt8 aByte = static_cast< sal_uInt8 >( i%2 ? ((*pSrc) >> 8) & 0xff : (*pSrc) & 0xff );
283 		pNew->PutByte( aByte );
284 		pNew->SetFlag( SBX_WRITE );
285 		pArray->Put( pNew, i );
286 		if( i%2 )
287 			pSrc++;
288 	}
289 	return pArray;
290 }
291 
292 // Convert an array of bytes to string (2bytes per character)
293 ::rtl::OUString ByteArrayToString(SbxArray* pArr)
294 {
295 	sal_uInt16 nCount = pArr->Count();
296 	OUStringBuffer aStrBuf;
297 	sal_Unicode aChar = 0;
298 	for( sal_uInt16 i = 0 ; i < nCount ; i++ )
299 	{
300 		sal_Unicode aTempChar = pArr->Get(i)->GetByte();
301 		if( i%2 )
302 		{
303 			aChar = (aTempChar << 8 ) | aChar;
304 			aStrBuf.append(aChar);
305 			aChar = 0;
306 		}
307 		else
308 		{
309 			aChar = aTempChar;
310 		}
311 	}
312 
313 	if( nCount%2 )
314 	{
315 		aStrBuf.append(aChar);
316 	}
317 
318 	return aStrBuf.makeStringAndClear();
319 }
320