xref: /AOO41X/main/basic/source/sbx/sbxstr.cxx (revision e1f63238eb022c8a12b30d46a012444ff20e0951)
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