summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-01-12 23:49:43 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-01-12 23:49:43 (GMT)
commita116aeb2cf5a84fa03f9814c3884561149029267 (patch)
treebdd7dfc15ec1e38edcc9a7532ffad03fe4f6f823
parent6d0622c0bb8f0e52589c82252f2cc1eb847ad9bf (diff)
downloaduscxml-a116aeb2cf5a84fa03f9814c3884561149029267.zip
uscxml-a116aeb2cf5a84fa03f9814c3884561149029267.tar.gz
uscxml-a116aeb2cf5a84fa03f9814c3884561149029267.tar.bz2
Refactored to PIMPL pattern
-rw-r--r--CMakeLists.txt8
-rw-r--r--src/uscxml/Factory.cpp43
-rw-r--r--src/uscxml/Factory.h128
-rw-r--r--src/uscxml/Interpreter.cpp177
-rw-r--r--src/uscxml/Interpreter.h29
-rw-r--r--src/uscxml/URL.cpp52
-rw-r--r--src/uscxml/URL.h47
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp6
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h6
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp4
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h6
-rw-r--r--src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp8
-rw-r--r--src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h10
-rw-r--r--src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp10
-rw-r--r--src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.h10
-rw-r--r--src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp19
-rw-r--r--src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h11
-rw-r--r--src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp22
-rw-r--r--src/uscxml/plugins/invoker/umundo/UmundoInvoker.h10
-rw-r--r--src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp8
-rw-r--r--src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h6
-rw-r--r--test/CMakeLists.txt5
-rw-r--r--test/src/test-url.cpp42
23 files changed, 403 insertions, 264 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c7d0ca2..0c24682 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -557,10 +557,11 @@ elseif(WIN32)
endif()
find_package(OpenSceneGraph COMPONENTS osgViewer osgGA osgText osgFX osgManipulator osgDB osgUtil OpenThreads)
-if (OPENSCENEGRAPH_FOUND)
- set(CAN_BUILD_OPENSCENEGRAPH_INVOKER ON)
+find_package(OpenGL)
+if (OPENSCENEGRAPH_FOUND AND OPENGL_FOUND)
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})
+ include_directories(${OPENGL_INCLUDE_DIR})
file(GLOB_RECURSE OPENSCENEGRAPH_INVOKER
src/uscxml/plugins/invoker/graphics/openscenegraph/*.cpp
src/uscxml/plugins/invoker/graphics/openscenegraph/*.h)
@@ -571,11 +572,12 @@ if (OPENSCENEGRAPH_FOUND)
${OPENSCENEGRAPH_INVOKER})
target_link_libraries(invoker_openscenegraph
${OPENSCENEGRAPH_LIBRARIES}
+ ${OPENGL_LIBRARIES}
uscxml)
set_target_properties(invoker_openscenegraph PROPERTIES FOLDER "Plugin Invoker")
else()
list (APPEND USCXML_FILES ${OPENSCENEGRAPH_INVOKER})
- list (APPEND USCXML_OPT_LIBS ${OPENSCENEGRAPH_LIBRARIES})
+ list (APPEND USCXML_OPT_LIBS ${OPENSCENEGRAPH_LIBRARIES} ${OPENGL_LIBRARIES})
endif()
endif()
diff --git a/src/uscxml/Factory.cpp b/src/uscxml/Factory.cpp
index 3cac6b1..478d282 100644
--- a/src/uscxml/Factory.cpp
+++ b/src/uscxml/Factory.cpp
@@ -127,7 +127,7 @@ Factory::~Factory() {
#endif
}
-void Factory::registerIOProcessor(IOProcessor* ioProcessor) {
+void Factory::registerIOProcessor(IOProcessorImpl* ioProcessor) {
std::set<std::string> names = ioProcessor->getNames();
std::set<std::string>::iterator nameIter = names.begin();
if (nameIter != names.end()) {
@@ -140,7 +140,7 @@ void Factory::registerIOProcessor(IOProcessor* ioProcessor) {
}
}
-void Factory::registerDataModel(DataModel* dataModel) {
+void Factory::registerDataModel(DataModelImpl* dataModel) {
std::set<std::string> names = dataModel->getNames();
std::set<std::string>::iterator nameIter = names.begin();
if (nameIter != names.end()) {
@@ -153,7 +153,7 @@ void Factory::registerDataModel(DataModel* dataModel) {
}
}
-void Factory::registerInvoker(Invoker* invoker) {
+void Factory::registerInvoker(InvokerImpl* invoker) {
std::set<std::string> names = invoker->getNames();
std::set<std::string>::iterator nameIter = names.begin();
if (nameIter != names.end()) {
@@ -166,55 +166,42 @@ void Factory::registerInvoker(Invoker* invoker) {
}
}
-void Factory::registerExecutableContent(const std::string tag, ExecutableContent* executableContent) {
- _executableContent[tag] = executableContent;
-}
-
-Invoker* Factory::getInvoker(const std::string type, Interpreter* interpreter) {
+boost::shared_ptr<InvokerImpl> Factory::createInvoker(const std::string& type, Interpreter* interpreter) {
Factory* factory = getInstance();
if (factory->_invokerAliases.find(type) == factory->_invokerAliases.end())
- return NULL;
+ return boost::shared_ptr<InvokerImpl>();
std::string canonicalName = factory->_invokerAliases[type];
if (factory->_invokers.find(canonicalName) == factory->_invokers.end())
- return NULL;
+ return boost::shared_ptr<InvokerImpl>();
- return factory->_invokers[canonicalName]->create(interpreter);
+ return boost::shared_ptr<InvokerImpl>(factory->_invokers[canonicalName]->create(interpreter));
}
-DataModel* Factory::getDataModel(const std::string type, Interpreter* interpreter) {
+boost::shared_ptr<DataModelImpl> Factory::createDataModel(const std::string& type, Interpreter* interpreter) {
Factory* factory = getInstance();
if (factory->_dataModelAliases.find(type) == factory->_dataModelAliases.end())
- return NULL;
+ return boost::shared_ptr<DataModelImpl>();
std::string canonicalName = factory->_dataModelAliases[type];
if (factory->_dataModels.find(canonicalName) == factory->_dataModels.end())
- return NULL;
+ return boost::shared_ptr<DataModelImpl>();
- return factory->_dataModels[canonicalName]->create(interpreter);
+ return boost::shared_ptr<DataModelImpl>(factory->_dataModels[canonicalName]->create(interpreter));
}
-IOProcessor* Factory::getIOProcessor(const std::string type, Interpreter* interpreter) {
+boost::shared_ptr<IOProcessorImpl> Factory::createIOProcessor(const std::string& type, Interpreter* interpreter) {
Factory* factory = getInstance();
if (factory->_ioProcessorAliases.find(type) == factory->_ioProcessorAliases.end())
- return NULL;
+ return boost::shared_ptr<IOProcessorImpl>();
std::string canonicalName = factory->_ioProcessorAliases[type];
if (factory->_ioProcessors.find(canonicalName) == factory->_ioProcessors.end())
- return NULL;
+ return boost::shared_ptr<IOProcessorImpl>();
- return factory->_ioProcessors[canonicalName]->create(interpreter);
+ return boost::shared_ptr<IOProcessorImpl>(factory->_ioProcessors[canonicalName]->create(interpreter));
}
-#if 0
-ExecutableContent* Factory::getExecutableContent(const std::string tag, Interpreter* interpreter) {
- Factory* factory = getInstance();
- if (factory->_executableContent.find(tag) != factory->_executableContent.end()) {
- return factory->_executableContent[tag]->create(interpreter);
- }
- return NULL;
-}
-#endif
Factory* Factory::getInstance() {
if (_instance == NULL) {
diff --git a/src/uscxml/Factory.h b/src/uscxml/Factory.h
index 16b26da..09bab7b 100644
--- a/src/uscxml/Factory.h
+++ b/src/uscxml/Factory.h
@@ -9,6 +9,7 @@
#include <string>
#include <set>
+#include <boost/shared_ptr.hpp>
namespace uscxml {
@@ -33,12 +34,12 @@ public:
ExecutableContent() {};
virtual ExecutableContent* create(Interpreter* interpreter) = 0;
};
-
-class IOProcessor {
+
+class IOProcessorImpl {
public:
- IOProcessor() {};
- virtual ~IOProcessor() {};
- virtual IOProcessor* create(Interpreter* interpreter) = 0;
+ IOProcessorImpl() {};
+ virtual ~IOProcessorImpl() {};
+ virtual IOProcessorImpl* create(Interpreter* interpreter) = 0;
virtual std::set<std::string> getNames() = 0;
virtual void setInterpreter(Interpreter* interpreter) {
@@ -46,7 +47,7 @@ public:
}
virtual Data getDataModelVariables() = 0;
- virtual void send(SendRequest& req) = 0;
+ virtual void send(const SendRequest& req) = 0;
virtual void runOnMainThread() {};
@@ -54,24 +55,69 @@ protected:
Interpreter* _interpreter;
};
-class Invoker : public IOProcessor {
+class IOProcessor {
+public:
+ IOProcessor() : _impl() {}
+ IOProcessor(boost::shared_ptr<IOProcessorImpl> const impl) : _impl(impl) { }
+ IOProcessor(const IOProcessor& other) : _impl(other._impl) { }
+ virtual ~IOProcessor() {};
+
+ operator bool() const { return _impl;}
+ bool operator< (const IOProcessor& other) const { return _impl < other._impl; }
+ bool operator==(const IOProcessor& other) const { return _impl == other._impl; }
+ bool operator!=(const IOProcessor& other) const { return _impl != other._impl; }
+ IOProcessor& operator= (const IOProcessor& other) { _impl = other._impl; return *this; }
+
+ virtual Data getDataModelVariables() const { return _impl->getDataModelVariables(); };
+ virtual void send(const SendRequest& req) { return _impl->send(req); };
+ virtual void runOnMainThread() { return _impl->runOnMainThread(); }
+
+protected:
+ boost::shared_ptr<IOProcessorImpl> _impl;
+};
+
+class InvokerImpl : public IOProcessorImpl {
public:
- virtual void invoke(InvokeRequest& req) = 0;
- virtual void sendToParent(SendRequest& req) = 0;
- virtual Invoker* create(Interpreter* interpreter) = 0;
+ virtual void invoke(const InvokeRequest& req) = 0;
+ virtual void sendToParent(const SendRequest& req) = 0;
+ virtual InvokerImpl* create(Interpreter* interpreter) = 0;
};
-class DataModel {
+class Invoker : public IOProcessor {
public:
- virtual ~DataModel() {}
- virtual DataModel* create(Interpreter* interpreter) = 0;
+ Invoker() : _impl() {}
+ Invoker(boost::shared_ptr<InvokerImpl> const impl) : IOProcessor(impl), _impl(impl) { }
+ Invoker(const Invoker& other) : IOProcessor(other._impl), _impl(other._impl) { }
+ virtual ~Invoker() {};
+
+ operator bool() const { return _impl;}
+ bool operator< (const Invoker& other) const { return _impl < other._impl; }
+ bool operator==(const Invoker& other) const { return _impl == other._impl; }
+ bool operator!=(const Invoker& other) const { return _impl != other._impl; }
+ Invoker& operator= (const Invoker& other) {
+ _impl = other._impl;
+ IOProcessor::_impl = _impl;
+ return *this;
+ }
+
+ virtual void invoke(InvokeRequest& req) { _impl->invoke(req); }
+ virtual void sendToParent(SendRequest& req) { _impl->sendToParent(req); }
+
+protected:
+ boost::shared_ptr<InvokerImpl> _impl;
+};
+
+class DataModelImpl {
+public:
+ virtual ~DataModelImpl() {}
+ virtual DataModelImpl* create(Interpreter* interpreter) = 0;
virtual std::set<std::string> getNames() = 0;
virtual bool validate(const std::string& location, const std::string& schema) = 0;
virtual void setEvent(const Event& event) = 0;
virtual Data getStringAsData(const std::string& content) = 0;
- virtual void registerIOProcessor(const std::string& name, IOProcessor* ioprocessor) = 0;
+ virtual void registerIOProcessor(const std::string& name, const IOProcessor& ioprocessor) = 0;
// foreach
virtual uint32_t getLength(const std::string& expr) = 0;
@@ -85,27 +131,57 @@ public:
virtual void assign(const std::string& location, const Data& data) = 0;
};
+class DataModel {
+public:
+ DataModel() : _impl() {}
+ DataModel(boost::shared_ptr<DataModelImpl> const impl) : _impl(impl) { }
+ DataModel(const DataModel& other) : _impl(other._impl) { }
+ virtual ~DataModel() {};
+
+ operator bool() const { return _impl;}
+ bool operator< (const DataModel& other) const { return _impl < other._impl; }
+ bool operator==(const DataModel& other) const { return _impl == other._impl; }
+ bool operator!=(const DataModel& other) const { return _impl != other._impl; }
+ DataModel& operator= (const DataModel& other) { _impl = other._impl; return *this; }
+
+ virtual bool validate(const std::string& location, const std::string& schema) { return _impl->validate(location, schema); }
+ virtual void setEvent(const Event& event) { return _impl->setEvent(event); }
+ virtual Data getStringAsData(const std::string& content) { return _impl->getStringAsData(content); }
+
+ virtual uint32_t getLength(const std::string& expr) { return _impl->getLength(expr); }
+ virtual void pushContext() { return _impl->pushContext(); }
+ virtual void popContext() { return _impl->popContext(); }
+
+ virtual void registerIOProcessor(const std::string& name, const IOProcessor& ioprocessor) { _impl->registerIOProcessor(name, ioprocessor); }
+
+ virtual void eval(const std::string& expr) { return _impl->eval(expr); }
+ virtual std::string evalAsString(const std::string& expr) { return _impl->evalAsString(expr); }
+ virtual bool evalAsBool(const std::string& expr) { return _impl->evalAsBool(expr); }
+ virtual void assign(const std::string& location, const std::string& expr) { return _impl->assign(location, expr); }
+ virtual void assign(const std::string& location, const Data& data) { return _impl->assign(location, data); }
+
+protected:
+ boost::shared_ptr<DataModelImpl> _impl;
+};
+
class Factory {
public:
- void registerIOProcessor(IOProcessor* ioProcessor);
- void registerDataModel(DataModel* dataModel);
- void registerInvoker(Invoker* invoker);
- void registerExecutableContent(const std::string tag, ExecutableContent* executableContent);
+ void registerIOProcessor(IOProcessorImpl* ioProcessor);
+ void registerDataModel(DataModelImpl* dataModel);
+ void registerInvoker(InvokerImpl* invoker);
- static DataModel* getDataModel(const std::string type, Interpreter* interpreter);
- static IOProcessor* getIOProcessor(const std::string type, Interpreter* interpreter);
- static ExecutableContent* getExecutableContent(const std::string tag, Interpreter* interpreter);
- static Invoker* getInvoker(const std::string type, Interpreter* interpreter);
+ static boost::shared_ptr<DataModelImpl> createDataModel(const std::string& type, Interpreter* interpreter);
+ static boost::shared_ptr<IOProcessorImpl> createIOProcessor(const std::string& type, Interpreter* interpreter);
+ static boost::shared_ptr<InvokerImpl> createInvoker(const std::string& type, Interpreter* interpreter);
static Factory* getInstance();
- std::map<std::string, DataModel*> _dataModels;
+ std::map<std::string, DataModelImpl*> _dataModels;
std::map<std::string, std::string> _dataModelAliases;
- std::map<std::string, IOProcessor*> _ioProcessors;
+ std::map<std::string, IOProcessorImpl*> _ioProcessors;
std::map<std::string, std::string> _ioProcessorAliases;
- std::map<std::string, Invoker*> _invokers;
+ std::map<std::string, InvokerImpl*> _invokers;
std::map<std::string, std::string> _invokerAliases;
- std::map<std::string, ExecutableContent*> _executableContent;
static std::string pluginPath;
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index 453bdd5..5681ff9 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -52,16 +52,23 @@ Interpreter* Interpreter::fromXML(const std::string& xml) {
}
Interpreter* Interpreter::fromURI(const std::string& uri) {
- Arabica::SAX::InputSource<std::string> inputSource(uri);
+ URL absUrl(uri);
+ if (!absUrl.isAbsolute()) {
+ if (!absUrl.toAbsoluteCwd()) {
+ LOG(ERROR) << "Given URL is not absolute or does not have file schema";
+ return NULL;
+ }
+ }
+ Arabica::SAX::InputSource<std::string> inputSource(absUrl.asString());
Interpreter* interpreter = fromInputSource(inputSource);
// try to establish URI root for relative src attributes in document
if (interpreter)
- interpreter->_baseURI = toBaseURI(Arabica::io::URI(uri));
+ interpreter->_baseURI = toBaseURI(absUrl);
return interpreter;
}
-Arabica::io::URI Interpreter::toBaseURI(const Arabica::io::URI& uri) {
+URL Interpreter::toBaseURI(const URL& uri) {
std::stringstream ssBaseURI;
if (uri.scheme().size() > 0) {
ssBaseURI << uri.scheme() << "://";
@@ -75,30 +82,20 @@ Arabica::io::URI Interpreter::toBaseURI(const Arabica::io::URI& uri) {
}
if (uri.path().size() > 0) {
std::string uriPath = uri.path();
- uriPath = uriPath.substr(0, uriPath.find_last_of("/\\"));
+ uriPath = uriPath.substr(0, uriPath.find_last_of("/\\") + 1);
ssBaseURI << uriPath;
}
- return Arabica::io::URI(ssBaseURI.str());
+ return URL(ssBaseURI.str());
}
-bool Interpreter::makeAbsolute(Arabica::io::URI& uri) {
- if (uri.is_absolute())
+bool Interpreter::toAbsoluteURI(URL& uri) {
+ if (uri.isAbsolute())
return true;
- if (_baseURI.as_string().size() > 0) {
- std::stringstream ssAbsoluteURI;
- if (_baseURI.scheme().size() > 0)
- ssAbsoluteURI << _baseURI.scheme() << "://";
- if (_baseURI.host().size() > 0) {
- ssAbsoluteURI << _baseURI.host();
- if (!boost::iequals(_baseURI.port(), "0"))
- ssAbsoluteURI << ":" << _baseURI.port();
- }
- if (_baseURI.path().size() > 0) {
- ssAbsoluteURI << _baseURI.path() << "/" << uri.path();
- }
- uri = Arabica::io::URI(ssAbsoluteURI.str());
- return true;
+ if (_baseURI.asString().size() > 0) {
+ if (uri.toAbsolute(_baseURI));
+ return true;
+ return false;
}
return false;
}
@@ -114,13 +111,13 @@ Interpreter* Interpreter::fromInputSource(Arabica::SAX::InputSource<std::string>
Arabica::SAX::CatchErrorHandler<std::string> errorHandler;
interpreter->setErrorHandler(errorHandler);
if(!interpreter->parse(source) || !interpreter->Arabica::SAX2DOM::Parser<std::string>::getDocument().hasChildNodes()) {
- LOG(INFO) << "could not parse input:";
if(errorHandler.errorsReported()) {
+ LOG(ERROR) << "could not parse input:";
LOG(ERROR) << errorHandler.errors() << std::endl;
} else {
Arabica::SAX::InputSourceResolver resolver(source, Arabica::default_string_adaptor<std::string>());
if (!resolver.resolve()) {
- LOG(ERROR) << "no such file";
+ LOG(ERROR) << source.getSystemId() << ": no such file";
}
}
return NULL;
@@ -134,8 +131,6 @@ Interpreter* Interpreter::fromInputSource(Arabica::SAX::InputSource<std::string>
void Interpreter::init() {
_lastRunOnMainThread = 0;
_thread = NULL;
- _dataModel = NULL;
- _invoker = NULL;
_running = false;
_sendQueue = new DelayedEventQueue();
_sendQueue->start();
@@ -163,18 +158,12 @@ void Interpreter::init() {
}
Interpreter::~Interpreter() {
- std::map<std::string, IOProcessor*>::iterator ioProcessorIter = _ioProcessors.begin();
- while(ioProcessorIter != _ioProcessors.end()) {
- delete ioProcessorIter->second;
- ioProcessorIter++;
- }
if (_thread) {
_running = false;
_externalQueue.push(Event());
_thread->join();
delete(_thread);
}
- delete _dataModel;
delete _sendQueue;
}
@@ -200,15 +189,15 @@ bool Interpreter::runOnMainThread(int fps, bool blocking) {
_lastRunOnMainThread = tthread::timeStamp();
- std::map<std::string, IOProcessor*>::iterator ioProcessorIter = _ioProcessors.begin();
+ std::map<std::string, IOProcessor>::iterator ioProcessorIter = _ioProcessors.begin();
while(ioProcessorIter != _ioProcessors.end()) {
- ioProcessorIter->second->runOnMainThread();
+ ioProcessorIter->second.runOnMainThread();
ioProcessorIter++;
}
- std::map<std::string, Invoker*>::iterator invokerIter = _invokers.begin();
+ std::map<std::string, Invoker>::iterator invokerIter = _invokers.begin();
while(invokerIter != _invokers.end()) {
- invokerIter->second->runOnMainThread();
+ invokerIter->second.runOnMainThread();
invokerIter++;
}
@@ -229,8 +218,8 @@ void Interpreter::interpret() {
_sessionId = getUUID();
if(HAS_ATTR(_scxml, "datamodel")) {
- _dataModel = Factory::getDataModel(ATTR(_scxml, "datamodel"), this);
- if(_dataModel == NULL) {
+ _dataModel = Factory::createDataModel(ATTR(_scxml, "datamodel"), this);
+ if(!_dataModel) {
LOG(ERROR) << "No datamodel for " << ATTR(_scxml, "datamodel") << " registered";
return;
}
@@ -298,19 +287,19 @@ void Interpreter::initializeData(const Arabica::DOM::Node<std::string>& data) {
if (HAS_ATTR(data, "expr")) {
std::string value = ATTR(data, "expr");
- _dataModel->assign(ATTR(data, "id"), value);
+ _dataModel.assign(ATTR(data, "id"), value);
} else if (HAS_ATTR(data, "src")) {
Arabica::SAX::InputSourceResolver resolver(Arabica::SAX::InputSource<std::string>(ATTR(data, "src")),
Arabica::default_string_adaptor<std::string>());
std::string value = std::string(std::istreambuf_iterator<char>(*resolver.resolve()), std::istreambuf_iterator<char>());
- _dataModel->assign(ATTR(data, "id"), value);
+ _dataModel.assign(ATTR(data, "id"), value);
} else if (data.hasChildNodes()) {
// search for the text node with the actual script
NodeList<std::string> dataChilds = data.getChildNodes();
for (int i = 0; i < dataChilds.getLength(); i++) {
if (dataChilds.item(i).getNodeType() == Node_base::TEXT_NODE) {
Data value = Data(dataChilds.item(i).getNodeValue());
- _dataModel->assign(ATTR(data, "id"), value);
+ _dataModel.assign(ATTR(data, "id"), value);
break;
}
}
@@ -408,7 +397,7 @@ void Interpreter::mainEventLoop() {
std::cout << "Received internal event " << internalEvent.name << std::endl;
#endif
if (_dataModel)
- _dataModel->setEvent(internalEvent);
+ _dataModel.setEvent(internalEvent);
enabledTransitions = selectTransitions(internalEvent.name);
}
}
@@ -446,7 +435,7 @@ void Interpreter::mainEventLoop() {
if (_dataModel)
try {
- _dataModel->setEvent(externalEvent);
+ _dataModel.setEvent(externalEvent);
} catch (Event e) {
LOG(ERROR) << "Syntax error while setting external event:" << std::endl << e << std::endl;
}
@@ -502,10 +491,10 @@ void Interpreter::internalDoneSend(const Arabica::DOM::Node<std::string>& state)
}
std::string paramValue;
if (HAS_ATTR(doneChilds.item(i), "expr") && _dataModel) {
- std::string location = _dataModel->evalAsString(ATTR(doneChilds.item(i), "expr"));
- paramValue = _dataModel->evalAsString(location);
+ std::string location = _dataModel.evalAsString(ATTR(doneChilds.item(i), "expr"));
+ paramValue = _dataModel.evalAsString(location);
} else if(HAS_ATTR(doneChilds.item(i), "location") && _dataModel) {
- paramValue = _dataModel->evalAsString(ATTR(doneChilds.item(i), "location"));
+ paramValue = _dataModel.evalAsString(ATTR(doneChilds.item(i), "location"));
} else {
LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
continue;
@@ -515,7 +504,7 @@ void Interpreter::internalDoneSend(const Arabica::DOM::Node<std::string>& state)
if (boost::iequals(TAGNAME(doneChilds.item(i)), "content")) {
if (HAS_ATTR(doneChilds.item(i), "expr")) {
if (_dataModel) {
- event.compound["content"] = Data(_dataModel->evalAsString(ATTR(doneChilds.item(i), "expr")), Data::VERBATIM);
+ event.compound["content"] = Data(_dataModel.evalAsString(ATTR(doneChilds.item(i), "expr")), Data::VERBATIM);
} else {
LOG(ERROR) << "content element has expr attribute but no datamodel is specified.";
}
@@ -539,19 +528,19 @@ void Interpreter::send(const Arabica::DOM::Node<std::string>& element) {
try {
// event
if (HAS_ATTR(element, "eventexpr") && _dataModel) {
- sendReq.name = _dataModel->evalAsString(ATTR(element, "eventexpr"));
+ sendReq.name = _dataModel.evalAsString(ATTR(element, "eventexpr"));
} else if (HAS_ATTR(element, "event")) {
sendReq.name = ATTR(element, "event");
}
// target
if (HAS_ATTR(element, "targetexpr") && _dataModel) {
- sendReq.target = _dataModel->evalAsString(ATTR(element, "targetexpr"));
+ sendReq.target = _dataModel.evalAsString(ATTR(element, "targetexpr"));
} else if (HAS_ATTR(element, "target")) {
sendReq.target = ATTR(element, "target");
}
// type
if (HAS_ATTR(element, "typeexpr") && _dataModel) {
- sendReq.type = _dataModel->evalAsString(ATTR(element, "typeexpr"));
+ sendReq.type = _dataModel.evalAsString(ATTR(element, "typeexpr"));
} else if (HAS_ATTR(element, "type")) {
sendReq.type = ATTR(element, "type");
} else {
@@ -559,7 +548,7 @@ void Interpreter::send(const Arabica::DOM::Node<std::string>& element) {
}
// id
if (HAS_ATTR(element, "idlocation") && _dataModel) {
- sendReq.sendid = _dataModel->evalAsString(ATTR(element, "idlocation"));
+ sendReq.sendid = _dataModel.evalAsString(ATTR(element, "idlocation"));
} else if (HAS_ATTR(element, "id")) {
sendReq.sendid = ATTR(element, "id");
} else {
@@ -588,7 +577,7 @@ void Interpreter::send(const Arabica::DOM::Node<std::string>& element) {
std::string delay;
sendReq.delayMs = 0;
if (HAS_ATTR(element, "delayexpr") && _dataModel) {
- delay = _dataModel->evalAsString(ATTR(element, "delayexpr"));
+ delay = _dataModel.evalAsString(ATTR(element, "delayexpr"));
} else if (HAS_ATTR(element, "delay")) {
delay = ATTR(element, "delay");
}
@@ -610,7 +599,7 @@ void Interpreter::send(const Arabica::DOM::Node<std::string>& element) {
if (HAS_ATTR(element, "namelist")) {
std::vector<std::string> names = tokenizeIdRefs(ATTR(element, "namelist"));
for (int i = 0; i < names.size(); i++) {
- sendReq.namelist[names[i]] = _dataModel->evalAsString(names[i]);
+ sendReq.namelist[names[i]] = _dataModel.evalAsString(names[i]);
}
}
@@ -623,9 +612,9 @@ void Interpreter::send(const Arabica::DOM::Node<std::string>& element) {
}
std::string paramValue;
if (HAS_ATTR(params[i], "expr") && _dataModel) {
- paramValue = _dataModel->evalAsString(ATTR(params[i], "expr"));
+ paramValue = _dataModel.evalAsString(ATTR(params[i], "expr"));
} else if(HAS_ATTR(params[i], "location") && _dataModel) {
- paramValue = _dataModel->evalAsString(ATTR(params[i], "location"));
+ paramValue = _dataModel.evalAsString(ATTR(params[i], "location"));
} else {
LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
continue;
@@ -640,7 +629,7 @@ void Interpreter::send(const Arabica::DOM::Node<std::string>& element) {
if (contents.size() > 0) {
if (HAS_ATTR(contents[0], "expr")) {
if (_dataModel) {
- sendReq.content = _dataModel->evalAsString(ATTR(contents[0], "expr"));
+ sendReq.content = _dataModel.evalAsString(ATTR(contents[0], "expr"));
} else {
LOG(ERROR) << "content element has expr attribute but no datamodel is specified.";
}
@@ -672,8 +661,8 @@ void Interpreter::delayedSend(void* userdata, std::string eventName) {
if (boost::iequals(sendReq.target, "#_parent")) {
// send to parent scxml session
- if (INSTANCE->_invoker != NULL) {
- INSTANCE->_invoker->sendToParent(sendReq);
+ if (INSTANCE->_invoker) {
+ INSTANCE->_invoker.sendToParent(sendReq);
} else {
LOG(ERROR) << "Can not send to parent, we were not invoked" << std::endl;
}
@@ -681,16 +670,16 @@ void Interpreter::delayedSend(void* userdata, std::string eventName) {
// send to invoker
std::string invokeId = sendReq.target.substr(2, sendReq.target.length() - 2);
if (INSTANCE->_invokers.find(invokeId) != INSTANCE->_invokers.end()) {
- INSTANCE->_invokers[invokeId]->send(sendReq);
+ INSTANCE->_invokers[invokeId].send(sendReq);
} else {
LOG(ERROR) << "Can not send to invoked component '" << invokeId << "', no such invokeId" << std::endl;
}
} else if (sendReq.target.length() == 0) {
INSTANCE->receive(sendReq);
} else {
- IOProcessor* ioProc = INSTANCE->getIOProcessor(sendReq.type);
- if (ioProc != NULL) {
- ioProc->send(sendReq);
+ IOProcessor ioProc = INSTANCE->getIOProcessor(sendReq.type);
+ if (ioProc) {
+ ioProc.send(sendReq);
}
}
assert(INSTANCE->_sendIds.find(sendReq.sendid) != INSTANCE->_sendIds.end());
@@ -704,7 +693,7 @@ void Interpreter::invoke(const Arabica::DOM::Node<std::string>& element) {
try {
// type
if (HAS_ATTR(element, "typeexpr") && _dataModel) {
- invokeReq.type = _dataModel->evalAsString(ATTR(element, "typeexpr"));
+ invokeReq.type = _dataModel.evalAsString(ATTR(element, "typeexpr"));
} else if (HAS_ATTR(element, "type")) {
invokeReq.type = ATTR(element, "type");
} else {
@@ -714,22 +703,22 @@ void Interpreter::invoke(const Arabica::DOM::Node<std::string>& element) {
// src
std::string source;
if (HAS_ATTR(element, "srcexpr") && _dataModel) {
- source = _dataModel->evalAsString(ATTR(element, "srcexpr"));
+ source = _dataModel.evalAsString(ATTR(element, "srcexpr"));
} else if (HAS_ATTR(element, "src")) {
source = ATTR(element, "src");
}
if (source.length() > 0) {
- Arabica::io::URI srcURI(source);
- if (!makeAbsolute(srcURI)) {
+ URL srcURI(source);
+ if (!toAbsoluteURI(srcURI)) {
LOG(ERROR) << "invoke element has relative src URI with no baseURI set.";
return;
}
- invokeReq.src = srcURI.as_string();
+ invokeReq.src = srcURI.asString();
}
// id
if (HAS_ATTR(element, "idlocation") && _dataModel) {
- invokeReq.invokeid = _dataModel->evalAsString(ATTR(element, "idlocation"));
+ invokeReq.invokeid = _dataModel.evalAsString(ATTR(element, "idlocation"));
} else if (HAS_ATTR(element, "id")) {
invokeReq.invokeid = ATTR(element, "id");
} else {
@@ -760,12 +749,12 @@ void Interpreter::invoke(const Arabica::DOM::Node<std::string>& element) {
std::string paramValue;
if (HAS_ATTR(params[i], "expr")) {
if (_dataModel) {
- paramValue = _dataModel->evalAsString(ATTR(params[i], "expr"));
+ paramValue = _dataModel.evalAsString(ATTR(params[i], "expr"));
} else {
paramValue = ATTR(params[i], "expr");
}
} else if(HAS_ATTR(params[i], "location") && _dataModel) {
- paramValue = _dataModel->evalAsString(ATTR(params[i], "location"));
+ paramValue = _dataModel.evalAsString(ATTR(params[i], "location"));
} else {
LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
continue;
@@ -783,11 +772,11 @@ void Interpreter::invoke(const Arabica::DOM::Node<std::string>& element) {
invokeReq.content = contents[0].getNodeValue();
}
- Invoker* invoker = Factory::getInvoker(invokeReq.type, this);
- if (invoker != NULL) {
+ Invoker invoker(Factory::createInvoker(invokeReq.type, this));
+ if (invoker) {
_invokers[invokeReq.invokeid] = invoker;
LOG(INFO) << "Added invoker " << invokeReq.type << " at " << invokeReq.invokeid;
- invoker->invoke(invokeReq);
+ invoker.invoke(invokeReq);
} else {
LOG(ERROR) << "No invoker known for type " << invokeReq.type;
}
@@ -800,7 +789,7 @@ void Interpreter::invoke(const Arabica::DOM::Node<std::string>& element) {
void Interpreter::cancelInvoke(const Arabica::DOM::Node<std::string>& element) {
std::string invokeId;
if (HAS_ATTR(element, "idlocation") && _dataModel) {
- invokeId = _dataModel->evalAsString(ATTR(element, "idlocation"));
+ invokeId = _dataModel.evalAsString(ATTR(element, "idlocation"));
} else if (HAS_ATTR(element, "id")) {
invokeId = ATTR(element, "id");
} else {
@@ -808,7 +797,6 @@ void Interpreter::cancelInvoke(const Arabica::DOM::Node<std::string>& element) {
}
if (_invokers.find(invokeId) != _invokers.end()) {
LOG(INFO) << "Removed invoker at " << invokeId;
- delete (_invokers[invokeId]);
_invokers.erase(invokeId);
} else {
LOG(ERROR) << "Cannot cancel invoke for id " << invokeId << ": no soch invokation";
@@ -930,7 +918,7 @@ LOOP:
bool Interpreter::hasConditionMatch(const Arabica::DOM::Node<std::string>& conditional) {
try {
if (_dataModel && HAS_ATTR(conditional, "cond"))
- return _dataModel->evalAsBool(ATTR(conditional, "cond"));
+ return _dataModel.evalAsBool(ATTR(conditional, "cond"));
} catch (Event e) {
LOG(ERROR) << "Syntax error in cond attribute of " << TAGNAME(conditional) << " element:" << std::endl << e << std::endl;
return false;
@@ -1073,25 +1061,25 @@ ELSIF_ELEM_MATCH:
std::string array = ATTR(content, "array");
std::string item = ATTR(content, "item");
std::string index = (HAS_ATTR(content, "index") ? ATTR(content, "index") : "");
- uint32_t iterations = _dataModel->getLength(array);
- _dataModel->pushContext(); // copy old and enter new context
+ uint32_t iterations = _dataModel.getLength(array);
+ _dataModel.pushContext(); // copy old and enter new context
for (uint32_t iteration = 0; iteration < iterations; iteration++) {
{
// assign array element to item
std::stringstream ss;
ss << array << "[" << iteration << "]";
- _dataModel->assign(item, ss.str());
+ _dataModel.assign(item, ss.str());
}
if (index.length() > 0) {
// assign iteration element to index
std::stringstream ss;
ss << iteration;
- _dataModel->assign(index,ss.str());
+ _dataModel.assign(index,ss.str());
}
if (content.hasChildNodes())
executeContent(content.getChildNodes());
}
- _dataModel->popContext(); // leave stacked context
+ _dataModel.popContext(); // leave stacked context
} else {
LOG(ERROR) << "Expected array and item attributes with foreach element!" << std::endl;
}
@@ -1102,7 +1090,7 @@ ELSIF_ELEM_MATCH:
if (logElem.hasAttribute("expr")) {
if (_dataModel) {
try {
- std::cout << _dataModel->evalAsString(logElem.getAttribute("expr")) << std::endl;
+ std::cout << _dataModel.evalAsString(logElem.getAttribute("expr")) << std::endl;
} catch (Event e) {
LOG(ERROR) << "Syntax error in expr attribute of log element:" << std::endl << e << std::endl;
}
@@ -1114,7 +1102,7 @@ ELSIF_ELEM_MATCH:
// --- ASSIGN --------------------------
if (_dataModel && HAS_ATTR(content, "location") && HAS_ATTR(content, "expr")) {
try {
- _dataModel->assign(ATTR(content, "location"), ATTR(content, "expr"));
+ _dataModel.assign(ATTR(content, "location"), ATTR(content, "expr"));
} catch (Event e) {
LOG(ERROR) << "Syntax error in attributes of assign element:" << std::endl << e << std::endl;
}
@@ -1124,24 +1112,23 @@ ELSIF_ELEM_MATCH:
if (_dataModel) {
std::string location = (HAS_ATTR(content, "location") ? ATTR(content, "location") : "");
std::string schema = (HAS_ATTR(content, "schema") ? ATTR(content, "schema") : "");
- _dataModel->validate(location, schema);
+ _dataModel.validate(location, schema);
}
} else if (boost::iequals(TAGNAME(content), "script")) {
// --- SCRIPT --------------------------
if (_dataModel) {
if (HAS_ATTR(content, "src")) {
- Arabica::io::URI url(ATTR(content, "src"));
- if (!makeAbsolute(url)) {
+ URL scriptUrl(ATTR(content, "src"));
+ if (!toAbsoluteURI(scriptUrl)) {
LOG(ERROR) << "script element has relative URI " << ATTR(content, "src") << " with no base URI set for interpreter";
return;
}
std::stringstream srcContent;
- URL scriptUrl(url.as_string());
srcContent << scriptUrl;
try {
- _dataModel->eval(srcContent.str());
+ _dataModel.eval(srcContent.str());
} catch (Event e) {
LOG(ERROR) << "Syntax error while executing script element from '" << ATTR(content, "src") << "':" << std::endl << e << std::endl;
}
@@ -1150,7 +1137,7 @@ ELSIF_ELEM_MATCH:
// search for the text node with the actual script
if (content.getFirstChild().getNodeType() == Node_base::TEXT_NODE) {
try {
- _dataModel->eval(content.getFirstChild().getNodeValue());
+ _dataModel.eval(content.getFirstChild().getNodeValue());
} catch (Event e) {
LOG(ERROR) << "Syntax error while executing script element" << std::endl << e << std::endl;
}
@@ -1166,7 +1153,7 @@ ELSIF_ELEM_MATCH:
std::string sendId;
try {
if (HAS_ATTR(content, "sendidexpr")) {
- sendId = _dataModel->evalAsString(ATTR(content, "sendidexpr"));
+ sendId = _dataModel.evalAsString(ATTR(content, "sendidexpr"));
} else if(HAS_ATTR(content, "sendid")) {
sendId = ATTR(content, "sendid");
} else {
@@ -1806,12 +1793,12 @@ bool Interpreter::isCompound(const Arabica::DOM::Node<std::string>& state) {
}
void Interpreter::setupIOProcessors() {
- std::map<std::string, IOProcessor*>::iterator ioProcIter = Factory::getInstance()->_ioProcessors.begin();
+ std::map<std::string, IOProcessorImpl*>::iterator ioProcIter = Factory::getInstance()->_ioProcessors.begin();
while(ioProcIter != Factory::getInstance()->_ioProcessors.end()) {
- _ioProcessors[ioProcIter->first] = Factory::getIOProcessor(ioProcIter->first, this);
+ _ioProcessors[ioProcIter->first] = Factory::createIOProcessor(ioProcIter->first, this);
if (_dataModel) {
try {
- _dataModel->registerIOProcessor(ioProcIter->first, _ioProcessors[ioProcIter->first]);
+ _dataModel.registerIOProcessor(ioProcIter->first, _ioProcessors[ioProcIter->first]);
} catch (Event e) {
LOG(ERROR) << "Syntax error when setting _ioprocessors:" << std::endl << e << std::endl;
}
@@ -1822,10 +1809,10 @@ void Interpreter::setupIOProcessors() {
}
}
-IOProcessor* Interpreter::getIOProcessor(const std::string& type) {
+IOProcessor Interpreter::getIOProcessor(const std::string& type) {
if (_ioProcessors.find(type) == _ioProcessors.end()) {
LOG(ERROR) << "No ioProcessor known for type " << type;
- return NULL;
+ return IOProcessor();
}
return _ioProcessors[type];
}
@@ -1842,7 +1829,7 @@ bool Interpreter::validate() {
bool validationErrors = false;
if (!_document) {
- LOG(ERROR) << "Document " << _baseURI.as_string() << " was not parsed successfully" << std::endl;
+ LOG(ERROR) << "Document " << _baseURI.asString() << " was not parsed successfully" << std::endl;
return false;
}
diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h
index edfdfd2..33204b5 100644
--- a/src/uscxml/Interpreter.h
+++ b/src/uscxml/Interpreter.h
@@ -2,6 +2,7 @@
#define RUNTIME_H_SQ1MBKGN
#include "uscxml/Common.h"
+#include "uscxml/URL.h"
#include <boost/uuid/uuid_generators.hpp>
#include <boost/algorithm/string.hpp>
@@ -76,20 +77,19 @@ public:
bool validate();
void setBaseURI(std::string baseURI) {
- _baseURI = Arabica::io::URI(baseURI);
+ _baseURI = URL(baseURI);
}
- std::string getBaseURI() {
- return _baseURI.as_string();
+ URL getBaseURI() {
+ return _baseURI;
}
- bool makeAbsolute(Arabica::io::URI& uri);
- DataModel* getDataModel() {
+ DataModel getDataModel() {
return _dataModel;
}
- Invoker* getInvoker() {
+ Invoker getInvoker() {
return _invoker;
}
- void setInvoker(Invoker* invoker) {
+ void setInvoker(const Invoker& invoker) {
_invoker = invoker;
}
std::string getNSPrefix() {
@@ -162,7 +162,7 @@ protected:
tthread::mutex _mutex;
tthread::condition_variable _stabilized;
- Arabica::io::URI _baseURI;
+ URL _baseURI;
Arabica::DOM::Document<std::string> _document;
Arabica::DOM::Element<std::string> _scxml;
Arabica::XPath::XPath<std::string> _xpath;
@@ -174,15 +174,16 @@ protected:
Arabica::XPath::NodeSet<std::string> _configuration;
Arabica::XPath::NodeSet<std::string> _statesToInvoke;
- DataModel* _dataModel;
+ DataModel _dataModel;
std::map<std::string, Arabica::XPath::NodeSet<std::string> > _historyValue;
std::list<Event > _internalQueue;
uscxml::concurrency::BlockingQueue<Event> _externalQueue;
DelayedEventQueue* _sendQueue;
- Invoker* _invoker;
+ Invoker _invoker;
- static Arabica::io::URI toBaseURI(const Arabica::io::URI& uri);
+ static URL toBaseURI(const URL& url);
+ bool toAbsoluteURI(URL& uri);
void microstep(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
void exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
@@ -227,12 +228,12 @@ protected:
std::string _name;
std::string _sessionId;
- IOProcessor* getIOProcessor(const std::string& type);
+ IOProcessor getIOProcessor(const std::string& type);
// IOProcessor* getIOProcessorForId(const std::string& sendId);
- std::map<std::string, IOProcessor*> _ioProcessors;
+ std::map<std::string, IOProcessor> _ioProcessors;
std::map<std::string, std::pair<Interpreter*, SendRequest> > _sendIds;
- std::map<std::string, Invoker*> _invokers;
+ std::map<std::string, Invoker> _invokers;
/// We need to remember to adapt them when the DOM is operated upon
std::map<std::string, Arabica::DOM::Node<std::string> > _cachedStates;
diff --git a/src/uscxml/URL.cpp b/src/uscxml/URL.cpp
index 592c0c6..59fca34 100644
--- a/src/uscxml/URL.cpp
+++ b/src/uscxml/URL.cpp
@@ -19,6 +19,14 @@
#include "uscxml/config.h"
+#include <stdio.h> /* defines FILENAME_MAX */
+#ifdef WIN32
+#include <direct.h>
+#define getcwd _getcwd
+#else
+#include <unistd.h>
+#endif
+
#include <cstdlib> // mkstemp
#ifdef HAS_UNISTD_H
#include <unistd.h> // mkstemp legacy
@@ -26,38 +34,30 @@
namespace uscxml {
-URL::~URL() {
+URLImpl::~URLImpl() {
if (_localFile.length() > 0)
remove(_localFile.c_str());
}
-
-const bool URL::toAbsolute(const std::string& baseUrl) {
+
+const bool URLImpl::toAbsoluteCwd() {
+ char currPath[FILENAME_MAX];
+ if (!getcwd(currPath, sizeof(currPath))) {
+ return false;
+ }
+ currPath[sizeof(currPath) - 1] = '\0'; /* not really required */
+ return toAbsolute(std::string("file://" + std::string(currPath) + "/"));
+}
+
+const bool URLImpl::toAbsolute(const std::string& baseUrl) {
if (_uri.is_absolute())
return true;
-
- Arabica::io::URI baseUri(baseUrl);
- if (!baseUri.is_absolute())
+ _uri = Arabica::io::URI(baseUrl, _uri.as_string());
+ if (!_uri.is_absolute())
return false;
-
- std::stringstream ssAbsoluteURI;
- if (baseUri.scheme().size() > 0)
- ssAbsoluteURI << baseUri.scheme() << "://";
- if (baseUri.host().size() > 0) {
- ssAbsoluteURI << baseUri.host();
- if (!boost::iequals(baseUri.port(), "0"))
- ssAbsoluteURI << ":" << baseUri.port();
- }
- if (baseUri.path().size() > 0) {
- ssAbsoluteURI << baseUri.path() << "/" << _uri.path();
- } else {
- ssAbsoluteURI << "/" << _uri.path();
- }
- _uri = Arabica::io::URI(ssAbsoluteURI.str());
- assert(_uri.is_absolute());
return true;
}
-const std::string URL::asLocalFile(const std::string& suffix, bool reload) {
+const std::string URLImpl::asLocalFile(const std::string& suffix, bool reload) {
// this is already a local file
if (_uri.scheme().compare("file") == 0)
return _uri.path();
@@ -69,7 +69,7 @@ const std::string URL::asLocalFile(const std::string& suffix, bool reload) {
remove(_localFile.c_str());
// try hard to find a temporary directory
- char* tmpDir = NULL;
+ const char* tmpDir = NULL;
if (tmpDir == NULL)
tmpDir = getenv("TMPDIR");
if (tmpDir == NULL)
@@ -78,6 +78,8 @@ const std::string URL::asLocalFile(const std::string& suffix, bool reload) {
tmpDir = getenv("TEMP");
if (tmpDir == NULL)
tmpDir = getenv("USERPROFILE");
+ if (tmpDir == NULL)
+ tmpDir = "/tmp";
char* tmpl = (char*)malloc(strlen(tmpDir) + 11 + suffix.length());
char* writePtr = tmpl;
@@ -97,7 +99,7 @@ const std::string URL::asLocalFile(const std::string& suffix, bool reload) {
std::ofstream file(tmpl, std::ios_base::out);
if(file.is_open()) {
- file << *this;
+ file << URL(this->shared_from_this());
file.close();
} else {
_localFile = "";
diff --git a/src/uscxml/URL.h b/src/uscxml/URL.h
index 3a87fb1..07921f3 100644
--- a/src/uscxml/URL.h
+++ b/src/uscxml/URL.h
@@ -8,13 +8,17 @@
// use arabica URL parser
#include <io/uri.hpp>
-namespace uscxml {
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
-class URL {
+namespace uscxml {
+
+class URLImpl : public boost::enable_shared_from_this<URLImpl> {
public:
- URL() {}
- URL(const std::string uri) : _uri(uri) {}
- virtual ~URL();
+ URLImpl() {}
+ URLImpl(const std::string uri) : _uri(uri) {}
+ virtual ~URLImpl();
+ const bool toAbsoluteCwd();
const bool toAbsolute(const std::string& baseUrl);
const std::string asLocalFile(const std::string& suffix, bool reload = false);
@@ -28,9 +32,40 @@ public:
private:
Arabica::io::URI _uri;
std::string _localFile;
- friend std::ostream & operator<<(std::ostream &stream, const URL& p);
};
+class URL {
+public:
+ URL() : _impl() {}
+ URL(const std::string uri) : _impl(new URLImpl(uri)) {}
+ URL(boost::shared_ptr<URLImpl> const impl) : _impl(impl) { }
+ URL(const URL& other) : _impl(other._impl) { }
+ virtual ~URL() {};
+
+ operator bool() const { return _impl;}
+ bool operator< (const URL& other) const { return _impl < other._impl; }
+ bool operator==(const URL& other) const { return _impl == other._impl; }
+ bool operator!=(const URL& other) const { return _impl != other._impl; }
+ URL& operator= (const URL& other) { _impl = other._impl; return *this; }
+
+ const bool toAbsoluteCwd() { return _impl->toAbsoluteCwd(); }
+ const bool toAbsolute(const std::string& baseUrl) { return _impl->toAbsolute(baseUrl); }
+ const bool toAbsolute(const URL& baseUrl) { return _impl->toAbsolute(baseUrl.asString()); }
+ const std::string asLocalFile(const std::string& suffix, bool reload = false) { return _impl->asLocalFile(suffix, reload); }
+
+ const bool isAbsolute() const { return _impl->isAbsolute(); }
+ const std::string scheme() const { return _impl->scheme(); }
+ const std::string host() const { return _impl->host(); }
+ const std::string port() const { return _impl->port(); }
+ const std::string path() const { return _impl->path(); }
+ const std::string asString() const { return _impl->asString(); }
+
+ friend std::ostream & operator<<(std::ostream &stream, const URL& p);
+
+protected:
+ boost::shared_ptr<URLImpl> _impl;
+};
+
enum fcurl_type_e {
CFTYPE_NONE=0,
CFTYPE_FILE=1,
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
index 3bdf28c..5ab9b3e 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
@@ -23,7 +23,7 @@ V8DataModel::V8DataModel() {
// _contexts.push_back(v8::Context::New());
}
-DataModel* V8DataModel::create(Interpreter* interpreter) {
+DataModelImpl* V8DataModel::create(Interpreter* interpreter) {
V8DataModel* dm = new V8DataModel();
dm->_interpreter = interpreter;
v8::Locker locker;
@@ -62,8 +62,8 @@ DataModel* V8DataModel::create(Interpreter* interpreter) {
return dm;
}
-void V8DataModel::registerIOProcessor(const std::string& name, IOProcessor* ioprocessor) {
- assign("_ioprocessors['" + name + "']", ioprocessor->getDataModelVariables());
+void V8DataModel::registerIOProcessor(const std::string& name, const IOProcessor& ioprocessor) {
+ assign("_ioprocessors['" + name + "']", ioprocessor.getDataModelVariables());
}
void V8DataModel::setSessionId(const std::string& sessionId) {
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
index deee58c..e5c1bc8 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
@@ -17,11 +17,11 @@ class V8SCXMLDOM;
namespace uscxml {
-class V8DataModel : public DataModel {
+class V8DataModel : public DataModelImpl {
public:
V8DataModel();
virtual ~V8DataModel();
- virtual DataModel* create(Interpreter* interpreter);
+ virtual DataModelImpl* create(Interpreter* interpreter);
virtual std::set<std::string> getNames() {
std::set<std::string> names;
@@ -34,7 +34,7 @@ public:
virtual void setName(const std::string& name);
virtual void setEvent(const Event& event);
- virtual void registerIOProcessor(const std::string& name, IOProcessor* ioprocessor);
+ virtual void registerIOProcessor(const std::string& name, const IOProcessor& ioprocessor);
virtual bool validate(const std::string& location, const std::string& schema);
diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
index 77f0b66..3e20867 100644
--- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
@@ -20,7 +20,7 @@ bool connect(pluma::Host& host) {
SWIDataModel::SWIDataModel() {
}
-DataModel* SWIDataModel::create(Interpreter* interpreter) {
+DataModelImpl* SWIDataModel::create(Interpreter* interpreter) {
SWIDataModel* dm = new SWIDataModel();
dm->_interpreter = interpreter;
const char* swiPath = SWI_LIBRARY_PATH;
@@ -28,7 +28,7 @@ DataModel* SWIDataModel::create(Interpreter* interpreter) {
return dm;
}
-void SWIDataModel::registerIOProcessor(const std::string& name, IOProcessor* ioprocessor) {
+void SWIDataModel::registerIOProcessor(const std::string& name, const IOProcessor& ioprocessor) {
std::cout << "SWIDataModel::registerIOProcessor" << std::endl;
}
diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
index 16dee3c..f5f5247 100644
--- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
+++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
@@ -11,11 +11,11 @@
namespace uscxml {
-class SWIDataModel : public DataModel {
+class SWIDataModel : public DataModelImpl {
public:
SWIDataModel();
virtual ~SWIDataModel();
- virtual DataModel* create(Interpreter* interpreter);
+ virtual DataModelImpl* create(Interpreter* interpreter);
virtual std::set<std::string> getNames() {
std::set<std::string> names;
@@ -28,7 +28,7 @@ public:
virtual void setName(const std::string& name);
virtual void setEvent(const Event& event);
- virtual void registerIOProcessor(const std::string& name, IOProcessor* ioprocessor);
+ virtual void registerIOProcessor(const std::string& name, const IOProcessor& ioprocessor);
virtual bool validate(const std::string& location, const std::string& schema);
diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp
index 7a0e63a..94156c0 100644
--- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp
+++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp
@@ -22,7 +22,7 @@ OSGInvoker::OSGInvoker() {
OSGInvoker::~OSGInvoker() {
};
-Invoker* OSGInvoker::create(Interpreter* interpreter) {
+InvokerImpl* OSGInvoker::create(Interpreter* interpreter) {
OSGInvoker* invoker = new OSGInvoker();
invoker->_interpreter = interpreter;
return invoker;
@@ -33,16 +33,16 @@ Data OSGInvoker::getDataModelVariables() {
return data;
}
-void OSGInvoker::send(SendRequest& req) {
+void OSGInvoker::send(const SendRequest& req) {
}
void OSGInvoker::cancel(const std::string sendId) {
}
-void OSGInvoker::sendToParent(SendRequest& req) {
+void OSGInvoker::sendToParent(const SendRequest& req) {
}
-void OSGInvoker::invoke(InvokeRequest& req) {
+void OSGInvoker::invoke(const InvokeRequest& req) {
tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
// register default event handlers
diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h
index 90dda31..933ee4a 100644
--- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h
+++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h
@@ -16,11 +16,11 @@
namespace uscxml {
-class OSGInvoker : public Invoker, public Arabica::DOM::Events::EventListener<std::string> {
+class OSGInvoker : public InvokerImpl, public Arabica::DOM::Events::EventListener<std::string> {
public:
OSGInvoker();
virtual ~OSGInvoker();
- virtual Invoker* create(Interpreter* interpreter);
+ virtual InvokerImpl* create(Interpreter* interpreter);
virtual std::set<std::string> getNames() {
std::set<std::string> names;
@@ -31,10 +31,10 @@ public:
}
virtual Data getDataModelVariables();
- virtual void send(SendRequest& req);
+ virtual void send(const SendRequest& req);
virtual void cancel(const std::string sendId);
- virtual void invoke(InvokeRequest& req);
- virtual void sendToParent(SendRequest& req);
+ virtual void invoke(const InvokeRequest& req);
+ virtual void sendToParent(const SendRequest& req);
virtual void handleEvent(Arabica::DOM::Events::Event<std::string>& event);
virtual void runOnMainThread();
diff --git a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp
index 6bc06d9..eaf5eba 100644
--- a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp
+++ b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp
@@ -21,7 +21,7 @@ HeartbeatInvoker::HeartbeatInvoker() {
HeartbeatInvoker::~HeartbeatInvoker() {
};
-Invoker* HeartbeatInvoker::create(Interpreter* interpreter) {
+InvokerImpl* HeartbeatInvoker::create(Interpreter* interpreter) {
HeartbeatInvoker* invoker = new HeartbeatInvoker();
invoker->_interpreter = interpreter;
return invoker;
@@ -32,23 +32,23 @@ Data HeartbeatInvoker::getDataModelVariables() {
return data;
}
-void HeartbeatInvoker::send(SendRequest& req) {
+void HeartbeatInvoker::send(const SendRequest& req) {
}
void HeartbeatInvoker::cancel(const std::string sendId) {
HeartbeatDispatcher::getInstance()->cancelEvent(toStr(this));
}
-void HeartbeatInvoker::sendToParent(SendRequest& req) {
+void HeartbeatInvoker::sendToParent(const SendRequest& req) {
}
-void HeartbeatInvoker::invoke(InvokeRequest& req) {
+void HeartbeatInvoker::invoke(const InvokeRequest& req) {
_invokeId = req.invokeid;
_event.invokeid = _invokeId;
std::string intervalStr;
double interval = 0;
unsigned long intervalMs = 0;
- InvokeRequest::params_t::iterator paramIter = req.params.begin();
+ InvokeRequest::params_t::const_iterator paramIter = req.params.begin();
while(paramIter != req.params.end()) {
if (boost::iequals(paramIter->first, "interval")) {
intervalStr = paramIter->second;
diff --git a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.h b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.h
index 9a6cb47..8a90011 100644
--- a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.h
+++ b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.h
@@ -9,11 +9,11 @@
namespace uscxml {
-class HeartbeatInvoker : public Invoker {
+class HeartbeatInvoker : public InvokerImpl {
public:
HeartbeatInvoker();
virtual ~HeartbeatInvoker();
- virtual Invoker* create(Interpreter* interpreter);
+ virtual InvokerImpl* create(Interpreter* interpreter);
virtual std::set<std::string> getNames() {
std::set<std::string> names;
@@ -23,10 +23,10 @@ public:
}
virtual Data getDataModelVariables();
- virtual void send(SendRequest& req);
+ virtual void send(const SendRequest& req);
virtual void cancel(const std::string sendId);
- virtual void invoke(InvokeRequest& req);
- virtual void sendToParent(SendRequest& req);
+ virtual void invoke(const InvokeRequest& req);
+ virtual void sendToParent(const SendRequest& req);
static void dispatch(void* instance, std::string name);
diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp
index b4ee3eb..c90ef4d 100644
--- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp
+++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp
@@ -23,7 +23,7 @@ USCXMLInvoker::~USCXMLInvoker() {
delete _invokedInterpreter;
};
-Invoker* USCXMLInvoker::create(Interpreter* interpreter) {
+InvokerImpl* USCXMLInvoker::create(Interpreter* interpreter) {
USCXMLInvoker* invoker = new USCXMLInvoker();
invoker->_parentInterpreter = interpreter;
return invoker;
@@ -34,7 +34,7 @@ Data USCXMLInvoker::getDataModelVariables() {
return data;
}
-void USCXMLInvoker::send(SendRequest& req) {
+void USCXMLInvoker::send(const SendRequest& req) {
assert(false);
}
@@ -42,19 +42,20 @@ void USCXMLInvoker::cancel(const std::string sendId) {
assert(false);
}
-void USCXMLInvoker::sendToParent(SendRequest& req) {
- req.invokeid = _invokeId;
- _parentInterpreter->receive(req);
+void USCXMLInvoker::sendToParent(const SendRequest& req) {
+ SendRequest parentReq = req;
+ parentReq.invokeid = _invokeId;
+ _parentInterpreter->receive(parentReq);
}
-void USCXMLInvoker::invoke(InvokeRequest& req) {
+void USCXMLInvoker::invoke(const InvokeRequest& req) {
_invokeId = req.invokeid;
_invokedInterpreter = Interpreter::fromURI(req.src);
- DataModel* dataModel = _invokedInterpreter->getDataModel();
- if (dataModel != NULL) {
+ DataModel dataModel(_invokedInterpreter->getDataModel());
+ if (dataModel) {
}
- _invokedInterpreter->setInvoker(this);
+ _invokedInterpreter->setInvoker(boost::static_pointer_cast<InvokerImpl>(shared_from_this()));
_invokedInterpreter->start();
}
diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h
index 907df41..b1579a2 100644
--- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h
+++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h
@@ -2,6 +2,7 @@
#define USCXMLINVOKER_H_OQFA21IO
#include <uscxml/Interpreter.h>
+#include <boost//enable_shared_from_this.hpp>
#ifdef BUILD_AS_PLUGINS
#include "uscxml/plugins/Plugins.h"
@@ -11,11 +12,11 @@ namespace uscxml {
class Interpreter;
-class USCXMLInvoker : public Invoker {
+class USCXMLInvoker : public InvokerImpl, public boost::enable_shared_from_this<USCXMLInvoker> {
public:
USCXMLInvoker();
virtual ~USCXMLInvoker();
- virtual Invoker* create(Interpreter* interpreter);
+ virtual InvokerImpl* create(Interpreter* interpreter);
virtual std::set<std::string> getNames() {
std::set<std::string> names;
names.insert("uscxml");
@@ -25,10 +26,10 @@ public:
}
virtual Data getDataModelVariables();
- virtual void send(SendRequest& req);
+ virtual void send(const SendRequest& req);
virtual void cancel(const std::string sendId);
- virtual void invoke(InvokeRequest& req);
- virtual void sendToParent(SendRequest& req);
+ virtual void invoke(const InvokeRequest& req);
+ virtual void sendToParent(const SendRequest& req);
protected:
std::string _invokeId;
diff --git a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp
index 9957bfa..3ddc14a 100644
--- a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp
+++ b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp
@@ -28,7 +28,7 @@ UmundoInvoker::~UmundoInvoker() {
}
};
-Invoker* UmundoInvoker::create(Interpreter* interpreter) {
+InvokerImpl* UmundoInvoker::create(Interpreter* interpreter) {
UmundoInvoker* invoker = new UmundoInvoker();
invoker->_interpreter = interpreter;
return invoker;
@@ -39,7 +39,7 @@ Data UmundoInvoker::getDataModelVariables() {
return data;
}
-void UmundoInvoker::send(SendRequest& req) {
+void UmundoInvoker::send(const SendRequest& req) {
umundo::Message* msg = new umundo::Message();
if (req.name.length() > 0) {
@@ -50,9 +50,9 @@ void UmundoInvoker::send(SendRequest& req) {
if (req.params.find("type") != req.params.end()) {
// assume JSON in content to transform to protobuf object
- if (req.content.length() > 0 && _interpreter->getDataModel() != NULL) {
+ if (req.content.length() > 0 && _interpreter->getDataModel()) {
std::string type;
- std::multimap<std::string, std::string>::iterator typeIter = req.params.find("type");
+ std::multimap<std::string, std::string>::const_iterator typeIter = req.params.find("type");
if (typeIter != req.params.end())
type = typeIter->second;
const google::protobuf::Message* protoMsg = umundo::PBSerializer::getProto(type);
@@ -61,7 +61,7 @@ void UmundoInvoker::send(SendRequest& req) {
return;
}
try {
- Data data = _interpreter->getDataModel()->getStringAsData(req.content);
+ Data data = _interpreter->getDataModel().getStringAsData(req.content);
google::protobuf::Message* pbMsg = protoMsg->New();
if (!dataToProtobuf(pbMsg, data)) {
LOG(ERROR) << "Cannot create message from JSON - not sending";
@@ -105,11 +105,11 @@ void UmundoInvoker::cancel(const std::string sendId) {
assert(false);
}
-void UmundoInvoker::sendToParent(SendRequest& req) {
+void UmundoInvoker::sendToParent(const SendRequest& req) {
assert(false);
}
-void UmundoInvoker::invoke(InvokeRequest& req) {
+void UmundoInvoker::invoke(const InvokeRequest& req) {
_invokeId = req.invokeid;
std::string domain;
@@ -133,8 +133,8 @@ void UmundoInvoker::invoke(InvokeRequest& req) {
// add type from .proto or .desc files
if (req.params.find("type") != req.params.end()) {
- std::pair<InvokeRequest::params_t::iterator, InvokeRequest::params_t::iterator> typeRange = req.params.equal_range("types");
- for (InvokeRequest::params_t::iterator it = typeRange.first; it != typeRange.second; it++) {
+ std::pair<InvokeRequest::params_t::const_iterator, InvokeRequest::params_t::const_iterator> typeRange = req.params.equal_range("types");
+ for (InvokeRequest::params_t::const_iterator it = typeRange.first; it != typeRange.second; it++) {
URL typeURI(it->second);
if (typeURI.toAbsolute(_interpreter->getBaseURI())) {
std::string filename = typeURI.asLocalFile(".proto");
@@ -147,8 +147,8 @@ void UmundoInvoker::invoke(InvokeRequest& req) {
// add directory with .proto or .desc files
if (req.params.find("types") != req.params.end()) {
- std::pair<InvokeRequest::params_t::iterator, InvokeRequest::params_t::iterator> typeRange = req.params.equal_range("types");
- for (InvokeRequest::params_t::iterator it = typeRange.first; it != typeRange.second; it++) {
+ std::pair<InvokeRequest::params_t::const_iterator, InvokeRequest::params_t::const_iterator> typeRange = req.params.equal_range("types");
+ for (InvokeRequest::params_t::const_iterator it = typeRange.first; it != typeRange.second; it++) {
URL typeURI(it->second);
if (typeURI.toAbsolute(_interpreter->getBaseURI()) && typeURI.scheme().compare("file") == 0) {
umundo::PBSerializer::addProto(typeURI.path());
diff --git a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h
index 09d07bf..1aa37f2 100644
--- a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h
+++ b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h
@@ -16,11 +16,11 @@ namespace uscxml {
class Interpreter;
-class UmundoInvoker : public Invoker, public umundo::TypedReceiver, public umundo::ResultSet<umundo::ServiceDescription> {
+class UmundoInvoker : public InvokerImpl, public umundo::TypedReceiver, public umundo::ResultSet<umundo::ServiceDescription> {
public:
UmundoInvoker();
virtual ~UmundoInvoker();
- virtual Invoker* create(Interpreter* interpreter);
+ virtual InvokerImpl* create(Interpreter* interpreter);
virtual std::set<std::string> getNames() {
std::set<std::string> names;
@@ -31,10 +31,10 @@ public:
}
virtual Data getDataModelVariables();
- virtual void send(SendRequest& req);
+ virtual void send(const SendRequest& req);
virtual void cancel(const std::string sendId);
- virtual void invoke(InvokeRequest& req);
- virtual void sendToParent(SendRequest& req);
+ virtual void invoke(const InvokeRequest& req);
+ virtual void sendToParent(const SendRequest& req);
virtual void receive(void* object, umundo::Message* msg);
diff --git a/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp
index a50dcaf..1607e3e 100644
--- a/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp
+++ b/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp
@@ -46,7 +46,7 @@ EventIOProcessor::~EventIOProcessor() {
httpServer->unregisterProcessor(this);
}
-IOProcessor* EventIOProcessor::create(Interpreter* interpreter) {
+IOProcessorImpl* EventIOProcessor::create(Interpreter* interpreter) {
EventIOProcessor* io = new EventIOProcessor();
io->_interpreter = interpreter;
@@ -74,7 +74,7 @@ Data EventIOProcessor::getDataModelVariables() {
}
-void EventIOProcessor::send(SendRequest& req) {
+void EventIOProcessor::send(const SendRequest& req) {
// I cant figure out how to copy the reference into the struct :(
_sendData[req.sendid].req = req;
_sendData[req.sendid].ioProcessor = this;
@@ -122,7 +122,7 @@ void EventIOProcessor::send(SendRequest& req) {
// event namelist
if (req.namelist.size() > 0) {
- std::map<std::string, std::string>::iterator namelistIter = req.namelist.begin();
+ std::map<std::string, std::string>::const_iterator namelistIter = req.namelist.begin();
while (namelistIter != req.namelist.end()) {
evhttp_add_header(evhttp_request_get_output_headers(httpReq),
namelistIter->first.c_str(),
@@ -133,7 +133,7 @@ void EventIOProcessor::send(SendRequest& req) {
// event params
if (req.params.size() > 0) {
- std::multimap<std::string, std::string>::iterator paramIter = req.params.begin();
+ std::multimap<std::string, std::string>::const_iterator paramIter = req.params.begin();
while (paramIter != req.params.end()) {
// LOG(INFO) << paramIter->first << " = " << paramIter->second << std::endl;
evhttp_add_header(evhttp_request_get_output_headers(httpReq),
diff --git a/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h b/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h
index f0228e9..d3557f4 100644
--- a/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h
+++ b/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h
@@ -19,7 +19,7 @@ namespace uscxml {
class EventIOServer;
-class EventIOProcessor : public uscxml::IOProcessor {
+class EventIOProcessor : public IOProcessorImpl {
public:
struct SendData {
EventIOProcessor* ioProcessor;
@@ -28,7 +28,7 @@ public:
EventIOProcessor();
virtual ~EventIOProcessor();
- virtual IOProcessor* create(uscxml::Interpreter* interpreter);
+ virtual IOProcessorImpl* create(uscxml::Interpreter* interpreter);
virtual std::set<std::string> getNames() {
std::set<std::string> names;
@@ -37,7 +37,7 @@ public:
return names;
}
- virtual void send(uscxml::SendRequest& req);
+ virtual void send(const SendRequest& req);
Data getDataModelVariables();
void setURL(const std::string& url) {
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 39a4667..353faa2 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -53,3 +53,8 @@ add_executable(test-arabica-events src/test-arabica-events.cpp)
target_link_libraries(test-arabica-events uscxml)
add_test(test-arabica-events ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-arabica-events ${CMAKE_SOURCE_DIR}/test/samples/arabica/test-arabica-events.xml)
set_target_properties(test-arabica-events PROPERTIES FOLDER "Tests")
+
+add_executable(test-url src/test-url.cpp)
+target_link_libraries(test-url uscxml)
+add_test(test-url ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-url)
+set_target_properties(test-url PROPERTIES FOLDER "Tests")
diff --git a/test/src/test-url.cpp b/test/src/test-url.cpp
new file mode 100644
index 0000000..e7fbae4
--- /dev/null
+++ b/test/src/test-url.cpp
@@ -0,0 +1,42 @@
+#include "uscxml/URL.h"
+#include <assert.h>
+#include <boost/algorithm/string.hpp>
+
+using namespace uscxml;
+using namespace boost;
+
+int main(int argc, char** argv) {
+ {
+ URL url("http://www.heise.de/index.html");
+ std::cout << url.asString() << std::endl;
+ assert(url.isAbsolute());
+ assert(iequals(url.scheme(), "http"));
+ assert(iequals(url.host(), "www.heise.de"));
+ assert(iequals(url.port(), "80"));
+ assert(iequals(url.path(), "/index.html"));
+ assert(iequals(url.asString(), "http://www.heise.de/index.html"));
+ }
+ {
+ URL url("file:Document/Text.foo");
+ std::cout << url.asString() << std::endl;
+ assert(!url.isAbsolute());
+ assert(iequals(url.scheme(), "file"));
+ assert(iequals(url.host(), ""));
+ assert(iequals(url.port(), "0"));
+ assert(iequals(url.path(), "Document/Text.foo"));
+ assert(iequals(url.asString(), "file:Document/Text.foo"));
+ }
+ {
+ URL url("test/index.html");
+ assert(iequals(url.scheme(), ""));
+ url.toAbsoluteCwd();
+ assert(iequals(url.scheme(), "file"));
+ std::cout << url.asString() << std::endl;
+ }
+ {
+ URL url("C:\\Document\\Some Spaces\\index.txt");
+ assert(url.isAbsolute());
+ assert(iequals(url.scheme(), "file"));
+ std::cout << url.asString() << std::endl;
+ }
+} \ No newline at end of file