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