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