xref: /trunk/main/basic/source/sbx/sbxchar.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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 
34 // AB 29.10.99 Unicode
35 #ifndef _USE_NO_NAMESPACE
36 using namespace rtl;
37 #endif
38 
39 xub_Unicode ImpGetChar( const SbxValues* p )
40 {
41     SbxValues aTmp;
42     xub_Unicode nRes = 0;
43 start:
44     switch( +p->eType )
45     {
46         case SbxNULL:
47             SbxBase::SetError( SbxERR_CONVERSION );
48         case SbxEMPTY:
49             nRes = 0; break;
50         case SbxCHAR:
51             nRes = p->nChar; break;
52         case SbxBYTE:
53             nRes = (xub_Unicode) p->nByte;
54             break;
55         case SbxINTEGER:
56         case SbxBOOL:
57             if( p->nInteger < SbxMINCHAR )
58             {
59                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
60             }
61             else
62                 nRes = (xub_Unicode) p->nInteger;
63             break;
64         case SbxERROR:
65         case SbxUSHORT:
66             nRes = (xub_Unicode) p->nUShort;
67             break;
68         case SbxLONG:
69             if( p->nLong > SbxMAXCHAR )
70             {
71                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
72             }
73             else if( p->nLong < SbxMINCHAR )
74             {
75                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
76             }
77             else
78                 nRes = (xub_Unicode) p->nLong;
79             break;
80         case SbxULONG:
81             if( p->nULong > SbxMAXCHAR )
82             {
83                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
84             }
85             else
86                 nRes = (xub_Unicode) p->nULong;
87             break;
88         case SbxSALINT64:
89             if( p->nInt64 > SbxMAXCHAR )
90             {
91                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
92             }
93             else if( p->nInt64 < SbxMINCHAR )
94             {
95                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
96             }
97             else
98                 nRes = (xub_Unicode) p->nInt64;
99             break;
100         case SbxSALUINT64:
101             if( p->uInt64 > SbxMAXCHAR )
102             {
103                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
104             }
105             else
106                 nRes = (xub_Unicode) p->uInt64;
107             break;
108         case SbxSINGLE:
109             if( p->nSingle > SbxMAXCHAR )
110             {
111                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
112             }
113             else if( p->nSingle < SbxMINCHAR )
114             {
115                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
116             }
117             else
118                 nRes = (xub_Unicode) ImpRound( p->nSingle );
119             break;
120         case SbxDATE:
121         case SbxDOUBLE:
122         case SbxLONG64:
123         case SbxULONG64:
124         case SbxCURRENCY:
125         case SbxDECIMAL:
126         case SbxBYREF | SbxDECIMAL:
127             {
128             double dVal;
129             if( p->eType == SbxCURRENCY )
130                 dVal = ImpCurrencyToDouble( p->nLong64 );
131             else if( p->eType == SbxLONG64 )
132                 dVal = ImpINT64ToDouble( p->nLong64 );
133             else if( p->eType == SbxULONG64 )
134                 dVal = ImpUINT64ToDouble( p->nULong64 );
135             else if( p->eType == SbxDECIMAL )
136             {
137                 dVal = 0.0;
138                 if( p->pDecimal )
139                     p->pDecimal->getDouble( dVal );
140             }
141             else
142                 dVal = p->nDouble;
143 
144             if( dVal > SbxMAXCHAR )
145             {
146                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
147             }
148             else if( dVal < SbxMINCHAR )
149             {
150                 SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
151             }
152             else
153                 nRes = (sal_uInt8) ImpRound( dVal );
154             break;
155             }
156         case SbxBYREF | SbxSTRING:
157         case SbxSTRING:
158         case SbxLPSTR:
159             if ( p->pOUString )
160             {
161                 double d;
162                 SbxDataType t;
163                 if( ImpScan( *p->pOUString, d, t, NULL ) != SbxERR_OK )
164                     nRes = 0;
165                 else if( d > SbxMAXCHAR )
166                 {
167                     SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
168                 }
169                 else if( d < SbxMINCHAR )
170                 {
171                     SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
172                 }
173                 else
174                     nRes = (xub_Unicode) ImpRound( d );
175             }
176             break;
177         case SbxOBJECT:
178         {
179             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
180             if( pVal )
181                 nRes = pVal->GetChar();
182             else
183             {
184                 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
185             }
186             break;
187         }
188 
189         case SbxBYREF | SbxCHAR:
190             nRes = *p->pChar; break;
191         // ab hier wird getestet
192         case SbxBYREF | SbxBYTE:
193             aTmp.nByte = *p->pByte; goto ref;
194         case SbxBYREF | SbxINTEGER:
195         case SbxBYREF | SbxBOOL:
196             aTmp.nInteger = *p->pInteger; goto ref;
197         case SbxBYREF | SbxLONG:
198             aTmp.nLong = *p->pLong; goto ref;
199         case SbxBYREF | SbxULONG:
200             aTmp.nULong = *p->pULong; goto ref;
201         case SbxBYREF | SbxERROR:
202         case SbxBYREF | SbxUSHORT:
203             aTmp.nUShort = *p->pUShort; goto ref;
204         case SbxBYREF | SbxSINGLE:
205             aTmp.nSingle = *p->pSingle; goto ref;
206         case SbxBYREF | SbxDATE:
207         case SbxBYREF | SbxDOUBLE:
208             aTmp.nDouble = *p->pDouble; goto ref;
209         case SbxBYREF | SbxULONG64:
210             aTmp.nULong64 = *p->pULong64; goto ref;
211         case SbxBYREF | SbxLONG64:
212         case SbxBYREF | SbxCURRENCY:
213             aTmp.nLong64 = *p->pLong64; goto ref;
214         case SbxBYREF | SbxSALINT64:
215             aTmp.nInt64 = *p->pnInt64; goto ref;
216         case SbxBYREF | SbxSALUINT64:
217             aTmp.uInt64 = *p->puInt64; goto ref;
218         ref:
219             aTmp.eType = SbxDataType( p->eType & 0x0FFF );
220             p = &aTmp; goto start;
221 
222         default:
223             SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
224     }
225     return nRes;
226 }
227 
228 void ImpPutChar( SbxValues* p, xub_Unicode n )
229 {
230     SbxValues aTmp;
231 start:
232     switch( +p->eType )
233     {
234         case SbxCHAR:
235             p->nChar = n; break;
236         case SbxINTEGER:
237         case SbxBOOL:
238             p->nInteger = n; break;
239         case SbxLONG:
240             p->nLong = n; break;
241         case SbxSINGLE:
242             p->nSingle = n; break;
243         case SbxDATE:
244         case SbxDOUBLE:
245             p->nDouble = n; break;
246         case SbxSALINT64:
247             p->nInt64 = n; break;
248         case SbxSALUINT64:
249             p->uInt64 = n; break;
250         case SbxULONG64:
251             p->nULong64 = ImpDoubleToUINT64( (double)n ); break;
252         case SbxLONG64:
253             p->nLong64 = ImpDoubleToINT64( (double)n ); break;
254         case SbxCURRENCY:
255             p->nLong64 = ImpDoubleToCurrency( (double)n ); break;
256         case SbxBYREF | SbxDECIMAL:
257             ImpCreateDecimal( p )->setChar( n );
258             break;
259 
260         // ab hier wird getestet
261         case SbxBYTE:
262             aTmp.pByte = &p->nByte; goto direct;
263         case SbxULONG:
264             aTmp.pULong = &p->nULong; goto direct;
265         case SbxERROR:
266         case SbxUSHORT:
267             aTmp.pUShort = &p->nUShort; goto direct;
268         direct:
269             aTmp.eType = SbxDataType( p->eType | SbxBYREF );
270             p = &aTmp; goto start;
271 
272         case SbxBYREF | SbxSTRING:
273         case SbxSTRING:
274         case SbxLPSTR:
275             if ( !p->pOUString )
276                 p->pOUString = new ::rtl::OUString( n );
277             else
278                 *p->pOUString = ::rtl::OUString( n );
279             break;
280         case SbxOBJECT:
281         {
282             SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
283             if( pVal )
284                 pVal->PutChar( n );
285             else
286                 SbxBase::SetError( SbxERR_NO_OBJECT );
287             break;
288         }
289         case SbxBYREF | SbxCHAR:
290             *p->pChar = n; break;
291         case SbxBYREF | SbxBYTE:
292             *p->pByte = (sal_uInt8) n; break;
293         case SbxBYREF | SbxINTEGER:
294         case SbxBYREF | SbxBOOL:
295             *p->pInteger = n; break;
296         case SbxBYREF | SbxERROR:
297         case SbxBYREF | SbxUSHORT:
298             *p->pUShort = (sal_uInt16) n; break;
299         case SbxBYREF | SbxLONG:
300             *p->pLong = (sal_Int32) n; break;
301         case SbxBYREF | SbxULONG:
302             *p->pULong = (sal_uInt32) n; break;
303         case SbxBYREF | SbxSINGLE:
304             *p->pSingle = (float) n; break;
305         case SbxBYREF | SbxDATE:
306         case SbxBYREF | SbxDOUBLE:
307             *p->pDouble = (double) n; break;
308         case SbxBYREF | SbxSALINT64:
309             *p->pnInt64 = n; break;
310         case SbxBYREF | SbxSALUINT64:
311             *p->puInt64 = n; break;
312         case SbxBYREF | SbxULONG64:
313             *p->pULong64 = ImpDoubleToUINT64( (double)n ); break;
314         case SbxBYREF | SbxLONG64:
315             *p->pLong64 = ImpDoubleToINT64( (double)n ); break;
316         case SbxBYREF | SbxCURRENCY:
317             *p->pLong64 = ImpDoubleToCurrency( (double)n ); break;
318 
319         default:
320             SbxBase::SetError( SbxERR_CONVERSION );
321     }
322 }
323 
324 
325