SourceForge Project Site
Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

FSMLoader.cpp

Go to the documentation of this file.
00001 // $Log: FSMLoader.cpp,v $
00002 // Revision 1.2  2002/08/20 14:48:41  vofka
00003 // FiniteStateMachine-config.h removed from installing. Loading exported to the loader class. Saver introduced. Error codes exported to FSMErrorCodes.
00004 //
00005 // Revision 1.1  2002/07/22 17:20:59  vofka
00006 // SimpleTransition, PushTransition, PopTransition added, not implemented yet
00007 //
00008 // Revision 1.2  2002/06/20 12:22:10  bobka
00009 // LGPL license
00010 //
00011 // Revision 1.1  2002/05/03 23:21:56  bobka
00012 // Loader externalisiert, aber der alte ist noch drin.
00013 // Iterators for states und variables added.
00014 // some minor bugs fixed.
00015 //
00016 
00017 #ifdef _MSC_VER
00018         #pragma warning( disable : 4786 ) // 'identifier' : identifier was truncated to 'number' characters in the debug information
00019 //      #pragma warning( disable : 4503 ) // 'identifier' : decorated name length exceeded, name was truncated
00020 //      #pragma warning( disable : 4250 ) // 'class1' : inherits 'class2::member' via dominance
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                         // Variable
00150                         if (strcmp(m_Tokenizer->GetTagName(),"Variable")==0)
00151                         {
00152                                 if (!LoadVariable())
00153                                 {
00154                                         iRethrow();
00155                                         return false;
00156                                 }
00157                         } else
00158 
00159                         // State
00160                         if (strcmp(m_Tokenizer->GetTagName(),"State")==0)
00161                         {
00162                                 if (!LoadState())
00163                                 {
00164                                         iRethrow();
00165                                         return false;
00166                                 }
00167                         } else
00168 
00169                         // EndOfTag
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                         // EnterAction
00268                         if (strcmp(m_Tokenizer->GetTagName(),"EnterAction")==0)
00269                         {
00270                                 if (!LoadEnterAction(state))
00271                                 {
00272                                         iRethrow();
00273                                         return false;
00274                                 }
00275                         } else
00276 
00277                         // Transition
00278                         if (strcmp(m_Tokenizer->GetTagName(),"Transition")==0)
00279                         {
00280                                 if (!LoadTransition(state))
00281                                 {
00282                                         iRethrow();
00283                                         return false;
00284                                 }
00285                         } else
00286 
00287                         // LeaveAction
00288                         if (strcmp(m_Tokenizer->GetTagName(),"LeaveAction")==0)
00289                         {
00290                                 if (!LoadLeaveAction(state))
00291                                 {
00292                                         iRethrow();
00293                                         return false;
00294                                 }
00295                         } else
00296 
00297                         // Param
00298                         if (strcmp(m_Tokenizer->GetTagName(),"Param")==0)
00299                         {
00300                                 if (!LoadParam(state))
00301                                 {
00302                                         iRethrow();
00303                                         return false;
00304                                 }
00305                         } else
00306 
00307                         // EndOfTag
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                         // Param
00397                         if (strcmp(m_Tokenizer->GetTagName(),"Param")==0)
00398                         {
00399                                 if (!LoadParam(action))
00400                                 {
00401                                         iRethrow();
00402                                         return false;
00403                                 }
00404                         } else
00405 
00406                         // EndOfTag
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                         // Param
00452                         if (strcmp(m_Tokenizer->GetTagName(),"Param")==0)
00453                         {
00454                                 if (!LoadParam(action))
00455                                 {
00456                                         iRethrow();
00457                                         return false;
00458                                 }
00459                         } else
00460 
00461                         // EndOfTag
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                         // Param
00507                         if (strcmp(m_Tokenizer->GetTagName(),"Param")==0)
00508                         {
00509                                 if (!LoadParam(action))
00510                                 {
00511                                         iRethrow();
00512                                         return false;
00513                                 }
00514                         } else
00515 
00516                         // EndOfTag
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         // down compatibility
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                         // Condition
00579                         if (strcmp(m_Tokenizer->GetTagName(),"Condition")==0)
00580                         {
00581                                 if (!LoadCondition(trans))
00582                                 {
00583                                         iRethrow();
00584                                         return false;
00585                                 }
00586                         } else
00587 
00588                         // Action
00589                         if (strcmp(m_Tokenizer->GetTagName(),"Action")==0)
00590                         {
00591                                 if (!LoadTransAction(trans))
00592                                 {
00593                                         iRethrow();
00594                                         return false;
00595                                 }
00596                         } else
00597 
00598                         // Param
00599                         if (strcmp(m_Tokenizer->GetTagName(),"Param")==0)
00600                         {
00601                                 if (!LoadParam(trans))
00602                                 {
00603                                         iRethrow();
00604                                         return false;
00605                                 }
00606                         } else
00607 
00608                         // EndOfTag
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                         // Param
00657                         if (strcmp(m_Tokenizer->GetTagName(),"Param")==0)
00658                         {
00659                                 if (!LoadParam(condition))
00660                                 {
00661                                         iRethrow();
00662                                         return false;
00663                                 }
00664                         } else
00665 
00666                         // EndOfTag
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 //      cerr << "startElement" << endl;
00723 //      cerr << (const char*)uri << ":" << (const char*)localname << endl;
00724         cerr << "<" << XMLString::transcode(qname);
00725 
00726         unsigned int len = attributes.getLength();
00727         for (unsigned int index = 0; index < len; index++)
00728         {
00729 //              cerr << (const char*)attributes.getURI(index) << ":" << (const char*)attributes.getLocalName(index) << endl;
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 //      cerr << (const char*)uri << ":" << (const char*)localname << endl;
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         //  Delete the parser itself.  Must be done prior to calling Terminate, below.
00800         //
00801         delete parser;
00802 
00803     // And call the termination method
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 } // namespace FSM

© 2002 by C-LAB
generated by doxygen