Salome HOME
Copyright update 2022
[modules/yacs.git] / src / yacsloader / LoadState.cxx
1 // Copyright (C) 2006-2022  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "LoadState.hxx"
21 #include "Proc.hxx"
22 #include "Node.hxx"
23 #include "ForLoop.hxx"
24 #include "WhileLoop.hxx"
25 #include "Switch.hxx"
26 #include "InGate.hxx"
27 #include "Runtime.hxx"
28 #include "InputPort.hxx"
29 #include "ElementaryNode.hxx"
30 #include "ForEachLoop.hxx"
31 #include "Any.hxx"
32 #include "TypeConversions.hxx"
33
34 #include <iostream>
35 #include <string>
36 #include <cstdlib>
37 #include <cstdarg>
38 #include <cassert>
39
40 //#define _DEVDEBUG_
41 #include "YacsTrace.hxx"
42
43 using namespace YACS::ENGINE;
44 using namespace std;
45
46 XMLReadState    stateParser::_state;
47 std::string     stateParser::_what;
48 std::stack<XMLReadState> stateParser::_stackState;
49 Proc* stateParser::_p;
50 Runtime* stateParser::_runtime;
51 std::map<std::string, YACS::StatesForNode> stateParser::_nodeStateValue;
52 std::map<std::string, YACS::StatesForNode> stateParser::_nodeStates;
53
54 // ----------------------------------------------------------------------------
55 void stateParser::setProc(Proc* p)
56 {
57   _p= p;
58 }
59
60 void stateParser::setRuntime(Runtime* runtime)
61 {
62   _runtime = runtime;
63 }
64
65 void stateParser::init(const xmlChar** p, xmlParserBase* father)
66 {
67   DEBTRACE("stateParser::init()");
68   _state = XMLNOCONTEXT;
69   _father = father;
70   _stackState.push(_state);
71   _nodeStateValue["READY"] =YACS::READY;
72   _nodeStateValue["TOLOAD"] =YACS::TOLOAD;
73   _nodeStateValue["LOADED"] =YACS::LOADED;
74   _nodeStateValue["TOACTIVATE"] =YACS::TOACTIVATE;
75   _nodeStateValue["ACTIVATED"] =YACS::ACTIVATED;
76   _nodeStateValue["DESACTIVATED"] =YACS::DESACTIVATED;
77   _nodeStateValue["DONE"] =YACS::DONE;
78   _nodeStateValue["SUSPENDED"] =YACS::SUSPENDED;
79   _nodeStateValue["LOADFAILED"] =YACS::LOADFAILED;
80   _nodeStateValue["EXECFAILED"] =YACS::EXECFAILED;
81   _nodeStateValue["PAUSE"] =YACS::PAUSE;
82   _nodeStateValue["INTERNALERR"] =YACS::INTERNALERR;
83   _nodeStateValue["DISABLED"] =YACS::DISABLED;
84   _nodeStateValue["FAILED"] =YACS::FAILED;
85   _nodeStateValue["ERROR"] =YACS::ERROR;
86   _nodeStates.clear();
87 }
88
89
90 void stateParser::onStart (const XML_Char* elem, const xmlChar** p)
91 {
92   DEBTRACE("stateParser::onStart");
93   string element(elem);
94   stateParser *parser = 0;
95   if (element == "graphState") parser = new graphParser();
96   else
97     { 
98       _what = "expected <graphState>, got <" + element + ">";
99       _state = XMLFATALERROR;
100       stopParse(_what);
101     }
102   if (parser)
103     {
104       _stackParser.push(parser);
105       XML_SetUserData(_xmlParser, parser);
106       parser->init(p);
107     }
108 }
109
110
111 void stateParser::onEnd   (const XML_Char* name)
112 {
113   _stackState.pop();
114   _state = _stackState.top();
115   //cerr << "end " << name << " " << _stackParser.size() << " " << _state << endl;
116 }
117
118
119 void stateParser::charData(std::string data)
120 {
121   //cerr << "data " << data << endl;
122 }
123
124 // ----------------------------------------------------------------------------
125
126 void graphParser::init(const xmlChar** p, xmlParserBase* father)
127 {
128   //  DEBTRACE("graphParser::init()");
129   _state = XMLINGRAPH;
130   _father = father;
131   _stackState.push(_state);
132   if (p) getAttributes(p);
133 }
134
135 void graphParser::onStart (const XML_Char* elem, const xmlChar** p)
136 {
137   string element(elem);
138   stateParser *parser = 0;
139   if (element == "node") parser = new nodeParser();
140   else
141     { 
142       _what = "expected <node>, got <" + element + ">";
143       _state = XMLFATALERROR;
144       stopParse(_what);
145     }
146   if (parser)
147     {
148       _stackParser.push(parser);
149       XML_SetUserData(_xmlParser, parser);
150       parser->init(p, this);
151     }
152 }
153
154
155 void graphParser::onEnd   (const XML_Char* name)
156 {
157   std::map<std::string, YACS::StatesForNode>::const_iterator it;
158   for (it = _nodeStates.begin(); it != _nodeStates.end(); it++)
159     {
160       Node *node =0;
161       string nodeName = it->first;
162       DEBTRACE("nodeName = " << nodeName);
163       if(_p->getName() == nodeName)
164         node = _p;
165       else
166         node = _p->getChildByName(nodeName);
167
168       InGate* inGate = node->getInGate();
169       list<OutGate*> backlinks = inGate->getBackLinks();
170       for (list<OutGate*>::iterator io = backlinks.begin(); io != backlinks.end(); io++)
171         {
172           Node* fromNode = (*io)->getNode();
173           string fromName;
174           if (fromNode == _p) fromName = fromNode->getName();
175           else fromName = _p->getChildName(fromNode);
176           if (_nodeStates[fromName] == YACS::DONE)
177             {
178               DEBTRACE("   fromNode = " << fromName);
179               inGate->setPrecursorDone(*io);
180             }
181         }
182     }
183   stateParser::onEnd(name);
184 }
185
186 // ----------------------------------------------------------------------------
187
188 class outputParser: public stateParser
189 {
190 public:
191   virtual void init(const xmlChar** p, xmlParserBase* father=0)
192   {
193     //DEBTRACE("outputParser::init()");
194     _state = XMLNOCONTEXT;
195     _father = father;
196     YASSERT( dynamic_cast<nodeParser*> (father));
197     _stackState.push(_state);
198     if (p) getAttributes(p);
199   }
200   virtual void onStart (const XML_Char* elem, const xmlChar** p)
201   {
202     //DEBTRACE("outputParser::onStart" << elem);
203     string element(elem);
204     stateParser *parser = 0;
205     if      (element == "name")      parser = new attrParser();
206     else if (element == "value")     parser = new valueParser();
207     else
208     { 
209       _what = "expected name or value, got <" + element + ">";
210       _state = XMLFATALERROR;
211       stopParse(_what);
212     }
213     if (parser)
214     {
215       _stackParser.push(parser);
216       XML_SetUserData(_xmlParser, parser);
217       parser->init(p, this);
218     }
219   }
220   virtual void onEnd   (const XML_Char* name)
221   {
222     //DEBTRACE("outputParser::onEnd" << elem);
223     //DEBTRACE("portName: " << _mapAttrib["name"] << "value: " << _data );
224     stateParser::onEnd(name);
225   }
226   virtual void addData(std::string /*value*/)
227   {
228     //DEBTRACE("outputParser::addData" << elem);
229   }
230 };
231
232 // ----------------------------------------------------------------------------
233
234 void nodeParser::init(const xmlChar** p, xmlParserBase* father)
235 {
236   DEBTRACE("nodeParser::init()");
237   _loopSamples.clear();
238   _state = XMLINNODE;
239   _father = father;
240   _stackState.push(_state);
241   if (p) getAttributes(p);
242 }
243
244
245 void nodeParser::onStart (const XML_Char* elem, const xmlChar** p)
246 {
247   DEBTRACE("nodeParser::onStart" << elem);
248   string element(elem);
249   stateParser *parser = 0;
250   if (element == "inputPort")      parser = new portParser();
251   else if (element == "name")      parser = new attrParser();
252   else if (element == "state")     parser = new attrParser();
253   else if (element == "nsteps")    parser = new attrParser();
254   else if (element == "nbdone")    parser = new attrParser();
255   else if (element == "condition") parser = new attrParser();
256   else if (element == "outputPort") parser = new outputParser();
257   else if (element == "loopOutputPort")
258   {
259     loopPortParser* sparser = new loopPortParser();
260     _loopSamples.push_back(sparser);
261     parser = sparser;
262   }
263   else
264     { 
265       _what = "expected name, state or inputPort, got <" + element + ">";
266       _state = XMLFATALERROR;
267       stopParse(_what);
268     }
269   if (parser)
270     {
271       _stackParser.push(parser);
272       XML_SetUserData(_xmlParser, parser);
273       parser->init(p, this);
274     }
275 }
276
277 void nodeParser::onEnd   (const XML_Char* name)
278 {
279   string nodeName = _mapAttrib["name"];
280   string nodeType = _mapAttrib["type"];
281   string nodeState = _mapAttrib["state"];
282   DEBTRACE( "nodeName: " << nodeName << " nodeType: " << nodeType << " nodeState: " << nodeState );
283 //   for (std::map< std::string, Node * >::iterator it=_p->nodeMap.begin(); it != _p->nodeMap.end(); it++)
284 //     cerr << "nodeMap: " << it->first << endl;
285   _nodeStates[nodeName] = _nodeStateValue[nodeState];
286   Node *node =0;
287   if(_p->getName() == nodeName)
288     node=_p;
289   else 
290     node = _p->getChildByName(nodeName);
291
292   YASSERT(_nodeStateValue.find(nodeState) != _nodeStateValue.end());
293   YACS::ENGINE::StateLoader(node, _nodeStateValue[nodeState]);
294
295   if (nodeType == "forLoop")
296     {
297       if (_mapAttrib.find("nsteps") == _mapAttrib.end())
298         {
299           _what = "no attribute nsteps in forLoop " + _mapAttrib["name"];
300           _state = XMLFATALERROR;
301           stopParse(_what);
302         }
303       int nsteps =  atoi(_mapAttrib["nsteps"].c_str());
304
305       if (_mapAttrib.find("nbdone") == _mapAttrib.end())
306         {
307           _what = "no attribute nbdone in forLoop " + _mapAttrib["name"];
308           _state = XMLFATALERROR;
309           stopParse(_what);
310         }
311       int nbdone =  atoi(_mapAttrib["nbdone"].c_str());
312       DEBTRACE("nsteps = " << nsteps << ", nbdone = " << nbdone);
313
314       ForLoop* loop = dynamic_cast<ForLoop*>(node);
315       if (!loop)
316         {
317           _what = "node is not a ForLoop: " + _mapAttrib["name"];
318           _state = XMLFATALERROR;
319           stopParse(_what);
320         }
321       loop->edGetNbOfTimesInputPort()->edInit(nsteps);
322       YACS::ENGINE::NbDoneLoader(loop, nbdone);
323     }
324
325   else if (nodeType == "whileLoop")
326     {
327       if (_mapAttrib.find("nbdone") == _mapAttrib.end())
328         {
329           _what = "no attribute nbdone in forLoop " + _mapAttrib["name"];
330           _state = XMLFATALERROR;
331           stopParse(_what);
332         }
333       int nbdone =  atoi(_mapAttrib["nbdone"].c_str());
334
335       if (_mapAttrib.find("condition") == _mapAttrib.end())
336         {
337           _what = "no attribute condition in forLoop " + _mapAttrib["name"];
338           _state = XMLFATALERROR;
339           stopParse(_what);
340         }
341       bool condition =  atoi(_mapAttrib["condition"].c_str());
342       DEBTRACE("condition = " << condition << ", nbdone = " << nbdone);
343
344       WhileLoop* loop = dynamic_cast<WhileLoop*>(node);
345       if (!loop)
346         {
347           _what = "node is not a WhileLoop: " + _mapAttrib["name"];
348           _state = XMLFATALERROR;
349           stopParse(_what);
350         }
351       loop->edGetConditionPort()->edInit(condition);
352       YACS::ENGINE::NbDoneLoader(loop, nbdone);
353     }
354
355   else if (nodeType == "switch")
356     {
357       if (_mapAttrib.find("condition") == _mapAttrib.end())
358         {
359           _what = "no attribute condition in switch " + _mapAttrib["name"];
360           _state = XMLFATALERROR;
361           stopParse(_what);
362         }
363       int condition =  atoi(_mapAttrib["condition"].c_str());
364       DEBTRACE("condition = " << condition);
365
366       Switch* mySwitch = dynamic_cast<Switch*>(node);
367       if (!mySwitch)
368         {
369           _what = "node is not a Switch: " + _mapAttrib["name"];
370           _state = XMLFATALERROR;
371           stopParse(_what);
372         }
373       mySwitch->edGetConditionPort()->edInit(condition);
374     }
375   else if (nodeType == "forEachLoop")
376   {
377     ForEachLoop* feNode = dynamic_cast<ForEachLoop*>(node);
378     if(!feNode)
379     {
380       _what = "node is not a ForEachLoop: " + _mapAttrib["name"];
381       _state = XMLFATALERROR;
382       stopParse(_what);
383     }
384     else
385     {
386       std::vector<unsigned int> passedIds;
387       std::vector<SequenceAny *> passedOutputs;
388       std::vector<std::string> nameOfOutputs;
389       bool firstPort = true;
390       std::list<loopPortParser*>::const_iterator itPort;
391       for(itPort=_loopSamples.begin(); itPort!=_loopSamples.end(); itPort++)
392       {
393         const std::string& portName =(*itPort)->getPortName();
394         nameOfOutputs.push_back(portName);
395         const YACS::ENGINE::TypeCode* tc = feNode->getOutputPortType(portName);
396         if(!tc)
397         {
398           _what = "Impossible to find the type of the port " + portName;
399           _state = XMLFATALERROR;
400           stopParse(_what);
401           return;
402         }
403         unsigned int nbSamples = (*itPort)->getNbSamples();
404         SequenceAny* seqValues = SequenceAny::New(tc, nbSamples);
405         passedOutputs.push_back(seqValues);
406         for(unsigned int i = 0; i < nbSamples; i++)
407         {
408           unsigned int sampleId = (*itPort)->getSampleId(i);
409           const std::string& sampleData = (*itPort)->getSampleData(i);
410           Any* value = xmlToAny(sampleData, tc);
411           if(firstPort)
412           {
413             passedIds.push_back(sampleId);
414             seqValues->setEltAtRank(i, value);
415           }
416           else
417           {
418             unsigned int pos = 0;
419             while(pos < passedIds.size() && sampleId != passedIds[pos])
420               pos++;
421             if(pos < passedIds.size())
422               seqValues->setEltAtRank(pos, value);
423             else
424             {
425               _what = "Inconsistent sample id in foreach node " + _mapAttrib["name"];
426               _state = XMLFATALERROR;
427               stopParse(_what);
428               itPort=_loopSamples.end();
429               return;
430             }
431           }
432         }
433         firstPort = false;
434       }
435       feNode->assignPassedResults(passedIds, passedOutputs, nameOfOutputs);
436     }
437   }
438
439   stateParser::onEnd(name);
440 }
441
442 Any* nodeParser::xmlToAny(const std::string& data, const YACS::ENGINE::TypeCode* tc)const
443 {
444   xmlDocPtr doc;
445   xmlNodePtr cur;
446   //YACS::ENGINE::Any *ob=YACS::ENGINE::AtomAny::New(0);
447   YACS::ENGINE::Any *ob=NULL;
448   {
449     doc = xmlParseMemory(data.c_str(), data.length());
450     if (doc == NULL )
451       {
452         stringstream msg;
453         msg << "Problem in conversion: XML Document not parsed successfully ";
454         msg << " (" << __FILE__ << ":" << __LINE__ << ")";
455         throw ConversionException(msg.str());
456       }
457     cur = xmlDocGetRootElement(doc);
458     if (cur == NULL)
459       {
460         xmlFreeDoc(doc);
461         stringstream msg;
462         msg << "Problem in conversion: empty XML Document";
463         msg << " (" << __FILE__ << ":" << __LINE__ << ")";
464         throw ConversionException(msg.str());
465       }
466     while (cur != NULL)
467       {
468         if ((!xmlStrcmp(cur->name, (const xmlChar *)"value")))
469           {
470             ob=convertXmlNeutral(tc,doc,cur);
471             break;
472           }
473         cur = cur->next;
474       }
475     xmlFreeDoc(doc);
476     if(ob==NULL)
477       {
478         stringstream msg;
479         msg << "Problem in conversion: incorrect XML value";
480         msg << " (" << __FILE__ << ":" << __LINE__ << ")";
481         throw ConversionException(msg.str());
482       }
483   }
484   return ob;
485 }
486
487 // ----------------------------------------------------------------------------
488
489 void attrParser::init(const xmlChar** p, xmlParserBase* father)
490 {
491   DEBTRACE("attrParser::init()");
492   //_state = XMLINNODE;
493   _father = father;
494   _stackState.push(_state); // keep current state
495   if (p) getAttributes(p);
496 }
497
498
499 void attrParser::onStart (const XML_Char* elem, const xmlChar** p)
500 {
501   string element(elem);
502   _what = "expected nothing, got <" + element + ">";
503   _state = XMLFATALERROR;
504   stopParse(_what);
505 }
506
507 void attrParser::charData(std::string data)
508 {
509   _attrValue = data;
510 }
511
512 void attrParser::onEnd   (const XML_Char* name)
513 {
514   // cerr << "end attrParser " << name << " " << _stackParser.size() << endl;
515   YASSERT(_father);
516   _father->setAttribute((char*)name, _attrValue);
517   stateParser::onEnd(name);
518 }
519
520 // ----------------------------------------------------------------------------
521
522 void portParser::init(const xmlChar** p, xmlParserBase* father)
523 {
524   DEBTRACE("portParser::init()");
525   _state = XMLINPORT;
526   _father = father;
527   YASSERT( dynamic_cast<nodeParser*> (father));
528   _stackState.push(_state);
529   if (p) getAttributes(p);
530 }
531
532
533 void portParser::onStart (const XML_Char* elem, const xmlChar** p)
534 {
535   DEBTRACE("portParser::onStart" << elem);
536   string element(elem);
537   stateParser *parser = 0;
538   if      (element == "name")      parser = new attrParser();
539   else if (element == "value")     parser = new valueParser();
540   else
541     { 
542       _what = "expected name or value, got <" + element + ">";
543       _state = XMLFATALERROR;
544       stopParse(_what);
545     }
546   if (parser)
547     {
548       _stackParser.push(parser);
549       XML_SetUserData(_xmlParser, parser);
550       parser->init(p, this);
551     }
552 }
553
554 void portParser::addData(std::string value)
555 {
556   _data = value;
557 }
558
559 void portParser::onEnd   (const XML_Char* name)
560 {
561   DEBTRACE("portName: " << _mapAttrib["name"] << "value: " << _data );
562   string nodeName = _father->getAttribute("name");
563   string nodeType = _father->getAttribute("type");
564   Node *node = _p->getChildByName(nodeName);
565   if (nodeType == "elementaryNode")
566     {
567       ElementaryNode* eNode = dynamic_cast<ElementaryNode*>(node);
568       YASSERT(eNode);
569       InputPort *port = eNode->getInputPort(_mapAttrib["name"]);
570       if(_data != "")
571         port->edInit("XML",_data.c_str());
572     }
573   else if (nodeType == "forLoop")
574     {
575       string what="no way to set a port value on port " +  _mapAttrib["name"];
576       what += " in node " + nodeName + " of type " + nodeType;
577       throw Exception(what);
578     }
579   else if (nodeType == "whileLoop")
580     {
581       string what="no way to set a port value on port " +  _mapAttrib["name"];
582       what += " in node " + nodeName + " of type " + nodeType;
583       throw Exception(what);
584     }
585   else if (nodeType == "switch")
586     {
587       string what="no way to set a port value on port " +  _mapAttrib["name"];
588       what += " in node " + nodeName + " of type " + nodeType;
589       throw Exception(what);
590     }
591   else if (nodeType == "forEachLoop")
592     {
593       ForEachLoop* eNode = dynamic_cast<ForEachLoop*>(node);
594       YASSERT(eNode);
595       InputPort *port = eNode->getInputPort(_mapAttrib["name"]);
596       if(_data != "")
597         port->edInit("XML",_data.c_str());
598     }
599   else 
600     {
601       string what="no way to set a port value on port " +  _mapAttrib["name"];
602       what += " in node " + nodeName + " of type " + nodeType;
603       throw Exception(what);
604     }
605
606   stateParser::onEnd(name);
607 }
608
609 // ----------------------------------------------------------------------------
610
611 void valueParser::init(const xmlChar** p, xmlParserBase* father)
612 {
613   DEBTRACE("valueParser::init()");
614   _state = XMLINVALUE;
615   _father = father;
616   _stackState.push(_state);
617   if (p) getAttributes(p);
618 }
619
620
621 void valueParser::onStart (const XML_Char* elem, const xmlChar** p)
622 {
623   string element(elem);
624   DEBTRACE("value type " << element );
625   stateParser *parser = 0;
626   if      (element == "data")      parser = new dataParser();
627   else if (element == "array")     parser = new arrayParser();
628   else                             parser = new simpleTypeParser();
629   if (parser)
630     {
631       _stackParser.push(parser);
632       XML_SetUserData(_xmlParser, parser);
633       parser->init(p, this);
634     }
635 }
636
637 void valueParser::addData(std::string value)
638 {
639   _data = "<value>" + value + "</value>";
640 }
641
642 void valueParser::onEnd   (const XML_Char* name)
643 {
644   DEBTRACE( _data );
645   _father->addData(_data);
646   string elem = (char *) name;
647   //if (elem == "value" || elem == "data" || elem == "array")
648   stateParser::onEnd(name);
649   //else YASSERT(0); //DEBTRACE("valueParser::onEnd " << elem);
650 }
651
652 // ----------------------------------------------------------------------------
653
654 void arrayParser::init(const xmlChar** p, xmlParserBase* father)
655 {
656   DEBTRACE("arrayParser::init()");
657   _state = XMLINVALUE;
658   _father = father;
659   _stackState.push(_state);
660   if (p) getAttributes(p);
661 }
662
663
664 void arrayParser::onStart (const XML_Char* elem, const xmlChar** p)
665 {
666   string element(elem);
667   DEBTRACE("array type " << element);
668   stateParser *parser = 0;
669   if      (element == "data")      parser = new dataParser();
670   else
671     { 
672       _what = "expected data, got <" + element + ">";
673       _state = XMLFATALERROR;
674       stopParse(_what);
675     }
676   if (parser)
677     {
678       _stackParser.push(parser);
679       XML_SetUserData(_xmlParser, parser);
680       parser->init(p, this);
681     }
682 }
683
684 void arrayParser::addData(std::string value)
685 {
686   string val = "<array>" + value + "</array>";
687   _data = val;
688 }
689
690
691 void arrayParser::onEnd   (const XML_Char* name)
692 {
693   // cerr << "arrayParser::onEnd " << name << endl;
694   // cerr << _data << endl;
695   _father->addData(_data);
696   stateParser::onEnd(name);
697 }
698
699 // ----------------------------------------------------------------------------
700
701 void dataParser::init(const xmlChar** p, xmlParserBase* father)
702 {
703   DEBTRACE("dataParser::init()");
704   _state = XMLINVALUE;
705   _father = father;
706   _stackState.push(_state);
707   if (p) getAttributes(p);
708 }
709
710
711 void dataParser::onStart (const XML_Char* elem, const xmlChar** p)
712 {
713   string element(elem);
714   DEBTRACE("data type " << element );
715   stateParser *parser = 0;
716   if      (element == "value")      parser = new valueParser();
717   else
718     { 
719       _what = "expected value, got <" + element + ">";
720       _state = XMLFATALERROR;
721       stopParse(_what);
722     }
723   if (parser)
724     {
725       _stackParser.push(parser);
726       XML_SetUserData(_xmlParser, parser);
727       parser->init(p, this);
728     }
729 }
730
731 void dataParser::addData(std::string value)
732 {
733   _dataList.push_back(value);
734 }
735
736 void dataParser::onEnd   (const XML_Char* name)
737 {
738   // cerr << "dataParser::onEnd " << name << endl;
739   string val = "<data>";
740   while (!_dataList.empty())
741     {
742       val += _dataList.front();
743       _dataList.pop_front();
744     }
745   val += "</data>";
746   // cerr << val << endl;
747   _father->addData(val);
748   stateParser::onEnd(name);
749 }
750
751 // ----------------------------------------------------------------------------
752
753 void simpleTypeParser::init(const xmlChar** p, xmlParserBase* father)
754 {
755   DEBTRACE("simpleTypeParser::init()");
756   _state = XMLINVALUE;
757   _father = father;
758   _stackState.push(_state);
759   if (p) getAttributes(p);
760 }
761
762 void simpleTypeParser::onStart (const XML_Char* elem, const xmlChar** p)
763 {
764   string element(elem);
765   _what = "expected nothing, got <" + element + ">";
766   _state = XMLFATALERROR;
767   stopParse(_what);
768 }
769
770 void simpleTypeParser::onEnd   (const XML_Char* name)
771 {
772   string val = string("<") + (char*) name + ">" + _data + "</"  + (char*) name +">";
773   DEBTRACE( val );
774   _father->addData(val);
775   stateParser::onEnd(name);
776 }
777
778 void simpleTypeParser::charData(std::string data)
779 {
780   _data = _data + data;
781 }
782
783 // ----------------------------------------------------------------------------
784
785 void loopPortParser::init(const xmlChar** p, xmlParserBase* father)
786 {
787   DEBTRACE("loopPortParser::init()");
788   //_state = XMLINPORT;
789   _father = father;
790   _stackState.push(_state);
791   _ids.clear();
792   _sampleData.clear();
793   if (p) getAttributes(p);
794 }
795
796 void loopPortParser::onStart(const XML_Char* elem, const xmlChar** p)
797 {
798   DEBTRACE("loopPortParser::onStart" << elem);
799   string element(elem);
800   stateParser *parser = 0;
801   if (element == "name")      parser = new attrParser();
802   else if (element == "sample") parser = new sampleParser(this);
803   else
804     { 
805       _what = "expected name or sample, got <" + element + ">";
806       _state = XMLFATALERROR;
807       stopParse(_what);
808     }
809   if (parser)
810     {
811       _stackParser.push(parser);
812       XML_SetUserData(_xmlParser, parser);
813       parser->init(p, this);
814     }
815 }
816
817 void loopPortParser::onEnd(const XML_Char* name)
818 {
819   stateParser::onEnd(name);
820 }
821
822 void loopPortParser::charData(std::string data)
823 {
824 }
825
826 void loopPortParser::addSample(int index, const std::string data)
827 {
828   _ids.push_back(index);
829   _sampleData.push_back(data);
830 }
831
832 unsigned int loopPortParser::getNbSamples()const
833 {
834   return _ids.size();
835 }
836
837 unsigned int loopPortParser::getSampleId(unsigned int i)const
838 {
839   return _ids[i];
840 }
841
842 const std::string& loopPortParser::getSampleData(unsigned int i)const
843 {
844   return _sampleData[i];
845 }
846
847 const std::string& loopPortParser::getPortName()const
848 {
849   return _mapAttrib.at("name");
850 }
851
852 // ----------------------------------------------------------------------------
853
854 sampleParser::sampleParser(loopPortParser* father)
855 : stateParser(),
856   _sampleFather(father)
857 {
858 }
859
860 void sampleParser::init(const xmlChar** p, xmlParserBase* father)
861 {
862   DEBTRACE("sampleParser::init()");
863   //_state = XMLINPORT;
864   _father = father;
865   _stackState.push(_state);
866   if (p) getAttributes(p);
867 }
868
869 void sampleParser::onStart(const XML_Char* elem, const xmlChar** p)
870 {
871   DEBTRACE("sampleParser::onStart" << elem);
872   string element(elem);
873   stateParser *parser = 0;
874   if (element == "index")      parser = new attrParser();
875   else if (element == "value") parser = new valueParser();
876   else
877     { 
878       _what = "expected index or value, got <" + element + ">";
879       _state = XMLFATALERROR;
880       stopParse(_what);
881     }
882   if (parser)
883     {
884       _stackParser.push(parser);
885       XML_SetUserData(_xmlParser, parser);
886       parser->init(p, this);
887     }
888 }
889
890 void sampleParser::onEnd(const XML_Char* name)
891 {
892   if (_mapAttrib.find("index") == _mapAttrib.end())
893     {
894       _what = "no attribute index in sample ";
895       _state = XMLFATALERROR;
896       stopParse(_what);
897     }
898   int index =  atoi(_mapAttrib["index"].c_str());
899   _sampleFather->addSample(index, _data);
900   stateParser::onEnd(name);
901 }
902
903 void sampleParser::charData(std::string data)
904 {
905   _data = _data + data;
906 }
907
908 // ----------------------------------------------------------------------------
909
910 stateLoader::stateLoader(xmlParserBase* parser,
911                          YACS::ENGINE::Proc* p) : xmlReader(parser)
912 {
913   _runtime = getRuntime();
914   _p = p;
915 }
916
917 void stateLoader::parse(std::string xmlState)
918 {
919   DEBTRACE("stateLoader::parse");
920   stateParser *parser = dynamic_cast<stateParser*> (_rootParser);
921   parser->setProc(_p);
922   parser->setRuntime(_runtime);
923
924   xmlReader::parse(xmlState);
925
926   DEBTRACE(parser->_state);
927   switch (parser->_state)
928     {
929     case XMLNOCONTEXT:
930     case XMLDONE:
931       {
932         DEBTRACE("parse OK");
933         break;
934       }
935     case XMLFATALERROR:
936       {
937         string what = "Abort Parse: " + parser->_what;
938         throw Exception(what);
939         break;
940       }
941     default:
942       {
943         string what = "Abort Parse: unknown execution problem";
944         throw Exception(what);
945         break;
946       }
947     }
948 }
949
950 void YACS::ENGINE::loadState(YACS::ENGINE::Proc *p,const std::string& xmlStateFile)
951 {
952   DEBTRACE("YACS::ENGINE::loadState");
953   p->init();
954   p->exUpdateState();
955   stateParser* rootParser = new stateParser();
956   stateLoader myStateLoader(rootParser, p);
957   myStateLoader.parse(xmlStateFile);
958 }