00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef _MSC_VER
00018 #pragma warning( disable : 4786 ) // 'identifier' : identifier was truncated to 'number' characters in the debug information
00019
00020
00021 #pragma warning( disable : 4251 ) // 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2'
00022 #endif
00023 #ifdef __INTEL_COMPILER
00024 #pragma warning( disable : 985 ) // == C4786
00025 #endif
00026
00027 #include "FSM.h"
00028 #include "FiniteStateMachine-config.h"
00029 #include "FSMErrorCodes.h"
00030 #include "Tokenizer.h"
00031
00032 #ifdef HAVE_XERCES
00033 # include <util/PlatformUtils.hpp>
00034 # include <sax2/DefaultHandler.hpp>
00035 # include <sax2/Attributes.hpp>
00036 # include <sax2/XMLReaderFactory.hpp>
00037 #endif
00038
00039 # include <cstdlib>
00040 # include <cstdio>
00041 # include <iostream>
00042 namespace FSM {
00043
00044 CFSMLoader::CFSMLoader(CFiniteStateMachine *fsm)
00045 :m_FSM(fsm)
00046 {
00047 }
00048
00049 CFSMLoader::~CFSMLoader()
00050 {
00051 }
00052
00054
00055 CFSMSimpleLoaderXML::CFSMSimpleLoaderXML(CFiniteStateMachine *fsm)
00056 :CFSMLoader(fsm)
00057 ,m_Tokenizer(NULL)
00058 {
00059 }
00060
00061 CFSMSimpleLoaderXML::~CFSMSimpleLoaderXML()
00062 {
00063 }
00064
00065 bool CFSMSimpleLoaderXML::Load(const char *filename)
00066 {
00067 bool res = false;
00068 FILE *inFile = fopen(filename, "rb");
00069 if (inFile)
00070 {
00071 res = Load(inFile);
00072 fclose(inFile);
00073 if (!res) iRethrow();
00074 } else {
00075 iThrow(CRITICAL(FSM_OPEN_FILE_FAILED), filename);
00076 }
00077 return res;
00078 }
00079
00080 bool CFSMSimpleLoaderXML::Load(FILE *inFile)
00081 {
00082 bool res = false;
00083
00084 if(!m_FSM->Clear())
00085 {
00086 iRethrow();
00087 return false;
00088 }
00089
00090 m_Tokenizer = new CTokenizer(inFile);
00091 if (!m_Tokenizer->GetTag())
00092 {
00093 delete m_Tokenizer;
00094 m_Tokenizer=NULL;
00095 iRethrow();
00096 return false;
00097 }
00098
00099 if(strcmp(m_Tokenizer->GetTagName(), "?xml")==0)
00100 {
00101 if (!m_Tokenizer->GetTag())
00102 {
00103 delete m_Tokenizer;
00104 m_Tokenizer=NULL;
00105 iRethrow();
00106 return false;
00107 }
00108 }
00109
00110 if(strcmp(m_Tokenizer->GetTagName(), "Finite-State-Machine")!=0)
00111 {
00112 delete m_Tokenizer;
00113 m_Tokenizer=NULL;
00114 iThrow(CRITICAL(FSM_TAG_NOT_FOUND), "Finite-State-Machine");
00115 return false;
00116 }
00117
00118 res = LoadFSM();
00119 if (!res)
00120 {
00121 m_FSM->Clear();
00122 }
00123
00124 delete m_Tokenizer;
00125 m_Tokenizer=NULL;
00126 return res;
00127 }
00128
00129 bool CFSMSimpleLoaderXML::LoadFSM()
00130 {
00131 const int bufferLen=1024;
00132 char buffer[bufferLen];
00133
00134 if(m_Tokenizer->GetAttribute("InitialState", buffer, bufferLen))
00135 {
00136 m_FSM->SetInitialState(buffer);
00137 }
00138
00139 if (!m_Tokenizer->IsTagClosed())
00140 {
00141 do
00142 {
00143 if (!m_Tokenizer->GetTag())
00144 {
00145 iRethrow();
00146 return false;
00147 }
00148
00149
00150 if (strcmp(m_Tokenizer->GetTagName(),"Variable")==0)
00151 {
00152 if (!LoadVariable())
00153 {
00154 iRethrow();
00155 return false;
00156 }
00157 } else
00158
00159
00160 if (strcmp(m_Tokenizer->GetTagName(),"State")==0)
00161 {
00162 if (!LoadState())
00163 {
00164 iRethrow();
00165 return false;
00166 }
00167 } else
00168
00169
00170 if (strcmp(m_Tokenizer->GetTagName(),"/Finite-State-Machine")==0)
00171 {
00172 break;
00173 } else
00174
00175 {
00176 iThrow(CRITICAL(FSM_UNKNOWN_TAG), m_Tokenizer->GetTagName(), "Finite-State-Machine");
00177 return false;
00178 }
00179
00180 } while(true);
00181 }
00182
00183 return true;
00184 }
00185
00186 bool CFSMSimpleLoaderXML::LoadVariable()
00187 {
00188 string name;
00189 const int bufferLen=1024;
00190 char buffer[bufferLen];
00191 int value = 0;
00192
00193 if (!m_Tokenizer->GetAttribute("Name", buffer, bufferLen))
00194 {
00195 iThrow(CRITICAL(FSM_MISSED_ATTRIBUTE), "Name", "Variable");
00196 return false;
00197 }
00198 name=buffer;
00199 value=0;
00200 if(m_Tokenizer->GetAttribute("Value", buffer, bufferLen))
00201 {
00202 value = atoi(buffer);
00203 }
00204
00205 if(!m_FSM->AddVariable(name.c_str(), value))
00206 {
00207 iRethrow();
00208 return false;
00209 }
00210
00211 if (!m_Tokenizer->IsTagClosed())
00212 {
00213 if (!m_Tokenizer->GetTag())
00214 {
00215 iRethrow();
00216 return false;
00217 }
00218
00219 if (strcmp(m_Tokenizer->GetTagName(),"/Variable")!=0)
00220 {
00221 iThrow(CRITICAL(FSM_TAG_NOT_FOUND), "/Variable");
00222 return false;
00223 }
00224 }
00225
00226 return true;
00227 }
00228
00229 bool CFSMSimpleLoaderXML::LoadState()
00230 {
00231 CFSMState* state=NULL;
00232 string name;
00233 const int bufferLen=1024;
00234 char buffer[bufferLen];
00235
00236 if (!m_Tokenizer->GetAttribute("Name", buffer, 1024))
00237 {
00238 iThrow(CRITICAL(FSM_MISSED_ATTRIBUTE), "Name", "State");
00239 return false;
00240 }
00241 name = buffer;
00242
00243 if (m_Tokenizer->GetAttribute("Class", buffer, 1024))
00244 {
00245 state = m_FSM->AddState(name.c_str(), buffer);
00246 } else
00247 {
00248 state = m_FSM->AddState(name.c_str());
00249 }
00250
00251 if (!state)
00252 {
00253 iRethrow();
00254 return false;
00255 }
00256
00257 if (!m_Tokenizer->IsTagClosed())
00258 {
00259 do
00260 {
00261 if (!m_Tokenizer->GetTag())
00262 {
00263 iRethrow();
00264 return false;
00265 }
00266
00267
00268 if (strcmp(m_Tokenizer->GetTagName(),"EnterAction")==0)
00269 {
00270 if (!LoadEnterAction(state))
00271 {
00272 iRethrow();
00273 return false;
00274 }
00275 } else
00276
00277
00278 if (strcmp(m_Tokenizer->GetTagName(),"Transition")==0)
00279 {
00280 if (!LoadTransition(state))
00281 {
00282 iRethrow();
00283 return false;
00284 }
00285 } else
00286
00287
00288 if (strcmp(m_Tokenizer->GetTagName(),"LeaveAction")==0)
00289 {
00290 if (!LoadLeaveAction(state))
00291 {
00292 iRethrow();
00293 return false;
00294 }
00295 } else
00296
00297
00298 if (strcmp(m_Tokenizer->GetTagName(),"Param")==0)
00299 {
00300 if (!LoadParam(state))
00301 {
00302 iRethrow();
00303 return false;
00304 }
00305 } else
00306
00307
00308 if (strcmp(m_Tokenizer->GetTagName(),"/State")==0)
00309 {
00310 break;
00311 } else
00312
00313 {
00314 iThrow(CRITICAL(FSM_UNKNOWN_TAG), m_Tokenizer->GetTagName(), "State");
00315 return false;
00316 }
00317
00318 } while(true);
00319 }
00320
00321 return true;
00322 }
00323
00324 bool CFSMSimpleLoaderXML::LoadParam(CFSMObject* obj)
00325 {
00326 string name;
00327 const int bufferLen=1024;
00328 char buffer[bufferLen];
00329
00330 if (!m_Tokenizer->GetAttribute("Name", buffer, bufferLen))
00331 {
00332 iThrow(CRITICAL(FSM_MISSED_ATTRIBUTE), "Name", "Param");
00333 return false;
00334 }
00335 name = buffer;
00336
00337 if (!m_Tokenizer->GetAttribute("Value", buffer, bufferLen))
00338 {
00339 iThrow(CRITICAL(FSM_MISSED_ATTRIBUTE), "Value", "Param");
00340 return false;
00341 }
00342
00343 if (!obj->SetParameter(name.c_str(), buffer))
00344 {
00345 iRethrow();
00346 return false;
00347 }
00348
00349 if (!m_Tokenizer->IsTagClosed())
00350 {
00351 if (!m_Tokenizer->GetTag())
00352 {
00353 iRethrow();
00354 return false;
00355 }
00356
00357 if (strcmp(m_Tokenizer->GetTagName(),"/Param")!=0)
00358 {
00359 iThrow(CRITICAL(FSM_TAG_NOT_FOUND), "/Param");
00360 return false;
00361 }
00362 }
00363
00364 return true;
00365 }
00366
00367 bool CFSMSimpleLoaderXML::LoadEnterAction(CFSMState* state)
00368 {
00369 CFSMAction* action;
00370 const int bufferLen=1024;
00371 char buffer[bufferLen];
00372 string name;
00373
00374 if (!m_Tokenizer->GetAttribute("Class", buffer, bufferLen))
00375 {
00376 iThrow(CRITICAL(FSM_MISSED_ATTRIBUTE), "Class", "Action");
00377 }
00378 action = state->AddEnterAction(buffer);
00379
00380 if (!action)
00381 {
00382 iRethrow();
00383 return false;
00384 }
00385
00386 if (!m_Tokenizer->IsTagClosed())
00387 {
00388 do
00389 {
00390 if (!m_Tokenizer->GetTag())
00391 {
00392 iRethrow();
00393 return false;
00394 }
00395
00396
00397 if (strcmp(m_Tokenizer->GetTagName(),"Param")==0)
00398 {
00399 if (!LoadParam(action))
00400 {
00401 iRethrow();
00402 return false;
00403 }
00404 } else
00405
00406
00407 if (strcmp(m_Tokenizer->GetTagName(),"/EnterAction")==0)
00408 {
00409 break;
00410 } else
00411
00412 {
00413 iThrow(CRITICAL(FSM_UNKNOWN_TAG), m_Tokenizer->GetTagName(), "EnterAction");
00414 return false;
00415 }
00416 } while(true);
00417 }
00418
00419 return true;
00420 }
00421
00422 bool CFSMSimpleLoaderXML::LoadLeaveAction(CFSMState* state)
00423 {
00424 CFSMAction* action;
00425 const int bufferLen=1024;
00426 char buffer[bufferLen];
00427 string name;
00428
00429 if (!m_Tokenizer->GetAttribute("Class", buffer, bufferLen))
00430 {
00431 iThrow(CRITICAL(FSM_MISSED_ATTRIBUTE), "Class", "Action");
00432 }
00433 action = state->AddLeaveAction(buffer);
00434
00435 if (!action)
00436 {
00437 iRethrow();
00438 return false;
00439 }
00440
00441 if (!m_Tokenizer->IsTagClosed())
00442 {
00443 do
00444 {
00445 if (!m_Tokenizer->GetTag())
00446 {
00447 iRethrow();
00448 return false;
00449 }
00450
00451
00452 if (strcmp(m_Tokenizer->GetTagName(),"Param")==0)
00453 {
00454 if (!LoadParam(action))
00455 {
00456 iRethrow();
00457 return false;
00458 }
00459 } else
00460
00461
00462 if (strcmp(m_Tokenizer->GetTagName(),"/LeaveAction")==0)
00463 {
00464 break;
00465 } else
00466
00467 {
00468 iThrow(CRITICAL(FSM_UNKNOWN_TAG), m_Tokenizer->GetTagName(), "LeaveAction");
00469 return false;
00470 }
00471 } while(true);
00472 }
00473
00474 return true;
00475 }
00476
00477 bool CFSMSimpleLoaderXML::LoadTransAction(CFSMTransition* trans)
00478 {
00479 CFSMAction* action;
00480 const int bufferLen=1024;
00481 char buffer[bufferLen];
00482 string name;
00483
00484 if (!m_Tokenizer->GetAttribute("Class", buffer, bufferLen))
00485 {
00486 iThrow(CRITICAL(FSM_MISSED_ATTRIBUTE), "Class", "Action");
00487 }
00488 action = trans->AddAction(buffer);
00489
00490 if (!action)
00491 {
00492 iRethrow();
00493 return false;
00494 }
00495
00496 if (!m_Tokenizer->IsTagClosed())
00497 {
00498 do
00499 {
00500 if (!m_Tokenizer->GetTag())
00501 {
00502 iRethrow();
00503 return false;
00504 }
00505
00506
00507 if (strcmp(m_Tokenizer->GetTagName(),"Param")==0)
00508 {
00509 if (!LoadParam(action))
00510 {
00511 iRethrow();
00512 return false;
00513 }
00514 } else
00515
00516
00517 if (strcmp(m_Tokenizer->GetTagName(),"/Action")==0)
00518 {
00519 break;
00520 } else
00521
00522 {
00523 iThrow(CRITICAL(FSM_UNKNOWN_TAG), m_Tokenizer->GetTagName(), "Action");
00524 return false;
00525 }
00526 } while(true);
00527 }
00528
00529 return true;
00530 }
00531
00532 bool CFSMSimpleLoaderXML::LoadTransition(CFSMState* state)
00533 {
00534 CFSMTransition* trans;
00535 const int bufferLen=1024;
00536 char buffer[bufferLen];
00537 string className = "SimpleTransition";
00538
00539 if (m_Tokenizer->GetAttribute("Class", buffer, 1024))
00540 {
00541 className=buffer;
00542 }
00543
00544 if (m_Tokenizer->GetAttribute("OnEvent", buffer, 1024))
00545 {
00546 trans = state->AddTransition(buffer, className.c_str());
00547 } else
00548 {
00549 trans = state->AddTransition(NULL, className.c_str());
00550 }
00551
00552 if (!trans)
00553 {
00554 iRethrow();
00555 return false;
00556 }
00557
00558
00559 if (m_Tokenizer->GetAttribute("ToState", buffer, 1024))
00560 {
00561 if (!trans->SetParameter("ToState", buffer))
00562 {
00563 iRethrow();
00564 return false;
00565 }
00566 }
00567
00568 if (!m_Tokenizer->IsTagClosed())
00569 {
00570 do
00571 {
00572 if (!m_Tokenizer->GetTag())
00573 {
00574 iRethrow();
00575 return false;
00576 }
00577
00578
00579 if (strcmp(m_Tokenizer->GetTagName(),"Condition")==0)
00580 {
00581 if (!LoadCondition(trans))
00582 {
00583 iRethrow();
00584 return false;
00585 }
00586 } else
00587
00588
00589 if (strcmp(m_Tokenizer->GetTagName(),"Action")==0)
00590 {
00591 if (!LoadTransAction(trans))
00592 {
00593 iRethrow();
00594 return false;
00595 }
00596 } else
00597
00598
00599 if (strcmp(m_Tokenizer->GetTagName(),"Param")==0)
00600 {
00601 if (!LoadParam(trans))
00602 {
00603 iRethrow();
00604 return false;
00605 }
00606 } else
00607
00608
00609 if (strcmp(m_Tokenizer->GetTagName(),"/Transition")==0)
00610 {
00611 break;
00612 } else
00613
00614 {
00615 iThrow(CRITICAL(FSM_UNKNOWN_TAG), m_Tokenizer->GetTagName(), "Transition");
00616 return false;
00617 }
00618
00619 } while(true);
00620 }
00621
00622 return true;
00623 }
00624
00625 bool CFSMSimpleLoaderXML::LoadCondition(CFSMTransition* trans)
00626 {
00627 CFSMCondition* condition;
00628 const int bufferLen=1024;
00629 char buffer[bufferLen];
00630 string name;
00631
00632 if (m_Tokenizer->GetAttribute("Class", buffer, bufferLen))
00633 {
00634 condition = trans->AddCondition(buffer);
00635 } else
00636 {
00637 condition = trans->AddCondition();
00638 }
00639
00640 if (!condition)
00641 {
00642 iRethrow();
00643 return false;
00644 }
00645
00646 if (!m_Tokenizer->IsTagClosed())
00647 {
00648 do
00649 {
00650 if (!m_Tokenizer->GetTag())
00651 {
00652 iRethrow();
00653 return false;
00654 }
00655
00656
00657 if (strcmp(m_Tokenizer->GetTagName(),"Param")==0)
00658 {
00659 if (!LoadParam(condition))
00660 {
00661 iRethrow();
00662 return false;
00663 }
00664 } else
00665
00666
00667 if (strcmp(m_Tokenizer->GetTagName(),"/Condition")==0)
00668 {
00669 break;
00670 } else
00671
00672 {
00673 iThrow(CRITICAL(FSM_UNKNOWN_TAG), m_Tokenizer->GetTagName(), "Condition");
00674 return false;
00675 }
00676 } while(true);
00677 }
00678
00679 return true;
00680 }
00681
00682
00684 #ifdef HAVE_XERCES
00685
00686 class SAX2LoaderHandler : public DefaultHandler
00687 {
00688 public:
00689 SAX2LoaderHandler(CFiniteStateMachine *fsm);
00690 ~SAX2LoaderHandler();
00691
00692
00693 void startElement( const XMLCh* const uri,
00694 const XMLCh* const localname,
00695 const XMLCh* const qname,
00696 const Attributes& attributes);
00697
00698
00699 void endElement( const XMLCh* const uri,
00700 const XMLCh* const localname,
00701 const XMLCh* const qname);
00702 private:
00703 CFiniteStateMachine* m_FSM;
00704 };
00705
00706
00708 SAX2LoaderHandler::SAX2LoaderHandler(CFiniteStateMachine *fsm)
00709 :m_FSM(fsm)
00710 {
00711 }
00712
00713 SAX2LoaderHandler::~SAX2LoaderHandler()
00714 {
00715 }
00716
00717 void SAX2LoaderHandler::startElement(const XMLCh* const uri,
00718 const XMLCh* const localname,
00719 const XMLCh* const qname,
00720 const Attributes& attributes)
00721 {
00722
00723
00724 cerr << "<" << XMLString::transcode(qname);
00725
00726 unsigned int len = attributes.getLength();
00727 for (unsigned int index = 0; index < len; index++)
00728 {
00729
00730 cerr << " " << XMLString::transcode(attributes.getQName(index)) << "=\"";
00731 cerr << XMLString::transcode(attributes.getValue(index)) << "\"";
00732 }
00733 cerr << ">" << endl;
00734 }
00735
00736 void SAX2LoaderHandler::endElement(const XMLCh* const uri,
00737 const XMLCh* const localname,
00738 const XMLCh* const qname)
00739 {
00740
00741 cerr << "</" << XMLString::transcode(qname) << ">" << endl;
00742 }
00743
00744 #endif
00745
00747 CFSMLoaderXML::CFSMLoaderXML(CFiniteStateMachine *fsm)
00748 :CFSMLoader(fsm)
00749 {
00750 }
00751
00752 CFSMLoaderXML::~CFSMLoaderXML()
00753 {
00754 }
00755
00756 bool CFSMLoaderXML::Load(const char *filename)
00757 {
00758 bool res = false;
00759
00760 #ifdef HAVE_XERCES
00761
00762 if(!m_FSM->Clear())
00763 {
00764 iRethrow();
00765 return false;
00766 }
00767
00768 try
00769 {
00770 XMLPlatformUtils::Initialize();
00771 }
00772
00773 catch (const XMLException& toCatch)
00774 {
00775 cerr << "Error during initialization! :\n" << toCatch.getMessage() << endl;
00776 return false;
00777 }
00778
00779 SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
00780
00781 int errorCount = 0;
00782 try
00783 {
00784 SAX2LoaderHandler handler(m_FSM);
00785 parser->setContentHandler(&handler);
00786 parser->setErrorHandler(&handler);
00787 parser->parse(filename);
00788 errorCount = parser->getErrorCount();
00789 if (errorCount==0) res = true;
00790 } catch (const XMLException& toCatch)
00791 {
00792 cerr << "An error occured" << endl
00793 << " Error: " << toCatch.getMessage() << endl;
00794 XMLPlatformUtils::Terminate();
00795 return false;
00796 }
00797
00798
00799
00800
00801 delete parser;
00802
00803
00804 XMLPlatformUtils::Terminate();
00805
00806 #else
00807 iThrow(CRITICAL(FSM_LOAD_NOT_IMPLEMENTED));
00808 #endif
00809
00810 return res;
00811 }
00812
00814 CFSMSaver::CFSMSaver(const CFiniteStateMachine *fsm)
00815 :m_FSM(fsm)
00816 {
00817 }
00818
00819 CFSMSaver::~CFSMSaver()
00820 {
00821 }
00822
00823 bool CFSMSaver::SaveParameters(const CFSMObject* obj)
00824 {
00825 bool res = obj->SaveParameters(this);
00826 if (!res) {iRethrow();}
00827 return true;
00828 }
00829
00831 CFSMSaverXML::CFSMSaverXML(const CFiniteStateMachine *fsm)
00832 :CFSMSaver(fsm)
00833 ,m_File(NULL)
00834 {
00835 }
00836
00837 CFSMSaverXML::~CFSMSaverXML()
00838 {
00839 }
00840
00841 bool CFSMSaverXML::Save(const char *filename)
00842 {
00843 bool res = false;
00844 FILE *outFile = fopen(filename, "wb");
00845 if(outFile)
00846 {
00847 fprintf(outFile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
00848 if (Save(outFile))
00849 {
00850 res = true;
00851 } else
00852 {
00853 iRethrow();
00854 }
00855 fflush(outFile);
00856 fclose(outFile);
00857
00858 } else
00859 {
00860 iThrow(CRITICAL(FSM_OPEN_FILE_FAILED), filename);
00861 }
00862
00863 return res;
00864 }
00865
00866
00867 bool CFSMSaverXML::Save(FILE *outFile)
00868 {
00869 m_File=outFile;
00870 fprintf(m_File, "<Finite-State-Machine Version=\"0.3\" ");
00871 fprintf(m_File, "InitialState=\"%s\">\n", m_FSM->GetInitialState());
00872
00873 for(Var_Map::const_iterator j = m_FSM->GetVarsBegin(); j != m_FSM->GetVarsEnd() ; ++j)
00874 {
00875 fprintf(m_File, "\t<Variable Name=\"%s", (*j).first.c_str());
00876 fprintf(m_File, "\" Value=\"%d\"> ", (*j).second);
00877 fprintf(m_File, "</Variable>\n");
00878 }
00879
00880 for(State_Map::const_iterator i = m_FSM->GetStatesBegin() ; i != m_FSM->GetStatesEnd() ; ++i)
00881 {
00882 if(!SaveState((*i).second))
00883 {
00884 iRethrow();
00885 return false;
00886 }
00887 }
00888 fprintf(m_File, "</Finite-State-Machine>\n");
00889 m_File=NULL;
00890 return true;
00891 }
00892
00893 bool CFSMSaverXML::SaveState(const CFSMState* state)
00894 {
00895 fprintf(m_File, "\t<State Name=\"%s\"", state->GetName());
00896 if (strcmp(state->GetNameOfClass(), "State")!=0)
00897 {
00898 fprintf(m_File, " Class=\"%s\"", state->GetNameOfClass());
00899 }
00900 fprintf(m_File, ">\n");
00901 if (!SaveParameters(state)) {iRethrow(); return false;}
00902 Action_List::const_iterator i;
00903 for(i = state->GetEnterActionsBegin() ; i != state->GetEnterActionsEnd() ; ++i)
00904 {
00905 SaveAction((*i), "EnterAction");
00906 }
00907 for(Transition_List::const_iterator j = state->GetTransitionsBegin() ; j != state->GetTransitionsEnd() ; ++j)
00908 {
00909 SaveTransition((*j));
00910 }
00911 for(i = state->GetLeaveActionsBegin() ; i != state->GetLeaveActionsEnd() ; ++i)
00912 {
00913 SaveAction((*i), "LeaveAction");
00914 }
00915 fprintf(m_File, "\t</State>\n");
00916 return true;
00917 }
00918
00919 bool CFSMSaverXML::SaveTransition(const CFSMTransition* trans)
00920 {
00921 fprintf(m_File, "\t\t<Transition");
00922 if (strcmp(trans->GetOnEvent(), "ANY")!=0)
00923 {
00924 fprintf(m_File, " OnEvent=\"%s\"", trans->GetOnEvent());
00925 }
00926 if (strcmp(trans->GetNameOfClass(), "Transition")!=0)
00927 {
00928 fprintf(m_File, " Class=\"%s\"", trans->GetNameOfClass());
00929 }
00930 fprintf(m_File, ">\n");
00931 if (!SaveParameters(trans)) {iRethrow(); return false;}
00932 for(Condition_List::const_iterator i = trans->GetConditionsBegin() ; i != trans->GetConditionsEnd() ; ++i)
00933 {
00934 if (!SaveCondition((*i)))
00935 {
00936 iRethrow();
00937 return false;
00938 }
00939 }
00940 for(Action_List::const_iterator j = trans->GetActionsBegin() ; j != trans->GetActionsEnd() ; ++j)
00941 {
00942 if (!SaveAction((*j), "Action"))
00943 {
00944 iRethrow();
00945 return false;
00946 }
00947 }
00948 fprintf(m_File, "\t\t</Transition>\n");
00949 return true;
00950 }
00951
00952 bool CFSMSaverXML::SaveAction(const CFSMAction* action, const char* tag)
00953 {
00954 fprintf(m_File, "\t\t\t<%s Class=\"%s\">\n", tag, action->GetNameOfClass());
00955 if (!SaveParameters(action)) {iRethrow(); return false;}
00956 fprintf(m_File, "\t\t\t</%s>\n", tag);
00957 return true;
00958 }
00959
00960 bool CFSMSaverXML::SaveCondition(const CFSMCondition* cond)
00961 {
00962 fprintf(m_File, "\t\t\t<Condition");
00963 if (strcmp(cond->GetNameOfClass(), "TestVariable")!=0)
00964 {
00965 fprintf(m_File, " Class=\"%s\"", cond->GetNameOfClass());
00966 }
00967 fprintf(m_File, ">\n");
00968 if (!SaveParameters(cond)) {iRethrow(); return false;}
00969 fprintf(m_File, "\t\t\t</Condition>\n");
00970 return true;
00971 }
00972
00973 bool CFSMSaverXML::SaveParameter(const char* name, const char* value)
00974 {
00975 fprintf(m_File, "\t\t\t\t<Param Name=\"%s\" Value=\"%s\"> </Param>\n", name, value);
00976 return true;
00977 }
00978
00980 }