#include <sstream>
#include <algorithm> // std::replace_if
--//#define _DEVDEBUG_
++#define _DEVDEBUG_
#include "YacsTrace.hxx"
using namespace YACS::ENGINE;
_passedData=new ForEachLoopPassedData(passedIds,passedOutputs,nameOfOutputs);
}
+int ForEachLoop::getFEDeltaBetween(OutPort *start, InPort *end)
+{
+ Node *ns(start->getNode()),*ne(end->getNode());
+ ComposedNode *co(getLowestCommonAncestor(ns,ne));
+ int ret(0);
+ Node *work(ns);
+ while(work!=co)
+ {
+ ForEachLoop *isFE(dynamic_cast<ForEachLoop *>(work));
+ if(isFE)
+ ret++;
+ work=work->getFather();
+ }
+ if(dynamic_cast<AnySplitOutputPort *>(start))
+ ret--;
+ return ret;
+}
++
+ /*!
+ * This method is used to obtain the values already processed by the ForEachLoop.
+ * A new ForEachLoopPassedData object is returned. You have to delete it.
+ */
+ ForEachLoopPassedData* ForEachLoop::getProcessedData()const
+ {
+ std::vector<SequenceAny *> outputs;
+ std::vector<std::string> nameOfOutputs;
+ if(_execVals.empty() || _execOutGoingPorts.empty())
+ return new ForEachLoopPassedData(std::vector<unsigned int>(), outputs, nameOfOutputs);
+ std::size_t sz(_execVals.size());
+ outputs.resize(sz);
+ nameOfOutputs.resize(sz);
+ const std::vector<AnyInputPort *>& ports(_execOutGoingPorts[0]);
+ for(std::size_t i=0;i<sz;i++)
+ {
+ outputs[i]=_execVals[i]->removeUnsetItemsFromThis();
+ nameOfOutputs[i]=ports[i]->getName();
+ }
+ return new ForEachLoopPassedData(_execVals[0]->getSetItems(), outputs, nameOfOutputs);
+ }
+
+ void ForEachLoop::setProcessedData(ForEachLoopPassedData* processedData)
+ {
+ if(_passedData)
+ delete _passedData;
+ _passedData = processedData;
+ }
++
++/*!
++ * \param portName : "interceptorized" name of port.
++ */
++const YACS::ENGINE::TypeCode* ForEachLoop::getOutputPortType(const std::string& portName)const
++{
++ const YACS::ENGINE::TypeCode* ret=NULL;
++ vector<AnySplitOutputPort *>::const_iterator it;
++ for(it=_outGoingPorts.begin();it!=_outGoingPorts.end() && ret==NULL;it++)
++ {
++ std::string originalPortName(getPortName(*it));
++ //InterceptorizeNameOfPort(originalPortName);
++ DEBTRACE("ForEachLoop::getOutputPortType compare " << portName << " == " << originalPortName);
++ if(originalPortName == portName)
++ {
++ ret = (*it)->edGetType()->contentType();
++ }
++ }
++ return ret;
++}
#include "Runtime.hxx"
#include "InputPort.hxx"
#include "ElementaryNode.hxx"
+ #include "ForEachLoop.hxx"
+ #include "Any.hxx"
++#include "TypeConversions.hxx"
#include <iostream>
#include <string>
#include <cstdarg>
#include <cassert>
--//#define _DEVDEBUG_
++#define _DEVDEBUG_
#include "YacsTrace.hxx"
using namespace YACS::ENGINE;
void nodeParser::init(const xmlChar** p, xmlParserBase* father)
{
DEBTRACE("nodeParser::init()");
++ _loopSamples.clear();
_state = XMLINNODE;
_father = father;
_stackState.push(_state);
else if (element == "nbdone") parser = new attrParser();
else if (element == "condition") parser = new attrParser();
else if (element == "outputPort") parser = new outputParser();
- else if (element == "loopOutputPort") parser = new loopPortParser();
++ else if (element == "loopOutputPort")
++ {
++ loopPortParser* sparser = new loopPortParser();
++ _loopSamples.push_back(sparser);
++ parser = sparser;
++ }
else
{
_what = "expected name, state or inputPort, got <" + element + ">";
}
mySwitch->edGetConditionPort()->edInit(condition);
}
++ else if (nodeType == "forEachLoop")
++ {
++ ForEachLoop* feNode = dynamic_cast<ForEachLoop*>(node);
++ if(!feNode)
++ {
++ _what = "node is not a ForEachLoop: " + _mapAttrib["name"];
++ _state = XMLFATALERROR;
++ stopParse(_what);
++ }
++ else
++ {
++ std::vector<unsigned int> passedIds;
++ std::vector<SequenceAny *> passedOutputs;
++ std::vector<std::string> nameOfOutputs;
++ bool firstPort = true;
++ std::list<loopPortParser*>::const_iterator itPort;
++ for(itPort=_loopSamples.begin(); itPort!=_loopSamples.end(); itPort++)
++ {
++ const std::string& portName =(*itPort)->getPortName();
++ nameOfOutputs.push_back(portName);
++ const YACS::ENGINE::TypeCode* tc = feNode->getOutputPortType(portName);
++ if(!tc)
++ {
++ _what = "Impossible to find the type of the port " + portName;
++ _state = XMLFATALERROR;
++ stopParse(_what);
++ return;
++ }
++ unsigned int nbSamples = (*itPort)->getNbSamples();
++ SequenceAny* seqValues = SequenceAny::New(tc, nbSamples);
++ passedOutputs.push_back(seqValues);
++ for(unsigned int i = 0; i < nbSamples; i++)
++ {
++ unsigned int sampleId = (*itPort)->getSampleId(i);
++ const std::string& sampleData = (*itPort)->getSampleData(i);
++ Any* value = xmlToAny(sampleData, tc);
++ if(firstPort)
++ {
++ passedIds.push_back(sampleId);
++ seqValues->setEltAtRank(i, value);
++ }
++ else
++ {
++ unsigned int pos = 0;
++ while(pos < passedIds.size() && sampleId != passedIds[pos])
++ pos++;
++ if(pos < passedIds.size())
++ seqValues->setEltAtRank(pos, value);
++ else
++ {
++ _what = "Inconsistent sample id in foreach node " + _mapAttrib["name"];
++ _state = XMLFATALERROR;
++ stopParse(_what);
++ itPort=_loopSamples.end();
++ return;
++ }
++ }
++ }
++ firstPort = false;
++ }
++ feNode->assignPassedResults(passedIds, passedOutputs, nameOfOutputs);
++ }
++ }
stateParser::onEnd(name);
}
++Any* nodeParser::xmlToAny(const std::string& data, const YACS::ENGINE::TypeCode* tc)const
++{
++ xmlDocPtr doc;
++ xmlNodePtr cur;
++ //YACS::ENGINE::Any *ob=YACS::ENGINE::AtomAny::New(0);
++ YACS::ENGINE::Any *ob=NULL;
++ {
++ doc = xmlParseMemory(data.c_str(), data.length());
++ if (doc == NULL )
++ {
++ stringstream msg;
++ msg << "Problem in conversion: XML Document not parsed successfully ";
++ msg << " (" << __FILE__ << ":" << __LINE__ << ")";
++ throw ConversionException(msg.str());
++ }
++ cur = xmlDocGetRootElement(doc);
++ if (cur == NULL)
++ {
++ xmlFreeDoc(doc);
++ stringstream msg;
++ msg << "Problem in conversion: empty XML Document";
++ msg << " (" << __FILE__ << ":" << __LINE__ << ")";
++ throw ConversionException(msg.str());
++ }
++ while (cur != NULL)
++ {
++ if ((!xmlStrcmp(cur->name, (const xmlChar *)"value")))
++ {
++ ob=convertXmlNeutral(tc,doc,cur);
++ break;
++ }
++ cur = cur->next;
++ }
++ xmlFreeDoc(doc);
++ if(ob==NULL)
++ {
++ stringstream msg;
++ msg << "Problem in conversion: incorrect XML value";
++ msg << " (" << __FILE__ << ":" << __LINE__ << ")";
++ throw ConversionException(msg.str());
++ }
++ }
++ return ob;
++}
++
// ----------------------------------------------------------------------------
void attrParser::init(const xmlChar** p, xmlParserBase* father)
_data = _data + data;
}
- _state = XMLINPORT;
+ // ----------------------------------------------------------------------------
+
+ void loopPortParser::init(const xmlChar** p, xmlParserBase* father)
+ {
+ DEBTRACE("loopPortParser::init()");
- else if (element == "sample") parser = new sampleParser();
++ //_state = XMLINPORT;
+ _father = father;
+ _stackState.push(_state);
++ _ids.clear();
++ _sampleData.clear();
+ if (p) getAttributes(p);
+ }
+
+ void loopPortParser::onStart(const XML_Char* elem, const xmlChar** p)
+ {
+ DEBTRACE("loopPortParser::onStart" << elem);
+ string element(elem);
+ stateParser *parser = 0;
+ if (element == "name") parser = new attrParser();
- string portName = _mapAttrib["name"];
- string nodeName = _father->getAttribute("name");
- string nodeType = _father->getAttribute("type");
- Node *node = _p->getChildByName(nodeName);
- if (nodeType != "forEachLoop")
- {
- _what = "loopOutputPort attribute is not valid for node <" + nodeName + ">";
- _state = XMLFATALERROR;
- stopParse(_what);
- }
++ else if (element == "sample") parser = new sampleParser(this);
+ else
+ {
+ _what = "expected name or sample, got <" + element + ">";
+ _state = XMLFATALERROR;
+ stopParse(_what);
+ }
+ if (parser)
+ {
+ _stackParser.push(parser);
+ XML_SetUserData(_xmlParser, parser);
+ parser->init(p, this);
+ }
+ }
+
+ void loopPortParser::onEnd(const XML_Char* name)
+ {
++ stateParser::onEnd(name);
+ }
+
+ void loopPortParser::charData(std::string data)
+ {
+ }
- _state = XMLINPORT;
++void loopPortParser::addSample(int index, const std::string data)
++{
++ _ids.push_back(index);
++ _sampleData.push_back(data);
++}
++
++unsigned int loopPortParser::getNbSamples()const
++{
++ return _ids.size();
++}
++
++unsigned int loopPortParser::getSampleId(unsigned int i)const
++{
++ return _ids[i];
++}
++
++const std::string& loopPortParser::getSampleData(unsigned int i)const
++{
++ return _sampleData[i];
++}
++
++const std::string& loopPortParser::getPortName()const
++{
++ return _mapAttrib.at("name");
++}
++
+ // ----------------------------------------------------------------------------
+
++sampleParser::sampleParser(loopPortParser* father)
++: stateParser(),
++ _sampleFather(father)
++{
++}
++
+ void sampleParser::init(const xmlChar** p, xmlParserBase* father)
+ {
+ DEBTRACE("sampleParser::init()");
- Any * value;
- value = xmlToAny();
++ //_state = XMLINPORT;
+ _father = father;
+ _stackState.push(_state);
+ if (p) getAttributes(p);
+ }
+
+ void sampleParser::onStart(const XML_Char* elem, const xmlChar** p)
+ {
+ DEBTRACE("sampleParser::onStart" << elem);
+ string element(elem);
+ stateParser *parser = 0;
+ if (element == "index") parser = new attrParser();
+ else if (element == "value") parser = new valueParser();
+ else
+ {
+ _what = "expected index or value, got <" + element + ">";
+ _state = XMLFATALERROR;
+ stopParse(_what);
+ }
+ if (parser)
+ {
+ _stackParser.push(parser);
+ XML_SetUserData(_xmlParser, parser);
+ parser->init(p, this);
+ }
+ }
+
+ void sampleParser::onEnd(const XML_Char* name)
+ {
+ if (_mapAttrib.find("index") == _mapAttrib.end())
+ {
+ _what = "no attribute index in sample ";
+ _state = XMLFATALERROR;
+ stopParse(_what);
+ }
+ int index = atoi(_mapAttrib["index"].c_str());
-}
-
-Any* sampleParser::xmlToAny() throw(ConversionException)
-{
- xmlDocPtr doc;
- xmlNodePtr cur;
- YACS::ENGINE::Any *ob=NULL;
- {
- doc = xmlParseMemory(_data.c_str(), _data.length());
- if (doc == NULL )
- {
- stringstream msg;
- msg << "Problem in conversion: XML Document not parsed successfully ";
- msg << " (" << __FILE__ << ":" << __LINE__ << ")";
- throw ConversionException(msg.str());
- }
- cur = xmlDocGetRootElement(doc);
- if (cur == NULL)
- {
- xmlFreeDoc(doc);
- stringstream msg;
- msg << "Problem in conversion: empty XML Document";
- msg << " (" << __FILE__ << ":" << __LINE__ << ")";
- throw ConversionException(msg.str());
- }
- while (cur != NULL)
- {
- if ((!xmlStrcmp(cur->name, (const xmlChar *)"value")))
- {
- ob=convertXmlNeutral(edGetType(),doc,cur);
- break;
- }
- cur = cur->next;
- }
- xmlFreeDoc(doc);
- if(ob==NULL)
- {
- stringstream msg;
- msg << "Problem in conversion: incorrect XML value";
- msg << " (" << __FILE__ << ":" << __LINE__ << ")";
- throw ConversionException(msg.str());
- }
- }
- return ob;
++ _sampleFather->addSample(index, _data);
++ stateParser::onEnd(name);
+ }
+
+ void sampleParser::charData(std::string data)
+ {
++ _data = _data + data;
+ }
// ----------------------------------------------------------------------------
#include "define.hxx"
#include "Exception.hxx"
+ #include <vector>
++#include <list>
namespace YACS
{
{
class Proc;
class Runtime;
+ class SequenceAny;
+ class Any;
++ class TypeCode;
//! Load state from a file into a Proc
/*!
};
++ class loopPortParser;
class YACSLOADER_EXPORT nodeParser: public stateParser
{
public:
virtual void init(const xmlChar** p, xmlParserBase* father=0);
virtual void onStart (const XML_Char* elem, const xmlChar** p);
virtual void onEnd (const XML_Char* name);
++ Any* xmlToAny(const std::string& data, const TypeCode* tc)const;
std::string _nodeName;
std::string _nodeState;
++ private:
++ std::list<loopPortParser*> _loopSamples;
};
class YACSLOADER_EXPORT attrParser: public stateParser
virtual void charData(std::string data);
};
- std::vector<SequenceAny *> _outputValues;
- std::vector<std::string> _outputNames;
+ class YACSLOADER_EXPORT loopPortParser: public stateParser
+ {
+ public:
+ virtual void init(const xmlChar** p, xmlParserBase* father=0);
+ virtual void onStart (const XML_Char* elem, const xmlChar** p);
+ virtual void onEnd (const XML_Char* name);
+ virtual void charData(std::string data);
++ void addSample(int index, const std::string data);
++ unsigned int getNbSamples()const;
++ unsigned int getSampleId(unsigned int i)const;
++ const std::string& getSampleData(unsigned int i)const;
++ const std::string& getPortName()const;
++ private:
+ std::vector<unsigned int> _ids;
- protected:
- Any* xmlToAny()throw(ConversionException);
++ std::vector<std::string> _sampleData;
+ };
+
+ class YACSLOADER_EXPORT sampleParser: public stateParser
+ {
+ public:
++ sampleParser(loopPortParser* father);
+ virtual void init(const xmlChar** p, xmlParserBase* father=0);
+ virtual void onStart (const XML_Char* elem, const xmlChar** p);
+ virtual void onEnd (const XML_Char* name);
+ virtual void charData(std::string data);
++ //protected:
++ // Any* xmlToAny()throw(ConversionException);
++ private:
++ loopPortParser* _sampleFather;
+ };
+
}
}
#endif