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_connectivity.hxx"
26 #include "file/fcode.hxx"
27 #include <osl/diagnose.h>
28 #include "connectivity/sqlparse.hxx"
29 #include <i18npool/mslangid.hxx>
30 #include <tools/debug.hxx>
31 #include <tools/string.hxx>
32 #include "TConnection.hxx"
33 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
34 #include <comphelper/types.hxx>
35 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
36 #include <rtl/logfile.hxx>
37 
38 using namespace ::comphelper;
39 using namespace connectivity;
40 using namespace connectivity::file;
41 //using namespace ::com::sun::star::uno;
42 //using namespace ::com::sun::star::lang;
43 using namespace ::com::sun::star::sdbc;
44 using namespace ::com::sun::star::sdb;
45 //using namespace ::com::sun::star::container;
46 //using namespace ::com::sun::star::beans;
47 //using namespace ::com::sun::star::sdbcx;
48 
49 TYPEINIT0(OCode);
50 TYPEINIT1(OOperand, OCode);
51 TYPEINIT1(OOperandRow, OOperand);
52 TYPEINIT1(OOperandAttr, OOperandRow);
53 TYPEINIT1(OOperandParam, OOperandRow);
54 TYPEINIT1(OOperandValue, OOperand);
55 TYPEINIT1(OOperandConst, OOperandValue);
56 TYPEINIT1(OOperandResult, OOperandValue);
57 TYPEINIT1(OStopOperand, OOperandValue);
58 
59 TYPEINIT1(OOperator, OCode);
60 TYPEINIT1(OBoolOperator,OOperator);
61 TYPEINIT1(OOp_NOT, OBoolOperator);
62 TYPEINIT1(OOp_AND, OBoolOperator);
63 TYPEINIT1(OOp_OR, OBoolOperator);
64 TYPEINIT1(OOp_ISNULL, OBoolOperator);
65 TYPEINIT1(OOp_ISNOTNULL, OOp_ISNULL);
66 TYPEINIT1(OOp_LIKE, OBoolOperator);
67 TYPEINIT1(OOp_NOTLIKE, OOp_LIKE);
68 TYPEINIT1(OOp_COMPARE, OBoolOperator);
69 TYPEINIT1(ONumOperator, OOperator);
70 TYPEINIT1(ONthOperator, OOperator);
71 TYPEINIT1(OBinaryOperator, OOperator);
72 TYPEINIT1(OUnaryOperator, OOperator);
73 
74 //------------------------------------------------------------------
DBG_NAME(OCode)75 DBG_NAME(OCode )
76 OCode::OCode()
77 {
78 	DBG_CTOR(OCode ,NULL);
79 }
80 // -----------------------------------------------------------------------------
~OCode()81 OCode::~OCode()
82 {
83 	DBG_DTOR(OCode,NULL);
84 }
85 
86 //------------------------------------------------------------------
preProcess(OBoolOperator *,OOperand *)87 OEvaluateSet* OOperand::preProcess(OBoolOperator* /*pOp*/, OOperand* /*pRight*/)
88 {
89 	return NULL;
90 }
91 // -----------------------------------------------------------------------------
OOperandRow(sal_uInt16 _nPos,sal_Int32 _rType)92 OOperandRow::OOperandRow(sal_uInt16 _nPos, sal_Int32 _rType)
93 	: OOperand(_rType)
94 	, m_nRowPos(_nPos)
95 {}
96 //------------------------------------------------------------------
bindValue(const OValueRefRow & _pRow)97 void OOperandRow::bindValue(const OValueRefRow& _pRow)
98 {
99     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandRow::OOperandRow" );
100 	OSL_ENSURE(_pRow.isValid(),"NO EMPTY row allowed!");
101 	m_pRow = _pRow;
102 	OSL_ENSURE(m_pRow.isValid() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()");
103 	(m_pRow->get())[m_nRowPos]->setBound(sal_True);
104 }
105 // -----------------------------------------------------------------------------
setValue(const ORowSetValue & _rVal)106 void OOperandRow::setValue(const ORowSetValue& _rVal)
107 {
108     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandRow::setValue" );
109 	OSL_ENSURE(m_pRow.isValid() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()");
110 	(*(m_pRow->get())[m_nRowPos]) = _rVal;
111 }
112 //------------------------------------------------------------------
getValue() const113 const ORowSetValue& OOperandRow::getValue() const
114 {
115     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandRow::getValue" );
116 	OSL_ENSURE(m_pRow.isValid() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()");
117 	return (m_pRow->get())[m_nRowPos]->getValue();
118 }
119 
120 // -----------------------------------------------------------------------------
setValue(const ORowSetValue & _rVal)121 void OOperandValue::setValue(const ORowSetValue& _rVal)
122 {
123     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandValue::setValue" );
124 	m_aValue = _rVal;
125 }
126 // -------------------------------------------------------------------------
isIndexed() const127 sal_Bool OOperandAttr::isIndexed() const
128 {
129 	return sal_False;
130 }
131 //------------------------------------------------------------------
OOperandParam(OSQLParseNode * pNode,sal_Int32 _nPos)132 OOperandParam::OOperandParam(OSQLParseNode* pNode, sal_Int32 _nPos)
133 	: OOperandRow(static_cast<sal_uInt16>(_nPos), DataType::VARCHAR)		 // Standard-Typ
134 {
135 	OSL_ENSURE(SQL_ISRULE(pNode,parameter),"Argument ist kein Parameter");
136 	OSL_ENSURE(pNode->count() > 0,"Fehler im Parse Tree");
137 	OSQLParseNode *pMark = pNode->getChild(0);
138 
139 	String aParameterName;
140 	if (SQL_ISPUNCTUATION(pMark,"?"))
141 		aParameterName = '?';
142 	else if (SQL_ISPUNCTUATION(pMark,":"))
143 		aParameterName = pNode->getChild(1)->getTokenValue();
144 	else
145 	{
146 		OSL_ASSERT("Fehler im Parse Tree");
147 	}
148 
149     // Parameter-Column aufsetzen mit defult typ, kann zu einem spaeteren Zeitpunkt ueber DescribeParameter
150 	// genauer spezifiziert werden
151 
152 	// Identitaet merken (hier eigentlich nicht erforderlich, aber aus
153 	// Symmetriegruenden ...)
154 
155 	// todo
156 	//	OColumn* pColumn = new OFILEColumn(aParameterName,eDBType,255,0,SQL_FLAGS_NULLALLOWED);
157 	//	rParamColumns->AddColumn(pColumn);
158 
159 	// der Wert wird erst kurz vor der Auswertung gesetzt
160 }
161 
162 
163 //------------------------------------------------------------------
getValue() const164 const ORowSetValue& OOperandValue::getValue() const
165 {
166     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandValue::getValue" );
167 	return m_aValue;
168 }
169 
170 //------------------------------------------------------------------
OOperandConst(const OSQLParseNode & rColumnRef,const rtl::OUString & aStrValue)171 OOperandConst::OOperandConst(const OSQLParseNode& rColumnRef, const rtl::OUString& aStrValue)
172 {
173     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandConst::OOperandConst" );
174 	switch (rColumnRef.getNodeType())
175 	{
176 		case SQL_NODE_STRING:
177 			m_aValue	= aStrValue;
178 			m_eDBType	= DataType::VARCHAR;
179 			m_aValue.setBound(sal_True);
180 			return;
181 		case SQL_NODE_INTNUM:
182 		case SQL_NODE_APPROXNUM:
183 		{
184 			m_aValue	= aStrValue.toDouble();
185 			m_eDBType	= DataType::DOUBLE;
186 			m_aValue.setBound(sal_True);
187 			return;
188 		}
189         default:
190             break;
191 	}
192 
193 	if (SQL_ISTOKEN(&rColumnRef,TRUE))
194 	{
195 		m_aValue = 1.0;
196 		m_eDBType = DataType::BIT;
197 	}
198 	else if (SQL_ISTOKEN(&rColumnRef,FALSE))
199 	{
200 		m_aValue = 0.0;
201 		m_eDBType = DataType::BIT;
202 	}
203 	else
204 	{
205 		OSL_ASSERT("Parse Error");
206 	}
207 	m_aValue.setBound(sal_True);
208 }
209 
210 /////////////////////////////////////////////////////////////////////////////////////////
211 // Implementation of the operators
212 
213 //------------------------------------------------------------------
getRequestedOperands() const214 sal_uInt16 OOperator::getRequestedOperands() const {return 2;}
215 
216 //------------------------------------------------------------------
operate(const OOperand *,const OOperand *) const217 sal_Bool OBoolOperator::operate(const OOperand*, const OOperand*) const
218 {
219     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OBoolOperator::operate" );
220 	return sal_False;
221 }
222 
223 
224 //------------------------------------------------------------------
Exec(OCodeStack & rCodeStack)225 void OBoolOperator::Exec(OCodeStack& rCodeStack)
226 {
227     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OBoolOperator::Exec" );
228 	OOperand  *pRight	= rCodeStack.top();
229 	rCodeStack.pop();
230 	OOperand  *pLeft	= rCodeStack.top();
231 	rCodeStack.pop();
232 
233 	rCodeStack.push(new OOperandResultBOOL(operate(pLeft, pRight)));
234 	if (IS_TYPE(OOperandResult,pLeft))
235 		delete pLeft;
236 	if (IS_TYPE(OOperandResult,pRight))
237 		delete pRight;
238 }
239 //------------------------------------------------------------------
operate(const OOperand * pLeft,const OOperand *) const240 sal_Bool OOp_NOT::operate(const OOperand* pLeft, const OOperand* ) const
241 {
242     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_AND::operate" );
243 	return !pLeft->isValid();
244 }
245 //------------------------------------------------------------------
Exec(OCodeStack & rCodeStack)246 void OOp_NOT::Exec(OCodeStack& rCodeStack)
247 {
248     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::Exec" );
249 	OOperand* pOperand = rCodeStack.top();
250 	rCodeStack.pop();
251 
252 	rCodeStack.push(new OOperandResultBOOL(operate(pOperand)));
253 	if (IS_TYPE(OOperandResult,pOperand))
254 		delete pOperand;
255 }
256 //------------------------------------------------------------------
getRequestedOperands() const257 sal_uInt16 OOp_NOT::getRequestedOperands() const
258 {
259     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_NOT::getRequestedOperands" );
260     return 1;
261 }
262 
263 //------------------------------------------------------------------
operate(const OOperand * pLeft,const OOperand * pRight) const264 sal_Bool OOp_AND::operate(const OOperand* pLeft, const OOperand* pRight) const
265 {
266     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_AND::operate" );
267 	return pLeft->isValid() && pRight->isValid();
268 }
269 
270 //------------------------------------------------------------------
operate(const OOperand * pLeft,const OOperand * pRight) const271 sal_Bool OOp_OR::operate(const OOperand* pLeft, const OOperand* pRight) const
272 {
273     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_OR::operate" );
274 	return pLeft->isValid() || pRight->isValid();
275 }
276 
277 //------------------------------------------------------------------
getRequestedOperands() const278 sal_uInt16 OOp_ISNULL::getRequestedOperands() const
279 {
280     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::getRequestedOperands" );
281     return 1;
282 }
283 
284 //------------------------------------------------------------------
Exec(OCodeStack & rCodeStack)285 void OOp_ISNULL::Exec(OCodeStack& rCodeStack)
286 {
287     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::Exec" );
288 	OOperand* pOperand = rCodeStack.top();
289 	rCodeStack.pop();
290 
291 	rCodeStack.push(new OOperandResultBOOL(operate(pOperand)));
292 	if (IS_TYPE(OOperandResult,pOperand))
293 		delete pOperand;
294 }
295 
296 //------------------------------------------------------------------
operate(const OOperand * pOperand,const OOperand *) const297 sal_Bool OOp_ISNULL::operate(const OOperand* pOperand, const OOperand*) const
298 {
299     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::operate" );
300 	return pOperand->getValue().isNull();
301 }
302 
303 //------------------------------------------------------------------
operate(const OOperand * pOperand,const OOperand *) const304 sal_Bool OOp_ISNOTNULL::operate(const OOperand* pOperand, const OOperand*) const
305 {
306 	return !OOp_ISNULL::operate(pOperand);
307 }
308 
309 //------------------------------------------------------------------
operate(const OOperand * pLeft,const OOperand * pRight) const310 sal_Bool OOp_LIKE::operate(const OOperand* pLeft, const OOperand* pRight) const
311 {
312     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::operate" );
313 	sal_Bool bMatch;
314 	ORowSetValue aLH(pLeft->getValue());
315 	ORowSetValue aRH(pRight->getValue());
316 
317 	if (aLH.isNull() || aRH.isNull())
318 		bMatch = sal_False;
319 	else
320 	{
321 		bMatch = match(aRH.getString(), aLH.getString(), cEscape);
322 	}
323 	return bMatch;
324 }
325 
326 //------------------------------------------------------------------
operate(const OOperand * pLeft,const OOperand * pRight) const327 sal_Bool OOp_NOTLIKE::operate(const OOperand* pLeft, const OOperand* pRight) const
328 {
329     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_NOTLIKE::operate" );
330 	return !OOp_LIKE::operate(pLeft, pRight);
331 }
332 
333 //------------------------------------------------------------------
operate(const OOperand * pLeft,const OOperand * pRight) const334 sal_Bool OOp_COMPARE::operate(const OOperand* pLeft, const OOperand* pRight) const
335 {
336     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_COMPARE::operate" );
337 	ORowSetValue aLH(pLeft->getValue());
338 	ORowSetValue aRH(pRight->getValue());
339 
340 	if (aLH.isNull() || aRH.isNull()) // if (!aLH.getValue() || !aRH.getValue())
341 		return sal_False;
342 
343 	sal_Bool bResult = sal_False;
344 	sal_Int32 eDBType = pLeft->getDBType();
345 
346 	// Vergleich (je nach Datentyp):
347 	switch (eDBType)
348 	{
349 		case DataType::CHAR:
350 		case DataType::VARCHAR:
351         case DataType::LONGVARCHAR:
352 		{
353 			rtl::OUString sLH = aLH, sRH = aRH;
354             sal_Int32 nRes = rtl_ustr_compareIgnoreAsciiCase_WithLength
355                 (
356                  sLH.pData->buffer,
357                  sLH.pData->length,
358                  sRH.pData->buffer,
359                  sRH.pData->length );
360 			switch(aPredicateType)
361 			{
362 				case SQLFilterOperator::EQUAL:			bResult = (nRes == 0); break;
363 				case SQLFilterOperator::NOT_EQUAL:			bResult = (nRes != 0); break;
364 				case SQLFilterOperator::LESS:				bResult = (nRes <  0); break;
365 				case SQLFilterOperator::LESS_EQUAL:		bResult = (nRes <= 0); break;
366 				case SQLFilterOperator::GREATER:			bResult = (nRes >  0); break;
367 				case SQLFilterOperator::GREATER_EQUAL:	bResult = (nRes >= 0); break;
368 				default:						bResult = sal_False;
369 			}
370 		} break;
371 		case DataType::TINYINT:
372 		case DataType::SMALLINT:
373 		case DataType::INTEGER:
374 		case DataType::DECIMAL:
375 		case DataType::NUMERIC:
376 		case DataType::REAL:
377 		case DataType::DOUBLE:
378 		case DataType::BIT:
379 		case DataType::TIMESTAMP:
380 		case DataType::DATE:
381 		case DataType::TIME:
382 		{
383 			double n = aLH ,m = aRH;
384 
385 			switch (aPredicateType)
386 			{
387 				case SQLFilterOperator::EQUAL:			bResult = (n == m); break;
388 				case SQLFilterOperator::LIKE:				bResult = (n == m); break;
389 				case SQLFilterOperator::NOT_EQUAL:			bResult = (n != m); break;
390 				case SQLFilterOperator::NOT_LIKE:			bResult = (n != m); break;
391 				case SQLFilterOperator::LESS:				bResult = (n < m); break;
392 				case SQLFilterOperator::LESS_EQUAL:		bResult = (n <= m); break;
393 				case SQLFilterOperator::GREATER:			bResult = (n > m); break;
394 				case SQLFilterOperator::GREATER_EQUAL:	bResult = (n >= m); break;
395 				default:						bResult = sal_False;
396 			}
397 		} break;
398 		default:
399 			bResult = aLH == aRH;
400 	}
401 	return bResult;
402 }
403 
404 //------------------------------------------------------------------
Exec(OCodeStack & rCodeStack)405 void ONumOperator::Exec(OCodeStack& rCodeStack)
406 {
407     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "ONumOperator::Exec" );
408 
409 	OOperand  *pRight	= rCodeStack.top();
410 	rCodeStack.pop();
411 	OOperand  *pLeft	= rCodeStack.top();
412 	rCodeStack.pop();
413 
414 	rCodeStack.push(new OOperandResultNUM(operate(pLeft->getValue(), pRight->getValue())));
415 	if (IS_TYPE(OOperandResult,pLeft))
416 		delete pLeft;
417 	if (IS_TYPE(OOperandResult,pRight))
418 		delete pRight;
419 }
420 //------------------------------------------------------------------
operate(const double & fLeft,const double & fRight) const421 double OOp_ADD::operate(const double& fLeft,const double& fRight) const
422 {
423     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ADD::operate" );
424 	return fLeft + fRight;
425 }
426 
427 //------------------------------------------------------------------
operate(const double & fLeft,const double & fRight) const428 double OOp_SUB::operate(const double& fLeft,const double& fRight) const
429 {
430     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_SUB::operate" );
431 	return fLeft - fRight;
432 }
433 
434 //------------------------------------------------------------------
operate(const double & fLeft,const double & fRight) const435 double OOp_MUL::operate(const double& fLeft,const double& fRight) const
436 {
437     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_MUL::operate" );
438 	return fLeft * fRight;
439 }
440 
441 //------------------------------------------------------------------
operate(const double & fLeft,const double & fRight) const442 double OOp_DIV::operate(const double& fLeft,const double& fRight) const
443 {
444     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_DIV::operate" );
445 	return fLeft / fRight;
446 }
447 // -----------------------------------------------------------------------------
preProcess(OBoolOperator *,OOperand *)448 OEvaluateSet* OOperandAttr::preProcess(OBoolOperator* /*pOp*/, OOperand* /*pRight*/)
449 {
450     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandAttr::preProcess" );
451 	return NULL;
452 }
453 //------------------------------------------------------------------
Exec(OCodeStack & rCodeStack)454 void ONthOperator::Exec(OCodeStack& rCodeStack)
455 {
456     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "ONthOperator::Exec" );
457 	::std::vector<ORowSetValue> aValues;
458 	::std::vector<OOperand*> aOperands;
459 	OOperand* pOperand;
460 	do
461 	{
462 		OSL_ENSURE(!rCodeStack.empty(),"Stack must be none empty!");
463 		pOperand	= rCodeStack.top();
464 		rCodeStack.pop();
465 		if ( !IS_TYPE(OStopOperand,pOperand) )
466 			aValues.push_back( pOperand->getValue() );
467 		aOperands.push_back( pOperand );
468 	}
469 	while ( !IS_TYPE(OStopOperand,pOperand) );
470 
471 	rCodeStack.push(new OOperandResult(operate(aValues)));
472 
473 	::std::vector<OOperand*>::iterator aIter = aOperands.begin();
474 	::std::vector<OOperand*>::iterator aEnd = aOperands.end();
475 	for (; aIter != aEnd; ++aIter)
476 	{
477 		if (IS_TYPE(OOperandResult,*aIter))
478 			delete *aIter;
479 	}
480 }
481 //------------------------------------------------------------------
Exec(OCodeStack & rCodeStack)482 void OBinaryOperator::Exec(OCodeStack& rCodeStack)
483 {
484     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OBinaryOperator::Exec" );
485 	OOperand  *pRight	= rCodeStack.top();
486 	rCodeStack.pop();
487 	OOperand  *pLeft	= rCodeStack.top();
488 	rCodeStack.pop();
489 
490 	if ( !rCodeStack.empty() && IS_TYPE(OStopOperand,rCodeStack.top()) )
491 		rCodeStack.pop();
492 
493 	rCodeStack.push(new OOperandResult(operate(pLeft->getValue(),pRight->getValue())));
494 	if (IS_TYPE(OOperandResult,pRight))
495 		delete pRight;
496 	if (IS_TYPE(OOperandResult,pLeft))
497 		delete pLeft;
498 }
499 //------------------------------------------------------------------
Exec(OCodeStack & rCodeStack)500 void OUnaryOperator::Exec(OCodeStack& rCodeStack)
501 {
502     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OUnaryOperator::Exec" );
503 	OSL_ENSURE(!rCodeStack.empty(),"Stack is empty!");
504 	OOperand* pOperand = rCodeStack.top();
505 	rCodeStack.pop();
506 
507 	rCodeStack.push(new OOperandResult(operate(pOperand->getValue())));
508 	if (IS_TYPE(OOperandResult,pOperand))
509 		delete pOperand;
510 }
511 // -----------------------------------------------------------------------------
getRequestedOperands() const512 sal_uInt16 OUnaryOperator::getRequestedOperands() const {return 1;}
513 
514 
515 
516