xref: /trunk/main/basic/source/sbx/sbxchar.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 
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