1 /* 2 Copyright (c) 2008-2009 NetAllied Systems GmbH 3 4 This file is part of COLLADASaxFrameworkLoader. 5 6 Licensed under the MIT Open Source License, 7 for details please see LICENSE file or the website 8 http://www.opensource.org/licenses/mit-license.php 9 */ 10 11 #include "COLLADASaxFWLStableHeaders.h" 12 #include "COLLADASaxFWLFormulasLoader.h" 13 14 #include "COLLADASaxFWLFileLoader.h" 15 #include "COLLADASaxFWLFilePartLoader.h" 16 #include "COLLADASaxFWLCOLLADACsymbol.h" 17 18 #include "COLLADAFWFormula.h" 19 #include "COLLADAFWFormulaNewParam.h" 20 21 #include "GeneratedSaxParserUtils.h" 22 23 #include "MathMLASTUnaryArithmeticExpression.h" 24 #include "MathMLASTArithmeticExpression.h" 25 #include "MathMLASTConstantExpression.h" 26 #include "MathMLASTVariableExpression.h" 27 #include "MathMLASTLogicExpression.h" 28 #include "MathMLASTBinaryComparisionExpression.h" 29 #include "MathMLASTFunctionExpression.h" 30 #include "MathMLParserConstants.h" 31 32 33 namespace COLLADASaxFWL 34 { 35 36 //----------------------------------------------------------------- FormulasLoader()37 FormulasLoader::FormulasLoader( ) 38 : mCurrentFormula( 0 ) 39 , mSepOccurred( false ) 40 , mCurrentCSymbolFunctionUniqueId(COLLADAFW::UniqueId::INVALID) 41 , mCurrentCSymbolIsFunction(false) 42 , mCurrentApplyHasChild(false) 43 , mWithinNewParam(false) 44 , mCurrentFormulaNewParam(0) 45 { 46 } 47 48 //----------------------------------------------------------------- ~FormulasLoader()49 FormulasLoader::~FormulasLoader() 50 { 51 } 52 53 //----------------------------------------------------------------- getUniqueId()54 const COLLADAFW::UniqueId& FormulasLoader::getUniqueId () 55 { 56 if ( mCurrentFormula ) 57 return mCurrentFormula->getUniqueId (); 58 return COLLADAFW::UniqueId::INVALID; 59 } 60 61 //----------------------------------------------------------------- begin__formula(const formula__AttributeData & attributeData)62 bool FormulasLoader::begin__formula( const formula__AttributeData& attributeData ) 63 { 64 mCurrentFormula = FW_NEW COLLADAFW::Formula( getHandlingFilePartLoader()->createUniqueIdFromId( attributeData.id, COLLADAFW::Formula::ID()) ); 65 if ( attributeData.name ) 66 mCurrentFormula->setName( attributeData.name ); 67 else if ( attributeData.id ) 68 mCurrentFormula->setName( attributeData.id ); 69 else if ( attributeData.sid ) 70 mCurrentFormula->setName( attributeData.sid ); 71 72 if ( attributeData.id ) 73 mCurrentFormula->setOriginalId ( attributeData.id ); 74 75 getHandlingFilePartLoader()->addToSidTree( attributeData.id, attributeData.sid, mCurrentFormula ); 76 77 return true; 78 } 79 80 //----------------------------------------------------------------- end__formula()81 bool FormulasLoader::end__formula() 82 { 83 getHandlingFilePartLoader()->getFileLoader()->addFormula( mCurrentFormula ); 84 mCurrentFormula = 0; 85 getHandlingFilePartLoader()->moveUpInSidTree(); 86 87 return true; 88 } 89 90 //----------------------------------------------------------------- begin__newparam(const formula_newparam_type__AttributeData & attributeData)91 bool FormulasLoader::begin__newparam( const formula_newparam_type__AttributeData& attributeData ) 92 { 93 mWithinNewParam = true; 94 if ( attributeData.sid ) 95 { 96 mCurrentFormulaNewParamSid = attributeData.sid; 97 } 98 return true; 99 } 100 101 //----------------------------------------------------------------- end__newparam()102 bool FormulasLoader::end__newparam() 103 { 104 COLLADAFW::FormulaNewParamPointerArray& newParams = mCurrentFormula->getNewParams(); 105 newParams.append(mCurrentFormulaNewParam); 106 mWithinNewParam = false; 107 mCurrentFormulaNewParamSid.clear(); 108 mCurrentFormulaNewParam = 0; 109 return true; 110 } 111 112 //----------------------------------------------------------------- begin__float()113 bool FormulasLoader::begin__float() 114 { 115 if ( mWithinNewParam ) 116 { 117 mCurrentFormulaNewParam = FW_NEW COLLADAFW::FormulaNewParam(COLLADAFW::FormulaNewParam::VALUETYPE_FLOAT); 118 mCurrentFormulaNewParam->setName(mCurrentFormulaNewParamSid); 119 } 120 return true; 121 } 122 123 //----------------------------------------------------------------- end__float()124 bool FormulasLoader::end__float() 125 { 126 return true; 127 } 128 129 //----------------------------------------------------------------- data__float(float value)130 bool FormulasLoader::data__float( float value ) 131 { 132 if ( mWithinNewParam ) 133 { 134 mCurrentFormulaNewParam->setDoubleValue( value ); 135 } 136 return true; 137 } 138 139 //----------------------------------------------------------------- begin__int()140 bool FormulasLoader::begin__int() 141 { 142 if ( mWithinNewParam ) 143 { 144 mCurrentFormulaNewParam = FW_NEW COLLADAFW::FormulaNewParam(COLLADAFW::FormulaNewParam::VALUETYPE_INT); 145 mCurrentFormulaNewParam->setName(mCurrentFormulaNewParamSid); 146 } 147 return true; 148 } 149 150 //----------------------------------------------------------------- end__int()151 bool FormulasLoader::end__int() 152 { 153 return true; 154 } 155 156 //----------------------------------------------------------------- data__int(int value)157 bool FormulasLoader::data__int( int value ) 158 { 159 if ( mWithinNewParam ) 160 { 161 mCurrentFormulaNewParam->setIntValue( value ); 162 } 163 return true; 164 } 165 166 //----------------------------------------------------------------- begin__bool()167 bool FormulasLoader::begin__bool() 168 { 169 if ( mWithinNewParam ) 170 { 171 mCurrentFormulaNewParam = FW_NEW COLLADAFW::FormulaNewParam(COLLADAFW::FormulaNewParam::VALUETYPE_BOOL); 172 mCurrentFormulaNewParam->setName(mCurrentFormulaNewParamSid); 173 } 174 return true; 175 } 176 177 //----------------------------------------------------------------- end__bool()178 bool FormulasLoader::end__bool() 179 { 180 return true; 181 } 182 183 //----------------------------------------------------------------- data__bool(bool value)184 bool FormulasLoader::data__bool( bool value ) 185 { 186 if ( mWithinNewParam ) 187 { 188 mCurrentFormulaNewParam->setBoolValue( value ); 189 } 190 return true; 191 } 192 193 //----------------------------------------------------------------- begin__math(const math__AttributeData & attributeData)194 bool FormulasLoader::begin__math( const math__AttributeData& attributeData ) 195 { 196 NodeVector newArray; 197 mNodeListStack.push( newArray ); 198 return true; 199 } 200 201 //----------------------------------------------------------------- end__math()202 bool FormulasLoader::end__math() 203 { 204 return end__apply(); 205 } 206 207 //----------------------------------------------------------------- begin__apply(const apply__AttributeData & attributeData)208 bool FormulasLoader::begin__apply( const apply__AttributeData& attributeData ) 209 { 210 mCurrentApplyHasChild = false; 211 NodeVector newArray; 212 mNodeListStack.push( newArray ); 213 return true; 214 } 215 216 //----------------------------------------------------------------- end__apply()217 bool FormulasLoader::end__apply() 218 { 219 mCurrentApplyHasChild = true; 220 221 if ( mNodeListStack.empty() ) 222 { 223 // TODO error handling 224 return false; 225 } 226 227 NodeVector nodes = mNodeListStack.top(); 228 mNodeListStack.pop(); 229 size_t numOfNodes = nodes.size(); 230 231 if ( numOfNodes == 0 ) 232 { 233 // TODO error handling 234 return false; 235 } 236 237 if ( mOperatorStack.empty() ) 238 { 239 mCurrentFormula->getMathmlAsts().allocMemory( nodes.size() ); 240 for (size_t i=0; i<nodes.size(); ++i) 241 { 242 mCurrentFormula->getMathmlAsts().append( nodes[ i ] ); 243 } 244 } 245 else 246 { 247 Operator op = mOperatorStack.top(); 248 mOperatorStack.pop(); 249 250 if ( isFunction( op ) ) 251 { 252 MathML::AST::INode* node = createFunctionOperation( nodes, op ); 253 appendNewNode( node ); 254 } 255 else if ( op == USER_DEFINED_FUNCTION ) 256 { 257 MathML::AST::INode* node = createUserDefinedFunctionOperation( nodes ); 258 appendNewNode( node ); 259 } 260 else 261 { 262 switch ( numOfNodes ) 263 { 264 265 case 1: 266 { 267 MathML::AST::INode* node = createUnaryOperation( nodes, op ); 268 appendNewNode( node ); 269 break; 270 } 271 default: 272 { 273 MathML::AST::INode* node = createMultiOperandOperation( nodes, op ); 274 appendNewNode( node ); 275 break; 276 } 277 } 278 } 279 } 280 281 return true; 282 } 283 284 //----------------------------------------------------------------- appendNewNode(MathML::AST::INode * node)285 bool FormulasLoader::appendNewNode( MathML::AST::INode* node ) 286 { 287 if ( node ) 288 { 289 if ( mNodeListStack.empty() ) 290 mCurrentFormula->getMathmlAsts().append( node ); 291 else 292 mNodeListStack.top().push_back( node ); 293 } 294 else 295 { 296 // TODO error handling 297 } 298 return true; 299 } 300 301 //----------------------------------------------------------------- createUnaryOperation(const NodeVector & nodes,Operator op)302 MathML::AST::INode* FormulasLoader::createUnaryOperation( const NodeVector& nodes, Operator op ) 303 { 304 MathML::AST::UnaryExpression::Operator mmlOp; 305 switch ( op ) 306 { 307 case ADD: 308 mmlOp = MathML::AST::UnaryExpression::ADD; 309 break; 310 case SUB: 311 mmlOp = MathML::AST::UnaryExpression::SUB; 312 break; 313 case NOT: 314 mmlOp = MathML::AST::UnaryExpression::NOT; 315 break; 316 default: 317 // invalid operator 318 return 0; 319 } 320 321 MathML::AST::UnaryExpression* expression = new MathML::AST::UnaryExpression(); 322 expression->setOperator( mmlOp ); 323 expression->setOperand( nodes[ 0 ] ); 324 325 return expression; 326 } 327 328 //----------------------------------------------------------------- createMultiOperandOperation(const NodeVector & nodes,Operator op)329 MathML::AST::INode* FormulasLoader::createMultiOperandOperation( const NodeVector& nodes, Operator op ) 330 { 331 MathML::AST::INode* node; 332 switch ( op ) 333 { 334 case ADD: 335 case SUB: 336 case MUL: 337 case DIV: 338 node = createArithmeticOperation( nodes, op ); 339 break; 340 case AND: 341 case OR: 342 case XOR: 343 node = createLogicOperation( nodes, op ); 344 break; 345 case EQ: 346 case NEQ: 347 case LT: 348 case LTE: 349 case GT: 350 case GTE: 351 node = createBinaryComparisonOperation( nodes, op ); 352 break; 353 default: 354 // invalid operator 355 node = 0; 356 } 357 358 return node; 359 } 360 361 //----------------------------------------------------------------- createArithmeticOperation(const NodeVector & nodes,Operator op)362 MathML::AST::INode* FormulasLoader::createArithmeticOperation( const NodeVector& nodes, Operator op ) 363 { 364 MathML::AST::ArithmeticExpression::Operator mmlOp; 365 switch ( op ) 366 { 367 case ADD: 368 mmlOp = MathML::AST::ArithmeticExpression::ADD; 369 break; 370 case SUB: 371 mmlOp = MathML::AST::ArithmeticExpression::SUB; 372 break; 373 case MUL: 374 mmlOp = MathML::AST::ArithmeticExpression::MUL; 375 break; 376 case DIV: 377 mmlOp = MathML::AST::ArithmeticExpression::DIV; 378 break; 379 default: 380 // invalid operator 381 return 0; 382 } 383 384 MathML::AST::ArithmeticExpression* expression = new MathML::AST::ArithmeticExpression(); 385 expression->setOperator( mmlOp ); 386 for (size_t i=0; i<nodes.size(); ++i) 387 { 388 expression->addOperand( nodes[ i ] ); 389 } 390 391 return expression; 392 } 393 394 //----------------------------------------------------------------- createLogicOperation(const NodeVector & nodes,Operator op)395 MathML::AST::INode* FormulasLoader::createLogicOperation( const NodeVector& nodes, Operator op ) 396 { 397 MathML::AST::LogicExpression::Operator mmlOp; 398 switch ( op ) 399 { 400 case AND: 401 mmlOp = MathML::AST::LogicExpression::AND; 402 break; 403 case OR: 404 mmlOp = MathML::AST::LogicExpression::OR; 405 break; 406 case XOR: 407 mmlOp = MathML::AST::LogicExpression::XOR; 408 break; 409 default: 410 // invalid operator 411 return 0; 412 } 413 414 MathML::AST::LogicExpression* expression = new MathML::AST::LogicExpression(); 415 expression->setOperator( mmlOp ); 416 for (size_t i=0; i<nodes.size(); ++i) 417 { 418 expression->addOperand( nodes[ i ] ); 419 } 420 421 return expression; 422 } 423 424 //----------------------------------------------------------------- createBinaryComparisonOperation(const NodeVector & nodes,Operator op)425 MathML::AST::INode* FormulasLoader::createBinaryComparisonOperation( const NodeVector& nodes, Operator op ) 426 { 427 if ( nodes.size() != 2 ) 428 { 429 // TODO error handling 430 return 0; 431 } 432 433 MathML::AST::BinaryComparisonExpression::Operator mmlOp; 434 switch ( op ) 435 { 436 case EQ: 437 mmlOp = MathML::AST::BinaryComparisonExpression::EQ; 438 break; 439 case NEQ: 440 mmlOp = MathML::AST::BinaryComparisonExpression::NEQ; 441 break; 442 case LT: 443 mmlOp = MathML::AST::BinaryComparisonExpression::LT; 444 break; 445 case LTE: 446 mmlOp = MathML::AST::BinaryComparisonExpression::LTE; 447 break; 448 case GT: 449 mmlOp = MathML::AST::BinaryComparisonExpression::GT; 450 break; 451 case GTE: 452 mmlOp = MathML::AST::BinaryComparisonExpression::GTE; 453 break; 454 default: 455 // invalid operator 456 return 0; 457 } 458 459 MathML::AST::BinaryComparisonExpression* expression = new MathML::AST::BinaryComparisonExpression(); 460 expression->setOperator( mmlOp ); 461 expression->setLeftOperand( nodes[ 0 ] ); 462 expression->setRightOperand( nodes[ 1 ] ); 463 464 return expression; 465 } 466 467 //----------------------------------------------------------------- createFunctionOperation(const NodeVector & nodes,Operator op)468 MathML::AST::INode* FormulasLoader::createFunctionOperation( const NodeVector& nodes, Operator op ) 469 { 470 const MathML::String* functionName; 471 switch ( op ) 472 { 473 case POW: 474 functionName = &MathML::FUNCTION_POW; 475 break; 476 case FACTORIAL: 477 functionName = &MathML::FUNCTION_FACTORIAL; 478 break; 479 case ABS: 480 functionName = &MathML::FUNCTION_ABS; 481 break; 482 case EXP: 483 functionName = &MathML::FUNCTION_EXP; 484 break; 485 case LN: 486 functionName = &MathML::FUNCTION_LOGN; 487 break; 488 case MIN: 489 functionName = &MathML::FUNCTION_MIN; 490 break; 491 case MAX: 492 functionName = &MathML::FUNCTION_MAX; 493 break; 494 case CEIL: 495 functionName = &MathML::FUNCTION_CEILING; 496 break; 497 case FLOOR: 498 functionName = &MathML::FUNCTION_FLOOR; 499 break; 500 case GCD: 501 functionName = &MathML::FUNCTION_GCD; 502 break; 503 case LCM: 504 functionName = &MathML::FUNCTION_LCM; 505 break; 506 case REM: 507 functionName = &MathML::FUNCTION_REM; 508 break; 509 case ROOT: 510 functionName = &MathML::FUNCTION_ROOT; 511 break; 512 case LOG: 513 functionName = &MathML::FUNCTION_LOG; 514 break; 515 case SIN: 516 functionName = &MathML::FUNCTION_SIN; 517 break; 518 case COS: 519 functionName = &MathML::FUNCTION_COS; 520 break; 521 case TAN: 522 functionName = &MathML::FUNCTION_TAN; 523 break; 524 case SEC: 525 functionName = &MathML::FUNCTION_SEC; 526 break; 527 case CSC: 528 functionName = &MathML::FUNCTION_CSC; 529 break; 530 case COT: 531 functionName = &MathML::FUNCTION_COT; 532 break; 533 case ARCSIN: 534 functionName = &MathML::FUNCTION_ARCSIN; 535 break; 536 case ARCCOS: 537 functionName = &MathML::FUNCTION_ARCCOS; 538 break; 539 case ARCTAN: 540 functionName = &MathML::FUNCTION_ARCTAN; 541 break; 542 case ARCSEC: 543 functionName = &MathML::FUNCTION_ARCSEC; 544 break; 545 case ARCCSC: 546 functionName = &MathML::FUNCTION_ARCCSC; 547 break; 548 case ARCCOT: 549 functionName = &MathML::FUNCTION_ARCCOT; 550 break; 551 case SINH: 552 functionName = &MathML::FUNCTION_SINH; 553 break; 554 case COSH: 555 functionName = &MathML::FUNCTION_COSH; 556 break; 557 case TANH: 558 functionName = &MathML::FUNCTION_TANH; 559 break; 560 case SECH: 561 functionName = &MathML::FUNCTION_SECH; 562 break; 563 case CSCH: 564 functionName = &MathML::FUNCTION_CSCH; 565 break; 566 case COTH: 567 functionName = &MathML::FUNCTION_COTH; 568 break; 569 case ARCSINH: 570 functionName = &MathML::FUNCTION_ARCSINH; 571 break; 572 case ARCCOSH: 573 functionName = &MathML::FUNCTION_ARCCOSH; 574 break; 575 case ARCTANH: 576 functionName = &MathML::FUNCTION_ARCTANH; 577 break; 578 case ARCCOTH: 579 functionName = &MathML::FUNCTION_ARCCOTH; 580 break; 581 case ARCSECH: 582 functionName = &MathML::FUNCTION_ARCSECH; 583 break; 584 case ARCCSCH: 585 functionName = &MathML::FUNCTION_ARCCSCH; 586 break; 587 default: 588 // invalid operator 589 return 0; 590 } 591 592 MathML::AST::FunctionExpression* expression = new MathML::AST::FunctionExpression( *functionName ); 593 expression->setParameterList( nodes ); 594 595 return expression; 596 } 597 598 599 //----------------------------------------------------------------- createUserDefinedFunctionOperation(const NodeVector & nodes)600 MathML::AST::INode* FormulasLoader::createUserDefinedFunctionOperation( const NodeVector& nodes ) 601 { 602 COLLADABU_ASSERT(!nodes.empty()); 603 MathML::AST::INode* firstNode = nodes.front(); 604 605 COLLADABU_ASSERT( firstNode->getNodeType() == MathML::AST::INode::USERDEFINED); 606 COLLADACsymbol* csymbol = (COLLADACsymbol*)firstNode; 607 size_t nodesCount = nodes.size(); 608 if ( nodesCount > 1) 609 { 610 //we have parameters. copy them into csymbol 611 COLLADACsymbol::ParameterList& parameterList = csymbol->getParameterList(); 612 parameterList.reserve( nodesCount - 1 ); 613 NodeVector::const_iterator it = nodes.begin() + 1; 614 for ( ; it != nodes.end(); ++it) 615 { 616 parameterList.push_back(*it); 617 } 618 } 619 620 return csymbol; 621 } 622 623 //----------------------------------------------------------------- isFunction(Operator op)624 bool FormulasLoader::isFunction( Operator op ) 625 { 626 switch ( op ) 627 { 628 case POW: 629 case FACTORIAL: 630 case ABS: 631 case EXP: 632 case LN: 633 case MIN: 634 case MAX: 635 case CEIL: 636 case FLOOR: 637 case GCD: 638 case LCM: 639 case REM: 640 case ROOT: 641 case LOG: 642 case SIN: 643 case COS: 644 case TAN: 645 case SEC: 646 case CSC: 647 case COT: 648 case ARCSIN: 649 case ARCCOS: 650 case ARCTAN: 651 case ARCSEC: 652 case ARCCSC: 653 case ARCCOT: 654 case SINH: 655 case COSH: 656 case TANH: 657 case SECH: 658 case CSCH: 659 case COTH: 660 case ARCSINH: 661 case ARCCOSH: 662 case ARCTANH: 663 case ARCCOTH: 664 case ARCSECH: 665 case ARCCSCH: 666 return true; 667 default: 668 return false; 669 } 670 } 671 672 //----------------------------------------------------------------- begin__quotient(const quotient__AttributeData & attributeData)673 bool FormulasLoader::begin__quotient( const quotient__AttributeData& attributeData ) 674 { 675 mCurrentApplyHasChild = true; 676 mOperatorStack.push( DIV ); 677 return true; 678 } 679 680 //----------------------------------------------------------------- begin__divide(const divide__AttributeData & attributeData)681 bool FormulasLoader::begin__divide( const divide__AttributeData& attributeData ) 682 { 683 mCurrentApplyHasChild = true; 684 mOperatorStack.push( DIV ); 685 return true; 686 } 687 688 //----------------------------------------------------------------- begin__minus(const minus__AttributeData & attributeData)689 bool FormulasLoader::begin__minus( const minus__AttributeData& attributeData ) 690 { 691 mCurrentApplyHasChild = true; 692 mOperatorStack.push( SUB ); 693 return true; 694 } 695 696 //----------------------------------------------------------------- begin__plus(const plus__AttributeData & attributeData)697 bool FormulasLoader::begin__plus( const plus__AttributeData& attributeData ) 698 { 699 mCurrentApplyHasChild = true; 700 mOperatorStack.push( ADD ); 701 return true; 702 } 703 704 //----------------------------------------------------------------- begin__times(const times__AttributeData & attributeData)705 bool FormulasLoader::begin__times( const times__AttributeData& attributeData ) 706 { 707 mCurrentApplyHasChild = true; 708 mOperatorStack.push( MUL ); 709 return true; 710 } 711 712 //----------------------------------------------------------------- begin__sum(const sum__AttributeData & attributeData)713 bool FormulasLoader::begin__sum( const sum__AttributeData& attributeData ) 714 { 715 mCurrentApplyHasChild = true; 716 mOperatorStack.push( ADD ); 717 return true; 718 } 719 720 //----------------------------------------------------------------- begin__product(const product__AttributeData & attributeData)721 bool FormulasLoader::begin__product( const product__AttributeData& attributeData ) 722 { 723 mCurrentApplyHasChild = true; 724 mOperatorStack.push( MUL ); 725 return true; 726 } 727 728 //----------------------------------------------------------------- begin__cn(const cn__AttributeData & attributeData)729 bool FormulasLoader::begin__cn( const cn__AttributeData& attributeData ) 730 { 731 mCurrentApplyHasChild = true; 732 return true; 733 } 734 735 //----------------------------------------------------------------- end__cn()736 bool FormulasLoader::end__cn() 737 { 738 MathML::AST::INode* node; 739 740 if ( mSepOccurred ) 741 { 742 // TODO support for other types than rational 743 MathML::AST::ConstantExpression* constant1 = createConstant( mCurrentTextData ); 744 MathML::AST::ConstantExpression* constant2 = createConstant( mCurrentTextDataAfterSep ); 745 MathML::AST::ArithmeticExpression* expression = new MathML::AST::ArithmeticExpression(); 746 expression->setOperator( MathML::AST::ArithmeticExpression::DIV ); 747 expression->addOperand( constant1 ); 748 expression->addOperand( constant2 ); 749 node = expression; 750 } 751 else 752 { 753 MathML::AST::ConstantExpression* constant = createConstant( mCurrentTextData ); 754 node = constant; 755 } 756 757 mNodeListStack.top().push_back( node ); 758 mSepOccurred = false; 759 mCurrentTextDataAfterSep.clear(); 760 mCurrentTextData.clear(); 761 762 return true; 763 } 764 765 //----------------------------------------------------------------- data__cn(const ParserChar * value,size_t length)766 bool FormulasLoader::data__cn( const ParserChar* value, size_t length ) 767 { 768 if ( mSepOccurred ) 769 { 770 mCurrentTextDataAfterSep.append( value, length ); 771 } 772 else 773 { 774 mCurrentTextData.append( value, length ); 775 } 776 return true; 777 } 778 779 //----------------------------------------------------------------- createConstant(const String & value)780 MathML::AST::ConstantExpression* FormulasLoader::createConstant( const String& value ) 781 { 782 MathML::AST::ConstantExpression* constant = FW_NEW MathML::AST::ConstantExpression( value ); 783 784 bool failed = false; 785 double doubleValue = GeneratedSaxParser::Utils::toDouble( value.c_str(), failed ); 786 if ( !failed ) 787 { 788 constant->setValue( doubleValue ); 789 } 790 else 791 { 792 bool boolValue = GeneratedSaxParser::Utils::toBool( value.c_str(), failed ); 793 if ( !failed ) 794 { 795 constant->setValue( boolValue ); 796 } 797 } 798 799 return constant; 800 } 801 802 //----------------------------------------------------------------- begin__ci(const ci__AttributeData & attributeData)803 bool FormulasLoader::begin__ci( const ci__AttributeData& attributeData ) 804 { 805 mCurrentApplyHasChild = true; 806 return true; 807 } 808 809 //----------------------------------------------------------------- end__ci()810 bool FormulasLoader::end__ci() 811 { 812 MathML::AST::VariableExpression* variable = FW_NEW MathML::AST::VariableExpression( mCurrentTextData ); 813 mCurrentTextData.clear(); 814 mNodeListStack.top().push_back( variable ); 815 816 return true; 817 } 818 819 //----------------------------------------------------------------- data__ci(const ParserChar * value,size_t length)820 bool FormulasLoader::data__ci( const ParserChar* value, size_t length ) 821 { 822 mCurrentTextData.append( value, length ); 823 return true; 824 } 825 826 //----------------------------------------------------------------- begin__csymbol(const csymbol__AttributeData & attributeData)827 bool FormulasLoader::begin__csymbol( const csymbol__AttributeData& attributeData ) 828 { 829 if ( !mCurrentApplyHasChild ) 830 { 831 // The csymbol appears as first child of apply. I must be a user defined function. 832 mOperatorStack.push(USER_DEFINED_FUNCTION); 833 mCurrentCSymbolIsFunction = true; 834 if (attributeData.definitionURL) 835 { 836 mCurrentCSymbolFunctionUniqueId = getHandlingFilePartLoader()->createUniqueIdFromUrl(attributeData.definitionURL, COLLADAFW::Formula::ID()); 837 } 838 } 839 mCurrentApplyHasChild = true; 840 return true; 841 } 842 843 //----------------------------------------------------------------- end__csymbol()844 bool FormulasLoader::end__csymbol() 845 { 846 COLLADACsymbol* csymbol = 0; 847 if ( mCurrentCSymbolIsFunction ) 848 { 849 csymbol = FW_NEW COLLADACsymbol( mCurrentTextData, mCurrentCSymbolFunctionUniqueId ); 850 } 851 else 852 { 853 csymbol = FW_NEW COLLADACsymbol( mCurrentTextData); 854 } 855 mCurrentTextData.clear(); 856 mNodeListStack.top().push_back( csymbol ); 857 mCurrentCSymbolIsFunction = false; 858 mCurrentCSymbolFunctionUniqueId = COLLADAFW::UniqueId::INVALID; 859 return true; 860 } 861 862 //----------------------------------------------------------------- data__csymbol(const ParserChar * value,size_t length)863 bool FormulasLoader::data__csymbol( const ParserChar* value, size_t length ) 864 { 865 mCurrentTextData.append( value, length ); 866 return true; 867 } 868 869 //----------------------------------------------------------------- begin__exponentiale(const exponentiale__AttributeData & attributeData)870 bool FormulasLoader::begin__exponentiale( const exponentiale__AttributeData& attributeData ) 871 { 872 mCurrentApplyHasChild = true; 873 MathML::AST::ConstantExpression* constant = FW_NEW MathML::AST::ConstantExpression( MathML::EULERS_NUMBER ); 874 mNodeListStack.top().push_back( constant ); 875 876 return true; 877 } 878 879 //----------------------------------------------------------------- begin__pi(const pi__AttributeData & attributeData)880 bool FormulasLoader::begin__pi( const pi__AttributeData& attributeData ) 881 { 882 mCurrentApplyHasChild = true; 883 MathML::AST::ConstantExpression* constant = FW_NEW MathML::AST::ConstantExpression( MathML::PI_NUMBER ); 884 mNodeListStack.top().push_back( constant ); 885 886 return true; 887 } 888 889 //----------------------------------------------------------------- begin__true(const true__AttributeData & attributeData)890 bool FormulasLoader::begin__true( const true__AttributeData& attributeData ) 891 { 892 mCurrentApplyHasChild = true; 893 MathML::AST::ConstantExpression* constant = FW_NEW MathML::AST::ConstantExpression( true ); 894 mNodeListStack.top().push_back( constant ); 895 896 return true; 897 } 898 899 //----------------------------------------------------------------- begin__false(const false__AttributeData & attributeData)900 bool FormulasLoader::begin__false( const false__AttributeData& attributeData ) 901 { 902 mCurrentApplyHasChild = true; 903 MathML::AST::ConstantExpression* constant = FW_NEW MathML::AST::ConstantExpression( false ); 904 mNodeListStack.top().push_back( constant ); 905 906 return true; 907 } 908 909 //----------------------------------------------------------------- begin__and(const and__AttributeData & attributeData)910 bool FormulasLoader::begin__and( const and__AttributeData& attributeData ) 911 { 912 mCurrentApplyHasChild = true; 913 mOperatorStack.push( AND); 914 return true; 915 } 916 917 //----------------------------------------------------------------- begin__or(const or__AttributeData & attributeData)918 bool FormulasLoader::begin__or( const or__AttributeData& attributeData ) 919 { 920 mCurrentApplyHasChild = true; 921 mOperatorStack.push( OR ); 922 return true; 923 } 924 925 //----------------------------------------------------------------- begin__xor(const xor__AttributeData & attributeData)926 bool FormulasLoader::begin__xor( const xor__AttributeData& attributeData ) 927 { 928 mCurrentApplyHasChild = true; 929 mOperatorStack.push( XOR ); 930 return true; 931 } 932 933 //----------------------------------------------------------------- begin__not(const not__AttributeData & attributeData)934 bool FormulasLoader::begin__not( const not__AttributeData& attributeData ) 935 { 936 mCurrentApplyHasChild = true; 937 mOperatorStack.push( NOT ); 938 return true; 939 } 940 941 //----------------------------------------------------------------- begin__eq(const eq__AttributeData & attributeData)942 bool FormulasLoader::begin__eq( const eq__AttributeData& attributeData ) 943 { 944 mCurrentApplyHasChild = true; 945 mOperatorStack.push( EQ ); 946 return true; 947 } 948 949 //----------------------------------------------------------------- begin__neq(const neq__AttributeData & attributeData)950 bool FormulasLoader::begin__neq( const neq__AttributeData& attributeData ) 951 { 952 mCurrentApplyHasChild = true; 953 mOperatorStack.push( NEQ ); 954 return true; 955 } 956 957 //----------------------------------------------------------------- begin__leq(const leq__AttributeData & attributeData)958 bool FormulasLoader::begin__leq( const leq__AttributeData& attributeData ) 959 { 960 mCurrentApplyHasChild = true; 961 mOperatorStack.push( LTE ); 962 return true; 963 } 964 965 //----------------------------------------------------------------- begin__lt(const lt__AttributeData & attributeData)966 bool FormulasLoader::begin__lt( const lt__AttributeData& attributeData ) 967 { 968 mCurrentApplyHasChild = true; 969 mOperatorStack.push( LT ); 970 return true; 971 } 972 973 //----------------------------------------------------------------- begin__geq(const geq__AttributeData & attributeData)974 bool FormulasLoader::begin__geq( const geq__AttributeData& attributeData ) 975 { 976 mCurrentApplyHasChild = true; 977 mOperatorStack.push( GTE ); 978 return true; 979 } 980 981 //----------------------------------------------------------------- begin__gt(const gt__AttributeData & attributeData)982 bool FormulasLoader::begin__gt( const gt__AttributeData& attributeData ) 983 { 984 mCurrentApplyHasChild = true; 985 mOperatorStack.push( GT ); 986 return true; 987 } 988 989 //----------------------------------------------------------------- begin__equivalent(const equivalent__AttributeData & attributeData)990 bool FormulasLoader::begin__equivalent( const equivalent__AttributeData& attributeData ) 991 { 992 mCurrentApplyHasChild = true; 993 mOperatorStack.push( EQ ); 994 return true; 995 } 996 997 //----------------------------------------------------------------- begin__abs(const abs__AttributeData & attributeData)998 bool FormulasLoader::begin__abs( const abs__AttributeData& attributeData ) 999 { 1000 mCurrentApplyHasChild = true; 1001 mOperatorStack.push( ABS ); 1002 return true; 1003 } 1004 1005 //----------------------------------------------------------------- begin__factorial(const factorial__AttributeData & attributeData)1006 bool FormulasLoader::begin__factorial( const factorial__AttributeData& attributeData ) 1007 { 1008 mCurrentApplyHasChild = true; 1009 mOperatorStack.push( FACTORIAL ); 1010 return true; 1011 } 1012 1013 //----------------------------------------------------------------- begin__floor(const floor__AttributeData & attributeData)1014 bool FormulasLoader::begin__floor( const floor__AttributeData& attributeData ) 1015 { 1016 mCurrentApplyHasChild = true; 1017 mOperatorStack.push( FLOOR ); 1018 return true; 1019 } 1020 1021 //----------------------------------------------------------------- begin__ceiling(const ceiling__AttributeData & attributeData)1022 bool FormulasLoader::begin__ceiling( const ceiling__AttributeData& attributeData ) 1023 { 1024 mCurrentApplyHasChild = true; 1025 mOperatorStack.push( CEIL ); 1026 return true; 1027 } 1028 1029 //----------------------------------------------------------------- begin__rem(const rem__AttributeData & attributeData)1030 bool FormulasLoader::begin__rem( const rem__AttributeData& attributeData ) 1031 { 1032 mCurrentApplyHasChild = true; 1033 mOperatorStack.push( REM ); 1034 return true; 1035 } 1036 1037 //----------------------------------------------------------------- begin__power(const power__AttributeData & attributeData)1038 bool FormulasLoader::begin__power( const power__AttributeData& attributeData ) 1039 { 1040 mCurrentApplyHasChild = true; 1041 mOperatorStack.push( POW ); 1042 return true; 1043 } 1044 1045 //----------------------------------------------------------------- begin__root(const root__AttributeData & attributeData)1046 bool FormulasLoader::begin__root( const root__AttributeData& attributeData ) 1047 { 1048 mCurrentApplyHasChild = true; 1049 mOperatorStack.push( ROOT ); 1050 return true; 1051 } 1052 1053 //----------------------------------------------------------------- begin__max(const max__AttributeData & attributeData)1054 bool FormulasLoader::begin__max( const max__AttributeData& attributeData ) 1055 { 1056 mCurrentApplyHasChild = true; 1057 mOperatorStack.push( MAX ); 1058 return true; 1059 } 1060 1061 //----------------------------------------------------------------- begin__min(const min__AttributeData & attributeData)1062 bool FormulasLoader::begin__min( const min__AttributeData& attributeData ) 1063 { 1064 mCurrentApplyHasChild = true; 1065 mOperatorStack.push( MIN ); 1066 return true; 1067 } 1068 1069 //----------------------------------------------------------------- begin__gcd(const gcd__AttributeData & attributeData)1070 bool FormulasLoader::begin__gcd( const gcd__AttributeData& attributeData ) 1071 { 1072 mCurrentApplyHasChild = true; 1073 mOperatorStack.push( GCD ); 1074 return true; 1075 } 1076 1077 //----------------------------------------------------------------- begin__lcm(const lcm__AttributeData & attributeData)1078 bool FormulasLoader::begin__lcm( const lcm__AttributeData& attributeData ) 1079 { 1080 mCurrentApplyHasChild = true; 1081 mOperatorStack.push( LCM ); 1082 return true; 1083 } 1084 1085 //----------------------------------------------------------------- begin__exp(const exp__AttributeData & attributeData)1086 bool FormulasLoader::begin__exp( const exp__AttributeData& attributeData ) 1087 { 1088 mCurrentApplyHasChild = true; 1089 mOperatorStack.push( EXP ); 1090 return true; 1091 } 1092 1093 //----------------------------------------------------------------- begin__ln(const ln__AttributeData & attributeData)1094 bool FormulasLoader::begin__ln( const ln__AttributeData& attributeData ) 1095 { 1096 mCurrentApplyHasChild = true; 1097 mOperatorStack.push( LN ); 1098 return true; 1099 } 1100 1101 //----------------------------------------------------------------- begin__log(const log__AttributeData & attributeData)1102 bool FormulasLoader::begin__log( const log__AttributeData& attributeData ) 1103 { 1104 mCurrentApplyHasChild = true; 1105 mOperatorStack.push( LOG ); 1106 return true; 1107 } 1108 1109 //----------------------------------------------------------------- begin__logbase(const logbase__AttributeData & attributeData)1110 bool FormulasLoader::begin__logbase( const logbase__AttributeData& attributeData ) 1111 { 1112 mCurrentApplyHasChild = true; 1113 NodeVector newArray; 1114 mNodeListStack.push( newArray ); 1115 return true; 1116 } 1117 1118 //----------------------------------------------------------------- end__logbase()1119 bool FormulasLoader::end__logbase() 1120 { 1121 if ( mNodeListStack.empty() ) 1122 { 1123 // TODO error handling 1124 return false; 1125 } 1126 1127 NodeVector nodes = mNodeListStack.top(); 1128 mNodeListStack.pop(); 1129 size_t numOfNodes = nodes.size(); 1130 1131 if ( numOfNodes == 0 ) 1132 { 1133 // TODO error handling 1134 return false; 1135 } 1136 1137 appendNewNode( nodes[ 0 ] ); 1138 1139 return true; 1140 } 1141 1142 //----------------------------------------------------------------- begin__sin(const sin__AttributeData & attributeData)1143 bool FormulasLoader::begin__sin( const sin__AttributeData& attributeData ) 1144 { 1145 mCurrentApplyHasChild = true; 1146 mOperatorStack.push( SIN ); 1147 return true; 1148 } 1149 1150 //----------------------------------------------------------------- begin__cos(const cos__AttributeData & attributeData)1151 bool FormulasLoader::begin__cos( const cos__AttributeData& attributeData ) 1152 { 1153 mCurrentApplyHasChild = true; 1154 mOperatorStack.push( COS ); 1155 return true; 1156 } 1157 1158 //----------------------------------------------------------------- begin__tan(const tan__AttributeData & attributeData)1159 bool FormulasLoader::begin__tan( const tan__AttributeData& attributeData ) 1160 { 1161 mCurrentApplyHasChild = true; 1162 mOperatorStack.push( TAN ); 1163 return true; 1164 } 1165 1166 //----------------------------------------------------------------- begin__sec(const sec__AttributeData & attributeData)1167 bool FormulasLoader::begin__sec( const sec__AttributeData& attributeData ) 1168 { 1169 mCurrentApplyHasChild = true; 1170 mOperatorStack.push( SEC ); 1171 return true; 1172 } 1173 1174 //----------------------------------------------------------------- begin__csc(const csc__AttributeData & attributeData)1175 bool FormulasLoader::begin__csc( const csc__AttributeData& attributeData ) 1176 { 1177 mCurrentApplyHasChild = true; 1178 mOperatorStack.push( CSC ); 1179 return true; 1180 } 1181 1182 //----------------------------------------------------------------- begin__cot(const cot__AttributeData & attributeData)1183 bool FormulasLoader::begin__cot( const cot__AttributeData& attributeData ) 1184 { 1185 mCurrentApplyHasChild = true; 1186 mOperatorStack.push( COT ); 1187 return true; 1188 } 1189 1190 //----------------------------------------------------------------- begin__arcsin(const arcsin__AttributeData & attributeData)1191 bool FormulasLoader::begin__arcsin( const arcsin__AttributeData& attributeData ) 1192 { 1193 mCurrentApplyHasChild = true; 1194 mOperatorStack.push( ARCSIN ); 1195 return true; 1196 } 1197 1198 //----------------------------------------------------------------- begin__arccos(const arccos__AttributeData & attributeData)1199 bool FormulasLoader::begin__arccos( const arccos__AttributeData& attributeData ) 1200 { 1201 mCurrentApplyHasChild = true; 1202 mOperatorStack.push( ARCCOS ); 1203 return true; 1204 } 1205 1206 //----------------------------------------------------------------- begin__arctan(const arctan__AttributeData & attributeData)1207 bool FormulasLoader::begin__arctan( const arctan__AttributeData& attributeData ) 1208 { 1209 mCurrentApplyHasChild = true; 1210 mOperatorStack.push( ARCTAN ); 1211 return true; 1212 } 1213 1214 //----------------------------------------------------------------- begin__arcsec(const arcsec__AttributeData & attributeData)1215 bool FormulasLoader::begin__arcsec( const arcsec__AttributeData& attributeData ) 1216 { 1217 mCurrentApplyHasChild = true; 1218 mOperatorStack.push( ARCSEC ); 1219 return true; 1220 } 1221 1222 //----------------------------------------------------------------- begin__arccsc(const arccsc__AttributeData & attributeData)1223 bool FormulasLoader::begin__arccsc( const arccsc__AttributeData& attributeData ) 1224 { 1225 mCurrentApplyHasChild = true; 1226 mOperatorStack.push( ARCCSC ); 1227 return true; 1228 } 1229 1230 //----------------------------------------------------------------- begin__arccot(const arccot__AttributeData & attributeData)1231 bool FormulasLoader::begin__arccot( const arccot__AttributeData& attributeData ) 1232 { 1233 mCurrentApplyHasChild = true; 1234 mOperatorStack.push( ARCCOT ); 1235 return true; 1236 } 1237 1238 //----------------------------------------------------------------- begin__sinh(const sinh__AttributeData & attributeData)1239 bool FormulasLoader::begin__sinh( const sinh__AttributeData& attributeData ) 1240 { 1241 mCurrentApplyHasChild = true; 1242 mOperatorStack.push( SINH ); 1243 return true; 1244 } 1245 1246 //----------------------------------------------------------------- begin__cosh(const cosh__AttributeData & attributeData)1247 bool FormulasLoader::begin__cosh( const cosh__AttributeData& attributeData ) 1248 { 1249 mCurrentApplyHasChild = true; 1250 mOperatorStack.push( COSH ); 1251 return true; 1252 } 1253 1254 //----------------------------------------------------------------- begin__tanh(const tanh__AttributeData & attributeData)1255 bool FormulasLoader::begin__tanh( const tanh__AttributeData& attributeData ) 1256 { 1257 mCurrentApplyHasChild = true; 1258 mOperatorStack.push( TANH ); 1259 return true; 1260 } 1261 1262 //----------------------------------------------------------------- begin__sech(const sech__AttributeData & attributeData)1263 bool FormulasLoader::begin__sech( const sech__AttributeData& attributeData ) 1264 { 1265 mCurrentApplyHasChild = true; 1266 mOperatorStack.push( SECH ); 1267 return true; 1268 } 1269 1270 //----------------------------------------------------------------- begin__csch(const csch__AttributeData & attributeData)1271 bool FormulasLoader::begin__csch( const csch__AttributeData& attributeData ) 1272 { 1273 mCurrentApplyHasChild = true; 1274 mOperatorStack.push( CSCH ); 1275 return true; 1276 } 1277 1278 //----------------------------------------------------------------- begin__coth(const coth__AttributeData & attributeData)1279 bool FormulasLoader::begin__coth( const coth__AttributeData& attributeData ) 1280 { 1281 mCurrentApplyHasChild = true; 1282 mOperatorStack.push( COTH ); 1283 return true; 1284 } 1285 1286 //----------------------------------------------------------------- begin__arccosh(const arccosh__AttributeData & attributeData)1287 bool FormulasLoader::begin__arccosh( const arccosh__AttributeData& attributeData ) 1288 { 1289 mCurrentApplyHasChild = true; 1290 mOperatorStack.push( ARCCOSH ); 1291 return true; 1292 } 1293 1294 //----------------------------------------------------------------- begin__arccoth(const arccoth__AttributeData & attributeData)1295 bool FormulasLoader::begin__arccoth( const arccoth__AttributeData& attributeData ) 1296 { 1297 mCurrentApplyHasChild = true; 1298 mOperatorStack.push( ARCCOTH ); 1299 return true; 1300 } 1301 1302 //----------------------------------------------------------------- begin__arccsch(const arccsch__AttributeData & attributeData)1303 bool FormulasLoader::begin__arccsch( const arccsch__AttributeData& attributeData ) 1304 { 1305 mCurrentApplyHasChild = true; 1306 mOperatorStack.push( ARCCSCH ); 1307 return true; 1308 } 1309 1310 //----------------------------------------------------------------- begin__arcsech(const arcsech__AttributeData & attributeData)1311 bool FormulasLoader::begin__arcsech( const arcsech__AttributeData& attributeData ) 1312 { 1313 mCurrentApplyHasChild = true; 1314 mOperatorStack.push( ARCSECH ); 1315 return true; 1316 } 1317 1318 //----------------------------------------------------------------- begin__arcsinh(const arcsinh__AttributeData & attributeData)1319 bool FormulasLoader::begin__arcsinh( const arcsinh__AttributeData& attributeData ) 1320 { 1321 mCurrentApplyHasChild = true; 1322 mOperatorStack.push( ARCSINH ); 1323 return true; 1324 } 1325 1326 //----------------------------------------------------------------- begin__arctanh(const arctanh__AttributeData & attributeData)1327 bool FormulasLoader::begin__arctanh( const arctanh__AttributeData& attributeData ) 1328 { 1329 mCurrentApplyHasChild = true; 1330 mOperatorStack.push( ARCTANH ); 1331 return true; 1332 } 1333 1334 } // namespace COLLADASaxFWL 1335