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