1 : /******************************************************************************
2 : * $Id: ods_formula_node.cpp 23831 2012-01-30 23:12:23Z rouault $
3 : *
4 : * Component: ODS formula Engine
5 : * Purpose: Implementation of the ods_formula_node class used to represent a
6 : * node in a ODS expression.
7 : * Author: Even Rouault <even dot rouault at mines dash paris dot org>
8 : *
9 : ******************************************************************************
10 : * Copyright (C) 2010 Frank Warmerdam <warmerdam@pobox.com>
11 : * Copyright (c) 2012, Even Rouault <even dot rouault at mines dash paris dot org>
12 : *
13 : * Permission is hereby granted, free of charge, to any person obtaining a
14 : * copy of this software and associated documentation files (the "Software"),
15 : * to deal in the Software without restriction, including without limitation
16 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 : * and/or sell copies of the Software, and to permit persons to whom the
18 : * Software is furnished to do so, subject to the following conditions:
19 : *
20 : * The above copyright notice and this permission notice shall be included
21 : * in all copies or substantial portions of the Software.
22 : *
23 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 : * DEALINGS IN THE SOFTWARE.
30 : ****************************************************************************/
31 :
32 : #include "cpl_conv.h"
33 : #include "ods_formula.h"
34 :
35 : #ifndef PI
36 : #define PI 3.14159265358979323846
37 : #endif
38 :
39 : /************************************************************************/
40 : /* ods_formula_node() */
41 : /************************************************************************/
42 :
43 12 : ods_formula_node::ods_formula_node()
44 :
45 : {
46 12 : Initialize();
47 12 : }
48 :
49 : /************************************************************************/
50 : /* ods_formula_node(int) */
51 : /************************************************************************/
52 :
53 220 : ods_formula_node::ods_formula_node( int nValueIn )
54 :
55 : {
56 220 : Initialize();
57 :
58 220 : field_type = ODS_FIELD_TYPE_INTEGER;
59 220 : int_value = nValueIn;
60 220 : }
61 :
62 : /************************************************************************/
63 : /* ods_formula_node(double) */
64 : /************************************************************************/
65 :
66 124 : ods_formula_node::ods_formula_node( double dfValueIn )
67 :
68 : {
69 124 : Initialize();
70 :
71 124 : field_type = ODS_FIELD_TYPE_FLOAT;
72 124 : float_value = dfValueIn;
73 124 : }
74 :
75 : /************************************************************************/
76 : /* ods_formula_node(const char*) */
77 : /************************************************************************/
78 :
79 194 : ods_formula_node::ods_formula_node( const char *pszValueIn,
80 : ods_formula_field_type field_type_in )
81 :
82 : {
83 194 : Initialize();
84 :
85 194 : field_type = field_type_in;
86 194 : string_value = CPLStrdup( pszValueIn ? pszValueIn : "" );
87 194 : }
88 :
89 : /************************************************************************/
90 : /* ods_formula_node(ods_formula_op) */
91 : /************************************************************************/
92 :
93 334 : ods_formula_node::ods_formula_node( ods_formula_op eOpIn )
94 :
95 : {
96 334 : Initialize();
97 :
98 334 : eNodeType = SNT_OPERATION;
99 :
100 334 : eOp = eOpIn;
101 334 : }
102 :
103 : /************************************************************************/
104 : /* ods_formula_node(const ods_formula_node&) */
105 : /************************************************************************/
106 :
107 122 : ods_formula_node::ods_formula_node( const ods_formula_node& other )
108 : {
109 122 : eNodeType = other.eNodeType;
110 122 : eOp = other.eOp;
111 122 : field_type = other.field_type;
112 122 : int_value = other.int_value;
113 122 : float_value = other.float_value;
114 122 : string_value = other.string_value ? CPLStrdup(other.string_value) : NULL;
115 122 : nSubExprCount = other.nSubExprCount;
116 122 : if (nSubExprCount)
117 : {
118 : papoSubExpr = (ods_formula_node **)
119 0 : CPLMalloc( sizeof(void*) * nSubExprCount );
120 0 : for(int i=0;i<nSubExprCount;i++)
121 : {
122 0 : papoSubExpr[i] = new ods_formula_node( *(other.papoSubExpr[i]) );
123 : }
124 : }
125 : else
126 122 : papoSubExpr = NULL;
127 122 : }
128 :
129 : /************************************************************************/
130 : /* Initialize() */
131 : /************************************************************************/
132 :
133 884 : void ods_formula_node::Initialize()
134 :
135 : {
136 884 : eNodeType = SNT_CONSTANT;
137 884 : field_type = ODS_FIELD_TYPE_EMPTY;
138 884 : int_value = 0;
139 884 : float_value = 0;
140 884 : string_value = NULL;
141 884 : papoSubExpr = NULL;
142 884 : nSubExprCount = 0;
143 884 : }
144 :
145 : /************************************************************************/
146 : /* ~ods_formula_node() */
147 : /************************************************************************/
148 :
149 1006 : ods_formula_node::~ods_formula_node()
150 :
151 : {
152 1006 : CPLFree( string_value );
153 1006 : FreeSubExpr();
154 1006 : }
155 :
156 : /************************************************************************/
157 : /* PushSubExpression() */
158 : /************************************************************************/
159 :
160 566 : void ods_formula_node::PushSubExpression( ods_formula_node *child )
161 :
162 : {
163 566 : nSubExprCount++;
164 : papoSubExpr = (ods_formula_node **)
165 566 : CPLRealloc( papoSubExpr, sizeof(void*) * nSubExprCount );
166 :
167 566 : papoSubExpr[nSubExprCount-1] = child;
168 566 : }
169 :
170 : /************************************************************************/
171 : /* ReverseSubExpressions() */
172 : /************************************************************************/
173 :
174 28 : void ods_formula_node::ReverseSubExpressions()
175 :
176 : {
177 : int i;
178 46 : for( i = 0; i < nSubExprCount / 2; i++ )
179 : {
180 : ods_formula_node *temp;
181 :
182 18 : temp = papoSubExpr[i];
183 18 : papoSubExpr[i] = papoSubExpr[nSubExprCount - i - 1];
184 18 : papoSubExpr[nSubExprCount - i - 1] = temp;
185 : }
186 28 : }
187 :
188 : /************************************************************************/
189 : /* GetOperatorName() */
190 : /************************************************************************/
191 :
192 0 : static const char* ODSGetOperatorName( ods_formula_op eOp )
193 : {
194 0 : switch (eOp)
195 : {
196 0 : case ODS_OR : return "OR";
197 0 : case ODS_AND : return "AND";
198 0 : case ODS_NOT : return "NOT";
199 0 : case ODS_IF : return "IF";
200 :
201 0 : case ODS_PI : return "PI";
202 :
203 : //case ODS_T : return "T";
204 0 : case ODS_LEN : return "LEN";
205 0 : case ODS_LEFT : return "LEFT";
206 0 : case ODS_RIGHT : return "RIGHT";
207 0 : case ODS_MID : return "MID";
208 :
209 0 : case ODS_SUM : return "SUM";
210 0 : case ODS_AVERAGE : return "AVERAGE";
211 0 : case ODS_MIN : return "MIN";
212 0 : case ODS_MAX : return "MAX";
213 0 : case ODS_COUNT : return "COUNT";
214 0 : case ODS_COUNTA : return "COUNTA";
215 :
216 0 : case ODS_EQ : return "=";
217 0 : case ODS_NE : return "<>";
218 0 : case ODS_GE : return ">=";
219 0 : case ODS_LE : return "<=";
220 0 : case ODS_LT : return "<";
221 0 : case ODS_GT : return ">";
222 :
223 0 : case ODS_ADD : return "+";
224 0 : case ODS_SUBTRACT : return "-";
225 0 : case ODS_MULTIPLY : return "*";
226 0 : case ODS_DIVIDE : return "/";
227 0 : case ODS_MODULUS : return "MOD";
228 0 : case ODS_CONCAT : return "&";
229 :
230 0 : case ODS_LIST : return "*list*";
231 0 : case ODS_CELL : return "*cell*";
232 0 : case ODS_CELL_RANGE : return "*cell_range*";
233 : default:
234 : {
235 0 : const SingleOpStruct* psSingleOp = ODSGetSingleOpEntry(eOp);
236 0 : if (psSingleOp != NULL)
237 0 : return psSingleOp->pszName;
238 0 : return "*unknown*";
239 : }
240 : }
241 : }
242 :
243 : /************************************************************************/
244 : /* Dump() */
245 : /************************************************************************/
246 :
247 0 : void ods_formula_node::Dump( FILE * fp, int depth )
248 :
249 : {
250 : char spaces[60];
251 : int i;
252 :
253 0 : for( i = 0; i < depth*2 && i < (int) sizeof(spaces); i++ )
254 0 : spaces[i] = ' ';
255 0 : spaces[i] = '\0';
256 :
257 0 : if( eNodeType == SNT_CONSTANT )
258 : {
259 0 : if( field_type == ODS_FIELD_TYPE_INTEGER )
260 0 : fprintf( fp, "%s %d\n", spaces, int_value );
261 0 : else if( field_type == ODS_FIELD_TYPE_FLOAT )
262 0 : fprintf( fp, "%s %.15g\n", spaces, float_value );
263 : else
264 0 : fprintf( fp, "%s \"%s\"\n", spaces, string_value );
265 0 : return;
266 : }
267 :
268 0 : CPLAssert( eNodeType == SNT_OPERATION );
269 :
270 0 : fprintf( fp, "%s%s\n", spaces, ODSGetOperatorName(eOp) );
271 :
272 0 : for( i = 0; i < nSubExprCount; i++ )
273 0 : papoSubExpr[i]->Dump( fp, depth+1 );
274 : }
275 :
276 : /************************************************************************/
277 : /* FreeSubExpr() */
278 : /************************************************************************/
279 :
280 1278 : void ods_formula_node::FreeSubExpr()
281 : {
282 : int i;
283 1844 : for( i = 0; i < nSubExprCount; i++ )
284 566 : delete papoSubExpr[i];
285 1278 : CPLFree( papoSubExpr );
286 :
287 1278 : nSubExprCount = 0;
288 1278 : papoSubExpr = NULL;
289 1278 : }
290 :
291 : /************************************************************************/
292 : /* Evaluate() */
293 : /************************************************************************/
294 :
295 678 : int ods_formula_node::Evaluate(IODSCellEvaluator* poEvaluator)
296 : {
297 678 : if (eNodeType == SNT_CONSTANT)
298 384 : return TRUE;
299 :
300 294 : CPLAssert( eNodeType == SNT_OPERATION );
301 :
302 294 : switch (eOp)
303 : {
304 8 : case ODS_OR: return EvaluateOR(poEvaluator);
305 8 : case ODS_AND: return EvaluateAND(poEvaluator);
306 4 : case ODS_NOT: return EvaluateNOT(poEvaluator);
307 8 : case ODS_IF: return EvaluateIF(poEvaluator);
308 :
309 : case ODS_PI:
310 2 : eNodeType = SNT_CONSTANT;
311 2 : field_type = ODS_FIELD_TYPE_FLOAT;
312 2 : float_value = PI;
313 2 : return TRUE;
314 :
315 2 : case ODS_LEN : return EvaluateLEN(poEvaluator);
316 6 : case ODS_LEFT : return EvaluateLEFT(poEvaluator);
317 6 : case ODS_RIGHT : return EvaluateRIGHT(poEvaluator);
318 16 : case ODS_MID : return EvaluateMID(poEvaluator);
319 :
320 : case ODS_SUM:
321 : case ODS_AVERAGE:
322 : case ODS_MIN:
323 : case ODS_MAX:
324 : case ODS_COUNT:
325 : case ODS_COUNTA:
326 12 : return EvaluateListArgOp(poEvaluator);
327 :
328 : case ODS_ABS:
329 : case ODS_SQRT:
330 : case ODS_COS:
331 : case ODS_SIN:
332 : case ODS_TAN:
333 : case ODS_ACOS:
334 : case ODS_ASIN:
335 : case ODS_ATAN:
336 : case ODS_EXP:
337 : case ODS_LN:
338 : case ODS_LOG:
339 18 : return EvaluateSingleArgOp(poEvaluator);
340 :
341 :
342 20 : case ODS_EQ: return EvaluateEQ(poEvaluator);
343 20 : case ODS_NE: return EvaluateNE(poEvaluator);
344 20 : case ODS_LE: return EvaluateLE(poEvaluator);
345 20 : case ODS_GE: return EvaluateGE(poEvaluator);
346 28 : case ODS_LT: return EvaluateLT(poEvaluator);
347 20 : case ODS_GT: return EvaluateGT(poEvaluator);
348 :
349 : case ODS_ADD:
350 : case ODS_SUBTRACT:
351 : case ODS_MULTIPLY:
352 : case ODS_DIVIDE:
353 : case ODS_MODULUS:
354 18 : return EvaluateBinaryArithmetic(poEvaluator);
355 :
356 2 : case ODS_CONCAT: return EvaluateCONCAT(poEvaluator);
357 :
358 56 : case ODS_CELL: return EvaluateCELL(poEvaluator);
359 :
360 : default:
361 : {
362 : CPLError(CE_Failure, CPLE_AppDefined,
363 : "Unhandled case in Evaluate() for %s",
364 0 : ODSGetOperatorName(eOp));
365 0 : return FALSE;
366 : }
367 : }
368 : }
369 :
370 : /************************************************************************/
371 : /* EvaluateOR() */
372 : /************************************************************************/
373 :
374 8 : int ods_formula_node::EvaluateOR(IODSCellEvaluator* poEvaluator)
375 : {
376 8 : CPLAssert( eNodeType == SNT_OPERATION );
377 8 : CPLAssert( eOp == ODS_OR );
378 :
379 8 : CPLAssert(nSubExprCount == 1);
380 8 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_OPERATION );
381 8 : CPLAssert(papoSubExpr[0]->eOp == ODS_LIST );
382 8 : int bVal = FALSE;
383 24 : for(int i = 0; i < papoSubExpr[0]->nSubExprCount; i++)
384 : {
385 16 : if (!(papoSubExpr[0]->papoSubExpr[i]->Evaluate(poEvaluator)))
386 0 : return FALSE;
387 16 : CPLAssert(papoSubExpr[0]->papoSubExpr[i]->eNodeType == SNT_CONSTANT );
388 16 : if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_INTEGER)
389 : {
390 16 : bVal |= (papoSubExpr[0]->papoSubExpr[i]->int_value != 0);
391 : }
392 0 : else if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_FLOAT)
393 : {
394 0 : bVal |= (papoSubExpr[0]->papoSubExpr[i]->float_value != 0);
395 : }
396 : else
397 : {
398 : CPLError(CE_Failure, CPLE_NotSupported,
399 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
400 0 : return FALSE;
401 : }
402 : }
403 :
404 8 : FreeSubExpr();
405 :
406 8 : eNodeType = SNT_CONSTANT;
407 8 : field_type = ODS_FIELD_TYPE_INTEGER;
408 8 : int_value = bVal;
409 :
410 8 : return TRUE;
411 : }
412 :
413 : /************************************************************************/
414 : /* EvaluateAND() */
415 : /************************************************************************/
416 :
417 8 : int ods_formula_node::EvaluateAND(IODSCellEvaluator* poEvaluator)
418 : {
419 8 : CPLAssert( eNodeType == SNT_OPERATION );
420 8 : CPLAssert( eOp == ODS_AND );
421 :
422 8 : CPLAssert(nSubExprCount == 1);
423 8 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_OPERATION );
424 8 : CPLAssert(papoSubExpr[0]->eOp == ODS_LIST );
425 8 : int bVal = TRUE;
426 24 : for(int i = 0; i < papoSubExpr[0]->nSubExprCount; i++)
427 : {
428 16 : if (!(papoSubExpr[0]->papoSubExpr[i]->Evaluate(poEvaluator)))
429 0 : return FALSE;
430 16 : CPLAssert(papoSubExpr[0]->papoSubExpr[i]->eNodeType == SNT_CONSTANT );
431 16 : if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_INTEGER)
432 : {
433 16 : bVal &= (papoSubExpr[0]->papoSubExpr[i]->int_value != 0);
434 : }
435 0 : else if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_FLOAT)
436 : {
437 0 : bVal &= (papoSubExpr[0]->papoSubExpr[i]->float_value != 0);
438 : }
439 : else
440 : {
441 : CPLError(CE_Failure, CPLE_NotSupported,
442 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
443 0 : return FALSE;
444 : }
445 : }
446 :
447 8 : FreeSubExpr();
448 :
449 8 : eNodeType = SNT_CONSTANT;
450 8 : field_type = ODS_FIELD_TYPE_INTEGER;
451 8 : int_value = bVal;
452 :
453 8 : return TRUE;
454 : }
455 :
456 : /************************************************************************/
457 : /* EvaluateNOT() */
458 : /************************************************************************/
459 :
460 4 : int ods_formula_node::EvaluateNOT(IODSCellEvaluator* poEvaluator)
461 : {
462 4 : CPLAssert( eNodeType == SNT_OPERATION );
463 4 : CPLAssert( eOp == ODS_NOT );
464 :
465 4 : CPLAssert(nSubExprCount == 1);
466 4 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
467 0 : return FALSE;
468 4 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
469 :
470 4 : int bVal = FALSE;
471 4 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
472 : {
473 4 : bVal = !(papoSubExpr[0]->int_value != 0);
474 : }
475 0 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
476 : {
477 0 : bVal = !(papoSubExpr[0]->float_value != 0);
478 : }
479 : else
480 : {
481 : CPLError(CE_Failure, CPLE_NotSupported,
482 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
483 0 : return FALSE;
484 : }
485 :
486 4 : FreeSubExpr();
487 :
488 4 : eNodeType = SNT_CONSTANT;
489 4 : field_type = ODS_FIELD_TYPE_INTEGER;
490 4 : int_value = bVal;
491 :
492 4 : return TRUE;
493 : }
494 :
495 : /************************************************************************/
496 : /* EvaluateIF() */
497 : /************************************************************************/
498 :
499 8 : int ods_formula_node::EvaluateIF(IODSCellEvaluator* poEvaluator)
500 : {
501 8 : CPLAssert( eNodeType == SNT_OPERATION );
502 8 : CPLAssert( eOp == ODS_IF );
503 :
504 8 : CPLAssert(nSubExprCount == 2 || nSubExprCount == 3);
505 8 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
506 0 : return FALSE;
507 8 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
508 0 : return FALSE;
509 8 : if (nSubExprCount == 3 && !(papoSubExpr[2]->Evaluate(poEvaluator)))
510 0 : return FALSE;
511 :
512 8 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
513 8 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
514 8 : if (nSubExprCount == 3)
515 4 : CPLAssert(papoSubExpr[2]->eNodeType == SNT_CONSTANT );
516 :
517 8 : int bCond = FALSE;
518 8 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
519 : {
520 8 : bCond = (papoSubExpr[0]->int_value != 0);
521 : }
522 0 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
523 : {
524 0 : bCond = (papoSubExpr[0]->float_value != 0);
525 : }
526 : else
527 : {
528 : CPLError(CE_Failure, CPLE_NotSupported,
529 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
530 0 : return FALSE;
531 : }
532 :
533 8 : if (bCond)
534 : {
535 4 : eNodeType = SNT_CONSTANT;
536 4 : field_type = papoSubExpr[1]->field_type;
537 4 : if (field_type == ODS_FIELD_TYPE_INTEGER)
538 4 : int_value = papoSubExpr[1]->int_value;
539 0 : else if (field_type == ODS_FIELD_TYPE_FLOAT)
540 0 : float_value = papoSubExpr[1]->float_value;
541 0 : else if (field_type == ODS_FIELD_TYPE_STRING)
542 : {
543 0 : string_value = papoSubExpr[1]->string_value;
544 0 : papoSubExpr[1]->string_value = NULL;
545 : }
546 : }
547 4 : else if (nSubExprCount == 3)
548 : {
549 2 : eNodeType = SNT_CONSTANT;
550 2 : field_type = papoSubExpr[2]->field_type;
551 2 : if (field_type == ODS_FIELD_TYPE_INTEGER)
552 2 : int_value = papoSubExpr[2]->int_value;
553 0 : else if (field_type == ODS_FIELD_TYPE_FLOAT)
554 0 : float_value = papoSubExpr[2]->float_value;
555 0 : else if (field_type == ODS_FIELD_TYPE_STRING)
556 : {
557 0 : string_value = papoSubExpr[2]->string_value;
558 0 : papoSubExpr[2]->string_value = NULL;
559 : }
560 : }
561 : else
562 : {
563 2 : eNodeType = SNT_CONSTANT;
564 2 : field_type = ODS_FIELD_TYPE_INTEGER;
565 2 : int_value = FALSE;
566 : }
567 :
568 8 : FreeSubExpr();
569 :
570 8 : return TRUE;
571 : }
572 :
573 : /************************************************************************/
574 : /* EvaluateEQ() */
575 : /************************************************************************/
576 :
577 40 : int ods_formula_node::EvaluateEQ(IODSCellEvaluator* poEvaluator)
578 : {
579 40 : CPLAssert( eNodeType == SNT_OPERATION );
580 40 : CPLAssert( eOp == ODS_EQ );
581 :
582 40 : CPLAssert(nSubExprCount == 2);
583 40 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
584 0 : return FALSE;
585 40 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
586 0 : return FALSE;
587 :
588 40 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
589 40 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
590 :
591 40 : int bVal = FALSE;
592 40 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
593 : {
594 16 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
595 : {
596 8 : bVal = (papoSubExpr[0]->int_value == papoSubExpr[1]->int_value);
597 : }
598 8 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
599 : {
600 8 : bVal = (papoSubExpr[0]->int_value == papoSubExpr[1]->float_value);
601 : }
602 : }
603 24 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
604 : {
605 16 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
606 : {
607 8 : bVal = (papoSubExpr[0]->float_value == papoSubExpr[1]->int_value);
608 : }
609 8 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
610 : {
611 8 : bVal = (papoSubExpr[0]->float_value == papoSubExpr[1]->float_value);
612 : }
613 : }
614 8 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING)
615 : {
616 8 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_STRING)
617 : {
618 8 : bVal = (strcmp(papoSubExpr[0]->string_value,
619 16 : papoSubExpr[1]->string_value) == 0);
620 : }
621 : }
622 : else
623 : {
624 : CPLError(CE_Failure, CPLE_NotSupported,
625 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
626 0 : return FALSE;
627 : }
628 :
629 40 : eNodeType = SNT_CONSTANT;
630 40 : field_type = ODS_FIELD_TYPE_INTEGER;
631 40 : int_value = bVal;
632 :
633 40 : FreeSubExpr();
634 :
635 40 : return TRUE;
636 : }
637 :
638 : /************************************************************************/
639 : /* EvaluateNE() */
640 : /************************************************************************/
641 :
642 20 : int ods_formula_node::EvaluateNE(IODSCellEvaluator* poEvaluator)
643 : {
644 20 : CPLAssert( eNodeType == SNT_OPERATION );
645 20 : CPLAssert( eOp == ODS_NE );
646 :
647 20 : eOp = ODS_EQ;
648 20 : if (!EvaluateEQ(poEvaluator))
649 0 : return FALSE;
650 :
651 20 : int_value = !int_value;
652 20 : return TRUE;
653 : }
654 :
655 : /************************************************************************/
656 : /* GetCase() */
657 : /************************************************************************/
658 :
659 : typedef enum
660 : {
661 : CASE_LOWER,
662 : CASE_UPPER,
663 : CASE_UNKNOWN,
664 : } CaseType;
665 :
666 48 : static CaseType GetCase(const char* pszStr)
667 : {
668 48 : int bInit = TRUE;
669 : char ch;
670 48 : CaseType eCase = CASE_UNKNOWN;
671 144 : while((ch = *(pszStr++)) != '\0')
672 : {
673 48 : if (bInit)
674 : {
675 56 : if (ch >= 'a' && ch <= 'z')
676 8 : eCase = CASE_LOWER;
677 80 : else if (ch >= 'A' && ch <= 'Z')
678 40 : eCase = CASE_UPPER;
679 : else
680 0 : return CASE_UNKNOWN;
681 : }
682 0 : else if (ch >= 'a' && ch <= 'z' && eCase == CASE_LOWER)
683 : ;
684 0 : else if (ch >= 'A' && ch <= 'Z' && eCase == CASE_UPPER)
685 : ;
686 : else
687 0 : return CASE_UNKNOWN;
688 : }
689 48 : return eCase;
690 : }
691 :
692 : /************************************************************************/
693 : /* EvaluateLE() */
694 : /************************************************************************/
695 :
696 20 : int ods_formula_node::EvaluateLE(IODSCellEvaluator* poEvaluator)
697 : {
698 20 : CPLAssert( eNodeType == SNT_OPERATION );
699 20 : CPLAssert( eOp == ODS_LE );
700 :
701 20 : CPLAssert(nSubExprCount == 2);
702 20 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
703 0 : return FALSE;
704 20 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
705 0 : return FALSE;
706 :
707 20 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
708 20 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
709 :
710 20 : int bVal = FALSE;
711 20 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
712 : {
713 8 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
714 : {
715 4 : bVal = (papoSubExpr[0]->int_value <= papoSubExpr[1]->int_value);
716 : }
717 4 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
718 : {
719 4 : bVal = (papoSubExpr[0]->int_value <= papoSubExpr[1]->float_value);
720 : }
721 : else
722 0 : bVal = TRUE;
723 : }
724 12 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
725 : {
726 8 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
727 : {
728 4 : bVal = (papoSubExpr[0]->float_value <= papoSubExpr[1]->int_value);
729 : }
730 4 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
731 : {
732 4 : bVal = (papoSubExpr[0]->float_value <= papoSubExpr[1]->float_value);
733 : }
734 : else
735 0 : bVal = TRUE;
736 : }
737 4 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING)
738 : {
739 4 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_STRING)
740 : {
741 8 : if (GetCase(papoSubExpr[0]->string_value) ==
742 4 : GetCase(papoSubExpr[1]->string_value))
743 4 : bVal = (strcmp(papoSubExpr[0]->string_value,
744 8 : papoSubExpr[1]->string_value) <= 0);
745 : else
746 0 : bVal = (strcasecmp(papoSubExpr[0]->string_value,
747 0 : papoSubExpr[1]->string_value) <= 0);
748 : }
749 : }
750 : else
751 : {
752 : CPLError(CE_Failure, CPLE_NotSupported,
753 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
754 0 : return FALSE;
755 : }
756 :
757 20 : eNodeType = SNT_CONSTANT;
758 20 : field_type = ODS_FIELD_TYPE_INTEGER;
759 20 : int_value = bVal;
760 :
761 20 : FreeSubExpr();
762 :
763 20 : return TRUE;
764 : }
765 :
766 : /************************************************************************/
767 : /* EvaluateGE() */
768 : /************************************************************************/
769 :
770 20 : int ods_formula_node::EvaluateGE(IODSCellEvaluator* poEvaluator)
771 : {
772 20 : CPLAssert( eNodeType == SNT_OPERATION );
773 20 : CPLAssert( eOp == ODS_GE );
774 :
775 20 : CPLAssert(nSubExprCount == 2);
776 20 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
777 0 : return FALSE;
778 20 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
779 0 : return FALSE;
780 :
781 20 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
782 20 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
783 :
784 20 : int bVal = FALSE;
785 20 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
786 : {
787 8 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
788 : {
789 4 : bVal = (papoSubExpr[0]->int_value >= papoSubExpr[1]->int_value);
790 : }
791 4 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
792 : {
793 4 : bVal = (papoSubExpr[0]->int_value >= papoSubExpr[1]->float_value);
794 : }
795 : }
796 12 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
797 : {
798 8 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
799 : {
800 4 : bVal = (papoSubExpr[0]->float_value >= papoSubExpr[1]->int_value);
801 : }
802 4 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
803 : {
804 4 : bVal = (papoSubExpr[0]->float_value >= papoSubExpr[1]->float_value);
805 : }
806 : }
807 4 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING)
808 : {
809 4 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_STRING)
810 : {
811 8 : if (GetCase(papoSubExpr[0]->string_value) ==
812 4 : GetCase(papoSubExpr[1]->string_value))
813 4 : bVal = (strcmp(papoSubExpr[0]->string_value,
814 8 : papoSubExpr[1]->string_value) >= 0);
815 : else
816 0 : bVal = (strcasecmp(papoSubExpr[0]->string_value,
817 0 : papoSubExpr[1]->string_value) >= 0);
818 : }
819 : else
820 0 : bVal = TRUE;
821 : }
822 : else
823 : {
824 : CPLError(CE_Failure, CPLE_NotSupported,
825 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
826 0 : return FALSE;
827 : }
828 :
829 20 : eNodeType = SNT_CONSTANT;
830 20 : field_type = ODS_FIELD_TYPE_INTEGER;
831 20 : int_value = bVal;
832 :
833 20 : FreeSubExpr();
834 :
835 20 : return TRUE;
836 : }
837 :
838 : /************************************************************************/
839 : /* EvaluateLT() */
840 : /************************************************************************/
841 :
842 28 : int ods_formula_node::EvaluateLT(IODSCellEvaluator* poEvaluator)
843 : {
844 28 : CPLAssert( eNodeType == SNT_OPERATION );
845 28 : CPLAssert( eOp == ODS_LT );
846 :
847 28 : CPLAssert(nSubExprCount == 2);
848 28 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
849 0 : return FALSE;
850 28 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
851 0 : return FALSE;
852 :
853 28 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
854 28 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
855 :
856 28 : int bVal = FALSE;
857 28 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
858 : {
859 8 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
860 : {
861 4 : bVal = (papoSubExpr[0]->int_value < papoSubExpr[1]->int_value);
862 : }
863 4 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
864 : {
865 4 : bVal = (papoSubExpr[0]->int_value < papoSubExpr[1]->float_value);
866 : }
867 : else
868 0 : bVal = TRUE;
869 : }
870 20 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
871 : {
872 8 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
873 : {
874 4 : bVal = (papoSubExpr[0]->float_value < papoSubExpr[1]->int_value);
875 : }
876 4 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
877 : {
878 4 : bVal = (papoSubExpr[0]->float_value < papoSubExpr[1]->float_value);
879 : }
880 : else
881 0 : bVal = TRUE;
882 : }
883 12 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING)
884 : {
885 12 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_STRING)
886 : {
887 24 : if (GetCase(papoSubExpr[0]->string_value) ==
888 12 : GetCase(papoSubExpr[1]->string_value))
889 4 : bVal = (strcmp(papoSubExpr[0]->string_value,
890 8 : papoSubExpr[1]->string_value) < 0);
891 : else
892 8 : bVal = (strcasecmp(papoSubExpr[0]->string_value,
893 16 : papoSubExpr[1]->string_value) < 0);
894 : }
895 : }
896 : else
897 : {
898 : CPLError(CE_Failure, CPLE_NotSupported,
899 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
900 0 : return FALSE;
901 : }
902 :
903 28 : eNodeType = SNT_CONSTANT;
904 28 : field_type = ODS_FIELD_TYPE_INTEGER;
905 28 : int_value = bVal;
906 :
907 28 : FreeSubExpr();
908 :
909 28 : return TRUE;
910 : }
911 :
912 : /************************************************************************/
913 : /* EvaluateGT() */
914 : /************************************************************************/
915 :
916 20 : int ods_formula_node::EvaluateGT(IODSCellEvaluator* poEvaluator)
917 : {
918 20 : CPLAssert( eNodeType == SNT_OPERATION );
919 20 : CPLAssert( eOp == ODS_GT );
920 :
921 20 : CPLAssert(nSubExprCount == 2);
922 20 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
923 0 : return FALSE;
924 20 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
925 0 : return FALSE;
926 :
927 20 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
928 20 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
929 :
930 20 : int bVal = FALSE;
931 20 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
932 : {
933 8 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
934 : {
935 4 : bVal = (papoSubExpr[0]->int_value > papoSubExpr[1]->int_value);
936 : }
937 4 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
938 : {
939 4 : bVal = (papoSubExpr[0]->int_value > papoSubExpr[1]->float_value);
940 : }
941 : }
942 12 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
943 : {
944 8 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
945 : {
946 4 : bVal = (papoSubExpr[0]->float_value > papoSubExpr[1]->int_value);
947 : }
948 4 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
949 : {
950 4 : bVal = (papoSubExpr[0]->float_value > papoSubExpr[1]->float_value);
951 : }
952 : }
953 4 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING)
954 : {
955 4 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_STRING)
956 : {
957 8 : if (GetCase(papoSubExpr[0]->string_value) ==
958 4 : GetCase(papoSubExpr[1]->string_value))
959 4 : bVal = (strcmp(papoSubExpr[0]->string_value,
960 8 : papoSubExpr[1]->string_value) > 0);
961 : else
962 0 : bVal = (strcasecmp(papoSubExpr[0]->string_value,
963 0 : papoSubExpr[1]->string_value) > 0);
964 : }
965 : else
966 0 : bVal = TRUE;
967 : }
968 : else
969 : {
970 : CPLError(CE_Failure, CPLE_NotSupported,
971 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
972 0 : return FALSE;
973 : }
974 :
975 20 : eNodeType = SNT_CONSTANT;
976 20 : field_type = ODS_FIELD_TYPE_INTEGER;
977 20 : int_value = bVal;
978 :
979 20 : FreeSubExpr();
980 :
981 20 : return TRUE;
982 : }
983 :
984 : /************************************************************************/
985 : /* EvaluateSingleArgOp() */
986 : /************************************************************************/
987 :
988 18 : int ods_formula_node::EvaluateSingleArgOp(IODSCellEvaluator* poEvaluator)
989 : {
990 18 : CPLAssert( eNodeType == SNT_OPERATION );
991 :
992 18 : const SingleOpStruct* psSingleOp = ODSGetSingleOpEntry(eOp);
993 18 : CPLAssert(psSingleOp);
994 :
995 18 : CPLAssert(nSubExprCount == 1);
996 18 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
997 0 : return FALSE;
998 :
999 18 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1000 18 : double dfVal = 0;
1001 :
1002 18 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
1003 : {
1004 2 : dfVal = psSingleOp->pfnEval(papoSubExpr[0]->int_value);
1005 : }
1006 16 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
1007 : {
1008 16 : dfVal = psSingleOp->pfnEval(papoSubExpr[0]->float_value);
1009 : }
1010 : else
1011 : {
1012 : CPLError(CE_Failure, CPLE_NotSupported, "Bad argument type for %s",
1013 0 : psSingleOp->pszName);
1014 0 : return FALSE;
1015 : }
1016 :
1017 18 : eNodeType = SNT_CONSTANT;
1018 18 : field_type = ODS_FIELD_TYPE_FLOAT;
1019 18 : float_value = dfVal;
1020 :
1021 18 : FreeSubExpr();
1022 :
1023 18 : return TRUE;
1024 : }
1025 :
1026 : /************************************************************************/
1027 : /* EvaluateBinaryArithmetic() */
1028 : /************************************************************************/
1029 :
1030 18 : int ods_formula_node::EvaluateBinaryArithmetic(IODSCellEvaluator* poEvaluator)
1031 : {
1032 18 : CPLAssert( eNodeType == SNT_OPERATION );
1033 18 : CPLAssert( eOp >= ODS_ADD && eOp<= ODS_MODULUS );
1034 :
1035 18 : CPLAssert(nSubExprCount == 2);
1036 18 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
1037 0 : return FALSE;
1038 18 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
1039 0 : return FALSE;
1040 :
1041 18 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1042 18 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
1043 :
1044 18 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
1045 : {
1046 12 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
1047 : {
1048 : int nVal;
1049 8 : switch (eOp)
1050 : {
1051 2 : case ODS_ADD : nVal = (papoSubExpr[0]->int_value + papoSubExpr[1]->int_value); break;
1052 2 : case ODS_SUBTRACT : nVal = (papoSubExpr[0]->int_value - papoSubExpr[1]->int_value); break;
1053 2 : case ODS_MULTIPLY : nVal = (papoSubExpr[0]->int_value * papoSubExpr[1]->int_value); break;
1054 : case ODS_DIVIDE :
1055 2 : if (papoSubExpr[1]->int_value != 0)
1056 2 : nVal = (papoSubExpr[0]->int_value / papoSubExpr[1]->int_value);
1057 : else
1058 0 : return FALSE;
1059 2 : break;
1060 : case ODS_MODULUS :
1061 0 : if (papoSubExpr[1]->int_value != 0)
1062 0 : nVal = (papoSubExpr[0]->int_value % papoSubExpr[1]->int_value);
1063 : else
1064 0 : return FALSE;
1065 0 : break;
1066 0 : default: CPLAssert(0);
1067 : }
1068 :
1069 8 : eNodeType = SNT_CONSTANT;
1070 8 : field_type = ODS_FIELD_TYPE_INTEGER;
1071 8 : int_value = nVal;
1072 :
1073 8 : FreeSubExpr();
1074 :
1075 8 : return TRUE;
1076 : }
1077 4 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
1078 : {
1079 4 : papoSubExpr[0]->field_type = ODS_FIELD_TYPE_FLOAT;
1080 4 : papoSubExpr[0]->float_value = papoSubExpr[0]->int_value;
1081 : }
1082 : else
1083 : {
1084 : CPLError(CE_Failure, CPLE_NotSupported,
1085 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
1086 0 : return FALSE;
1087 : }
1088 : }
1089 :
1090 10 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
1091 : {
1092 10 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
1093 : {
1094 4 : papoSubExpr[1]->field_type = ODS_FIELD_TYPE_FLOAT;
1095 4 : papoSubExpr[1]->float_value = papoSubExpr[1]->int_value;
1096 : }
1097 :
1098 10 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
1099 : {
1100 : float dfVal;
1101 10 : switch (eOp)
1102 : {
1103 0 : case ODS_ADD : dfVal = (papoSubExpr[0]->float_value + papoSubExpr[1]->float_value); break;
1104 0 : case ODS_SUBTRACT : dfVal = (papoSubExpr[0]->float_value - papoSubExpr[1]->float_value); break;
1105 6 : case ODS_MULTIPLY : dfVal = (papoSubExpr[0]->float_value * papoSubExpr[1]->float_value); break;
1106 : case ODS_DIVIDE :
1107 2 : if (papoSubExpr[1]->float_value != 0)
1108 2 : dfVal = (papoSubExpr[0]->float_value / papoSubExpr[1]->float_value);
1109 : else
1110 0 : return FALSE;
1111 2 : break;
1112 : case ODS_MODULUS :
1113 2 : if (papoSubExpr[1]->float_value != 0)
1114 2 : dfVal = fmod(papoSubExpr[0]->float_value, papoSubExpr[1]->float_value);
1115 : else
1116 0 : return FALSE;
1117 2 : break;
1118 0 : default: CPLAssert(0);
1119 : }
1120 :
1121 10 : eNodeType = SNT_CONSTANT;
1122 10 : field_type = ODS_FIELD_TYPE_FLOAT;
1123 10 : float_value = dfVal;
1124 :
1125 10 : FreeSubExpr();
1126 :
1127 10 : return TRUE;
1128 : }
1129 : else
1130 : {
1131 : CPLError(CE_Failure, CPLE_NotSupported,
1132 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
1133 0 : return FALSE;
1134 : }
1135 : }
1136 : else
1137 : {
1138 : CPLError(CE_Failure, CPLE_NotSupported,
1139 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
1140 0 : return FALSE;
1141 : }
1142 : }
1143 :
1144 :
1145 : /************************************************************************/
1146 : /* TransformToString() */
1147 : /************************************************************************/
1148 :
1149 34 : std::string ods_formula_node::TransformToString() const
1150 : {
1151 : char szTmp[128];
1152 34 : if (field_type == ODS_FIELD_TYPE_INTEGER)
1153 : {
1154 0 : snprintf(szTmp, sizeof(szTmp), "%d", int_value);
1155 0 : return szTmp;
1156 : }
1157 34 : else if (field_type == ODS_FIELD_TYPE_FLOAT)
1158 : {
1159 0 : snprintf(szTmp, sizeof(szTmp), "%.16g", float_value);
1160 0 : return szTmp;
1161 : }
1162 34 : else if (field_type == ODS_FIELD_TYPE_STRING)
1163 : {
1164 34 : return string_value;
1165 : }
1166 : else
1167 : {
1168 0 : return "";
1169 : }
1170 : }
1171 :
1172 : /************************************************************************/
1173 : /* EvaluateCONCAT() */
1174 : /************************************************************************/
1175 :
1176 2 : int ods_formula_node::EvaluateCONCAT(IODSCellEvaluator* poEvaluator)
1177 : {
1178 2 : CPLAssert( eNodeType == SNT_OPERATION );
1179 2 : CPLAssert( eOp == ODS_CONCAT );
1180 :
1181 2 : CPLAssert(nSubExprCount == 2);
1182 2 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
1183 0 : return FALSE;
1184 2 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
1185 0 : return FALSE;
1186 :
1187 2 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1188 2 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
1189 :
1190 2 : std::string osLeft(papoSubExpr[0]->TransformToString());
1191 2 : std::string osRight(papoSubExpr[1]->TransformToString());
1192 :
1193 2 : eNodeType = SNT_CONSTANT;
1194 2 : field_type = ODS_FIELD_TYPE_STRING;
1195 2 : string_value = CPLStrdup((osLeft + osRight).c_str());
1196 :
1197 2 : FreeSubExpr();
1198 :
1199 2 : return TRUE;
1200 : }
1201 :
1202 : /************************************************************************/
1203 : /* GetRowCol() */
1204 : /************************************************************************/
1205 :
1206 80 : static int GetRowCol(const char* pszCell, int& nRow, int& nCol)
1207 : {
1208 : int i;
1209 :
1210 80 : if (pszCell[0] != '.')
1211 : {
1212 : CPLError(CE_Failure, CPLE_AppDefined,
1213 0 : "Invalid cell %s", pszCell);
1214 0 : return FALSE;
1215 : }
1216 :
1217 80 : nCol = 0;
1218 160 : for(i=1; pszCell[i]>='A' && pszCell[i]<='Z';i++)
1219 : {
1220 80 : nCol = nCol * 26 + (pszCell[i] - 'A');
1221 : }
1222 80 : nRow = atoi(pszCell + i) - 1;
1223 :
1224 80 : return TRUE;
1225 : }
1226 :
1227 : /************************************************************************/
1228 : /* EvaluateListArgOp() */
1229 : /************************************************************************/
1230 :
1231 12 : int ods_formula_node::EvaluateListArgOp(IODSCellEvaluator* poEvaluator)
1232 : {
1233 12 : CPLAssert( eNodeType == SNT_OPERATION );
1234 12 : CPLAssert( eOp >= ODS_SUM && eOp <= ODS_COUNTA );
1235 :
1236 12 : CPLAssert(nSubExprCount == 1);
1237 12 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_OPERATION );
1238 12 : CPLAssert(papoSubExpr[0]->eOp == ODS_LIST );
1239 :
1240 12 : std::vector<double> adfVal;
1241 : int i;
1242 :
1243 12 : int nCount = 0, nCountA = 0;
1244 :
1245 26 : for(i=0;i<papoSubExpr[0]->nSubExprCount;i++)
1246 : {
1247 38 : if (papoSubExpr[0]->papoSubExpr[i]->eNodeType == SNT_OPERATION &&
1248 12 : papoSubExpr[0]->papoSubExpr[i]->eOp == ODS_CELL_RANGE)
1249 : {
1250 12 : CPLAssert (papoSubExpr[0]->papoSubExpr[i]->nSubExprCount == 2);
1251 12 : CPLAssert (papoSubExpr[0]->papoSubExpr[i]->papoSubExpr[0]->eNodeType == SNT_CONSTANT);
1252 12 : CPLAssert (papoSubExpr[0]->papoSubExpr[i]->papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING);
1253 12 : CPLAssert (papoSubExpr[0]->papoSubExpr[i]->papoSubExpr[1]->eNodeType == SNT_CONSTANT);
1254 12 : CPLAssert (papoSubExpr[0]->papoSubExpr[i]->papoSubExpr[1]->field_type == ODS_FIELD_TYPE_STRING);
1255 :
1256 12 : if (poEvaluator == NULL)
1257 : {
1258 0 : CPLError(CE_Failure, CPLE_AppDefined, "No cell evaluator provided");
1259 0 : return FALSE;
1260 : }
1261 :
1262 12 : const char* psz1 = papoSubExpr[0]->papoSubExpr[i]->papoSubExpr[0]->string_value;
1263 12 : const char* psz2 = papoSubExpr[0]->papoSubExpr[i]->papoSubExpr[1]->string_value;
1264 12 : int nRow1 = 0,nCol1 = 0;
1265 12 : if (!GetRowCol(psz1, nRow1, nCol1))
1266 0 : return FALSE;
1267 12 : int nRow2 = 0,nCol2 = 0;
1268 12 : if (!GetRowCol(psz2, nRow2, nCol2))
1269 0 : return FALSE;
1270 :
1271 12 : std::vector<ods_formula_node> aoOutValues;
1272 12 : if (poEvaluator->EvaluateRange(nRow1, nCol1, nRow2, nCol2, aoOutValues))
1273 : {
1274 60 : for(size_t j = 0; j < aoOutValues.size(); j++)
1275 : {
1276 48 : if (aoOutValues[j].eNodeType == SNT_CONSTANT)
1277 : {
1278 48 : if (aoOutValues[j].field_type == ODS_FIELD_TYPE_INTEGER)
1279 : {
1280 0 : adfVal.push_back(aoOutValues[j].int_value);
1281 0 : nCount ++;
1282 0 : nCountA ++;
1283 : }
1284 48 : else if (aoOutValues[j].field_type == ODS_FIELD_TYPE_FLOAT)
1285 : {
1286 24 : adfVal.push_back(aoOutValues[j].float_value);
1287 24 : nCount ++;
1288 24 : nCountA ++;
1289 : }
1290 24 : else if (aoOutValues[j].field_type == ODS_FIELD_TYPE_STRING)
1291 : {
1292 12 : nCountA ++;
1293 : }
1294 : }
1295 : }
1296 12 : }
1297 : }
1298 : else
1299 : {
1300 2 : if (!(papoSubExpr[0]->papoSubExpr[i]->Evaluate(poEvaluator)))
1301 0 : return FALSE;
1302 :
1303 2 : CPLAssert (papoSubExpr[0]->papoSubExpr[i]->eNodeType == SNT_CONSTANT );
1304 2 : if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_INTEGER)
1305 : {
1306 2 : adfVal.push_back(papoSubExpr[0]->papoSubExpr[i]->int_value);
1307 2 : nCount ++;
1308 2 : nCountA ++;
1309 : }
1310 0 : else if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_FLOAT)
1311 : {
1312 0 : adfVal.push_back(papoSubExpr[0]->papoSubExpr[i]->float_value);
1313 0 : nCount ++;
1314 0 : nCountA ++;
1315 : }
1316 0 : else if (eOp == ODS_COUNT || eOp == ODS_COUNTA)
1317 : {
1318 0 : if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_STRING)
1319 0 : nCountA ++;
1320 : }
1321 : else
1322 : {
1323 :
1324 : CPLError(CE_Failure, CPLE_NotSupported,
1325 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
1326 0 : return FALSE;
1327 : }
1328 : }
1329 : }
1330 :
1331 12 : if (eOp == ODS_COUNT)
1332 : {
1333 2 : eNodeType = SNT_CONSTANT;
1334 2 : field_type = ODS_FIELD_TYPE_INTEGER;
1335 2 : int_value = nCount;
1336 :
1337 2 : FreeSubExpr();
1338 2 : return TRUE;
1339 : }
1340 :
1341 10 : if (eOp == ODS_COUNTA)
1342 : {
1343 2 : eNodeType = SNT_CONSTANT;
1344 2 : field_type = ODS_FIELD_TYPE_INTEGER;
1345 2 : int_value = nCountA;
1346 :
1347 2 : FreeSubExpr();
1348 2 : return TRUE;
1349 : }
1350 :
1351 8 : double dfVal = 0;
1352 :
1353 8 : switch(eOp)
1354 : {
1355 : case ODS_SUM:
1356 : {
1357 6 : for(i=0;i<(int)adfVal.size();i++)
1358 : {
1359 4 : dfVal += adfVal[i];
1360 : }
1361 2 : break;
1362 : }
1363 :
1364 : case ODS_AVERAGE:
1365 : {
1366 6 : for(i=0;i<(int)adfVal.size();i++)
1367 : {
1368 4 : dfVal += adfVal[i];
1369 : }
1370 2 : dfVal /= adfVal.size();
1371 2 : break;
1372 : }
1373 :
1374 : case ODS_MIN:
1375 : {
1376 2 : dfVal = (adfVal.size() == 0) ? 0 :adfVal[0];
1377 6 : for(i=1;i<(int)adfVal.size();i++)
1378 : {
1379 4 : if (adfVal[i] < dfVal) dfVal = adfVal[i];
1380 : }
1381 2 : break;
1382 : }
1383 :
1384 : case ODS_MAX:
1385 : {
1386 2 : dfVal = (adfVal.size() == 0) ? 0 :adfVal[0];
1387 4 : for(i=1;i<(int)adfVal.size();i++)
1388 : {
1389 2 : if (adfVal[i] > dfVal) dfVal = adfVal[i];
1390 : }
1391 : break;
1392 : }
1393 :
1394 : default:
1395 : break;
1396 : }
1397 :
1398 8 : eNodeType = SNT_CONSTANT;
1399 8 : field_type = ODS_FIELD_TYPE_FLOAT;
1400 8 : float_value = dfVal;
1401 :
1402 8 : FreeSubExpr();
1403 :
1404 8 : return TRUE;
1405 : }
1406 :
1407 : /************************************************************************/
1408 : /* EvaluateCELL() */
1409 : /************************************************************************/
1410 :
1411 56 : int ods_formula_node::EvaluateCELL(IODSCellEvaluator* poEvaluator)
1412 : {
1413 56 : CPLAssert( eNodeType == SNT_OPERATION );
1414 56 : CPLAssert( eOp == ODS_CELL );
1415 :
1416 56 : CPLAssert(nSubExprCount == 1);
1417 56 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1418 56 : CPLAssert(papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING );
1419 :
1420 56 : if (poEvaluator == NULL)
1421 : {
1422 0 : CPLError(CE_Failure, CPLE_AppDefined, "No cell evaluator provided");
1423 0 : return FALSE;
1424 : }
1425 :
1426 56 : int nRow = 0,nCol = 0;
1427 56 : if (!GetRowCol(papoSubExpr[0]->string_value, nRow, nCol))
1428 0 : return FALSE;
1429 :
1430 56 : std::vector<ods_formula_node> aoOutValues;
1431 56 : if (poEvaluator->EvaluateRange(nRow, nCol, nRow, nCol, aoOutValues) &&
1432 : aoOutValues.size() == 1)
1433 : {
1434 38 : if (aoOutValues[0].eNodeType == SNT_CONSTANT)
1435 : {
1436 38 : FreeSubExpr();
1437 :
1438 38 : eNodeType = aoOutValues[0].eNodeType;
1439 38 : field_type = aoOutValues[0].field_type;
1440 38 : int_value = aoOutValues[0].int_value;
1441 38 : float_value = aoOutValues[0].float_value;
1442 38 : string_value = aoOutValues[0].string_value ? CPLStrdup(aoOutValues[0].string_value) : NULL;
1443 :
1444 38 : return TRUE;
1445 : }
1446 : }
1447 :
1448 18 : return FALSE;
1449 : }
1450 :
1451 : /************************************************************************/
1452 : /* EvaluateLEN() */
1453 : /************************************************************************/
1454 :
1455 2 : int ods_formula_node::EvaluateLEN(IODSCellEvaluator* poEvaluator)
1456 : {
1457 2 : CPLAssert( eNodeType == SNT_OPERATION );
1458 :
1459 2 : CPLAssert(nSubExprCount == 1);
1460 2 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
1461 0 : return FALSE;
1462 :
1463 2 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1464 :
1465 2 : std::string osVal = papoSubExpr[0]->TransformToString();
1466 :
1467 2 : eNodeType = SNT_CONSTANT;
1468 2 : field_type = ODS_FIELD_TYPE_INTEGER;
1469 2 : int_value = strlen(osVal.c_str()); // FIXME : UTF8 support
1470 :
1471 2 : FreeSubExpr();
1472 :
1473 2 : return TRUE;
1474 : }
1475 :
1476 : /************************************************************************/
1477 : /* EvaluateLEFT() */
1478 : /************************************************************************/
1479 :
1480 6 : int ods_formula_node::EvaluateLEFT(IODSCellEvaluator* poEvaluator)
1481 : {
1482 6 : CPLAssert( eNodeType == SNT_OPERATION );
1483 :
1484 6 : CPLAssert(nSubExprCount == 2);
1485 6 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
1486 0 : return FALSE;
1487 6 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
1488 0 : return FALSE;
1489 :
1490 6 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1491 6 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
1492 :
1493 6 : std::string osVal = papoSubExpr[0]->TransformToString();
1494 :
1495 6 : if (papoSubExpr[1]->field_type != ODS_FIELD_TYPE_INTEGER)
1496 0 : return FALSE;
1497 :
1498 : // FIXME : UTF8 support
1499 6 : int nVal = papoSubExpr[1]->int_value;
1500 6 : if (nVal < 0)
1501 0 : return FALSE;
1502 :
1503 6 : osVal = osVal.substr(0,nVal);
1504 :
1505 6 : eNodeType = SNT_CONSTANT;
1506 6 : field_type = ODS_FIELD_TYPE_STRING;
1507 6 : string_value = CPLStrdup(osVal.c_str());
1508 :
1509 6 : FreeSubExpr();
1510 :
1511 6 : return TRUE;
1512 : }
1513 :
1514 : /************************************************************************/
1515 : /* EvaluateRIGHT() */
1516 : /************************************************************************/
1517 :
1518 6 : int ods_formula_node::EvaluateRIGHT(IODSCellEvaluator* poEvaluator)
1519 : {
1520 6 : CPLAssert( eNodeType == SNT_OPERATION );
1521 :
1522 6 : CPLAssert(nSubExprCount == 2);
1523 6 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
1524 0 : return FALSE;
1525 6 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
1526 0 : return FALSE;
1527 :
1528 6 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1529 6 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
1530 :
1531 6 : std::string osVal = papoSubExpr[0]->TransformToString();
1532 :
1533 6 : if (papoSubExpr[1]->field_type != ODS_FIELD_TYPE_INTEGER)
1534 0 : return FALSE;
1535 :
1536 : // FIXME : UTF8 support
1537 6 : size_t nLen = osVal.size();
1538 6 : int nVal = papoSubExpr[1]->int_value;
1539 6 : if (nVal < 0)
1540 0 : return FALSE;
1541 :
1542 6 : if (nLen > (size_t) nVal)
1543 4 : osVal = osVal.substr(nLen-nVal);
1544 :
1545 6 : eNodeType = SNT_CONSTANT;
1546 6 : field_type = ODS_FIELD_TYPE_STRING;
1547 6 : string_value = CPLStrdup(osVal.c_str());
1548 :
1549 6 : FreeSubExpr();
1550 :
1551 6 : return TRUE;
1552 : }
1553 :
1554 : /************************************************************************/
1555 : /* EvaluateMID() */
1556 : /************************************************************************/
1557 :
1558 16 : int ods_formula_node::EvaluateMID(IODSCellEvaluator* poEvaluator)
1559 : {
1560 16 : CPLAssert( eNodeType == SNT_OPERATION );
1561 :
1562 16 : CPLAssert(nSubExprCount == 3);
1563 16 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
1564 0 : return FALSE;
1565 16 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
1566 0 : return FALSE;
1567 16 : if (!(papoSubExpr[2]->Evaluate(poEvaluator)))
1568 0 : return FALSE;
1569 :
1570 16 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1571 16 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
1572 16 : CPLAssert(papoSubExpr[2]->eNodeType == SNT_CONSTANT );
1573 :
1574 16 : std::string osVal = papoSubExpr[0]->TransformToString();
1575 :
1576 16 : if (papoSubExpr[1]->field_type != ODS_FIELD_TYPE_INTEGER)
1577 0 : return FALSE;
1578 :
1579 16 : if (papoSubExpr[2]->field_type != ODS_FIELD_TYPE_INTEGER)
1580 0 : return FALSE;
1581 :
1582 : // FIXME : UTF8 support
1583 16 : size_t nLen = osVal.size();
1584 16 : int nStart = papoSubExpr[1]->int_value;
1585 16 : int nExtractLen = papoSubExpr[2]->int_value;
1586 16 : if (nStart <= 0)
1587 2 : return FALSE;
1588 14 : if (nExtractLen < 0)
1589 0 : return FALSE;
1590 :
1591 14 : if ((size_t)nStart <= nLen)
1592 : {
1593 12 : if (nStart-1 + nExtractLen >= (int)nLen)
1594 6 : osVal = osVal.substr(nStart - 1);
1595 : else
1596 6 : osVal = osVal.substr(nStart - 1, nExtractLen);
1597 : }
1598 : else
1599 2 : osVal = "";
1600 :
1601 14 : eNodeType = SNT_CONSTANT;
1602 14 : field_type = ODS_FIELD_TYPE_STRING;
1603 14 : string_value = CPLStrdup(osVal.c_str());
1604 :
1605 14 : FreeSubExpr();
1606 :
1607 14 : return TRUE;
1608 : }
|