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