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