diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2012-12-20 21:34:09 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2012-12-20 21:34:09 (GMT) |
commit | 498f6f80e9ca01236ca1491596875ab7eb4cd8c3 (patch) | |
tree | e627ae19475bb93a98dfa50db1950f6e3403f569 /src/uscxml/plugins | |
parent | d779abe6ff76a78f92d229fcf1f006f5cf1f9295 (diff) | |
download | uscxml-498f6f80e9ca01236ca1491596875ab7eb4cd8c3.zip uscxml-498f6f80e9ca01236ca1491596875ab7eb4cd8c3.tar.gz uscxml-498f6f80e9ca01236ca1491596875ab7eb4cd8c3.tar.bz2 |
Refactoring finished
Support datamodels, invokers and ioprocessors as plugins
Comply to HTTP1.1 by sending host header field
Started prolog datamodel
Diffstat (limited to 'src/uscxml/plugins')
25 files changed, 2503 insertions, 2308 deletions
diff --git a/src/uscxml/plugins/Plugins.cpp b/src/uscxml/plugins/Plugins.cpp index 4e819bb..04b5b99 100644 --- a/src/uscxml/plugins/Plugins.cpp +++ b/src/uscxml/plugins/Plugins.cpp @@ -7,5 +7,5 @@ PLUMA_PROVIDER_SOURCE(DataModel, 1, 1); PLUMA_PROVIDER_SOURCE(IOProcessor, 1, 1); PLUMA_PROVIDER_SOURCE(Invoker, 1, 1); #endif - + }
\ No newline at end of file diff --git a/src/uscxml/plugins/Pluma/DLibrary.cpp b/src/uscxml/plugins/Pluma/DLibrary.cpp index 9b617db..0cbf309 100755..100644 --- a/src/uscxml/plugins/Pluma/DLibrary.cpp +++ b/src/uscxml/plugins/Pluma/DLibrary.cpp @@ -31,75 +31,74 @@ #include <string>
-namespace pluma{
+namespace pluma {
////////////////////////////////////////////////////////////
-DLibrary* DLibrary::load(const std::string& path){
- if ( path.empty() ){
- fprintf(stderr, "Failed to load library: Empty path\n");
- return NULL;
- }
- void* handle = NULL;
+DLibrary* DLibrary::load(const std::string& path) {
+ if ( path.empty() ) {
+ fprintf(stderr, "Failed to load library: Empty path\n");
+ return NULL;
+ }
+ void* handle = NULL;
- // load library - OS dependent operation
- #ifdef PLUMA_SYS_WINDOWS
- handle = ::LoadLibraryA(path.c_str());
- if (!handle){
- fprintf(stderr, "Failed to load library \"%s\".\n", path.c_str());
- return NULL;
- }
- #else
- handle = ::dlopen(path.c_str(), RTLD_NOW);
- if (!handle){
- const char* errorString = ::dlerror();
- fprintf(stderr, "Failed to load library \"%s\".", path.c_str());
- if(errorString) fprintf(stderr, " OS returned error: \"%s\".", errorString);
- fprintf(stderr, "\n");
- return NULL;
- }
- #endif
- // return a DLibrary with the DLL handle
- return new DLibrary(handle);
+ // load library - OS dependent operation
+#ifdef PLUMA_SYS_WINDOWS
+ handle = ::LoadLibraryA(path.c_str());
+ if (!handle) {
+ fprintf(stderr, "Failed to load library \"%s\".\n", path.c_str());
+ return NULL;
+ }
+#else
+ handle = ::dlopen(path.c_str(), RTLD_NOW);
+ if (!handle) {
+ const char* errorString = ::dlerror();
+ fprintf(stderr, "Failed to load library \"%s\".", path.c_str());
+ if(errorString) fprintf(stderr, " OS returned error: \"%s\".", errorString);
+ fprintf(stderr, "\n");
+ return NULL;
+ }
+#endif
+ // return a DLibrary with the DLL handle
+ return new DLibrary(handle);
}
////////////////////////////////////////////////////////////
-DLibrary::~DLibrary(){
- if (handle){
- #ifdef PLUMA_SYS_WINDOWS
- ::FreeLibrary( (HMODULE)handle );
- #else
- ::dlclose(handle);
- #endif
- }
+DLibrary::~DLibrary() {
+ if (handle) {
+#ifdef PLUMA_SYS_WINDOWS
+ ::FreeLibrary( (HMODULE)handle );
+#else
+ ::dlclose(handle);
+#endif
+ }
}
////////////////////////////////////////////////////////////
-void* DLibrary::getSymbol(const std::string& symbol){
- if (!handle){
- fprintf(stderr, "Cannot inspect library symbols, library isn't loaded.\n");
- return NULL;
- }
- void* res;
- #ifdef PLUMA_SYS_WINDOWS
- res = (void*)(::GetProcAddress((HMODULE)handle, symbol.c_str()));
- #else
- res = (void*)(::dlsym(handle, symbol.c_str()));
- #endif
- if (!res){
- fprintf(stderr, "Library symbol \"%s\" not found.\n", symbol.c_str());
- return NULL;
- }
- return res;
+void* DLibrary::getSymbol(const std::string& symbol) {
+ if (!handle) {
+ fprintf(stderr, "Cannot inspect library symbols, library isn't loaded.\n");
+ return NULL;
+ }
+ void* res;
+#ifdef PLUMA_SYS_WINDOWS
+ res = (void*)(::GetProcAddress((HMODULE)handle, symbol.c_str()));
+#else
+ res = (void*)(::dlsym(handle, symbol.c_str()));
+#endif
+ if (!res) {
+ fprintf(stderr, "Library symbol \"%s\" not found.\n", symbol.c_str());
+ return NULL;
+ }
+ return res;
}
////////////////////////////////////////////////////////////
DLibrary::DLibrary(void* handle):
- handle(handle)
-{
- // Nothing to do
+ handle(handle) {
+ // Nothing to do
}
} // namespace pluma
diff --git a/src/uscxml/plugins/Pluma/Dir.cpp b/src/uscxml/plugins/Pluma/Dir.cpp index 860220e..73271ea 100755..100644 --- a/src/uscxml/plugins/Pluma/Dir.cpp +++ b/src/uscxml/plugins/Pluma/Dir.cpp @@ -32,68 +32,68 @@ #include <queue>
-namespace pluma{
+namespace pluma {
-namespace dir{
+namespace dir {
////////////////////////////////////////////////////////////
-void listFiles(std::list<std::string>& list, const std::string& folder, const std::string& extension, bool recursive){
- DIR* dir;
- DIR* subDir;
- struct dirent *ent;
- // try to open top folder
- dir = opendir(folder.c_str());
- if (dir == NULL){
- // could not open directory
- fprintf(stderr, "Could not open \"%s\" directory.\n", folder.c_str());
- return;
- }else{
- // close, we'll process it next
- closedir(dir);
- }
- // enqueue top folder
- std::queue<std::string> folders;
- folders.push(folder);
+void listFiles(std::list<std::string>& list, const std::string& folder, const std::string& extension, bool recursive) {
+ DIR* dir;
+ DIR* subDir;
+ struct dirent *ent;
+ // try to open top folder
+ dir = opendir(folder.c_str());
+ if (dir == NULL) {
+ // could not open directory
+ fprintf(stderr, "Could not open \"%s\" directory.\n", folder.c_str());
+ return;
+ } else {
+ // close, we'll process it next
+ closedir(dir);
+ }
+ // enqueue top folder
+ std::queue<std::string> folders;
+ folders.push(folder);
- // run while has queued folders
- while (!folders.empty()){
- std::string currFolder = folders.front();
- folders.pop();
- dir = opendir(currFolder.c_str());
- if (dir == NULL) continue;
- // iterate through all the files and directories
- while ((ent = readdir (dir)) != NULL) {
- std::string name(ent->d_name);
- // ignore "." and ".." directories
- if ( name.compare(".") == 0 || name.compare("..") == 0) continue;
- // add path to the file name
- std::string path = currFolder;
- path.append("/");
- path.append(name);
- // check if it's a folder by trying to open it
- subDir = opendir(path.c_str());
- if (subDir != NULL){
- // it's a folder: close, we can process it later
- closedir(subDir);
- if (recursive) folders.push(path);
- }else{
- // it's a file
- if (extension.empty()){
- list.push_back(path);
- }else{
- // check file extension
- size_t lastDot = name.find_last_of('.');
- std::string ext = name.substr(lastDot+1);
- if (ext.compare(extension) == 0){
- // match
- list.push_back(path);
- }
- } // endif (extension test)
- } // endif (folder test)
- } // endwhile (nextFile)
- closedir(dir);
- } // endwhile (queued folders)
+ // run while has queued folders
+ while (!folders.empty()) {
+ std::string currFolder = folders.front();
+ folders.pop();
+ dir = opendir(currFolder.c_str());
+ if (dir == NULL) continue;
+ // iterate through all the files and directories
+ while ((ent = readdir (dir)) != NULL) {
+ std::string name(ent->d_name);
+ // ignore "." and ".." directories
+ if ( name.compare(".") == 0 || name.compare("..") == 0) continue;
+ // add path to the file name
+ std::string path = currFolder;
+ path.append("/");
+ path.append(name);
+ // check if it's a folder by trying to open it
+ subDir = opendir(path.c_str());
+ if (subDir != NULL) {
+ // it's a folder: close, we can process it later
+ closedir(subDir);
+ if (recursive) folders.push(path);
+ } else {
+ // it's a file
+ if (extension.empty()) {
+ list.push_back(path);
+ } else {
+ // check file extension
+ size_t lastDot = name.find_last_of('.');
+ std::string ext = name.substr(lastDot+1);
+ if (ext.compare(extension) == 0) {
+ // match
+ list.push_back(path);
+ }
+ } // endif (extension test)
+ } // endif (folder test)
+ } // endwhile (nextFile)
+ closedir(dir);
+ } // endwhile (queued folders)
} // end listFiles
diff --git a/src/uscxml/plugins/Pluma/Host.cpp b/src/uscxml/plugins/Pluma/Host.cpp index eb37c33..73979a6 100755..100644 --- a/src/uscxml/plugins/Pluma/Host.cpp +++ b/src/uscxml/plugins/Pluma/Host.cpp @@ -30,149 +30,149 @@ #include <cstdio>
-namespace pluma{
+namespace pluma {
////////////////////////////////////////////////////////////
-Host::Host(){
- // Nothing to do
+Host::Host() {
+ // Nothing to do
}
////////////////////////////////////////////////////////////
-bool Host::add(Provider* provider){
- if (provider == NULL){
- fprintf(stderr, "Trying to add a null provider.\n");
- return false;
- }
- if (!validateProvider(provider)){
- delete provider;
- return false;
- }
- addRequests[ provider->plumaGetType() ].push_back(provider);
- return true;
+bool Host::add(Provider* provider) {
+ if (provider == NULL) {
+ fprintf(stderr, "Trying to add a null provider.\n");
+ return false;
+ }
+ if (!validateProvider(provider)) {
+ delete provider;
+ return false;
+ }
+ addRequests[ provider->plumaGetType() ].push_back(provider);
+ return true;
}
////////////////////////////////////////////////////////////
-Host::~Host(){
- clearProviders();
- // map frees itself
+Host::~Host() {
+ clearProviders();
+ // map frees itself
}
////////////////////////////////////////////////////////////
-void Host::clearProviders(){
- ProvidersMap::iterator it;
- for (it = knownTypes.begin() ; it != knownTypes.end() ; ++it){
- std::list<Provider*>& providers = it->second.providers;
- std::list<Provider*>::iterator provIt;
- for (provIt = providers.begin() ; provIt != providers.end() ; ++provIt){
- delete *provIt;
- }
- std::list<Provider*>().swap(providers);
- }
+void Host::clearProviders() {
+ ProvidersMap::iterator it;
+ for (it = knownTypes.begin() ; it != knownTypes.end() ; ++it) {
+ std::list<Provider*>& providers = it->second.providers;
+ std::list<Provider*>::iterator provIt;
+ for (provIt = providers.begin() ; provIt != providers.end() ; ++provIt) {
+ delete *provIt;
+ }
+ std::list<Provider*>().swap(providers);
+ }
}
////////////////////////////////////////////////////////////
-bool Host::knows(const std::string& type) const{
- return knownTypes.find(type) != knownTypes.end();
+bool Host::knows(const std::string& type) const {
+ return knownTypes.find(type) != knownTypes.end();
}
////////////////////////////////////////////////////////////
-unsigned int Host::getVersion(const std::string& type) const{
- ProvidersMap::const_iterator it = knownTypes.find(type);
- if (it != knownTypes.end())
- return it->second.version;
- return 0;
+unsigned int Host::getVersion(const std::string& type) const {
+ ProvidersMap::const_iterator it = knownTypes.find(type);
+ if (it != knownTypes.end())
+ return it->second.version;
+ return 0;
}
////////////////////////////////////////////////////////////
-unsigned int Host::getLowestVersion(const std::string& type) const{
- ProvidersMap::const_iterator it = knownTypes.find(type);
- if (it != knownTypes.end())
- return it->second.lowestVersion;
- return 0;
+unsigned int Host::getLowestVersion(const std::string& type) const {
+ ProvidersMap::const_iterator it = knownTypes.find(type);
+ if (it != knownTypes.end())
+ return it->second.lowestVersion;
+ return 0;
}
////////////////////////////////////////////////////////////
-void Host::registerType(const std::string& type, unsigned int version, unsigned int lowestVersion){
- if (!knows(type)){
- ProviderInfo pi;
- pi.version = version;
- pi.lowestVersion = lowestVersion;
- knownTypes[type] = pi;
- }
+void Host::registerType(const std::string& type, unsigned int version, unsigned int lowestVersion) {
+ if (!knows(type)) {
+ ProviderInfo pi;
+ pi.version = version;
+ pi.lowestVersion = lowestVersion;
+ knownTypes[type] = pi;
+ }
}
////////////////////////////////////////////////////////////
-const std::list<Provider*>* Host::getProviders(const std::string& type) const{
- ProvidersMap::const_iterator it = knownTypes.find(type);
- if (it != knownTypes.end())
- return &it->second.providers;
- return NULL;
+const std::list<Provider*>* Host::getProviders(const std::string& type) const {
+ ProvidersMap::const_iterator it = knownTypes.find(type);
+ if (it != knownTypes.end())
+ return &it->second.providers;
+ return NULL;
}
////////////////////////////////////////////////////////////
-bool Host::validateProvider(Provider* provider) const{
- const std::string& type = provider->plumaGetType();
- if ( !knows(type) ){
- fprintf(stderr, "%s provider type isn't registered.\n", type.c_str());
- return false;
- }
- if (!provider->isCompatible(*this)){
- fprintf(stderr, "Incompatible %s provider version.\n", type.c_str());
- return false;
- }
- return true;
+bool Host::validateProvider(Provider* provider) const {
+ const std::string& type = provider->plumaGetType();
+ if ( !knows(type) ) {
+ fprintf(stderr, "%s provider type isn't registered.\n", type.c_str());
+ return false;
+ }
+ if (!provider->isCompatible(*this)) {
+ fprintf(stderr, "Incompatible %s provider version.\n", type.c_str());
+ return false;
+ }
+ return true;
}
////////////////////////////////////////////////////////////
-bool Host::registerProvider(Provider* provider){
- if (!validateProvider(provider)){
- delete provider;
- return false;
- }
- knownTypes[ provider->plumaGetType() ].providers.push_back(provider);
- return true;
+bool Host::registerProvider(Provider* provider) {
+ if (!validateProvider(provider)) {
+ delete provider;
+ return false;
+ }
+ knownTypes[ provider->plumaGetType() ].providers.push_back(provider);
+ return true;
}
////////////////////////////////////////////////////////////
-void Host::cancelAddictions(){
- TempProvidersMap::iterator it;
- for( it = addRequests.begin() ; it != addRequests.end() ; ++it){
- std::list<Provider*> lst = it->second;
- std::list<Provider*>::iterator providerIt;
- for (providerIt = lst.begin() ; providerIt != lst.end() ; ++providerIt){
- delete *providerIt;
- }
- }
- // clear map
- TempProvidersMap().swap(addRequests);
+void Host::cancelAddictions() {
+ TempProvidersMap::iterator it;
+ for( it = addRequests.begin() ; it != addRequests.end() ; ++it) {
+ std::list<Provider*> lst = it->second;
+ std::list<Provider*>::iterator providerIt;
+ for (providerIt = lst.begin() ; providerIt != lst.end() ; ++providerIt) {
+ delete *providerIt;
+ }
+ }
+ // clear map
+ TempProvidersMap().swap(addRequests);
}
////////////////////////////////////////////////////////////
-bool Host::confirmAddictions(){
- if (addRequests.empty()) return false;
- TempProvidersMap::iterator it;
- for( it = addRequests.begin() ; it != addRequests.end() ; ++it){
- std::list<Provider*> lst = it->second;
- std::list<Provider*>::iterator providerIt;
- for (providerIt = lst.begin() ; providerIt != lst.end() ; ++providerIt){
- knownTypes[it->first].providers.push_back(*providerIt);
- }
- }
- // clear map
- TempProvidersMap().swap(addRequests);
- return true;
+bool Host::confirmAddictions() {
+ if (addRequests.empty()) return false;
+ TempProvidersMap::iterator it;
+ for( it = addRequests.begin() ; it != addRequests.end() ; ++it) {
+ std::list<Provider*> lst = it->second;
+ std::list<Provider*>::iterator providerIt;
+ for (providerIt = lst.begin() ; providerIt != lst.end() ; ++providerIt) {
+ knownTypes[it->first].providers.push_back(*providerIt);
+ }
+ }
+ // clear map
+ TempProvidersMap().swap(addRequests);
+ return true;
}
diff --git a/src/uscxml/plugins/Pluma/PluginManager.cpp b/src/uscxml/plugins/Pluma/PluginManager.cpp index 1124505..60cb46e 100755..100644 --- a/src/uscxml/plugins/Pluma/PluginManager.cpp +++ b/src/uscxml/plugins/Pluma/PluginManager.cpp @@ -31,168 +31,168 @@ #include <Pluma/Dir.hpp>
#include <cstdio>
-namespace pluma{
+namespace pluma {
////////////////////////////////////////////////////////////
-PluginManager::PluginManager(){
- // Nothing to do
+PluginManager::PluginManager() {
+ // Nothing to do
}
////////////////////////////////////////////////////////////
-PluginManager::~PluginManager(){
- unloadAll();
+PluginManager::~PluginManager() {
+ unloadAll();
}
////////////////////////////////////////////////////////////
-bool PluginManager::load(const std::string& path){
- std::string plugName = getPluginName(path);
- std::string realPath = resolvePathExtension(path);
- DLibrary* lib = DLibrary::load(realPath);
- if (!lib) return false;
-
- fnRegisterPlugin* registerFunction;
- registerFunction = reinterpret_cast<fnRegisterPlugin*>(lib->getSymbol("connect"));
-
- if(!registerFunction){
- fprintf(stderr, "Failed to initialize plugin \"%s\": connect function not found\n", plugName.c_str());
- delete lib;
- return false;
- }
- // try to initialize plugin:
- if (!registerFunction(host)){
- // plugin decided to fail
- fprintf(stderr, "Self registry failed on plugin \"%s\".\n", plugName.c_str());
- host.cancelAddictions();
- delete lib;
- return false;
- }
- // Store the library if addictions are confirmed
- if (host.confirmAddictions())
- libraries[plugName] = lib;
- else{
- // otherwise nothing was registered
- fprintf(stderr, "Nothing registered by plugin \"%s\".\n", plugName.c_str());
- delete lib;
- return false;
- }
- return true;
+bool PluginManager::load(const std::string& path) {
+ std::string plugName = getPluginName(path);
+ std::string realPath = resolvePathExtension(path);
+ DLibrary* lib = DLibrary::load(realPath);
+ if (!lib) return false;
+
+ fnRegisterPlugin* registerFunction;
+ registerFunction = reinterpret_cast<fnRegisterPlugin*>(lib->getSymbol("connect"));
+
+ if(!registerFunction) {
+ fprintf(stderr, "Failed to initialize plugin \"%s\": connect function not found\n", plugName.c_str());
+ delete lib;
+ return false;
+ }
+ // try to initialize plugin:
+ if (!registerFunction(host)) {
+ // plugin decided to fail
+ fprintf(stderr, "Self registry failed on plugin \"%s\".\n", plugName.c_str());
+ host.cancelAddictions();
+ delete lib;
+ return false;
+ }
+ // Store the library if addictions are confirmed
+ if (host.confirmAddictions())
+ libraries[plugName] = lib;
+ else {
+ // otherwise nothing was registered
+ fprintf(stderr, "Nothing registered by plugin \"%s\".\n", plugName.c_str());
+ delete lib;
+ return false;
+ }
+ return true;
}
////////////////////////////////////////////////////////////
-bool PluginManager::load(const std::string& folder, const std::string& pluginName){
- if (folder.empty())
- return load(pluginName);
- else if (folder[folder.size()-1] == '/' || folder[folder.size()-1] == '\\')
- return load(folder + pluginName);
- return load(folder + '/' + pluginName);
+bool PluginManager::load(const std::string& folder, const std::string& pluginName) {
+ if (folder.empty())
+ return load(pluginName);
+ else if (folder[folder.size()-1] == '/' || folder[folder.size()-1] == '\\')
+ return load(folder + pluginName);
+ return load(folder + '/' + pluginName);
}
////////////////////////////////////////////////////////////
-int PluginManager::loadFromFolder(const std::string& folder, bool recursive){
- std::list<std::string> files;
- dir::listFiles(files, folder, PLUMA_LIB_EXTENSION, recursive);
- // try to load every library
- int res = 0;
- std::list<std::string>::const_iterator it;
- for (it = files.begin() ; it != files.end() ; ++it){
- if ( load(*it) ) ++res;
- }
- return res;
+int PluginManager::loadFromFolder(const std::string& folder, bool recursive) {
+ std::list<std::string> files;
+ dir::listFiles(files, folder, PLUMA_LIB_EXTENSION, recursive);
+ // try to load every library
+ int res = 0;
+ std::list<std::string>::const_iterator it;
+ for (it = files.begin() ; it != files.end() ; ++it) {
+ if ( load(*it) ) ++res;
+ }
+ return res;
}
////////////////////////////////////////////////////////////
-bool PluginManager::unload(const std::string& pluginName){
- std::string plugName = getPluginName(pluginName);
- LibMap::iterator it = libraries.find(plugName);
- if( it != libraries.end() ) {
- delete it->second;
- libraries.erase(it);
- return true;
- }
- return false;
+bool PluginManager::unload(const std::string& pluginName) {
+ std::string plugName = getPluginName(pluginName);
+ LibMap::iterator it = libraries.find(plugName);
+ if( it != libraries.end() ) {
+ delete it->second;
+ libraries.erase(it);
+ return true;
+ }
+ return false;
}
////////////////////////////////////////////////////////////
-void PluginManager::unloadAll(){
+void PluginManager::unloadAll() {
- host.clearProviders();
- LibMap::iterator it;
- for (it = libraries.begin() ; it != libraries.end() ; ++it){
- delete it->second;
- }
- libraries.clear();
+ host.clearProviders();
+ LibMap::iterator it;
+ for (it = libraries.begin() ; it != libraries.end() ; ++it) {
+ delete it->second;
+ }
+ libraries.clear();
}
////////////////////////////////////////////////////////////
-std::string PluginManager::getPluginName(const std::string& path){
- size_t lastDash = path.find_last_of("/\\");
- size_t lastDot = path.find_last_of('.');
- if (lastDash == std::string::npos) lastDash = 0;
- else ++lastDash;
- if (lastDot < lastDash || lastDot == std::string::npos){
- // path without extension
- lastDot = path.length();
- }
- return path.substr(lastDash, lastDot-lastDash);
+std::string PluginManager::getPluginName(const std::string& path) {
+ size_t lastDash = path.find_last_of("/\\");
+ size_t lastDot = path.find_last_of('.');
+ if (lastDash == std::string::npos) lastDash = 0;
+ else ++lastDash;
+ if (lastDot < lastDash || lastDot == std::string::npos) {
+ // path without extension
+ lastDot = path.length();
+ }
+ return path.substr(lastDash, lastDot-lastDash);
}
////////////////////////////////////////////////////////////
-std::string PluginManager::resolvePathExtension(const std::string& path){
- size_t lastDash = path.find_last_of("/\\");
- size_t lastDot = path.find_last_of('.');
- if (lastDash == std::string::npos) lastDash = 0;
- else ++lastDash;
- if (lastDot < lastDash || lastDot == std::string::npos){
- // path without extension, add it
- return path + "." + PLUMA_LIB_EXTENSION;
- }
- return path;
+std::string PluginManager::resolvePathExtension(const std::string& path) {
+ size_t lastDash = path.find_last_of("/\\");
+ size_t lastDot = path.find_last_of('.');
+ if (lastDash == std::string::npos) lastDash = 0;
+ else ++lastDash;
+ if (lastDot < lastDash || lastDot == std::string::npos) {
+ // path without extension, add it
+ return path + "." + PLUMA_LIB_EXTENSION;
+ }
+ return path;
}
////////////////////////////////////////////////////////////
-void PluginManager::registerType(const std::string& type, unsigned int version, unsigned int lowestVersion){
- host.registerType(type, version, lowestVersion);
+void PluginManager::registerType(const std::string& type, unsigned int version, unsigned int lowestVersion) {
+ host.registerType(type, version, lowestVersion);
}
////////////////////////////////////////////////////////////
-bool PluginManager::addProvider(Provider* provider){
- if (provider == NULL){
- fprintf(stderr, "Trying to add null provider\n");
- return false;
- }
- return host.registerProvider(provider);
+bool PluginManager::addProvider(Provider* provider) {
+ if (provider == NULL) {
+ fprintf(stderr, "Trying to add null provider\n");
+ return false;
+ }
+ return host.registerProvider(provider);
}
////////////////////////////////////////////////////////////
-void PluginManager::getLoadedPlugins(std::vector<const std::string*>& pluginNames) const{
- pluginNames.reserve(pluginNames.size()+libraries.size());
- LibMap::const_iterator it;
- for(it = libraries.begin() ; it != libraries.end() ; ++it){
- pluginNames.push_back(&(it->first));
- }
+void PluginManager::getLoadedPlugins(std::vector<const std::string*>& pluginNames) const {
+ pluginNames.reserve(pluginNames.size()+libraries.size());
+ LibMap::const_iterator it;
+ for(it = libraries.begin() ; it != libraries.end() ; ++it) {
+ pluginNames.push_back(&(it->first));
+ }
}
////////////////////////////////////////////////////////////
-bool PluginManager::isLoaded(const std::string& pluginName) const{
- return libraries.find(getPluginName(pluginName)) != libraries.end();
+bool PluginManager::isLoaded(const std::string& pluginName) const {
+ return libraries.find(getPluginName(pluginName)) != libraries.end();
}
////////////////////////////////////////////////////////////
-const std::list<Provider*>* PluginManager::getProviders(const std::string& type) const{
- return host.getProviders(type);
+const std::list<Provider*>* PluginManager::getProviders(const std::string& type) const {
+ return host.getProviders(type);
}
diff --git a/src/uscxml/plugins/Pluma/Provider.cpp b/src/uscxml/plugins/Pluma/Provider.cpp index 36d4da3..7691eb1 100755..100644 --- a/src/uscxml/plugins/Pluma/Provider.cpp +++ b/src/uscxml/plugins/Pluma/Provider.cpp @@ -30,23 +30,23 @@ #include <Pluma/Host.hpp>
-namespace pluma{
+namespace pluma {
////////////////////////////////////////////////////////////
-Provider::~Provider(){
- // Nothing to do
+Provider::~Provider() {
+ // Nothing to do
}
////////////////////////////////////////////////////////////
-bool Provider::isCompatible(const Host& host) const{
- // check compatibility with host
- const std::string& type = this->plumaGetType();
- if (!host.knows(type)) return false;
- unsigned int lowest = host.getLowestVersion(type);
- unsigned int current = host.getVersion(type);
- unsigned int myVersion = this->getVersion();
- return lowest <= myVersion && myVersion <= current;
+bool Provider::isCompatible(const Host& host) const {
+ // check compatibility with host
+ const std::string& type = this->plumaGetType();
+ if (!host.knows(type)) return false;
+ unsigned int lowest = host.getLowestVersion(type);
+ unsigned int current = host.getVersion(type);
+ unsigned int myVersion = this->getVersion();
+ return lowest <= myVersion && myVersion <= current;
}
} // namespace pluma
diff --git a/src/uscxml/plugins/Pluma/uce-dirent.h b/src/uscxml/plugins/Pluma/uce-dirent.h index ecf78eb..8cbd0e5 100755..100644 --- a/src/uscxml/plugins/Pluma/uce-dirent.h +++ b/src/uscxml/plugins/Pluma/uce-dirent.h @@ -1,8 +1,8 @@ /* * uce-dirent.h - operating system independent dirent implementation - * + * * Copyright (C) 1998-2002 Toni Ronkko - * + * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * ``Software''), to deal in the Software without restriction, including @@ -10,10 +10,10 @@ * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. @@ -21,8 +21,8 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. - * - * + * + * * May 28 1998, Toni Ronkko <tronkko@messi.uku.fi> * * $Id: uce-dirent.h,v 1.7 2002/05/13 10:48:35 tr Exp $ @@ -58,7 +58,7 @@ * Revision 1.1 1998/07/04 16:27:51 tr * Initial revision * - * + * * MSVC 1.0 scans automatic dependencies incorrectly when your project * contains this very header. The problem is that MSVC cannot handle * include directives inside #if..#endif block those are never entered. @@ -105,12 +105,12 @@ */ #if !defined(HAVE_DIRENT_H) && !defined(HAVE_DIRECT_H) && !defined(HAVE_SYS_DIR_H) && !defined(HAVE_NDIR_H) && !defined(HAVE_SYS_NDIR_H) && !defined(HAVE_DIR_H) # if defined(_MSC_VER) /* Microsoft C/C++ */ - /* no dirent.h */ +/* no dirent.h */ # elif defined(__BORLANDC__) /* Borland C/C++ */ # define HAVE_DIRENT_H # define VOID_CLOSEDIR # elif defined(__TURBOC__) /* Borland Turbo C */ - /* no dirent.h */ +/* no dirent.h */ # elif defined(__WATCOMC__) /* Watcom C/C++ */ # define HAVE_DIRECT_H # elif defined(__apollo) /* Apollo */ @@ -169,7 +169,7 @@ #elif defined(MSDOS) || defined(WIN32) - /* figure out type of underlaying directory interface to be used */ +/* figure out type of underlaying directory interface to be used */ # if defined(WIN32) # define DIRENT_WIN32_INTERFACE # elif defined(MSDOS) @@ -178,7 +178,7 @@ # error "missing native dirent interface" # endif - /*** WIN32 specifics ***/ +/*** WIN32 specifics ***/ # if defined(DIRENT_WIN32_INTERFACE) # include <windows.h> # if !defined(DIRENT_MAXNAMLEN) @@ -186,11 +186,11 @@ # endif - /*** MS-DOS specifics ***/ +/*** MS-DOS specifics ***/ # elif defined(DIRENT_MSDOS_INTERFACE) # include <dos.h> - /* Borland defines file length macros in dir.h */ +/* Borland defines file length macros in dir.h */ # if defined(__BORLANDC__) # include <dir.h> # if !defined(DIRENT_MAXNAMLEN) @@ -200,7 +200,7 @@ # define _find_t find_t # endif - /* Turbo C defines ffblk structure in dir.h */ +/* Turbo C defines ffblk structure in dir.h */ # elif defined(__TURBOC__) # include <dir.h> # if !defined(DIRENT_MAXNAMLEN) @@ -208,13 +208,13 @@ # endif # define DIRENT_USE_FFBLK - /* MSVC */ +/* MSVC */ # elif defined(_MSC_VER) # if !defined(DIRENT_MAXNAMLEN) # define DIRENT_MAXNAMLEN (12) # endif - /* Watcom */ +/* Watcom */ # elif defined(__WATCOMC__) # if !defined(DIRENT_MAXNAMLEN) # if defined(__OS2__) || defined(__NT__) @@ -227,7 +227,7 @@ # endif # endif - /*** generic MS-DOS and MS-Windows stuff ***/ +/*** generic MS-DOS and MS-Windows stuff ***/ # if !defined(NAME_MAX) && defined(DIRENT_MAXNAMLEN) # define NAME_MAX DIRENT_MAXNAMLEN # endif @@ -236,67 +236,67 @@ # endif - /* - * Substitute for real dirent structure. Note that `d_name' field is a - * true character array although we have it copied in the implementation - * dependent data. We could save some memory if we had declared `d_name' - * as a pointer refering the name within implementation dependent data. - * We have not done that since some code may rely on sizeof(d_name) to be - * something other than four. Besides, directory entries are typically so - * small that it takes virtually no time to copy them from place to place. - */ - typedef struct dirent { - char d_name[NAME_MAX + 1]; +/* + * Substitute for real dirent structure. Note that `d_name' field is a + * true character array although we have it copied in the implementation + * dependent data. We could save some memory if we had declared `d_name' + * as a pointer refering the name within implementation dependent data. + * We have not done that since some code may rely on sizeof(d_name) to be + * something other than four. Besides, directory entries are typically so + * small that it takes virtually no time to copy them from place to place. + */ +typedef struct dirent { + char d_name[NAME_MAX + 1]; - /*** Operating system specific part ***/ + /*** Operating system specific part ***/ # if defined(DIRENT_WIN32_INTERFACE) /*WIN32*/ - WIN32_FIND_DATA data; + WIN32_FIND_DATA data; # elif defined(DIRENT_MSDOS_INTERFACE) /*MSDOS*/ # if defined(DIRENT_USE_FFBLK) - struct ffblk data; + struct ffblk data; # else - struct _find_t data; + struct _find_t data; # endif # endif - } dirent; +} dirent; - /* DIR substitute structure containing directory name. The name is - * essential for the operation of ``rewinndir'' function. */ - typedef struct DIR { - char *dirname; /* directory being scanned */ - dirent current; /* current entry */ - int dirent_filled; /* is current un-processed? */ +/* DIR substitute structure containing directory name. The name is + * essential for the operation of ``rewinndir'' function. */ +typedef struct DIR { + char *dirname; /* directory being scanned */ + dirent current; /* current entry */ + int dirent_filled; /* is current un-processed? */ - /*** Operating system specific part ***/ + /*** Operating system specific part ***/ # if defined(DIRENT_WIN32_INTERFACE) - HANDLE search_handle; + HANDLE search_handle; # elif defined(DIRENT_MSDOS_INTERFACE) # endif - } DIR; +} DIR; # ifdef __cplusplus extern "C" { # endif -/* supply prototypes for dirent functions */ -static DIR *opendir (const char *dirname); -static struct dirent *readdir (DIR *dirp); -static int closedir (DIR *dirp); -static void rewinddir (DIR *dirp); - -/* - * Implement dirent interface as static functions so that the user does not - * need to change his project in any way to use dirent function. With this - * it is sufficient to include this very header from source modules using - * dirent functions and the functions will be pulled in automatically. - */ + /* supply prototypes for dirent functions */ + static DIR *opendir (const char *dirname); + static struct dirent *readdir (DIR *dirp); + static int closedir (DIR *dirp); + static void rewinddir (DIR *dirp); + + /* + * Implement dirent interface as static functions so that the user does not + * need to change his project in any way to use dirent function. With this + * it is sufficient to include this very header from source modules using + * dirent functions and the functions will be pulled in automatically. + */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <errno.h> -/* use ffblk instead of _find_t if requested */ + /* use ffblk instead of _find_t if requested */ #if defined(DIRENT_USE_FFBLK) # define _A_ARCH (FA_ARCH) # define _A_HIDDEN (FA_HIDDEN) @@ -309,362 +309,354 @@ static void rewinddir (DIR *dirp); # define _dos_findfirst(name,flags,dest) findfirst(name,dest,flags) #endif -static int _initdir (DIR *p); -static const char *_getdirname (const struct dirent *dp); -static void _setdirname (struct DIR *dirp); - -/* - * <function name="opendir"> - * <intro>open directory stream for reading - * <syntax>DIR *opendir (const char *dirname); - * - * <desc>Open named directory stream for read and return pointer to the - * internal working area that is used for retrieving individual directory - * entries. The internal working area has no fields of your interest. - * - * <ret>Returns a pointer to the internal working area or NULL in case the - * directory stream could not be opened. Global `errno' variable will set - * in case of error as follows: - * - * <table> - * [EACESS |Permission denied. - * [EMFILE |Too many open files used by the process. - * [ENFILE |Too many open files in system. - * [ENOENT |Directory does not exist. - * [ENOMEM |Insufficient memory. - * [ENOTDIR |dirname does not refer to directory. This value is not - * reliable on MS-DOS and MS-Windows platforms. Many - * implementations return ENOENT even when the name refers to a - * file.] - * </table> - * </function> - */ -static DIR * -opendir( - const char *dirname) -{ - DIR *dirp; - assert (dirname != NULL); - - dirp = (DIR*)malloc (sizeof (struct DIR)); - if (dirp != NULL) { - char *p; - - /* allocate room for directory name */ - dirp->dirname = (char*) malloc (strlen (dirname) + 1 + strlen ("\\*.*")); - if (dirp->dirname == NULL) { - /* failed to duplicate directory name. errno set by malloc() */ - free (dirp); - return NULL; - } - /* Copy directory name while appending directory separator and "*.*". - * Directory separator is not appended if the name already ends with - * drive or directory separator. Directory separator is assumed to be - * '/' or '\' and drive separator is assumed to be ':'. */ - strcpy (dirp->dirname, dirname); - p = strchr (dirp->dirname, '\0'); - if (dirp->dirname < p && - *(p - 1) != '\\' && *(p - 1) != '/' && *(p - 1) != ':') - { - strcpy (p++, "/"); - } + static int _initdir (DIR *p); + static const char *_getdirname (const struct dirent *dp); + static void _setdirname (struct DIR *dirp); + + /* + * <function name="opendir"> + * <intro>open directory stream for reading + * <syntax>DIR *opendir (const char *dirname); + * + * <desc>Open named directory stream for read and return pointer to the + * internal working area that is used for retrieving individual directory + * entries. The internal working area has no fields of your interest. + * + * <ret>Returns a pointer to the internal working area or NULL in case the + * directory stream could not be opened. Global `errno' variable will set + * in case of error as follows: + * + * <table> + * [EACESS |Permission denied. + * [EMFILE |Too many open files used by the process. + * [ENFILE |Too many open files in system. + * [ENOENT |Directory does not exist. + * [ENOMEM |Insufficient memory. + * [ENOTDIR |dirname does not refer to directory. This value is not + * reliable on MS-DOS and MS-Windows platforms. Many + * implementations return ENOENT even when the name refers to a + * file.] + * </table> + * </function> + */ + static DIR * + opendir( + const char *dirname) { + DIR *dirp; + assert (dirname != NULL); + + dirp = (DIR*)malloc (sizeof (struct DIR)); + if (dirp != NULL) { + char *p; + + /* allocate room for directory name */ + dirp->dirname = (char*) malloc (strlen (dirname) + 1 + strlen ("\\*.*")); + if (dirp->dirname == NULL) { + /* failed to duplicate directory name. errno set by malloc() */ + free (dirp); + return NULL; + } + /* Copy directory name while appending directory separator and "*.*". + * Directory separator is not appended if the name already ends with + * drive or directory separator. Directory separator is assumed to be + * '/' or '\' and drive separator is assumed to be ':'. */ + strcpy (dirp->dirname, dirname); + p = strchr (dirp->dirname, '\0'); + if (dirp->dirname < p && + *(p - 1) != '\\' && *(p - 1) != '/' && *(p - 1) != ':') { + strcpy (p++, "/"); + } # ifdef DIRENT_WIN32_INTERFACE - strcpy (p, "*"); /*scan files with and without extension in win32*/ + strcpy (p, "*"); /*scan files with and without extension in win32*/ # else - strcpy (p, "*.*"); /*scan files with and without extension in DOS*/ + strcpy (p, "*.*"); /*scan files with and without extension in DOS*/ # endif - /* open stream */ - if (_initdir (dirp) == 0) { - /* initialization failed */ - free (dirp->dirname); - free (dirp); - return NULL; - } - } - return dirp; -} - - -/* - * <function name="readdir"> - * <intro>read a directory entry - * <syntax>struct dirent *readdir (DIR *dirp); - * - * <desc>Read individual directory entry and return pointer to a structure - * containing the name of the entry. Individual directory entries returned - * include normal files, sub-directories, pseudo-directories "." and ".." - * and also volume labels, hidden files and system files in MS-DOS and - * MS-Windows. You might want to use stat(2) function to determinate which - * one are you dealing with. Many dirent implementations already contain - * equivalent information in dirent structure but you cannot depend on - * this. - * - * The dirent structure contains several system dependent fields that - * generally have no interest to you. The only interesting one is char - * d_name[] that is also portable across different systems. The d_name - * field contains the name of the directory entry without leading path. - * While d_name is portable across different systems the actual storage - * capacity of d_name varies from system to system and there is no portable - * way to find out it at compile time as different systems define the - * capacity of d_name with different macros and some systems do not define - * capacity at all (besides actual declaration of the field). If you really - * need to find out storage capacity of d_name then you might want to try - * NAME_MAX macro. The NAME_MAX is defined in POSIX standard althought - * there are many MS-DOS and MS-Windows implementations those do not define - * it. There are also systems that declare d_name as "char d_name[1]" and - * then allocate suitable amount of memory at run-time. Thanks to Alain - * Decamps (Alain.Decamps@advalvas.be) for pointing it out to me. - * - * This all leads to the fact that it is difficult to allocate space - * for the directory names when the very same program is being compiled on - * number of operating systems. Therefore I suggest that you always - * allocate space for directory names dynamically. - * - * <ret> - * Returns a pointer to a structure containing name of the directory entry - * in `d_name' field or NULL if there was an error. In case of an error the - * global `errno' variable will set as follows: - * - * <table> - * [EBADF |dir parameter refers to an invalid directory stream. This value - * is not set reliably on all implementations.] - * </table> - * </function> - */ -static struct dirent * -readdir (DIR *dirp) -{ - assert (dirp != NULL); - if (dirp == NULL) { - errno = EBADF; - return NULL; - } + /* open stream */ + if (_initdir (dirp) == 0) { + /* initialization failed */ + free (dirp->dirname); + free (dirp); + return NULL; + } + } + return dirp; + } + + + /* + * <function name="readdir"> + * <intro>read a directory entry + * <syntax>struct dirent *readdir (DIR *dirp); + * + * <desc>Read individual directory entry and return pointer to a structure + * containing the name of the entry. Individual directory entries returned + * include normal files, sub-directories, pseudo-directories "." and ".." + * and also volume labels, hidden files and system files in MS-DOS and + * MS-Windows. You might want to use stat(2) function to determinate which + * one are you dealing with. Many dirent implementations already contain + * equivalent information in dirent structure but you cannot depend on + * this. + * + * The dirent structure contains several system dependent fields that + * generally have no interest to you. The only interesting one is char + * d_name[] that is also portable across different systems. The d_name + * field contains the name of the directory entry without leading path. + * While d_name is portable across different systems the actual storage + * capacity of d_name varies from system to system and there is no portable + * way to find out it at compile time as different systems define the + * capacity of d_name with different macros and some systems do not define + * capacity at all (besides actual declaration of the field). If you really + * need to find out storage capacity of d_name then you might want to try + * NAME_MAX macro. The NAME_MAX is defined in POSIX standard althought + * there are many MS-DOS and MS-Windows implementations those do not define + * it. There are also systems that declare d_name as "char d_name[1]" and + * then allocate suitable amount of memory at run-time. Thanks to Alain + * Decamps (Alain.Decamps@advalvas.be) for pointing it out to me. + * + * This all leads to the fact that it is difficult to allocate space + * for the directory names when the very same program is being compiled on + * number of operating systems. Therefore I suggest that you always + * allocate space for directory names dynamically. + * + * <ret> + * Returns a pointer to a structure containing name of the directory entry + * in `d_name' field or NULL if there was an error. In case of an error the + * global `errno' variable will set as follows: + * + * <table> + * [EBADF |dir parameter refers to an invalid directory stream. This value + * is not set reliably on all implementations.] + * </table> + * </function> + */ + static struct dirent * + readdir (DIR *dirp) { + assert (dirp != NULL); + if (dirp == NULL) { + errno = EBADF; + return NULL; + } #if defined(DIRENT_WIN32_INTERFACE) - if (dirp->search_handle == INVALID_HANDLE_VALUE) { - /* directory stream was opened/rewound incorrectly or it ended normally */ - errno = EBADF; - return NULL; - } + if (dirp->search_handle == INVALID_HANDLE_VALUE) { + /* directory stream was opened/rewound incorrectly or it ended normally */ + errno = EBADF; + return NULL; + } #endif - if (dirp->dirent_filled != 0) { - /* - * Directory entry has already been retrieved and there is no need to - * retrieve a new one. Directory entry will be retrieved in advance - * when the user calls readdir function for the first time. This is so - * because real dirent has separate functions for opening and reading - * the stream whereas Win32 and DOS dirents open the stream - * automatically when we retrieve the first file. Therefore, we have to - * save the first file when opening the stream and later we have to - * return the saved entry when the user tries to read the first entry. - */ - dirp->dirent_filled = 0; - } else { - /* fill in entry and return that */ + if (dirp->dirent_filled != 0) { + /* + * Directory entry has already been retrieved and there is no need to + * retrieve a new one. Directory entry will be retrieved in advance + * when the user calls readdir function for the first time. This is so + * because real dirent has separate functions for opening and reading + * the stream whereas Win32 and DOS dirents open the stream + * automatically when we retrieve the first file. Therefore, we have to + * save the first file when opening the stream and later we have to + * return the saved entry when the user tries to read the first entry. + */ + dirp->dirent_filled = 0; + } else { + /* fill in entry and return that */ #if defined(DIRENT_WIN32_INTERFACE) - if (FindNextFile (dirp->search_handle, &dirp->current.data) == FALSE) { - /* Last file has been processed or an error occured */ - FindClose (dirp->search_handle); - dirp->search_handle = INVALID_HANDLE_VALUE; - errno = ENOENT; - return NULL; - } + if (FindNextFile (dirp->search_handle, &dirp->current.data) == FALSE) { + /* Last file has been processed or an error occured */ + FindClose (dirp->search_handle); + dirp->search_handle = INVALID_HANDLE_VALUE; + errno = ENOENT; + return NULL; + } # elif defined(DIRENT_MSDOS_INTERFACE) - if (_dos_findnext (&dirp->current.data) != 0) { - /* _dos_findnext and findnext will set errno to ENOENT when no - * more entries could be retrieved. */ - return NULL; - } + if (_dos_findnext (&dirp->current.data) != 0) { + /* _dos_findnext and findnext will set errno to ENOENT when no + * more entries could be retrieved. */ + return NULL; + } # endif - _setdirname (dirp); - assert (dirp->dirent_filled == 0); - } - return &dirp->current; -} - - -/* - * <function name="closedir"> - * <intro>close directory stream. - * <syntax>int closedir (DIR *dirp); - * - * <desc>Close directory stream opened by the `opendir' function. Close of - * directory stream invalidates the DIR structure as well as previously read - * dirent entry. - * - * <ret>The function typically returns 0 on success and -1 on failure but - * the function may be declared to return void on same systems. At least - * Borland C/C++ and some UNIX implementations use void as a return type. - * The dirent wrapper tries to define VOID_CLOSEDIR whenever closedir is - * known to return nothing. The very same definition is made by the GNU - * autoconf if you happen to use it. - * - * The global `errno' variable will set to EBADF in case of error. - * </function> - */ -static int -closedir (DIR *dirp) -{ - int retcode = 0; - - /* make sure that dirp points to legal structure */ - assert (dirp != NULL); - if (dirp == NULL) { - errno = EBADF; - return -1; - } - - /* free directory name and search handles */ - if (dirp->dirname != NULL) free (dirp->dirname); + _setdirname (dirp); + assert (dirp->dirent_filled == 0); + } + return &dirp->current; + } + + + /* + * <function name="closedir"> + * <intro>close directory stream. + * <syntax>int closedir (DIR *dirp); + * + * <desc>Close directory stream opened by the `opendir' function. Close of + * directory stream invalidates the DIR structure as well as previously read + * dirent entry. + * + * <ret>The function typically returns 0 on success and -1 on failure but + * the function may be declared to return void on same systems. At least + * Borland C/C++ and some UNIX implementations use void as a return type. + * The dirent wrapper tries to define VOID_CLOSEDIR whenever closedir is + * known to return nothing. The very same definition is made by the GNU + * autoconf if you happen to use it. + * + * The global `errno' variable will set to EBADF in case of error. + * </function> + */ + static int + closedir (DIR *dirp) { + int retcode = 0; + + /* make sure that dirp points to legal structure */ + assert (dirp != NULL); + if (dirp == NULL) { + errno = EBADF; + return -1; + } + + /* free directory name and search handles */ + if (dirp->dirname != NULL) free (dirp->dirname); #if defined(DIRENT_WIN32_INTERFACE) - if (dirp->search_handle != INVALID_HANDLE_VALUE) { - if (FindClose (dirp->search_handle) == FALSE) { - /* Unknown error */ - retcode = -1; - errno = EBADF; - } - } -#endif - - /* clear dirp structure to make sure that it cannot be used anymore*/ - memset (dirp, 0, sizeof (*dirp)); + if (dirp->search_handle != INVALID_HANDLE_VALUE) { + if (FindClose (dirp->search_handle) == FALSE) { + /* Unknown error */ + retcode = -1; + errno = EBADF; + } + } +#endif + + /* clear dirp structure to make sure that it cannot be used anymore*/ + memset (dirp, 0, sizeof (*dirp)); # if defined(DIRENT_WIN32_INTERFACE) - dirp->search_handle = INVALID_HANDLE_VALUE; + dirp->search_handle = INVALID_HANDLE_VALUE; # endif - free (dirp); - return retcode; -} - - -/* - * <function name="rewinddir"> - * <intro>rewind directory stream to the beginning - * <syntax>void rewinddir (DIR *dirp); - * - * <desc>Rewind directory stream to the beginning so that the next call of - * readdir() returns the very first directory entry again. However, note - * that next call of readdir() may not return the same directory entry as it - * did in first time. The directory stream may have been affected by newly - * created files. - * - * Almost every dirent implementation ensure that rewinddir will update - * the directory stream to reflect any changes made to the directory entries - * since the previous ``opendir'' or ``rewinddir'' call. Keep an eye on - * this if your program depends on the feature. I know at least one dirent - * implementation where you are required to close and re-open the stream to - * see the changes. - * - * <ret>Returns nothing. If something went wrong while rewinding, you will - * notice it later when you try to retrieve the first directory entry. - */ -static void -rewinddir (DIR *dirp) -{ - /* make sure that dirp is legal */ - assert (dirp != NULL); - if (dirp == NULL) { - errno = EBADF; - return; - } - assert (dirp->dirname != NULL); - - /* close previous stream */ + free (dirp); + return retcode; + } + + + /* + * <function name="rewinddir"> + * <intro>rewind directory stream to the beginning + * <syntax>void rewinddir (DIR *dirp); + * + * <desc>Rewind directory stream to the beginning so that the next call of + * readdir() returns the very first directory entry again. However, note + * that next call of readdir() may not return the same directory entry as it + * did in first time. The directory stream may have been affected by newly + * created files. + * + * Almost every dirent implementation ensure that rewinddir will update + * the directory stream to reflect any changes made to the directory entries + * since the previous ``opendir'' or ``rewinddir'' call. Keep an eye on + * this if your program depends on the feature. I know at least one dirent + * implementation where you are required to close and re-open the stream to + * see the changes. + * + * <ret>Returns nothing. If something went wrong while rewinding, you will + * notice it later when you try to retrieve the first directory entry. + */ + static void + rewinddir (DIR *dirp) { + /* make sure that dirp is legal */ + assert (dirp != NULL); + if (dirp == NULL) { + errno = EBADF; + return; + } + assert (dirp->dirname != NULL); + + /* close previous stream */ #if defined(DIRENT_WIN32_INTERFACE) - if (dirp->search_handle != INVALID_HANDLE_VALUE) { - if (FindClose (dirp->search_handle) == FALSE) { - /* Unknown error */ - errno = EBADF; - } - } + if (dirp->search_handle != INVALID_HANDLE_VALUE) { + if (FindClose (dirp->search_handle) == FALSE) { + /* Unknown error */ + errno = EBADF; + } + } #endif - /* re-open previous stream */ - if (_initdir (dirp) == 0) { - /* initialization failed but we cannot deal with error. User will notice - * error later when she tries to retrieve first directory enty. */ - /*EMPTY*/; - } -} - - -/* - * Open native directory stream object and retrieve first file. - * Be sure to close previous stream before opening new one. - */ -static int -_initdir (DIR *dirp) -{ - assert (dirp != NULL); - assert (dirp->dirname != NULL); - dirp->dirent_filled = 0; + /* re-open previous stream */ + if (_initdir (dirp) == 0) { + /* initialization failed but we cannot deal with error. User will notice + * error later when she tries to retrieve first directory enty. */ + /*EMPTY*/; + } + } + + + /* + * Open native directory stream object and retrieve first file. + * Be sure to close previous stream before opening new one. + */ + static int + _initdir (DIR *dirp) { + assert (dirp != NULL); + assert (dirp->dirname != NULL); + dirp->dirent_filled = 0; # if defined(DIRENT_WIN32_INTERFACE) - /* Open stream and retrieve first file */ - dirp->search_handle = FindFirstFile (dirp->dirname, &dirp->current.data); - if (dirp->search_handle == INVALID_HANDLE_VALUE) { - /* something went wrong but we don't know what. GetLastError() could - * give us more information about the error, but then we should map - * the error code into errno. */ - errno = ENOENT; - return 0; - } + /* Open stream and retrieve first file */ + dirp->search_handle = FindFirstFile (dirp->dirname, &dirp->current.data); + if (dirp->search_handle == INVALID_HANDLE_VALUE) { + /* something went wrong but we don't know what. GetLastError() could + * give us more information about the error, but then we should map + * the error code into errno. */ + errno = ENOENT; + return 0; + } # elif defined(DIRENT_MSDOS_INTERFACE) - if (_dos_findfirst (dirp->dirname, - _A_SUBDIR | _A_RDONLY | _A_ARCH | _A_SYSTEM | _A_HIDDEN, - &dirp->current.data) != 0) - { - /* _dos_findfirst and findfirst will set errno to ENOENT when no - * more entries could be retrieved. */ - return 0; - } + if (_dos_findfirst (dirp->dirname, + _A_SUBDIR | _A_RDONLY | _A_ARCH | _A_SYSTEM | _A_HIDDEN, + &dirp->current.data) != 0) { + /* _dos_findfirst and findfirst will set errno to ENOENT when no + * more entries could be retrieved. */ + return 0; + } # endif - /* initialize DIR and it's first entry */ - _setdirname (dirp); - dirp->dirent_filled = 1; - return 1; -} + /* initialize DIR and it's first entry */ + _setdirname (dirp); + dirp->dirent_filled = 1; + return 1; + } -/* - * Return implementation dependent name of the current directory entry. - */ -static const char * -_getdirname (const struct dirent *dp) -{ + /* + * Return implementation dependent name of the current directory entry. + */ + static const char * + _getdirname (const struct dirent *dp) { #if defined(DIRENT_WIN32_INTERFACE) - return dp->data.cFileName; - + return dp->data.cFileName; + #elif defined(DIRENT_USE_FFBLK) - return dp->data.ff_name; - + return dp->data.ff_name; + #else - return dp->data.name; -#endif -} + return dp->data.name; +#endif + } -/* - * Copy name of implementation dependent directory entry to the d_name field. - */ -static void -_setdirname (struct DIR *dirp) { - /* make sure that d_name is long enough */ - assert (strlen (_getdirname (&dirp->current)) <= NAME_MAX); - - strncpy (dirp->current.d_name, - _getdirname (&dirp->current), - NAME_MAX); - dirp->current.d_name[NAME_MAX] = '\0'; /*char d_name[NAME_MAX+1]*/ -} - + /* + * Copy name of implementation dependent directory entry to the d_name field. + */ + static void + _setdirname (struct DIR *dirp) { + /* make sure that d_name is long enough */ + assert (strlen (_getdirname (&dirp->current)) <= NAME_MAX); + + strncpy (dirp->current.d_name, + _getdirname (&dirp->current), + NAME_MAX); + dirp->current.d_name[NAME_MAX] = '\0'; /*char d_name[NAME_MAX+1]*/ + } + # ifdef __cplusplus } # endif diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp index e25ece4..6073e26 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp @@ -12,9 +12,9 @@ namespace uscxml { #ifdef BUILD_AS_PLUGINS PLUMA_CONNECTOR -bool connect(pluma::Host& host){ - host.add( new V8DataModelProvider() ); - return true; +bool connect(pluma::Host& host) { + host.add( new V8DataModelProvider() ); + return true; } #endif @@ -23,306 +23,310 @@ V8DataModel::V8DataModel() { } DataModel* V8DataModel::create(Interpreter* interpreter) { - V8DataModel* dm = new V8DataModel(); - dm->_interpreter = interpreter; - v8::Locker locker; - v8::HandleScope scope; + V8DataModel* dm = new V8DataModel(); + dm->_interpreter = interpreter; + v8::Locker locker; + v8::HandleScope scope; - // see http://stackoverflow.com/questions/3171418/v8-functiontemplate-class-instance + // see http://stackoverflow.com/questions/3171418/v8-functiontemplate-class-instance // dm->_globalTemplate = v8::Persistent<v8::ObjectTemplate>(v8::ObjectTemplate::New()); // dm->_globalTemplate->Set(v8::String::New("In"), v8::FunctionTemplate::New(jsIn, v8::External::New(reinterpret_cast<void*>(this)))); - v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); - global->Set(v8::String::New("In"), v8::FunctionTemplate::New(jsIn, v8::External::New(reinterpret_cast<void*>(dm)))); - global->Set(v8::String::New("print"), v8::FunctionTemplate::New(jsPrint, v8::External::New(reinterpret_cast<void*>(dm)))); - global->Set(v8::String::New("document"), V8SCXMLDOM::getDocument(interpreter->getDocument())); - - dm->_contexts.push_back(v8::Context::New(NULL, global)); - dm->setName(interpreter->getName()); - dm->setSessionId(interpreter->getSessionId()); - dm->eval("_ioprocessors = {};"); - - return dm; + v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); + global->Set(v8::String::New("In"), v8::FunctionTemplate::New(jsIn, v8::External::New(reinterpret_cast<void*>(dm)))); + global->Set(v8::String::New("print"), v8::FunctionTemplate::New(jsPrint, v8::External::New(reinterpret_cast<void*>(dm)))); + global->Set(v8::String::New("document"), V8SCXMLDOM::getDocument(interpreter->getDocument())); + + dm->_contexts.push_back(v8::Context::New(NULL, global)); + dm->setName(interpreter->getName()); + dm->setSessionId(interpreter->getSessionId()); + dm->eval("_ioprocessors = {};"); + + return dm; +} + +void V8DataModel::registerIOProcessor(const std::string& name, IOProcessor* ioprocessor) { + assign("_ioprocessors['" + name + "']", ioprocessor->getDataModelVariables()); } void V8DataModel::setSessionId(const std::string& sessionId) { - _sessionId = sessionId; - v8::Locker locker; - v8::HandleScope handleScope; - v8::Context::Scope contextScope(_contexts.front()); - v8::Handle<v8::Object> global = _contexts.front()->Global(); + _sessionId = sessionId; + v8::Locker locker; + v8::HandleScope handleScope; + v8::Context::Scope contextScope(_contexts.front()); + v8::Handle<v8::Object> global = _contexts.front()->Global(); - global->Set(v8::String::New("_sessionid"), v8::String::New(sessionId.c_str())); + global->Set(v8::String::New("_sessionid"), v8::String::New(sessionId.c_str())); } void V8DataModel::setName(const std::string& name) { - _name = name; - v8::HandleScope handleScope; - v8::Context::Scope contextScope(_contexts.front()); - v8::Handle<v8::Object> global = _contexts.front()->Global(); - - global->Set(v8::String::New("_name"), v8::String::New(name.c_str())); + _name = name; + v8::HandleScope handleScope; + v8::Context::Scope contextScope(_contexts.front()); + v8::Handle<v8::Object> global = _contexts.front()->Global(); + + global->Set(v8::String::New("_name"), v8::String::New(name.c_str())); } V8DataModel::~V8DataModel() { - while(_contexts.size() > 0) { - _contexts.back().Dispose(); - _contexts.pop_back(); - } + while(_contexts.size() > 0) { + _contexts.back().Dispose(); + _contexts.pop_back(); + } } void V8DataModel::pushContext() { - _contexts.push_back(_contexts.back().New(_contexts.back())); + _contexts.push_back(_contexts.back().New(_contexts.back())); } void V8DataModel::popContext() { - if (_contexts.size() > 1) { - _contexts.back().Dispose(); - _contexts.pop_back(); - } + if (_contexts.size() > 1) { + _contexts.back().Dispose(); + _contexts.pop_back(); + } } void V8DataModel::initialize() { } void V8DataModel::setEvent(const Event& event) { - _event = event; - v8::Locker locker; - v8::HandleScope handleScope; - v8::Context::Scope contextScope(_contexts.front()); - v8::Handle<v8::Object> global = _contexts.front()->Global(); - - // this is unfortunate - can't we store the template in the object? - if (_eventTemplate.IsEmpty()) { - v8::Handle<v8::ObjectTemplate> localEventTemplate = v8::ObjectTemplate::New(); - localEventTemplate->SetInternalFieldCount(1); // we only have a single C++ object - localEventTemplate->SetAccessor(v8::String::New("name"), V8DataModel::jsGetEventName); - localEventTemplate->SetAccessor(v8::String::New("type"), V8DataModel::jsGetEventType); - localEventTemplate->SetAccessor(v8::String::New("sendid"), V8DataModel::jsGetEventSendId); - localEventTemplate->SetAccessor(v8::String::New("origin"), V8DataModel::jsGetEventOrigin); - localEventTemplate->SetAccessor(v8::String::New("origintype"), V8DataModel::jsGetEventOriginType); - localEventTemplate->SetAccessor(v8::String::New("invokeid"), V8DataModel::jsGetEventInvokeId); - _eventTemplate = v8::Persistent<v8::ObjectTemplate>::New(localEventTemplate); - } - - assert(_eventTemplate->InternalFieldCount() == 1); - v8::Handle<v8::Object> eventJS = _eventTemplate->NewInstance(); - eventJS->SetInternalField(0, v8::External::New(&_event)); - - eventJS->Set(v8::String::New("data"), getDataAsValue(event)); // set data part of _event - global->Set(v8::String::New("_event"), eventJS); + _event = event; + v8::Locker locker; + v8::HandleScope handleScope; + v8::Context::Scope contextScope(_contexts.front()); + v8::Handle<v8::Object> global = _contexts.front()->Global(); + + // this is unfortunate - can't we store the template in the object? + if (_eventTemplate.IsEmpty()) { + v8::Handle<v8::ObjectTemplate> localEventTemplate = v8::ObjectTemplate::New(); + localEventTemplate->SetInternalFieldCount(1); // we only have a single C++ object + localEventTemplate->SetAccessor(v8::String::New("name"), V8DataModel::jsGetEventName); + localEventTemplate->SetAccessor(v8::String::New("type"), V8DataModel::jsGetEventType); + localEventTemplate->SetAccessor(v8::String::New("sendid"), V8DataModel::jsGetEventSendId); + localEventTemplate->SetAccessor(v8::String::New("origin"), V8DataModel::jsGetEventOrigin); + localEventTemplate->SetAccessor(v8::String::New("origintype"), V8DataModel::jsGetEventOriginType); + localEventTemplate->SetAccessor(v8::String::New("invokeid"), V8DataModel::jsGetEventInvokeId); + _eventTemplate = v8::Persistent<v8::ObjectTemplate>::New(localEventTemplate); + } + + assert(_eventTemplate->InternalFieldCount() == 1); + v8::Handle<v8::Object> eventJS = _eventTemplate->NewInstance(); + eventJS->SetInternalField(0, v8::External::New(&_event)); + + eventJS->Set(v8::String::New("data"), getDataAsValue(event)); // set data part of _event + global->Set(v8::String::New("_event"), eventJS); } Data V8DataModel::getStringAsData(const std::string& content) { - v8::Locker locker; - v8::HandleScope handleScope; - v8::Context::Scope contextScope(_contexts.front()); - v8::Handle<v8::Value> result = evalAsValue(content); - Data data = getValueAsData(result); - return data; + v8::Locker locker; + v8::HandleScope handleScope; + v8::Context::Scope contextScope(_contexts.front()); + v8::Handle<v8::Value> result = evalAsValue(content); + Data data = getValueAsData(result); + return data; } Data V8DataModel::getValueAsData(const v8::Handle<v8::Value>& value) { - Data data; - if (false) { - } else if (value->IsArray()) { - v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value); - for (int i = 0; i < array->Length(); i++) { - data.array.push_back(getValueAsData(array->Get(i))); - } - } else if (value->IsBoolean()) { - data.atom = (value->ToBoolean()->Value() ? "true" : "false"); - } else if (value->IsBooleanObject()) { - LOG(ERROR) << "IsBooleanObject is unimplemented" << std::endl; - } else if (value->IsDate()) { - LOG(ERROR) << "IsDate is unimplemented" << std::endl; - } else if (value->IsExternal()) { - LOG(ERROR) << "IsExternal is unimplemented" << std::endl; - } else if (value->IsFalse()) { - LOG(ERROR) << "IsFalse is unimplemented" << std::endl; - } else if (value->IsFunction()) { - LOG(ERROR) << "IsFunction is unimplemented" << std::endl; - } else if (value->IsInt32()) { - int32_t prop = value->Int32Value(); - data.atom = toStr(prop); - } else if (value->IsNativeError()) { - LOG(ERROR) << "IsNativeError is unimplemented" << std::endl; - } else if (value->IsNull()) { - LOG(ERROR) << "IsNull is unimplemented" << std::endl; - } else if (value->IsNumber()) { - v8::String::AsciiValue prop(v8::Handle<v8::String>::Cast(v8::Handle<v8::Number>::Cast(value))); - data.atom = *prop; - } else if (value->IsNumberObject()) { - LOG(ERROR) << "IsNumberObject is unimplemented" << std::endl; - } else if (value->IsObject()) { - v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); - v8::Local<v8::Array> properties = object->GetPropertyNames(); - for (int i = 0; i < properties->Length(); i++) { - assert(properties->Get(i)->IsString()); - v8::String::AsciiValue key(v8::Handle<v8::String>::Cast(properties->Get(i))); - v8::Local<v8::Value> property = object->Get(properties->Get(i)); - data.compound[*key] = getValueAsData(property); - } - } else if (value->IsRegExp()) { - LOG(ERROR) << "IsRegExp is unimplemented" << std::endl; - } else if(value->IsString()) { - v8::String::AsciiValue property(v8::Handle<v8::String>::Cast(value)); - data.atom = *property; - } else if(value->IsStringObject()) { - LOG(ERROR) << "IsStringObject is unimplemented" << std::endl; - } else if(value->IsTrue()) { - LOG(ERROR) << "IsTrue is unimplemented" << std::endl; - } else if(value->IsUint32()) { - LOG(ERROR) << "IsUint32 is unimplemented" << std::endl; - } else if(value->IsUndefined()) { - LOG(ERROR) << "IsUndefined is unimplemented" << std::endl; - } - return data; + Data data; + if (false) { + } else if (value->IsArray()) { + v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value); + for (int i = 0; i < array->Length(); i++) { + data.array.push_back(getValueAsData(array->Get(i))); + } + } else if (value->IsBoolean()) { + data.atom = (value->ToBoolean()->Value() ? "true" : "false"); + } else if (value->IsBooleanObject()) { + LOG(ERROR) << "IsBooleanObject is unimplemented" << std::endl; + } else if (value->IsDate()) { + LOG(ERROR) << "IsDate is unimplemented" << std::endl; + } else if (value->IsExternal()) { + LOG(ERROR) << "IsExternal is unimplemented" << std::endl; + } else if (value->IsFalse()) { + LOG(ERROR) << "IsFalse is unimplemented" << std::endl; + } else if (value->IsFunction()) { + LOG(ERROR) << "IsFunction is unimplemented" << std::endl; + } else if (value->IsInt32()) { + int32_t prop = value->Int32Value(); + data.atom = toStr(prop); + } else if (value->IsNativeError()) { + LOG(ERROR) << "IsNativeError is unimplemented" << std::endl; + } else if (value->IsNull()) { + LOG(ERROR) << "IsNull is unimplemented" << std::endl; + } else if (value->IsNumber()) { + v8::String::AsciiValue prop(v8::Handle<v8::String>::Cast(v8::Handle<v8::Number>::Cast(value))); + data.atom = *prop; + } else if (value->IsNumberObject()) { + LOG(ERROR) << "IsNumberObject is unimplemented" << std::endl; + } else if (value->IsObject()) { + v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); + v8::Local<v8::Array> properties = object->GetPropertyNames(); + for (int i = 0; i < properties->Length(); i++) { + assert(properties->Get(i)->IsString()); + v8::String::AsciiValue key(v8::Handle<v8::String>::Cast(properties->Get(i))); + v8::Local<v8::Value> property = object->Get(properties->Get(i)); + data.compound[*key] = getValueAsData(property); + } + } else if (value->IsRegExp()) { + LOG(ERROR) << "IsRegExp is unimplemented" << std::endl; + } else if(value->IsString()) { + v8::String::AsciiValue property(v8::Handle<v8::String>::Cast(value)); + data.atom = *property; + } else if(value->IsStringObject()) { + LOG(ERROR) << "IsStringObject is unimplemented" << std::endl; + } else if(value->IsTrue()) { + LOG(ERROR) << "IsTrue is unimplemented" << std::endl; + } else if(value->IsUint32()) { + LOG(ERROR) << "IsUint32 is unimplemented" << std::endl; + } else if(value->IsUndefined()) { + LOG(ERROR) << "IsUndefined is unimplemented" << std::endl; + } + return data; } - + v8::Handle<v8::Value> V8DataModel::getDataAsValue(const Data& data) { - if (data.compound.size() > 0) { - v8::Handle<v8::Object> value = v8::Object::New(); - std::map<std::string, Data>::const_iterator compoundIter = data.compound.begin(); - while(compoundIter != data.compound.end()) { - value->Set(v8::String::New(compoundIter->first.c_str()), getDataAsValue(compoundIter->second)); - compoundIter++; - } - return value; - } - if (data.array.size() > 0) { - v8::Handle<v8::Object> value = v8::Array::New(); - std::list<Data>::const_iterator arrayIter = data.array.begin(); - uint32_t index = 0; - while(arrayIter != data.array.end()) { - value->Set(index++, getDataAsValue(*arrayIter)); - arrayIter++; - } - return value; - } - if (data.type == Data::VERBATIM) { - return v8::String::New(data.atom.c_str()); - } else { - return evalAsValue(data.atom); - } + if (data.compound.size() > 0) { + v8::Handle<v8::Object> value = v8::Object::New(); + std::map<std::string, Data>::const_iterator compoundIter = data.compound.begin(); + while(compoundIter != data.compound.end()) { + value->Set(v8::String::New(compoundIter->first.c_str()), getDataAsValue(compoundIter->second)); + compoundIter++; + } + return value; + } + if (data.array.size() > 0) { + v8::Handle<v8::Object> value = v8::Array::New(); + std::list<Data>::const_iterator arrayIter = data.array.begin(); + uint32_t index = 0; + while(arrayIter != data.array.end()) { + value->Set(index++, getDataAsValue(*arrayIter)); + arrayIter++; + } + return value; + } + if (data.type == Data::VERBATIM) { + return v8::String::New(data.atom.c_str()); + } else { + return evalAsValue(data.atom); + } } v8::Handle<v8::Value> V8DataModel::jsPrint(const v8::Arguments& args) { - if (args.Length() > 0) { - v8::String::AsciiValue printMsg(args[0]->ToString()); - std::cout << *printMsg; - } - return v8::Undefined(); + if (args.Length() > 0) { + v8::String::AsciiValue printMsg(args[0]->ToString()); + std::cout << *printMsg; + } + return v8::Undefined(); } - + v8::Handle<v8::Value> V8DataModel::jsIn(const v8::Arguments& args) { - V8DataModel* INSTANCE = static_cast<V8DataModel*>(v8::External::Unwrap(args.Data())); - for (unsigned int i = 0; i < args.Length(); i++) { - if (args[i]->IsString()) { - std::string stateName(*v8::String::AsciiValue(args[i]->ToString())); - if (Interpreter::isMember(INSTANCE->_interpreter->getState(stateName), INSTANCE->_interpreter->getConfiguration())) { - continue; - } - } - return v8::Boolean::New(false); - } - return v8::Boolean::New(true); + V8DataModel* INSTANCE = static_cast<V8DataModel*>(v8::External::Unwrap(args.Data())); + for (unsigned int i = 0; i < args.Length(); i++) { + if (args[i]->IsString()) { + std::string stateName(*v8::String::AsciiValue(args[i]->ToString())); + if (Interpreter::isMember(INSTANCE->_interpreter->getState(stateName), INSTANCE->_interpreter->getConfiguration())) { + continue; + } + } + return v8::Boolean::New(false); + } + return v8::Boolean::New(true); } v8::Handle<v8::Value> V8DataModel::jsGetEventName(v8::Local<v8::String> property, - const v8::AccessorInfo &info) { - Event* event = static_cast<Event*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); - return v8::String::New(event->name.c_str()); + const v8::AccessorInfo &info) { + Event* event = static_cast<Event*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); + return v8::String::New(event->name.c_str()); } v8::Handle<v8::Value> V8DataModel::jsGetEventType(v8::Local<v8::String> property, - const v8::AccessorInfo &info) { - Event* event = static_cast<Event*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); - switch (event->type) { - case Event::PLATFORM: - return v8::String::New("platform"); - break; - case Event::INTERNAL: - return v8::String::New("internal"); - break; - case Event::EXTERNAL: - return v8::String::New("external"); - break; - default: - return v8::String::New(""); - break; - } + const v8::AccessorInfo &info) { + Event* event = static_cast<Event*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); + switch (event->type) { + case Event::PLATFORM: + return v8::String::New("platform"); + break; + case Event::INTERNAL: + return v8::String::New("internal"); + break; + case Event::EXTERNAL: + return v8::String::New("external"); + break; + default: + return v8::String::New(""); + break; + } } v8::Handle<v8::Value> V8DataModel::jsGetEventSendId(v8::Local<v8::String> property, - const v8::AccessorInfo &info) { - Event* event = static_cast<Event*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); - return v8::String::New(event->sendid.c_str()); - + const v8::AccessorInfo &info) { + Event* event = static_cast<Event*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); + return v8::String::New(event->sendid.c_str()); + } v8::Handle<v8::Value> V8DataModel::jsGetEventOrigin(v8::Local<v8::String> property, - const v8::AccessorInfo &info) { - Event* event = static_cast<Event*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); - return v8::String::New(event->origin.c_str()); + const v8::AccessorInfo &info) { + Event* event = static_cast<Event*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); + return v8::String::New(event->origin.c_str()); } v8::Handle<v8::Value> V8DataModel::jsGetEventOriginType(v8::Local<v8::String> property, - const v8::AccessorInfo &info) { - Event* event = static_cast<Event*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); - return v8::String::New(event->origintype.c_str()); + const v8::AccessorInfo &info) { + Event* event = static_cast<Event*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); + return v8::String::New(event->origintype.c_str()); } v8::Handle<v8::Value> V8DataModel::jsGetEventInvokeId(v8::Local<v8::String> property, - const v8::AccessorInfo &info) { - Event* event = static_cast<Event*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); - return v8::String::New(event->invokeid.c_str()); + const v8::AccessorInfo &info) { + Event* event = static_cast<Event*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); + return v8::String::New(event->invokeid.c_str()); } bool V8DataModel::validate(const std::string& location, const std::string& schema) { - return true; + return true; } uint32_t V8DataModel::getLength(const std::string& expr) { - v8::Locker locker; - v8::HandleScope handleScope; - v8::Context::Scope contextScope(_contexts.back()); - v8::Handle<v8::Array> result = evalAsValue(expr).As<v8::Array>(); - return result->Length(); + v8::Locker locker; + v8::HandleScope handleScope; + v8::Context::Scope contextScope(_contexts.back()); + v8::Handle<v8::Array> result = evalAsValue(expr).As<v8::Array>(); + return result->Length(); } void V8DataModel::eval(const std::string& expr) { - v8::Locker locker; - v8::HandleScope handleScope; - v8::Context::Scope contextScope(_contexts.back()); - evalAsValue(expr); + v8::Locker locker; + v8::HandleScope handleScope; + v8::Context::Scope contextScope(_contexts.back()); + evalAsValue(expr); } bool V8DataModel::evalAsBool(const std::string& expr) { - v8::Locker locker; - v8::HandleScope handleScope; - v8::Context::Scope contextScope(_contexts.back()); - v8::Handle<v8::Value> result = evalAsValue(expr); - return(result->ToBoolean()->BooleanValue()); + v8::Locker locker; + v8::HandleScope handleScope; + v8::Context::Scope contextScope(_contexts.back()); + v8::Handle<v8::Value> result = evalAsValue(expr); + return(result->ToBoolean()->BooleanValue()); } std::string V8DataModel::evalAsString(const std::string& expr) { - v8::Locker locker; - v8::HandleScope handleScope; - v8::Context::Scope contextScope(_contexts.back()); - v8::Handle<v8::Value> result = evalAsValue(expr); - v8::String::AsciiValue data(result->ToString()); - return std::string(*data); + v8::Locker locker; + v8::HandleScope handleScope; + v8::Context::Scope contextScope(_contexts.back()); + v8::Handle<v8::Value> result = evalAsValue(expr); + v8::String::AsciiValue data(result->ToString()); + return std::string(*data); } void V8DataModel::assign(const std::string& location, const Data& data) { - v8::Locker locker; - v8::HandleScope handleScope; - v8::Context::Scope contextScope(_contexts.front()); - - std::stringstream ssJSON; - ssJSON << data; - assign(location, ssJSON.str()); + v8::Locker locker; + v8::HandleScope handleScope; + v8::Context::Scope contextScope(_contexts.front()); + + std::stringstream ssJSON; + ssJSON << data; + assign(location, ssJSON.str()); // v8::Handle<v8::Object> variable = evalAsValue(location).As<v8::Object>(); // assert(!variable.IsEmpty()); // if (data.compound.size() > 0) { @@ -348,62 +352,62 @@ void V8DataModel::assign(const std::string& location, const Data& data) { } void V8DataModel::assign(const std::string& location, const std::string& expr) { - v8::Locker locker; - v8::HandleScope handleScope; - v8::Context::Scope contextScope(_contexts.back()); - evalAsValue((location + " = " + expr).c_str()); + v8::Locker locker; + v8::HandleScope handleScope; + v8::Context::Scope contextScope(_contexts.back()); + evalAsValue((location + " = " + expr).c_str()); } v8::Handle<v8::Value> V8DataModel::evalAsValue(const std::string& expr) { - v8::TryCatch tryCatch; - v8::Handle<v8::String> source = v8::String::New(expr.c_str()); - v8::Handle<v8::Script> script = v8::Script::Compile(source); - - v8::Handle<v8::Value> result; - if (!script.IsEmpty()) - result = script->Run(); - - if (script.IsEmpty() || result.IsEmpty()) { - // throw an exception - assert(tryCatch.HasCaught()); - Event exceptionEvent; - exceptionEvent.name = "error.execution"; - - std::string exceptionString(*v8::String::AsciiValue(tryCatch.Exception())); - exceptionEvent.compound["exception"] = Data(exceptionString, Data::VERBATIM);; - - v8::Handle<v8::Message> message = tryCatch.Message(); - if (!message.IsEmpty()) { - std::string filename(*v8::String::AsciiValue(message->GetScriptResourceName())); - exceptionEvent.compound["filename"] = Data(filename, Data::VERBATIM); - - std::string sourceLine(*v8::String::AsciiValue(message->GetSourceLine())); - exceptionEvent.compound["sourceline"] = Data(sourceLine, Data::VERBATIM); - - std::stringstream ssLineNumber; - int lineNumber = message->GetLineNumber(); - ssLineNumber << lineNumber; - exceptionEvent.compound["linenumber"] = Data(ssLineNumber.str()); - - int startColumn = message->GetStartColumn(); - int endColumn = message->GetEndColumn(); - std::stringstream ssUnderline; - for (int i = 0; i < startColumn; i++) - ssUnderline << " "; - for (int i = startColumn; i < endColumn; i++) - ssUnderline << "^"; - exceptionEvent.compound["sourcemark"] = Data(ssUnderline.str(), Data::VERBATIM); - - std::string stackTrace(*v8::String::AsciiValue(tryCatch.StackTrace())); - exceptionEvent.compound["stacktrace"] = Data(stackTrace, Data::VERBATIM); - - } - - _interpreter->receiveInternal(exceptionEvent); - throw(exceptionEvent); - } - - return result; + v8::TryCatch tryCatch; + v8::Handle<v8::String> source = v8::String::New(expr.c_str()); + v8::Handle<v8::Script> script = v8::Script::Compile(source); + + v8::Handle<v8::Value> result; + if (!script.IsEmpty()) + result = script->Run(); + + if (script.IsEmpty() || result.IsEmpty()) { + // throw an exception + assert(tryCatch.HasCaught()); + Event exceptionEvent; + exceptionEvent.name = "error.execution"; + + std::string exceptionString(*v8::String::AsciiValue(tryCatch.Exception())); + exceptionEvent.compound["exception"] = Data(exceptionString, Data::VERBATIM);; + + v8::Handle<v8::Message> message = tryCatch.Message(); + if (!message.IsEmpty()) { + std::string filename(*v8::String::AsciiValue(message->GetScriptResourceName())); + exceptionEvent.compound["filename"] = Data(filename, Data::VERBATIM); + + std::string sourceLine(*v8::String::AsciiValue(message->GetSourceLine())); + exceptionEvent.compound["sourceline"] = Data(sourceLine, Data::VERBATIM); + + std::stringstream ssLineNumber; + int lineNumber = message->GetLineNumber(); + ssLineNumber << lineNumber; + exceptionEvent.compound["linenumber"] = Data(ssLineNumber.str()); + + int startColumn = message->GetStartColumn(); + int endColumn = message->GetEndColumn(); + std::stringstream ssUnderline; + for (int i = 0; i < startColumn; i++) + ssUnderline << " "; + for (int i = startColumn; i < endColumn; i++) + ssUnderline << "^"; + exceptionEvent.compound["sourcemark"] = Data(ssUnderline.str(), Data::VERBATIM); + + std::string stackTrace(*v8::String::AsciiValue(tryCatch.StackTrace())); + exceptionEvent.compound["stacktrace"] = Data(stackTrace, Data::VERBATIM); + + } + + _interpreter->receiveInternal(exceptionEvent); + throw(exceptionEvent); + } + + return result; } }
\ No newline at end of file diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h index 994ed18..deee58c 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h @@ -10,76 +10,78 @@ #endif namespace uscxml { - class Event; - class Data; - class V8SCXMLDOM; +class Event; +class Data; +class V8SCXMLDOM; } namespace uscxml { class V8DataModel : public DataModel { public: - V8DataModel(); - virtual ~V8DataModel(); - virtual DataModel* create(Interpreter* interpreter); - - virtual std::set<std::string> getNames() { + V8DataModel(); + virtual ~V8DataModel(); + virtual DataModel* create(Interpreter* interpreter); + + virtual std::set<std::string> getNames() { std::set<std::string> names; names.insert("ecmascript"); return names; } - virtual void initialize(); - virtual void setSessionId(const std::string& sessionId); - virtual void setName(const std::string& name); - virtual void setEvent(const Event& event); + virtual void initialize(); + virtual void setSessionId(const std::string& sessionId); + virtual void setName(const std::string& name); + virtual void setEvent(const Event& event); + + virtual void registerIOProcessor(const std::string& name, IOProcessor* ioprocessor); - virtual bool validate(const std::string& location, const std::string& schema); + virtual bool validate(const std::string& location, const std::string& schema); - virtual uint32_t getLength(const std::string& expr); - virtual void pushContext(); - virtual void popContext(); + virtual uint32_t getLength(const std::string& expr); + virtual void pushContext(); + virtual void popContext(); - virtual void eval(const std::string& expr); - virtual void assign(const std::string& location, const std::string& expr); - virtual void assign(const std::string& location, const Data& data); + virtual void eval(const std::string& expr); + virtual void assign(const std::string& location, const std::string& expr); + virtual void assign(const std::string& location, const Data& data); - virtual Data getStringAsData(const std::string& content); - virtual Data getValueAsData(const v8::Handle<v8::Value>& value); - - virtual std::string evalAsString(const std::string& expr); - virtual bool evalAsBool(const std::string& expr); + virtual Data getStringAsData(const std::string& content); + virtual Data getValueAsData(const v8::Handle<v8::Value>& value); - static v8::Handle<v8::Value> jsGetEventName(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> jsGetEventType(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> jsGetEventSendId(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> jsGetEventOrigin(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> jsGetEventOriginType(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> jsGetEventInvokeId(v8::Local<v8::String> property, - const v8::AccessorInfo &info); + virtual std::string evalAsString(const std::string& expr); + virtual bool evalAsBool(const std::string& expr); - static v8::Handle<v8::Value> jsIn(const v8::Arguments& args); - static v8::Handle<v8::Value> jsPrint(const v8::Arguments& args); + static v8::Handle<v8::Value> jsGetEventName(v8::Local<v8::String> property, + const v8::AccessorInfo &info); + static v8::Handle<v8::Value> jsGetEventType(v8::Local<v8::String> property, + const v8::AccessorInfo &info); + static v8::Handle<v8::Value> jsGetEventSendId(v8::Local<v8::String> property, + const v8::AccessorInfo &info); + static v8::Handle<v8::Value> jsGetEventOrigin(v8::Local<v8::String> property, + const v8::AccessorInfo &info); + static v8::Handle<v8::Value> jsGetEventOriginType(v8::Local<v8::String> property, + const v8::AccessorInfo &info); + static v8::Handle<v8::Value> jsGetEventInvokeId(v8::Local<v8::String> property, + const v8::AccessorInfo &info); + + static v8::Handle<v8::Value> jsIn(const v8::Arguments& args); + static v8::Handle<v8::Value> jsPrint(const v8::Arguments& args); protected: - std::list<v8::Persistent<v8::Context> > _contexts; - Interpreter* _interpreter; + std::list<v8::Persistent<v8::Context> > _contexts; + Interpreter* _interpreter; std::string _sessionId; std::string _name; - - Event _event; - v8::Persistent<v8::ObjectTemplate> _globalTemplate; - v8::Persistent<v8::ObjectTemplate> _eventTemplate; - v8::Handle<v8::Value> evalAsValue(const std::string& expr); - virtual v8::Handle<v8::Value> getDataAsValue(const Data& data); + Event _event; + v8::Persistent<v8::ObjectTemplate> _globalTemplate; + v8::Persistent<v8::ObjectTemplate> _eventTemplate; + + v8::Handle<v8::Value> evalAsValue(const std::string& expr); + virtual v8::Handle<v8::Value> getDataAsValue(const Data& data); }; diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLDOM.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLDOM.cpp index 6452330..585bdd7 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLDOM.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLDOM.cpp @@ -14,206 +14,206 @@ assert(args[0]->type1()); \ assert(args[1]->type2()); namespace uscxml { - - using namespace Arabica::DOM; - using namespace Arabica::XPath; - - V8SCXMLDOM::V8SCXMLDOM() { + +using namespace Arabica::DOM; +using namespace Arabica::XPath; + +V8SCXMLDOM::V8SCXMLDOM() { +} + +v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::getDocument(Arabica::DOM::Document<std::string>& document) { + v8::Handle<v8::ObjectTemplate> documentTmpl = v8::ObjectTemplate::New(); + documentTmpl->Set(v8::String::New("createElement"), v8::FunctionTemplate::New(jsDocumentCreateElement, v8::External::New(reinterpret_cast<void*>(&document)))); + documentTmpl->Set(v8::String::New("evaluate"), v8::FunctionTemplate::New(jsDocumentEvaluate, v8::External::New(reinterpret_cast<void*>(&document)))); + return documentTmpl; +} + +v8::Handle<v8::Value> V8SCXMLDOM::jsDocumentCreateElement(const v8::Arguments& args) { + assert(!args.Data().IsEmpty()); + assert(args.Data()->IsExternal()); + + ASSERT_ARGS1(args, IsString) + + Document<std::string>* document = static_cast<Document<std::string>*>(v8::External::Unwrap(args.Data())); + v8::Persistent<v8::Object> elementJS = v8::Persistent<v8::Object>::New(getElementTmpl()->NewInstance()); + + v8::String::AsciiValue tagName(args[0]); + Element<std::string>* element = new Element<std::string>(document->createElement(*tagName)); + + elementJS->SetInternalField(0, v8::External::New(element)); + elementJS.MakeWeak(NULL, jsElementDestructor); + return elementJS; +} + +v8::Handle<v8::Value> V8SCXMLDOM::jsDocumentEvaluate(const v8::Arguments& args) { + assert(!args.Data().IsEmpty()); + assert(args.Data()->IsExternal()); + + assert(args.Length() > 0); + assert(args[0]->IsString()); + + + Document<std::string>* document = static_cast<Document<std::string>*>(v8::External::Unwrap(args.Data())); + Node<std::string> context; + if (args.Length() > 1) { + assert(args[1]->ToObject()->InternalFieldCount() == 1); + context = *static_cast<Node<std::string>*>(v8::Local<v8::External>::Cast(args[1]->ToObject()->GetInternalField(0))->Value()); + } else { + context = *document; } + v8::String::AsciiValue xpathExpr(args[0]); + XPath<std::string> xpath; + XPathValue<std::string>* xpathValue = new XPathValue<std::string>(xpath.evaluate(*xpathExpr, context)); - v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::getDocument(Arabica::DOM::Document<std::string>& document) { - v8::Handle<v8::ObjectTemplate> documentTmpl = v8::ObjectTemplate::New(); - documentTmpl->Set(v8::String::New("createElement"), v8::FunctionTemplate::New(jsDocumentCreateElement, v8::External::New(reinterpret_cast<void*>(&document)))); - documentTmpl->Set(v8::String::New("evaluate"), v8::FunctionTemplate::New(jsDocumentEvaluate, v8::External::New(reinterpret_cast<void*>(&document)))); - return documentTmpl; - } - - v8::Handle<v8::Value> V8SCXMLDOM::jsDocumentCreateElement(const v8::Arguments& args) { - assert(!args.Data().IsEmpty()); - assert(args.Data()->IsExternal()); - - ASSERT_ARGS1(args, IsString) - - Document<std::string>* document = static_cast<Document<std::string>*>(v8::External::Unwrap(args.Data())); - v8::Persistent<v8::Object> elementJS = v8::Persistent<v8::Object>::New(getElementTmpl()->NewInstance()); - - v8::String::AsciiValue tagName(args[0]); - Element<std::string>* element = new Element<std::string>(document->createElement(*tagName)); - - elementJS->SetInternalField(0, v8::External::New(element)); - elementJS.MakeWeak(NULL, jsElementDestructor); - return elementJS; - } - - v8::Handle<v8::Value> V8SCXMLDOM::jsDocumentEvaluate(const v8::Arguments& args) { - assert(!args.Data().IsEmpty()); - assert(args.Data()->IsExternal()); - - assert(args.Length() > 0); - assert(args[0]->IsString()); - - - Document<std::string>* document = static_cast<Document<std::string>*>(v8::External::Unwrap(args.Data())); - Node<std::string> context; - if (args.Length() > 1) { - assert(args[1]->ToObject()->InternalFieldCount() == 1); - context = *static_cast<Node<std::string>*>(v8::Local<v8::External>::Cast(args[1]->ToObject()->GetInternalField(0))->Value()); - } else { - context = *document; - } - v8::String::AsciiValue xpathExpr(args[0]); - XPath<std::string> xpath; - XPathValue<std::string>* xpathValue = new XPathValue<std::string>(xpath.evaluate(*xpathExpr, context)); - - v8::Persistent<v8::Object> xpathValueJS = v8::Persistent<v8::Object>::New(getXPathValueTmpl()->NewInstance()); - xpathValueJS->SetInternalField(0, v8::External::New(xpathValue)); - xpathValueJS.MakeWeak(NULL, jsXPathValueDestructor); - return xpathValueJS; - } - - v8::Handle<v8::Value> V8SCXMLDOM::jsElementTagName(v8::Local<v8::String> property, const v8::AccessorInfo &info) { - Element<std::string>* element = static_cast<Element<std::string>*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); - return v8::String::New(element->getTagName().c_str()); - } - - v8::Handle<v8::Value> V8SCXMLDOM::jsElementGetAttribute(const v8::Arguments& args) { - assert(!args.Data().IsEmpty()); - assert(args.Data()->IsExternal()); - - ASSERT_ARGS1(args, IsString); - - Element<std::string>* element = static_cast<Element<std::string>*>(v8::External::Unwrap(args.Data())); - - v8::String::AsciiValue attribute(args[0]); - if (element->hasAttribute(*attribute)) { - return v8::String::New(element->getAttribute(*attribute).c_str()); - } - return v8::String::New(""); - } - - v8::Handle<v8::Value> V8SCXMLDOM::jsElementSetAttribute(const v8::Arguments& args) { - v8::Local<v8::Object> self = args.Holder(); - assert(self->InternalFieldCount() == 1); - - ASSERT_ARGS2(args, IsString, IsString); - - v8::String::AsciiValue attribute(args[0]); - v8::String::AsciiValue value(args[1]); - - Element<std::string>* element = static_cast<Element<std::string>*>(v8::External::Unwrap(self->GetInternalField(0))); - element->setAttribute(*attribute, *value); - return v8::Undefined(); - } - - v8::Handle<v8::Value> V8SCXMLDOM::jsXPathValueAsNodeSet(const v8::Arguments& args) { - v8::Local<v8::Object> self = args.Holder(); - assert(self->InternalFieldCount() == 1); - XPathValue<std::string>* xPathValue = static_cast<XPathValue<std::string>*>(v8::External::Unwrap(self->GetInternalField(0))); - - v8::Persistent<v8::Object> nodeSetJS = v8::Persistent<v8::Object>::New(getNodeSetTmpl()->NewInstance()); - nodeSetJS->SetInternalField(0, v8::External::New(new NodeSet<std::string>(xPathValue->asNodeSet()))); - nodeSetJS.MakeWeak(NULL, jsNodeSetDestructor); - return nodeSetJS; - - } - - void V8SCXMLDOM::jsNodeSetDestructor(v8::Persistent<v8::Value> object, void* data) { - NodeSet<std::string>* nodeSet = static_cast<NodeSet<std::string>*>(v8::Local<v8::External>::Cast(object->ToObject()->GetInternalField(0))->Value()); - delete nodeSet; - } - - void V8SCXMLDOM::jsNodeDestructor(v8::Persistent<v8::Value> object, void* data) { - Node<std::string>* node = static_cast<Node<std::string>*>(v8::Local<v8::External>::Cast(object->ToObject()->GetInternalField(0))->Value()); - delete node; - } - - void V8SCXMLDOM::jsXPathValueDestructor(v8::Persistent<v8::Value> object, void* data) { - XPathValue<std::string>* xPathValue = static_cast<XPathValue<std::string>*>(v8::Local<v8::External>::Cast(object->ToObject()->GetInternalField(0))->Value()); - delete xPathValue; - } - - void V8SCXMLDOM::jsElementDestructor(v8::Persistent<v8::Value> object, void* data) { - Element<std::string>* element = static_cast<Element<std::string>*>(v8::Local<v8::External>::Cast(object->ToObject()->GetInternalField(0))->Value()); - delete element; - } - - v8::Handle<v8::Value> V8SCXMLDOM::jsNodeSetGetIndex(uint32_t index, const v8::AccessorInfo &info) { - v8::Local<v8::Object> self = info.Holder(); - assert(self->InternalFieldCount() == 1); - NodeSet<std::string>* nodeSet = static_cast<NodeSet<std::string>*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); - - if (nodeSet->size() >= index) { - Node<std::string>* node = new Node<std::string>((*nodeSet)[index]); - v8::Persistent<v8::Object> nodeJS = v8::Persistent<v8::Object>::New(getNodeTmpl()->NewInstance()); - nodeJS->SetInternalField(0, v8::External::New(node)); - nodeJS.MakeWeak(NULL, jsNodeDestructor); - return nodeJS; - } - return v8::Undefined(); - } - - v8::Handle<v8::Value> V8SCXMLDOM::jsNodeSetLength(const v8::Arguments& args) { - v8::Local<v8::Object> self = args.Holder(); - assert(self->InternalFieldCount() == 1); - NodeSet<std::string>* nodeSet = static_cast<NodeSet<std::string>*>(v8::External::Unwrap(self->GetInternalField(0))); - return v8::Integer::New(nodeSet->size()); - } - - v8::Handle<v8::Value> V8SCXMLDOM::jsNodeAppendChild(const v8::Arguments& args) { - v8::Local<v8::Object> self = args.Holder(); - assert(self->InternalFieldCount() == 1); - Node<std::string>* node = static_cast<Node<std::string>*>(v8::External::Unwrap(self->GetInternalField(0))); - - assert(args.Length() == 1); - assert(args[0]->IsObject()); - - Node<std::string>* childToAppend = static_cast<Node<std::string>*>(v8::External::Unwrap(args[0]->ToObject()->GetInternalField(0))); - node->appendChild(*childToAppend); - - return v8::Undefined(); - } - - v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::xPathValueTmpl; - v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::getXPathValueTmpl() { - if (xPathValueTmpl.IsEmpty()) { - xPathValueTmpl = v8::ObjectTemplate::New(); - xPathValueTmpl->SetInternalFieldCount(1); - xPathValueTmpl->Set(v8::String::New("asNodeSet"), v8::FunctionTemplate::New(jsXPathValueAsNodeSet)); - } - return xPathValueTmpl; - } - - v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::nodeSetTmpl; - v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::getNodeSetTmpl() { - if (nodeSetTmpl.IsEmpty()) { - nodeSetTmpl = v8::ObjectTemplate::New(); - nodeSetTmpl->SetInternalFieldCount(1); - nodeSetTmpl->SetIndexedPropertyHandler(jsNodeSetGetIndex); - nodeSetTmpl->Set(v8::String::New("length"), v8::FunctionTemplate::New(jsNodeSetLength)); - } - return nodeSetTmpl; - } - - v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::nodeTmpl; - v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::getNodeTmpl() { - if (nodeTmpl.IsEmpty()) { - nodeTmpl = v8::ObjectTemplate::New(); - nodeTmpl->SetInternalFieldCount(1); - nodeTmpl->Set(v8::String::New("appendChild"), v8::FunctionTemplate::New(jsNodeAppendChild)); - } - return nodeTmpl; - } - - v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::elementTmpl; - v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::getElementTmpl() { - if (elementTmpl.IsEmpty()) { - elementTmpl = v8::ObjectTemplate::New(); - elementTmpl->SetAccessor(v8::String::New("tagName"), V8SCXMLDOM::jsElementTagName); - elementTmpl->Set(v8::String::New("getAttribute"), v8::FunctionTemplate::New(jsElementGetAttribute)); - elementTmpl->Set(v8::String::New("setAttribute"), v8::FunctionTemplate::New(jsElementSetAttribute)); - elementTmpl->SetInternalFieldCount(1); - } - return elementTmpl; - } + v8::Persistent<v8::Object> xpathValueJS = v8::Persistent<v8::Object>::New(getXPathValueTmpl()->NewInstance()); + xpathValueJS->SetInternalField(0, v8::External::New(xpathValue)); + xpathValueJS.MakeWeak(NULL, jsXPathValueDestructor); + return xpathValueJS; +} + +v8::Handle<v8::Value> V8SCXMLDOM::jsElementTagName(v8::Local<v8::String> property, const v8::AccessorInfo &info) { + Element<std::string>* element = static_cast<Element<std::string>*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); + return v8::String::New(element->getTagName().c_str()); +} + +v8::Handle<v8::Value> V8SCXMLDOM::jsElementGetAttribute(const v8::Arguments& args) { + assert(!args.Data().IsEmpty()); + assert(args.Data()->IsExternal()); + + ASSERT_ARGS1(args, IsString); + + Element<std::string>* element = static_cast<Element<std::string>*>(v8::External::Unwrap(args.Data())); + + v8::String::AsciiValue attribute(args[0]); + if (element->hasAttribute(*attribute)) { + return v8::String::New(element->getAttribute(*attribute).c_str()); + } + return v8::String::New(""); +} + +v8::Handle<v8::Value> V8SCXMLDOM::jsElementSetAttribute(const v8::Arguments& args) { + v8::Local<v8::Object> self = args.Holder(); + assert(self->InternalFieldCount() == 1); + + ASSERT_ARGS2(args, IsString, IsString); + + v8::String::AsciiValue attribute(args[0]); + v8::String::AsciiValue value(args[1]); + + Element<std::string>* element = static_cast<Element<std::string>*>(v8::External::Unwrap(self->GetInternalField(0))); + element->setAttribute(*attribute, *value); + return v8::Undefined(); +} + +v8::Handle<v8::Value> V8SCXMLDOM::jsXPathValueAsNodeSet(const v8::Arguments& args) { + v8::Local<v8::Object> self = args.Holder(); + assert(self->InternalFieldCount() == 1); + XPathValue<std::string>* xPathValue = static_cast<XPathValue<std::string>*>(v8::External::Unwrap(self->GetInternalField(0))); + + v8::Persistent<v8::Object> nodeSetJS = v8::Persistent<v8::Object>::New(getNodeSetTmpl()->NewInstance()); + nodeSetJS->SetInternalField(0, v8::External::New(new NodeSet<std::string>(xPathValue->asNodeSet()))); + nodeSetJS.MakeWeak(NULL, jsNodeSetDestructor); + return nodeSetJS; + +} + +void V8SCXMLDOM::jsNodeSetDestructor(v8::Persistent<v8::Value> object, void* data) { + NodeSet<std::string>* nodeSet = static_cast<NodeSet<std::string>*>(v8::Local<v8::External>::Cast(object->ToObject()->GetInternalField(0))->Value()); + delete nodeSet; +} + +void V8SCXMLDOM::jsNodeDestructor(v8::Persistent<v8::Value> object, void* data) { + Node<std::string>* node = static_cast<Node<std::string>*>(v8::Local<v8::External>::Cast(object->ToObject()->GetInternalField(0))->Value()); + delete node; +} + +void V8SCXMLDOM::jsXPathValueDestructor(v8::Persistent<v8::Value> object, void* data) { + XPathValue<std::string>* xPathValue = static_cast<XPathValue<std::string>*>(v8::Local<v8::External>::Cast(object->ToObject()->GetInternalField(0))->Value()); + delete xPathValue; +} + +void V8SCXMLDOM::jsElementDestructor(v8::Persistent<v8::Value> object, void* data) { + Element<std::string>* element = static_cast<Element<std::string>*>(v8::Local<v8::External>::Cast(object->ToObject()->GetInternalField(0))->Value()); + delete element; +} + +v8::Handle<v8::Value> V8SCXMLDOM::jsNodeSetGetIndex(uint32_t index, const v8::AccessorInfo &info) { + v8::Local<v8::Object> self = info.Holder(); + assert(self->InternalFieldCount() == 1); + NodeSet<std::string>* nodeSet = static_cast<NodeSet<std::string>*>(v8::Local<v8::External>::Cast(info.Holder()->GetInternalField(0))->Value()); + + if (nodeSet->size() >= index) { + Node<std::string>* node = new Node<std::string>((*nodeSet)[index]); + v8::Persistent<v8::Object> nodeJS = v8::Persistent<v8::Object>::New(getNodeTmpl()->NewInstance()); + nodeJS->SetInternalField(0, v8::External::New(node)); + nodeJS.MakeWeak(NULL, jsNodeDestructor); + return nodeJS; + } + return v8::Undefined(); +} + +v8::Handle<v8::Value> V8SCXMLDOM::jsNodeSetLength(const v8::Arguments& args) { + v8::Local<v8::Object> self = args.Holder(); + assert(self->InternalFieldCount() == 1); + NodeSet<std::string>* nodeSet = static_cast<NodeSet<std::string>*>(v8::External::Unwrap(self->GetInternalField(0))); + return v8::Integer::New(nodeSet->size()); +} + +v8::Handle<v8::Value> V8SCXMLDOM::jsNodeAppendChild(const v8::Arguments& args) { + v8::Local<v8::Object> self = args.Holder(); + assert(self->InternalFieldCount() == 1); + Node<std::string>* node = static_cast<Node<std::string>*>(v8::External::Unwrap(self->GetInternalField(0))); + + assert(args.Length() == 1); + assert(args[0]->IsObject()); + + Node<std::string>* childToAppend = static_cast<Node<std::string>*>(v8::External::Unwrap(args[0]->ToObject()->GetInternalField(0))); + node->appendChild(*childToAppend); + + return v8::Undefined(); +} + +v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::xPathValueTmpl; +v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::getXPathValueTmpl() { + if (xPathValueTmpl.IsEmpty()) { + xPathValueTmpl = v8::ObjectTemplate::New(); + xPathValueTmpl->SetInternalFieldCount(1); + xPathValueTmpl->Set(v8::String::New("asNodeSet"), v8::FunctionTemplate::New(jsXPathValueAsNodeSet)); + } + return xPathValueTmpl; +} + +v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::nodeSetTmpl; +v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::getNodeSetTmpl() { + if (nodeSetTmpl.IsEmpty()) { + nodeSetTmpl = v8::ObjectTemplate::New(); + nodeSetTmpl->SetInternalFieldCount(1); + nodeSetTmpl->SetIndexedPropertyHandler(jsNodeSetGetIndex); + nodeSetTmpl->Set(v8::String::New("length"), v8::FunctionTemplate::New(jsNodeSetLength)); + } + return nodeSetTmpl; +} + +v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::nodeTmpl; +v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::getNodeTmpl() { + if (nodeTmpl.IsEmpty()) { + nodeTmpl = v8::ObjectTemplate::New(); + nodeTmpl->SetInternalFieldCount(1); + nodeTmpl->Set(v8::String::New("appendChild"), v8::FunctionTemplate::New(jsNodeAppendChild)); + } + return nodeTmpl; +} + +v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::elementTmpl; +v8::Handle<v8::ObjectTemplate> V8SCXMLDOM::getElementTmpl() { + if (elementTmpl.IsEmpty()) { + elementTmpl = v8::ObjectTemplate::New(); + elementTmpl->SetAccessor(v8::String::New("tagName"), V8SCXMLDOM::jsElementTagName); + elementTmpl->Set(v8::String::New("getAttribute"), v8::FunctionTemplate::New(jsElementGetAttribute)); + elementTmpl->Set(v8::String::New("setAttribute"), v8::FunctionTemplate::New(jsElementSetAttribute)); + elementTmpl->SetInternalFieldCount(1); + } + return elementTmpl; +} }
\ No newline at end of file diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLDOM.h b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLDOM.h index c513e48..36c6b15 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLDOM.h +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLDOM.h @@ -14,46 +14,46 @@ class V8SCXMLDOM { public: V8SCXMLDOM(); virtual ~V8SCXMLDOM() {}; - - static v8::Handle<v8::ObjectTemplate> getDocument(Arabica::DOM::Document<std::string>& document); - static v8::Handle<v8::Value> jsDocumentCreateElement(const v8::Arguments& args); - static v8::Handle<v8::Value> jsDocumentEvaluate(const v8::Arguments& args); - - static v8::Handle<v8::Value> jsElementTagName(v8::Local<v8::String> property, const v8::AccessorInfo &info); - static v8::Handle<v8::Value> jsElementGetAttribute(const v8::Arguments& args); - static v8::Handle<v8::Value> jsElementSetAttribute(const v8::Arguments& args); - static void jsElementDestructor(v8::Persistent<v8::Value> object, void* data); - - static v8::Handle<v8::Value> jsXPathValueAsNodeSet(const v8::Arguments& args); - static void jsXPathValueDestructor(v8::Persistent<v8::Value> object, void* data); - - static v8::Handle<v8::Value> jsNodeSetGetIndex(uint32_t index, const v8::AccessorInfo &info); - static v8::Handle<v8::Value> jsNodeSetLength(const v8::Arguments& args); - static void jsNodeSetDestructor(v8::Persistent<v8::Value> object, void* data); - - static v8::Handle<v8::Value> jsNodeAppendChild(const v8::Arguments& args); - static void jsNodeDestructor(v8::Persistent<v8::Value> object, void* data); - - static v8::Handle<v8::ObjectTemplate> getXPathValueTmpl(); - static v8::Handle<v8::ObjectTemplate> getNodeSetTmpl(); - static v8::Handle<v8::ObjectTemplate> getNodeTmpl(); - static v8::Handle<v8::ObjectTemplate> getElementTmpl(); - - static v8::Handle<v8::ObjectTemplate> xPathValueTmpl; - static v8::Handle<v8::ObjectTemplate> nodeSetTmpl; - static v8::Handle<v8::ObjectTemplate> nodeTmpl; - static v8::Handle<v8::ObjectTemplate> elementTmpl; + + static v8::Handle<v8::ObjectTemplate> getDocument(Arabica::DOM::Document<std::string>& document); + static v8::Handle<v8::Value> jsDocumentCreateElement(const v8::Arguments& args); + static v8::Handle<v8::Value> jsDocumentEvaluate(const v8::Arguments& args); + + static v8::Handle<v8::Value> jsElementTagName(v8::Local<v8::String> property, const v8::AccessorInfo &info); + static v8::Handle<v8::Value> jsElementGetAttribute(const v8::Arguments& args); + static v8::Handle<v8::Value> jsElementSetAttribute(const v8::Arguments& args); + static void jsElementDestructor(v8::Persistent<v8::Value> object, void* data); + + static v8::Handle<v8::Value> jsXPathValueAsNodeSet(const v8::Arguments& args); + static void jsXPathValueDestructor(v8::Persistent<v8::Value> object, void* data); + + static v8::Handle<v8::Value> jsNodeSetGetIndex(uint32_t index, const v8::AccessorInfo &info); + static v8::Handle<v8::Value> jsNodeSetLength(const v8::Arguments& args); + static void jsNodeSetDestructor(v8::Persistent<v8::Value> object, void* data); + + static v8::Handle<v8::Value> jsNodeAppendChild(const v8::Arguments& args); + static void jsNodeDestructor(v8::Persistent<v8::Value> object, void* data); + + static v8::Handle<v8::ObjectTemplate> getXPathValueTmpl(); + static v8::Handle<v8::ObjectTemplate> getNodeSetTmpl(); + static v8::Handle<v8::ObjectTemplate> getNodeTmpl(); + static v8::Handle<v8::ObjectTemplate> getElementTmpl(); + + static v8::Handle<v8::ObjectTemplate> xPathValueTmpl; + static v8::Handle<v8::ObjectTemplate> nodeSetTmpl; + static v8::Handle<v8::ObjectTemplate> nodeTmpl; + static v8::Handle<v8::ObjectTemplate> elementTmpl; }; class V8Node { }; - + class V8DOMDocument { - V8DOMDocument(); - virtual ~V8DOMDocument(); - - v8::Handle<v8::Array> jsChildNodes(); + V8DOMDocument(); + virtual ~V8DOMDocument(); + + v8::Handle<v8::Array> jsChildNodes(); }; } diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp new file mode 100644 index 0000000..77f0b66 --- /dev/null +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp @@ -0,0 +1,103 @@ +#include "uscxml/Common.h" +#include "SWIDataModel.h" +#include "uscxml/Message.h" +#include <glog/logging.h> + +#ifdef BUILD_AS_PLUGINS +#include <Pluma/Connector.hpp> +#endif + +namespace uscxml { + +#ifdef BUILD_AS_PLUGINS +PLUMA_CONNECTOR +bool connect(pluma::Host& host) { + host.add( new SWIDataModelProvider() ); + return true; +} +#endif + +SWIDataModel::SWIDataModel() { +} + +DataModel* SWIDataModel::create(Interpreter* interpreter) { + SWIDataModel* dm = new SWIDataModel(); + dm->_interpreter = interpreter; + const char* swiPath = SWI_LIBRARY_PATH; + dm->_plEngine = new PlEngine((char*)swiPath); + return dm; +} + +void SWIDataModel::registerIOProcessor(const std::string& name, IOProcessor* ioprocessor) { + std::cout << "SWIDataModel::registerIOProcessor" << std::endl; +} + +void SWIDataModel::setSessionId(const std::string& sessionId) { + std::cout << "SWIDataModel::setSessionId" << std::endl; + _sessionId = sessionId; +} + +void SWIDataModel::setName(const std::string& name) { + std::cout << "SWIDataModel::setName" << std::endl; + _name = name; +} + +SWIDataModel::~SWIDataModel() { +} + +void SWIDataModel::pushContext() { + std::cout << "SWIDataModel::pushContext" << std::endl; +} + +void SWIDataModel::popContext() { + std::cout << "SWIDataModel::popContext" << std::endl; +} + +void SWIDataModel::initialize() { + std::cout << "SWIDataModel::initialize" << std::endl; +} + +void SWIDataModel::setEvent(const Event& event) { + std::cout << "SWIDataModel::setEvent" << std::endl; + _event = event; +} + +Data SWIDataModel::getStringAsData(const std::string& content) { + std::cout << "SWIDataModel::getStringAsData" << std::endl; + Data data; + return data; +} + +bool SWIDataModel::validate(const std::string& location, const std::string& schema) { + std::cout << "SWIDataModel::validate" << std::endl; + return true; +} + +uint32_t SWIDataModel::getLength(const std::string& expr) { + std::cout << "SWIDataModel::getLength" << std::endl; + return 0; +} + +void SWIDataModel::eval(const std::string& expr) { + std::cout << "SWIDataModel::eval" << std::endl; +} + +bool SWIDataModel::evalAsBool(const std::string& expr) { + std::cout << "SWIDataModel::evalAsBool" << std::endl; + return true; +} + +std::string SWIDataModel::evalAsString(const std::string& expr) { + std::cout << "SWIDataModel::evalAsString" << std::endl; + return std::string(""); +} + +void SWIDataModel::assign(const std::string& location, const Data& data) { + std::cout << "SWIDataModel::assign" << std::endl; +} + +void SWIDataModel::assign(const std::string& location, const std::string& expr) { + std::cout << "SWIDataModel::assign" << std::endl; +} + +}
\ No newline at end of file diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h new file mode 100644 index 0000000..16dee3c --- /dev/null +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h @@ -0,0 +1,66 @@ +#ifndef SWIDATAMODEL_H_KN8TWG0V +#define SWIDATAMODEL_H_KN8TWG0V + +#include "uscxml/Interpreter.h" +#include <list> +#include <SWI-cpp.h> + +#ifdef BUILD_AS_PLUGINS +#include "uscxml/plugins/Plugins.h" +#endif + +namespace uscxml { + +class SWIDataModel : public DataModel { +public: + SWIDataModel(); + virtual ~SWIDataModel(); + virtual DataModel* create(Interpreter* interpreter); + + virtual std::set<std::string> getNames() { + std::set<std::string> names; + names.insert("prolog"); + return names; + } + + virtual void initialize(); + virtual void setSessionId(const std::string& sessionId); + virtual void setName(const std::string& name); + virtual void setEvent(const Event& event); + + virtual void registerIOProcessor(const std::string& name, IOProcessor* ioprocessor); + + virtual bool validate(const std::string& location, const std::string& schema); + + virtual uint32_t getLength(const std::string& expr); + virtual void pushContext(); + virtual void popContext(); + + virtual void eval(const std::string& expr); + virtual void assign(const std::string& location, const std::string& expr); + virtual void assign(const std::string& location, const Data& data); + + virtual Data getStringAsData(const std::string& content); + + virtual std::string evalAsString(const std::string& expr); + virtual bool evalAsBool(const std::string& expr); + + +protected: + Interpreter* _interpreter; + + std::string _sessionId; + std::string _name; + + Event _event; + PlEngine* _plEngine; + +}; + +#ifdef BUILD_AS_PLUGINS +PLUMA_INHERIT_PROVIDER(SWIDataModel, DataModel); +#endif + +} + +#endif /* end of include guard: SWIDATAMODEL_H_KN8TWG0V */ diff --git a/src/uscxml/plugins/invoker/modality/MMIComponent.cpp b/src/uscxml/plugins/invoker/modality/MMIComponent.cpp index 0655806..170f4bc 100644 --- a/src/uscxml/plugins/invoker/modality/MMIComponent.cpp +++ b/src/uscxml/plugins/invoker/modality/MMIComponent.cpp @@ -2,41 +2,41 @@ #include "uscxml/Interpreter.h" namespace uscxml { - + MMIComponent::MMIComponent() { } - + MMIComponent::~MMIComponent() { }; - + Invoker* MMIComponent::create(Interpreter* interpreter) { - MMIComponent* invoker = new MMIComponent(); - invoker->_interpreter = interpreter; - return invoker; + MMIComponent* invoker = new MMIComponent(); + invoker->_interpreter = interpreter; + return invoker; } Data MMIComponent::getDataModelVariables() { - Data data; - return data; + Data data; + return data; } void MMIComponent::send(SendRequest& req) { - + } void MMIComponent::cancel(const std::string sendId) { - assert(false); + assert(false); } void MMIComponent::sendToParent(SendRequest& req) { - req.invokeid = _invokeId; - assert(false); + req.invokeid = _invokeId; + assert(false); } void MMIComponent::invoke(InvokeRequest& req) { - _invokeId = req.invokeid; - + _invokeId = req.invokeid; + } }
\ No newline at end of file diff --git a/src/uscxml/plugins/invoker/modality/MMIComponent.h b/src/uscxml/plugins/invoker/modality/MMIComponent.h index a83775f..96d796b 100644 --- a/src/uscxml/plugins/invoker/modality/MMIComponent.h +++ b/src/uscxml/plugins/invoker/modality/MMIComponent.h @@ -9,27 +9,27 @@ class Interpreter; class MMIComponent : public Invoker { public: - - enum State { - PAUSED, - RUNNING, - IDLE, - TERMINATED + + enum State { + PAUSED, + RUNNING, + IDLE, + TERMINATED }; MMIComponent(); - virtual ~MMIComponent(); - virtual Invoker* create(Interpreter* interpreter); - - virtual Data getDataModelVariables(); - virtual void send(SendRequest& req); - virtual void cancel(const std::string sendId); - virtual void invoke(InvokeRequest& req); - virtual void sendToParent(SendRequest& req); + virtual ~MMIComponent(); + virtual Invoker* create(Interpreter* interpreter); + + virtual Data getDataModelVariables(); + virtual void send(SendRequest& req); + virtual void cancel(const std::string sendId); + virtual void invoke(InvokeRequest& req); + virtual void sendToParent(SendRequest& req); protected: - std::string _invokeId; - Interpreter* _interpreter; + std::string _invokeId; + Interpreter* _interpreter; State _state; }; @@ -39,31 +39,31 @@ protected: class MMICoreMessage { public: - std::string source; - std::string target; - std::string data; - std::string requestId; + std::string source; + std::string target; + std::string data; + std::string requestId; }; class MMICtxMessage : public MMICoreMessage { public: - std::string context; + std::string context; }; class MMIStartMessage : public MMICtxMessage { public: - std::string content; - std::string contentURL; + std::string content; + std::string contentURL; }; class MMISimpleStatusMessage : public MMICtxMessage { public: - std::string status; + std::string status; }; class MMIStatusMessage : public MMISimpleStatusMessage { public: - std::string statusInfo; + std::string statusInfo; }; /** Concrete MMI messages */ @@ -86,7 +86,7 @@ class MMIPrepareRequest : public MMIStartMessage {}; /***/ class MMIExtensionNotification : public MMICtxMessage { - std::string name; + std::string name; }; /***/ diff --git a/src/uscxml/plugins/invoker/modality/UmundoComponent.cpp b/src/uscxml/plugins/invoker/modality/UmundoComponent.cpp index 22dd279..10f23d4 100644 --- a/src/uscxml/plugins/invoker/modality/UmundoComponent.cpp +++ b/src/uscxml/plugins/invoker/modality/UmundoComponent.cpp @@ -2,48 +2,48 @@ #include "uscxml/Interpreter.h" namespace uscxml { - -UmundoComponent::UmundoComponent() { + +UmundoComponent::UmundoComponent() { } - + UmundoComponent::~UmundoComponent() { - delete _invokedInterpreter; + delete _invokedInterpreter; }; - + Invoker* UmundoComponent::create(Interpreter* interpreter) { - UmundoComponent* invoker = new UmundoComponent(); - invoker->_parentInterpreter = interpreter; - return invoker; + UmundoComponent* invoker = new UmundoComponent(); + invoker->_parentInterpreter = interpreter; + return invoker; } Data UmundoComponent::getDataModelVariables() { - Data data; - return data; + Data data; + return data; } void UmundoComponent::send(SendRequest& req) { - assert(false); + assert(false); } void UmundoComponent::cancel(const std::string sendId) { - assert(false); + assert(false); } void UmundoComponent::sendToParent(SendRequest& req) { - req.invokeid = _invokeId; - _parentInterpreter->receive(req); + req.invokeid = _invokeId; + _parentInterpreter->receive(req); } void UmundoComponent::invoke(InvokeRequest& req) { - _invokeId = req.invokeid; - _invokedInterpreter = Interpreter::fromURI(req.src); - DataModel* dataModel = _invokedInterpreter->getDataModel(); - if (dataModel != NULL) { - - } - _invokedInterpreter->setInvoker(this); - _invokedInterpreter->start(); + _invokeId = req.invokeid; + _invokedInterpreter = Interpreter::fromURI(req.src); + DataModel* dataModel = _invokedInterpreter->getDataModel(); + if (dataModel != NULL) { + + } + _invokedInterpreter->setInvoker(this); + _invokedInterpreter->start(); } }
\ No newline at end of file diff --git a/src/uscxml/plugins/invoker/modality/UmundoComponent.h b/src/uscxml/plugins/invoker/modality/UmundoComponent.h index f2c76c4..69b3961 100644 --- a/src/uscxml/plugins/invoker/modality/UmundoComponent.h +++ b/src/uscxml/plugins/invoker/modality/UmundoComponent.h @@ -6,25 +6,25 @@ namespace uscxml { class Interpreter; - + class UmundoComponent : public MMIComponent { public: UmundoComponent(); - virtual ~UmundoComponent(); - virtual Invoker* create(Interpreter* interpreter); - - virtual Data getDataModelVariables(); - virtual void send(SendRequest& req); - virtual void cancel(const std::string sendId); - virtual void invoke(InvokeRequest& req); - virtual void sendToParent(SendRequest& req); + virtual ~UmundoComponent(); + virtual Invoker* create(Interpreter* interpreter); + + virtual Data getDataModelVariables(); + virtual void send(SendRequest& req); + virtual void cancel(const std::string sendId); + virtual void invoke(InvokeRequest& req); + virtual void sendToParent(SendRequest& req); protected: - std::string _invokeId; - Interpreter* _invokedInterpreter; - Interpreter* _parentInterpreter; + std::string _invokeId; + Interpreter* _invokedInterpreter; + Interpreter* _parentInterpreter; }; - + } #endif /* end of include guard: UMUNDOCOMPONENT_H_VMW54W1R */ diff --git a/src/uscxml/plugins/invoker/modality/miles/SpatialAudio.cpp b/src/uscxml/plugins/invoker/modality/miles/SpatialAudio.cpp index 13091ae..acc5c4b 100644 --- a/src/uscxml/plugins/invoker/modality/miles/SpatialAudio.cpp +++ b/src/uscxml/plugins/invoker/modality/miles/SpatialAudio.cpp @@ -14,184 +14,184 @@ namespace uscxml { #ifdef BUILD_AS_PLUGINS PLUMA_CONNECTOR -bool connect(pluma::Host& host){ - host.add( new SpatialAudioProvider() ); - return true; +bool connect(pluma::Host& host) { + host.add( new SpatialAudioProvider() ); + return true; } #endif SpatialAudio::SpatialAudio() { - _audioDevOpen = false; - _audioDev = NULL; - _audioDevIndex = -1; - _pos = new float[3]; - _pos[0] = _pos[1] = _pos[2] = 0.0; - _listener = new float[3]; - _listener[0] = _listener[1] = _listener[2] = 0.0; + _audioDevOpen = false; + _audioDev = NULL; + _audioDevIndex = -1; + _pos = new float[3]; + _pos[0] = _pos[1] = _pos[2] = 0.0; + _listener = new float[3]; + _listener[0] = _listener[1] = _listener[2] = 0.0; } - + SpatialAudio::~SpatialAudio() { }; - + Invoker* SpatialAudio::create(Interpreter* interpreter) { - SpatialAudio* invoker = new SpatialAudio(); - invoker->_interpreter = interpreter; - return invoker; + SpatialAudio* invoker = new SpatialAudio(); + invoker->_interpreter = interpreter; + return invoker; } Data SpatialAudio::getDataModelVariables() { - Data data; + Data data; // data.compound["foo"] = Data("32"); - return data; + return data; } void SpatialAudio::send(SendRequest& req) { - if (!_audioDevOpen) { - _audioDev = miles_audio_device_open(_audioDevIndex, 0, 22050, 2, 1, 0); - if (_audioDev != NULL) { - _audioDevOpen = true; - float rolloffFactor = 0.2; - miles_audio_device_control(_audioDev, MILES_AUDIO_DEVICE_CTRL_SET_ROLLOFF_FACTOR, &rolloffFactor); - } - } - - if (boost::iequals(req.name, "play")) { - if (_audioDevOpen) { - getPosFromParams(req.params, _pos); + if (!_audioDevOpen) { + _audioDev = miles_audio_device_open(_audioDevIndex, 0, 22050, 2, 1, 0); + if (_audioDev != NULL) { + _audioDevOpen = true; + float rolloffFactor = 0.2; + miles_audio_device_control(_audioDev, MILES_AUDIO_DEVICE_CTRL_SET_ROLLOFF_FACTOR, &rolloffFactor); + } + } + + if (boost::iequals(req.name, "play")) { + if (_audioDevOpen) { + getPosFromParams(req.params, _pos); // std::cout << "Source: "; // for (int i = 0; i < 3; i++) { // std::cout << _pos[i] << " "; // } // std::cout << std::endl; - - miles_audio_device_control(_audioDev, MILES_AUDIO_DEVICE_CTRL_SET_POSITION, _pos); - - char* buffer = (char*)malloc(_audioDev->chunk_size); - // skip wav header - _dataStream.seekg(44); - - while(_dataStream.readsome(buffer, _audioDev->chunk_size) != 0) { - miles_audio_device_write(_audioDev, buffer, _audioDev->chunk_size); - } - free(buffer); - } - } else if (boost::iequals(req.name, "move.listener")) { - if (_audioDevOpen) { - getPosFromParams(req.params, _listener); - - std::cout << "Listener: "; - for (int i = 0; i < 3; i++) { - std::cout << _listener[i] << " "; - } - std::cout << std::endl; - - miles_audio_device_control(_audioDev, MILES_AUDIO_DEVICE_CTRL_SET_LISTENER_POS, _listener); - - } - } + + miles_audio_device_control(_audioDev, MILES_AUDIO_DEVICE_CTRL_SET_POSITION, _pos); + + char* buffer = (char*)malloc(_audioDev->chunk_size); + // skip wav header + _dataStream.seekg(44); + + while(_dataStream.readsome(buffer, _audioDev->chunk_size) != 0) { + miles_audio_device_write(_audioDev, buffer, _audioDev->chunk_size); + } + free(buffer); + } + } else if (boost::iequals(req.name, "move.listener")) { + if (_audioDevOpen) { + getPosFromParams(req.params, _listener); + + std::cout << "Listener: "; + for (int i = 0; i < 3; i++) { + std::cout << _listener[i] << " "; + } + std::cout << std::endl; + + miles_audio_device_control(_audioDev, MILES_AUDIO_DEVICE_CTRL_SET_LISTENER_POS, _listener); + + } + } } void SpatialAudio::cancel(const std::string sendId) { - assert(false); + assert(false); } void SpatialAudio::sendToParent(SendRequest& req) { - req.invokeid = _invokeId; - assert(false); + req.invokeid = _invokeId; + assert(false); } void SpatialAudio::invoke(InvokeRequest& req) { - _invokeId = req.invokeid; - - if (req.src.length() > 0) { - Arabica::io::URI url(req.src); - if (!_interpreter->makeAbsolute(url)) { - LOG(ERROR) << "Source attribute for audio invoker has relative URI " << req.src << " with no base URI set for interpreter"; - return; - } - - URL scriptUrl(url.as_string()); - _dataStream << scriptUrl; - } - - getPosFromParams(req.params, _pos); - - struct miles_audio_device_description *devices; - int ndevs; - + _invokeId = req.invokeid; + + if (req.src.length() > 0) { + Arabica::io::URI url(req.src); + if (!_interpreter->makeAbsolute(url)) { + LOG(ERROR) << "Source attribute for audio invoker has relative URI " << req.src << " with no base URI set for interpreter"; + return; + } + + URL scriptUrl(url.as_string()); + _dataStream << scriptUrl; + } + + getPosFromParams(req.params, _pos); + + struct miles_audio_device_description *devices; + int ndevs; + ndevs = miles_audio_device_get_supported_devices(&devices); - - for (int i = 0; i < ndevs; i++) { + + for (int i = 0; i < ndevs; i++) { if ((devices[i].capabilities & MILES_AUDIO_DEVICE_CAPABILITY_SPATIAL) && - (devices[i].capabilities & MILES_AUDIO_DEVICE_CAPABILITY_OUTPUT)) { - _audioDevIndex = i; - break; - } - } + (devices[i].capabilities & MILES_AUDIO_DEVICE_CAPABILITY_OUTPUT)) { + _audioDevIndex = i; + break; + } + } } - void SpatialAudio::getPosFromParams(std::map<std::string, std::list<std::string> >& params, float* position) { - // vector explicitly given - try { - if (params.find("x") != params.end()) - position[0] = boost::lexical_cast<float>(params["x"].front()); - if (params.find("y") != params.end()) - position[1] = boost::lexical_cast<float>(params["y"].front()); - if (params.find("z") != params.end()) - position[2] = boost::lexical_cast<float>(params["z"].front()); - } catch (boost::bad_lexical_cast& e) { - LOG(ERROR) << "Cannot interpret x, y or z as float value in params: " << e.what(); - } - - try { - // right is an alias for x - if (params.find("right") != params.end()) - position[0] = boost::lexical_cast<float>(params["right"].front()); - // height is an alias for y - if (params.find("height") != params.end()) - position[1] = boost::lexical_cast<float>(params["height"].front()); - // front is an alias for z - if (params.find("front") != params.end()) - position[2] = boost::lexical_cast<float>(params["front"].front()); - } catch (boost::bad_lexical_cast& e) { - LOG(ERROR) << "Cannot interpret right, height or front as float value in params: " << e.what(); - } - - // do we have a position on a circle? - try { - if (params.find("circle") != params.end()) { - float rad = posToRadian(params["circle"].front()); - position[0] = cosf(rad); - position[2] = -1 * sinf(rad); // z axis increases to front - } - } catch (boost::bad_lexical_cast& e) { - LOG(ERROR) << "Cannot interpret circle as float value in params: " << e.what(); - } +void SpatialAudio::getPosFromParams(std::map<std::string, std::list<std::string> >& params, float* position) { + // vector explicitly given + try { + if (params.find("x") != params.end()) + position[0] = boost::lexical_cast<float>(params["x"].front()); + if (params.find("y") != params.end()) + position[1] = boost::lexical_cast<float>(params["y"].front()); + if (params.find("z") != params.end()) + position[2] = boost::lexical_cast<float>(params["z"].front()); + } catch (boost::bad_lexical_cast& e) { + LOG(ERROR) << "Cannot interpret x, y or z as float value in params: " << e.what(); + } + + try { + // right is an alias for x + if (params.find("right") != params.end()) + position[0] = boost::lexical_cast<float>(params["right"].front()); + // height is an alias for y + if (params.find("height") != params.end()) + position[1] = boost::lexical_cast<float>(params["height"].front()); + // front is an alias for z + if (params.find("front") != params.end()) + position[2] = boost::lexical_cast<float>(params["front"].front()); + } catch (boost::bad_lexical_cast& e) { + LOG(ERROR) << "Cannot interpret right, height or front as float value in params: " << e.what(); + } + + // do we have a position on a circle? + try { + if (params.find("circle") != params.end()) { + float rad = posToRadian(params["circle"].front()); + position[0] = cosf(rad); + position[2] = -1 * sinf(rad); // z axis increases to front + } + } catch (boost::bad_lexical_cast& e) { + LOG(ERROR) << "Cannot interpret circle as float value in params: " << e.what(); + } // std::cout << _pos[0] << ":" << _pos[1] << ":" << _pos[2] << std::endl; } - + float SpatialAudio::posToRadian(std::string& position) { - boost::trim(position); - float rad = 0; - - if (position.size() > 3 && boost::iequals("deg", position.substr(position.length() - 3, 3))) { - rad = boost::lexical_cast<float>(position.substr(0, position.size() - 3)); - rad = fmodf(rad, 360); // into range [0-360] - rad /= 180; // into range [0-2] - rad *= M_PI; // into range [0-2PI] - rad -= M_PI_2; // 0 to top; - rad *= -1; // make clockwise - rad += 2 * M_PI; // make positive - } else if (position.size() > 3 && boost::iequals("rad", position.substr(position.length() - 3, 3))) { - rad = boost::lexical_cast<float>(position.substr(0, position.size() - 3)); - rad = fmodf(rad, M_PI * 2); // into range [0-2*PI] - } else { - LOG(ERROR) << "Cannot make sense of position value " << position << ": does not end in 'deg', 'rad'"; - } - return rad; + boost::trim(position); + float rad = 0; + + if (position.size() > 3 && boost::iequals("deg", position.substr(position.length() - 3, 3))) { + rad = boost::lexical_cast<float>(position.substr(0, position.size() - 3)); + rad = fmodf(rad, 360); // into range [0-360] + rad /= 180; // into range [0-2] + rad *= M_PI; // into range [0-2PI] + rad -= M_PI_2; // 0 to top; + rad *= -1; // make clockwise + rad += 2 * M_PI; // make positive + } else if (position.size() > 3 && boost::iequals("rad", position.substr(position.length() - 3, 3))) { + rad = boost::lexical_cast<float>(position.substr(0, position.size() - 3)); + rad = fmodf(rad, M_PI * 2); // into range [0-2*PI] + } else { + LOG(ERROR) << "Cannot make sense of position value " << position << ": does not end in 'deg', 'rad'"; + } + return rad; } - + }
\ No newline at end of file diff --git a/src/uscxml/plugins/invoker/modality/miles/SpatialAudio.h b/src/uscxml/plugins/invoker/modality/miles/SpatialAudio.h index bbbf478..7632f52 100644 --- a/src/uscxml/plugins/invoker/modality/miles/SpatialAudio.h +++ b/src/uscxml/plugins/invoker/modality/miles/SpatialAudio.h @@ -14,14 +14,14 @@ extern "C" { namespace uscxml { class Interpreter; - + class SpatialAudio : public MMIComponent { public: SpatialAudio(); - virtual ~SpatialAudio(); - virtual Invoker* create(Interpreter* interpreter); - - virtual std::set<std::string> getNames() { + virtual ~SpatialAudio(); + virtual Invoker* create(Interpreter* interpreter); + + virtual std::set<std::string> getNames() { std::set<std::string> names; names.insert("spatial-audio"); names.insert("audio"); @@ -30,29 +30,29 @@ public: return names; } - virtual Data getDataModelVariables(); - virtual void send(SendRequest& req); - virtual void cancel(const std::string sendId); - virtual void invoke(InvokeRequest& req); - virtual void sendToParent(SendRequest& req); + virtual Data getDataModelVariables(); + virtual void send(SendRequest& req); + virtual void cancel(const std::string sendId); + virtual void invoke(InvokeRequest& req); + virtual void sendToParent(SendRequest& req); - void getPosFromParams(std::map<std::string, std::list<std::string> >& params, float* position); - static float posToRadian(std::string& position); + void getPosFromParams(std::map<std::string, std::list<std::string> >& params, float* position); + static float posToRadian(std::string& position); protected: - std::string _invokeId; - Interpreter* _invokedInterpreter; - - std::stringstream _dataStream; - - float* _pos; - float* _listener; - bool _audioDevOpen; - int _audioDevIndex; - struct miles_audio_device* _audioDev; + std::string _invokeId; + Interpreter* _invokedInterpreter; + + std::stringstream _dataStream; + + float* _pos; + float* _listener; + bool _audioDevOpen; + int _audioDevIndex; + struct miles_audio_device* _audioDev; }; - + } #endif /* end of include guard: SPATIALAUDIO_H_EH11SAQC */ diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp index 0e617b9..b4ee3eb 100644 --- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp @@ -1,6 +1,5 @@ -#include "uscxml/Common.h" #include "USCXMLInvoker.h" -#include "uscxml/Interpreter.h" +#include <glog/logging.h> #ifdef BUILD_AS_PLUGINS #include <Pluma/Connector.hpp> @@ -10,53 +9,53 @@ namespace uscxml { #ifdef BUILD_AS_PLUGINS PLUMA_CONNECTOR -bool connect(pluma::Host& host){ - host.add( new USCXMLInvokerProvider() ); - return true; +bool connect(pluma::Host& host) { + host.add( new USCXMLInvokerProvider() ); + return true; } #endif -USCXMLInvoker::USCXMLInvoker() { +USCXMLInvoker::USCXMLInvoker() { } - + USCXMLInvoker::~USCXMLInvoker() { - delete _invokedInterpreter; + delete _invokedInterpreter; }; - + Invoker* USCXMLInvoker::create(Interpreter* interpreter) { - USCXMLInvoker* invoker = new USCXMLInvoker(); - invoker->_parentInterpreter = interpreter; - return invoker; + USCXMLInvoker* invoker = new USCXMLInvoker(); + invoker->_parentInterpreter = interpreter; + return invoker; } Data USCXMLInvoker::getDataModelVariables() { - Data data; - return data; + Data data; + return data; } void USCXMLInvoker::send(SendRequest& req) { - assert(false); + assert(false); } void USCXMLInvoker::cancel(const std::string sendId) { - assert(false); + assert(false); } void USCXMLInvoker::sendToParent(SendRequest& req) { - req.invokeid = _invokeId; - _parentInterpreter->receive(req); + req.invokeid = _invokeId; + _parentInterpreter->receive(req); } void USCXMLInvoker::invoke(InvokeRequest& req) { - _invokeId = req.invokeid; - _invokedInterpreter = Interpreter::fromURI(req.src); - DataModel* dataModel = _invokedInterpreter->getDataModel(); - if (dataModel != NULL) { - - } - _invokedInterpreter->setInvoker(this); - _invokedInterpreter->start(); + _invokeId = req.invokeid; + _invokedInterpreter = Interpreter::fromURI(req.src); + DataModel* dataModel = _invokedInterpreter->getDataModel(); + if (dataModel != NULL) { + + } + _invokedInterpreter->setInvoker(this); + _invokedInterpreter->start(); } }
\ No newline at end of file diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h index 9068a24..907df41 100644 --- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h +++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h @@ -1,7 +1,7 @@ #ifndef USCXMLINVOKER_H_OQFA21IO #define USCXMLINVOKER_H_OQFA21IO -#include "uscxml/Factory.h" +#include <uscxml/Interpreter.h> #ifdef BUILD_AS_PLUGINS #include "uscxml/plugins/Plugins.h" @@ -10,13 +10,13 @@ namespace uscxml { class Interpreter; - + class USCXMLInvoker : public Invoker { public: USCXMLInvoker(); - virtual ~USCXMLInvoker(); - virtual Invoker* create(Interpreter* interpreter); - virtual std::set<std::string> getNames() { + virtual ~USCXMLInvoker(); + virtual Invoker* create(Interpreter* interpreter); + virtual std::set<std::string> getNames() { std::set<std::string> names; names.insert("uscxml"); names.insert("http://www.w3.org/TR/scxml"); @@ -24,16 +24,16 @@ public: return names; } - virtual Data getDataModelVariables(); - virtual void send(SendRequest& req); - virtual void cancel(const std::string sendId); - virtual void invoke(InvokeRequest& req); - virtual void sendToParent(SendRequest& req); + virtual Data getDataModelVariables(); + virtual void send(SendRequest& req); + virtual void cancel(const std::string sendId); + virtual void invoke(InvokeRequest& req); + virtual void sendToParent(SendRequest& req); protected: - std::string _invokeId; - Interpreter* _invokedInterpreter; - Interpreter* _parentInterpreter; + std::string _invokeId; + Interpreter* _invokedInterpreter; + Interpreter* _parentInterpreter; }; #ifdef BUILD_AS_PLUGINS diff --git a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp index 68ffe5a..ee6c903 100644 --- a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp +++ b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp @@ -1,7 +1,4 @@ -#include "uscxml/config.h" -#include "uscxml/Common.h" #include "UmundoInvoker.h" -#include "uscxml/Interpreter.h" #include <glog/logging.h> #ifdef BUILD_AS_PLUGINS @@ -12,9 +9,9 @@ namespace uscxml { #ifdef BUILD_AS_PLUGINS PLUMA_CONNECTOR -bool connect(pluma::Host& host){ - host.add( new UmundoInvokerProvider() ); - return true; +bool connect(pluma::Host& host) { + host.add( new UmundoInvokerProvider() ); + return true; } #endif @@ -22,213 +19,215 @@ UmundoInvoker::UmundoInvoker() { } UmundoInvoker::~UmundoInvoker() { - _node.removeSubscriber(_sub); - _node.removePublisher(_pub); + _node.removeSubscriber(_sub); + _node.removePublisher(_pub); }; Invoker* UmundoInvoker::create(Interpreter* interpreter) { - UmundoInvoker* invoker = new UmundoInvoker(); - invoker->_interpreter = interpreter; - return invoker; + UmundoInvoker* invoker = new UmundoInvoker(); + invoker->_interpreter = interpreter; + return invoker; } Data UmundoInvoker::getDataModelVariables() { - Data data; - return data; + Data data; + return data; } void UmundoInvoker::send(SendRequest& req) { - umundo::Message* msg = new umundo::Message(); - - if (req.name.length() > 0) { - msg->putMeta("event", req.name); - } else { - msg->putMeta("event", "umundo"); - } - - 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) { - std::string type = req.params["type"].front(); - const google::protobuf::Message* protoMsg = umundo::PBSerializer::getProto(type); - if (protoMsg == NULL) { - LOG(ERROR) << "No type " << type << " is known, pass a directory with proto .desc files via types param when invoking"; - return; - } - try { - 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"; - } else { - // add all s11n properties - if (!_isService) { - _pub.prepareMsg(msg, type, pbMsg); - _pub.send(msg); - } else { - std::map<umundo::ServiceDescription, umundo::ServiceStub*>::iterator svcIter = _svcs.begin(); - while(svcIter != _svcs.end()) { - umundo::ServiceStub* stub = svcIter->second; - Event event; - void* rv = NULL; - stub->callStubMethod(req.name, pbMsg, type, rv, ""); - protobufToData(event, *(const google::protobuf::Message*)rv); - - event.name = _invokeId + ".reply." + req.name; - event.invokeid = _invokeId; - event.origin = msg->getMeta("um.channel"); - event.origintype = "umundo"; - event.type = Event::EXTERNAL; - - _interpreter->receive(event); - svcIter++; - } - } - } - } catch (Event e) { - LOG(ERROR) << "Syntax error when invoking umundo:" << std::endl << e << std::endl; - return; - } - } else { - LOG(ERROR) << "Required JSON object in content" << std::endl; - return; - } - } + umundo::Message* msg = new umundo::Message(); + + if (req.name.length() > 0) { + msg->putMeta("event", req.name); + } else { + msg->putMeta("event", "umundo"); + } + + 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) { + std::string type; + std::multimap<std::string, std::string>::iterator typeIter = req.params.find("type"); + if (typeIter != req.params.end()) + type = typeIter->second; + const google::protobuf::Message* protoMsg = umundo::PBSerializer::getProto(type); + if (protoMsg == NULL) { + LOG(ERROR) << "No type " << type << " is known, pass a directory with proto .desc files via types param when invoking"; + return; + } + try { + 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"; + } else { + // add all s11n properties + if (!_isService) { + _pub.prepareMsg(msg, type, pbMsg); + _pub.send(msg); + } else { + std::map<umundo::ServiceDescription, umundo::ServiceStub*>::iterator svcIter = _svcs.begin(); + while(svcIter != _svcs.end()) { + umundo::ServiceStub* stub = svcIter->second; + Event event; + void* rv = NULL; + stub->callStubMethod(req.name, pbMsg, type, rv, ""); + protobufToData(event, *(const google::protobuf::Message*)rv); + + event.name = _invokeId + ".reply." + req.name; + event.invokeid = _invokeId; + event.origin = msg->getMeta("um.channel"); + event.origintype = "umundo"; + event.type = Event::EXTERNAL; + + _interpreter->receive(event); + svcIter++; + } + } + } + } catch (Event e) { + LOG(ERROR) << "Syntax error when invoking umundo:" << std::endl << e << std::endl; + return; + } + } else { + LOG(ERROR) << "Required JSON object in content" << std::endl; + return; + } + } } void UmundoInvoker::cancel(const std::string sendId) { - assert(false); + assert(false); } void UmundoInvoker::sendToParent(SendRequest& req) { - assert(false); + assert(false); } void UmundoInvoker::invoke(InvokeRequest& req) { - _invokeId = req.invokeid; - - std::string channelName; - std::string serviceName; - - if (req.params.find("channel") != req.params.end()) { - channelName = req.params["channel"].front(); - _isService = false; - } else if (req.params.find("service") != req.params.end()) { - serviceName = req.params["service"].front(); - _isService = true; - } else { - LOG(ERROR) << "Invoking umundo needs a service or a channel param"; - return; - } - - _node = getNode(_interpreter); - - // add types from .proto or .desc files - if (req.params.find("types") != req.params.end()) { - std::list<std::string>::iterator typeIter = req.params["types"].begin(); - while(typeIter != req.params["types"].end()) { - Arabica::io::URI srcURI(*typeIter); - // if (!_interpreter->makeAbsolute(srcURI)) { - // LOG(ERROR) << "Relative URI for types in umundo invoker " << *typeIter << " with no base URI set for interpreter"; - // return; - // } - umundo::PBSerializer::addProto(srcURI.path()); - typeIter++; - } - } - - if (!_isService) { - // use umundo to publish objects on a channel - _pub = umundo::TypedPublisher(channelName); - _sub = umundo::TypedSubscriber(channelName, this); - - _node.addPublisher(_pub); - _node.addSubscriber(_sub); - - } else if (serviceName.length() > 0) { - // use umundo to access services - _svcFilter = umundo::ServiceFilter(serviceName); - _node.connect(&_svcMgr); - _svcMgr.startQuery(_svcFilter, this); - } + _invokeId = req.invokeid; + + std::string channelName; + std::string serviceName; + + if (req.params.find("channel") != req.params.end()) { + channelName = req.params.find("type")->second; + _isService = false; + } else if (req.params.find("service") != req.params.end()) { + serviceName = req.params.find("service")->second; + _isService = true; + } else { + LOG(ERROR) << "Invoking umundo needs a service or a channel param"; + return; + } + + _node = getNode(_interpreter); + + // add types from .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++) { + Arabica::io::URI srcURI(it->first); + // if (!_interpreter->makeAbsolute(srcURI)) { + // LOG(ERROR) << "Relative URI for types in umundo invoker " << *typeIter << " with no base URI set for interpreter"; + // return; + // } + umundo::PBSerializer::addProto(srcURI.path()); + } + } + + if (!_isService) { + // use umundo to publish objects on a channel + _pub = umundo::TypedPublisher(channelName); + _sub = umundo::TypedSubscriber(channelName, this); + + _node.addPublisher(_pub); + _node.addSubscriber(_sub); + + } else if (serviceName.length() > 0) { + // use umundo to access services + _svcFilter = umundo::ServiceFilter(serviceName); + _node.connect(&_svcMgr); + _svcMgr.startQuery(_svcFilter, this); + } } void UmundoInvoker::receive(void* object, umundo::Message* msg) { - uscxml::Event event; - if (msg->getMeta().find("event") != msg->getMeta().end()) { - event.name = msg->getMeta("event"); - } else { - event.name = "umundo.rcvd"; - } - - event.invokeid = _invokeId; - event.origin = msg->getMeta("um.channel"); - event.origintype = "umundo"; - event.type = Event::EXTERNAL; - + uscxml::Event event; + if (msg->getMeta().find("event") != msg->getMeta().end()) { + event.name = msg->getMeta("event"); + } else { + event.name = "umundo.rcvd"; + } + + event.invokeid = _invokeId; + event.origin = msg->getMeta("um.channel"); + event.origintype = "umundo"; + event.type = Event::EXTERNAL; + // if (msg->getMeta().find("um.s11n.type") != msg->getMeta().end()) // event.compound["class"] = msg->getMeta("um.s11n.type"); - - if (object != NULL) - protobufToData(event, *(const google::protobuf::Message*)object); - - // get meta fields into event - std::map<std::string, std::string>::const_iterator metaIter = msg->getMeta().begin(); - while(metaIter != msg->getMeta().end()) { - if (metaIter->first.substr(0,3).compare("um.") != 0) - event.compound[metaIter->first] = Data(metaIter->second, Data::VERBATIM); - metaIter++; - } - - _interpreter->receive(event); + + if (object != NULL) + protobufToData(event, *(const google::protobuf::Message*)object); + + // get meta fields into event + std::map<std::string, std::string>::const_iterator metaIter = msg->getMeta().begin(); + while(metaIter != msg->getMeta().end()) { + if (metaIter->first.substr(0,3).compare("um.") != 0) + event.compound[metaIter->first] = Data(metaIter->second, Data::VERBATIM); + metaIter++; + } + + _interpreter->receive(event); } void UmundoInvoker::added(umundo::ServiceDescription desc) { - LOG(ERROR) << "Service found!"; - - umundo::ServiceStub* stub = new umundo::ServiceStub(desc); - _svcs[desc] = stub; - - Event addedEvent; - addedEvent.invokeid = _invokeId; - addedEvent.origin = desc.getName(); - addedEvent.origintype = "umundo"; - addedEvent.type = Event::EXTERNAL; - addedEvent.name = _invokeId + ".added"; - - std::map<std::string, std::string>::const_iterator propIter = desc.getProperties().begin(); - while(propIter != desc.getProperties().end()) { - addedEvent.compound[propIter->first] = Data(propIter->second, Data::VERBATIM); - propIter++; - } - - _interpreter->receive(addedEvent); + LOG(ERROR) << "Service found!"; + + umundo::ServiceStub* stub = new umundo::ServiceStub(desc); + _svcs[desc] = stub; + + Event addedEvent; + addedEvent.invokeid = _invokeId; + addedEvent.origin = desc.getName(); + addedEvent.origintype = "umundo"; + addedEvent.type = Event::EXTERNAL; + addedEvent.name = _invokeId + ".added"; + + std::map<std::string, std::string>::const_iterator propIter = desc.getProperties().begin(); + while(propIter != desc.getProperties().end()) { + addedEvent.compound[propIter->first] = Data(propIter->second, Data::VERBATIM); + propIter++; + } + + _interpreter->receive(addedEvent); } void UmundoInvoker::removed(umundo::ServiceDescription desc) { - LOG(ERROR) << "Service lost!"; - - if (_svcs.find(desc) == _svcs.end()) { - return; - } - - delete _svcs[desc]; - _svcs.erase(desc); - - Event addedEvent; - addedEvent.invokeid = _invokeId; - addedEvent.origin = desc.getName(); - addedEvent.origintype = "umundo"; - addedEvent.type = Event::EXTERNAL; - addedEvent.name = _invokeId + ".removed"; - - std::map<std::string, std::string>::const_iterator propIter = desc.getProperties().begin(); - while(propIter != desc.getProperties().end()) { - addedEvent.compound[propIter->first] = Data(propIter->second, Data::VERBATIM); - propIter++; - } - - _interpreter->receive(addedEvent); + LOG(ERROR) << "Service lost!"; + + if (_svcs.find(desc) == _svcs.end()) { + return; + } + + delete _svcs[desc]; + _svcs.erase(desc); + + Event addedEvent; + addedEvent.invokeid = _invokeId; + addedEvent.origin = desc.getName(); + addedEvent.origintype = "umundo"; + addedEvent.type = Event::EXTERNAL; + addedEvent.name = _invokeId + ".removed"; + + std::map<std::string, std::string>::const_iterator propIter = desc.getProperties().begin(); + while(propIter != desc.getProperties().end()) { + addedEvent.compound[propIter->first] = Data(propIter->second, Data::VERBATIM); + propIter++; + } + + _interpreter->receive(addedEvent); } void UmundoInvoker::changed(umundo::ServiceDescription desc) { @@ -236,252 +235,252 @@ void UmundoInvoker::changed(umundo::ServiceDescription desc) { std::map<std::string, umundo::Node> UmundoInvoker::_nodes; umundo::Node UmundoInvoker::getNode(Interpreter* interpreter) { - if ((_nodes.find(interpreter->getName()) == _nodes.end())) { - _nodes[interpreter->getName()] = umundo::Node(); - } - return _nodes[interpreter->getName()]; + if ((_nodes.find(interpreter->getName()) == _nodes.end())) { + _nodes[interpreter->getName()] = umundo::Node(); + } + return _nodes[interpreter->getName()]; } bool UmundoInvoker::protobufToData(Data& data, const google::protobuf::Message& msg) { - const google::protobuf::Descriptor* desc = msg.GetDescriptor(); - const google::protobuf::Reflection* reflect = msg.GetReflection(); - - data.compound["type"] = Data(desc->name(), Data::VERBATIM); - - for (int i = 0; i < desc->field_count(); i++) { - const google::protobuf::FieldDescriptor* fieldDesc = desc->field(i); - std::string key = fieldDesc->name(); - - if (!fieldDesc->is_repeated() && !reflect->HasField(msg, fieldDesc)) - continue; - - switch(fieldDesc->type()) { - case google::protobuf::FieldDescriptor::TYPE_BOOL: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(reflect->GetRepeatedBool(msg, fieldDesc, j) ? "true" : "false")); - } - } else { - data.compound[key].atom = (reflect->GetBool(msg, fieldDesc) ? "true" : "false"); - } - break; - case google::protobuf::FieldDescriptor::TYPE_BYTES: - case google::protobuf::FieldDescriptor::TYPE_STRING: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedString(msg, fieldDesc, j)), Data::VERBATIM)); - } - } else { - data.compound[key].atom = toStr(reflect->GetString(msg, fieldDesc)); - data.compound[key].type = Data::VERBATIM; - } - break; - case google::protobuf::FieldDescriptor::TYPE_DOUBLE: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedDouble(msg, fieldDesc, j)))); - } - } else { - data.compound[key].atom = toStr(reflect->GetDouble(msg, fieldDesc)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_ENUM: - LOG(ERROR) << "TYPE_ENUM is unimplemented" << std::endl; - break; - case google::protobuf::FieldDescriptor::TYPE_FIXED32: - case google::protobuf::FieldDescriptor::TYPE_UINT32: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedUInt32(msg, fieldDesc, j)))); - } - } else { - data.compound[key].atom = toStr(reflect->GetUInt32(msg, fieldDesc)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_FIXED64: - case google::protobuf::FieldDescriptor::TYPE_UINT64: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedUInt64(msg, fieldDesc, j)))); - } - } else { - data.compound[key].atom = toStr(reflect->GetUInt64(msg, fieldDesc)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_FLOAT: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedFloat(msg, fieldDesc, j)))); - } - } else { - data.compound[key].atom = toStr(reflect->GetFloat(msg, fieldDesc)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_GROUP: - LOG(ERROR) << "TYPE_GROUP is unimplemented" << std::endl; - break; - case google::protobuf::FieldDescriptor::TYPE_INT32: - case google::protobuf::FieldDescriptor::TYPE_SINT32: - case google::protobuf::FieldDescriptor::TYPE_SFIXED32: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedInt32(msg, fieldDesc, j)))); - } - } else { - data.compound[key].atom = toStr(reflect->GetInt32(msg, fieldDesc)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_INT64: - case google::protobuf::FieldDescriptor::TYPE_SINT64: - case google::protobuf::FieldDescriptor::TYPE_SFIXED64: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedInt64(msg, fieldDesc, j)))); - } - } else { - data.compound[key].atom = toStr(reflect->GetInt64(msg, fieldDesc)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_MESSAGE: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data()); - protobufToData(data.compound[key].array.back(), reflect->GetRepeatedMessage(msg, fieldDesc, j)); - } - } else { - protobufToData(data.compound[key], reflect->GetMessage(msg, fieldDesc)); - } - break; - } - } - return true; + const google::protobuf::Descriptor* desc = msg.GetDescriptor(); + const google::protobuf::Reflection* reflect = msg.GetReflection(); + + data.compound["type"] = Data(desc->name(), Data::VERBATIM); + + for (int i = 0; i < desc->field_count(); i++) { + const google::protobuf::FieldDescriptor* fieldDesc = desc->field(i); + std::string key = fieldDesc->name(); + + if (!fieldDesc->is_repeated() && !reflect->HasField(msg, fieldDesc)) + continue; + + switch(fieldDesc->type()) { + case google::protobuf::FieldDescriptor::TYPE_BOOL: + if (fieldDesc->is_repeated()) { + for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { + data.compound[key].array.push_back(Data(reflect->GetRepeatedBool(msg, fieldDesc, j) ? "true" : "false")); + } + } else { + data.compound[key].atom = (reflect->GetBool(msg, fieldDesc) ? "true" : "false"); + } + break; + case google::protobuf::FieldDescriptor::TYPE_BYTES: + case google::protobuf::FieldDescriptor::TYPE_STRING: + if (fieldDesc->is_repeated()) { + for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { + data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedString(msg, fieldDesc, j)), Data::VERBATIM)); + } + } else { + data.compound[key].atom = toStr(reflect->GetString(msg, fieldDesc)); + data.compound[key].type = Data::VERBATIM; + } + break; + case google::protobuf::FieldDescriptor::TYPE_DOUBLE: + if (fieldDesc->is_repeated()) { + for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { + data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedDouble(msg, fieldDesc, j)))); + } + } else { + data.compound[key].atom = toStr(reflect->GetDouble(msg, fieldDesc)); + } + break; + case google::protobuf::FieldDescriptor::TYPE_ENUM: + LOG(ERROR) << "TYPE_ENUM is unimplemented" << std::endl; + break; + case google::protobuf::FieldDescriptor::TYPE_FIXED32: + case google::protobuf::FieldDescriptor::TYPE_UINT32: + if (fieldDesc->is_repeated()) { + for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { + data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedUInt32(msg, fieldDesc, j)))); + } + } else { + data.compound[key].atom = toStr(reflect->GetUInt32(msg, fieldDesc)); + } + break; + case google::protobuf::FieldDescriptor::TYPE_FIXED64: + case google::protobuf::FieldDescriptor::TYPE_UINT64: + if (fieldDesc->is_repeated()) { + for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { + data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedUInt64(msg, fieldDesc, j)))); + } + } else { + data.compound[key].atom = toStr(reflect->GetUInt64(msg, fieldDesc)); + } + break; + case google::protobuf::FieldDescriptor::TYPE_FLOAT: + if (fieldDesc->is_repeated()) { + for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { + data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedFloat(msg, fieldDesc, j)))); + } + } else { + data.compound[key].atom = toStr(reflect->GetFloat(msg, fieldDesc)); + } + break; + case google::protobuf::FieldDescriptor::TYPE_GROUP: + LOG(ERROR) << "TYPE_GROUP is unimplemented" << std::endl; + break; + case google::protobuf::FieldDescriptor::TYPE_INT32: + case google::protobuf::FieldDescriptor::TYPE_SINT32: + case google::protobuf::FieldDescriptor::TYPE_SFIXED32: + if (fieldDesc->is_repeated()) { + for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { + data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedInt32(msg, fieldDesc, j)))); + } + } else { + data.compound[key].atom = toStr(reflect->GetInt32(msg, fieldDesc)); + } + break; + case google::protobuf::FieldDescriptor::TYPE_INT64: + case google::protobuf::FieldDescriptor::TYPE_SINT64: + case google::protobuf::FieldDescriptor::TYPE_SFIXED64: + if (fieldDesc->is_repeated()) { + for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { + data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedInt64(msg, fieldDesc, j)))); + } + } else { + data.compound[key].atom = toStr(reflect->GetInt64(msg, fieldDesc)); + } + break; + case google::protobuf::FieldDescriptor::TYPE_MESSAGE: + if (fieldDesc->is_repeated()) { + for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { + data.compound[key].array.push_back(Data()); + protobufToData(data.compound[key].array.back(), reflect->GetRepeatedMessage(msg, fieldDesc, j)); + } + } else { + protobufToData(data.compound[key], reflect->GetMessage(msg, fieldDesc)); + } + break; + } + } + return true; } bool UmundoInvoker::dataToProtobuf(google::protobuf::Message* msg, Data& data) { - const google::protobuf::Descriptor* desc = msg->GetDescriptor(); - const google::protobuf::Reflection* reflect = msg->GetReflection(); - - for (int i = 0; i < desc->field_count(); i++) { - const google::protobuf::FieldDescriptor* fieldDesc = desc->field(i); - std::string key = fieldDesc->name(); - - if (data.compound.find(key) == data.compound.end()) { - if (fieldDesc->is_required()) { - LOG(ERROR) << "required field " << key << " not given in JSON"; - return false; - } - continue; - } - - std::list<Data>::iterator arrayIter = data.compound[key].array.begin(); - - switch(fieldDesc->type()) { - case google::protobuf::FieldDescriptor::TYPE_BOOL: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddBool(msg, fieldDesc, arrayIter->atom.compare("false") == 0 ? false : true); - arrayIter++; - } - } else { - reflect->SetBool(msg, fieldDesc, (data.compound[key].atom.compare("false") == 0 ? false : true)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_BYTES: - case google::protobuf::FieldDescriptor::TYPE_STRING: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddString(msg, fieldDesc, arrayIter->atom); - arrayIter++; - } - } else { - reflect->SetString(msg, fieldDesc, data.compound[key].atom); - } - break; - case google::protobuf::FieldDescriptor::TYPE_DOUBLE: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddDouble(msg, fieldDesc, strTo<double>(arrayIter->atom)); - arrayIter++; - } - } else { - reflect->SetDouble(msg, fieldDesc, strTo<double>(data.compound[key].atom)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_ENUM: - LOG(ERROR) << "TYPE_ENUM is unimplemented" << std::endl; - break; - case google::protobuf::FieldDescriptor::TYPE_FIXED32: - case google::protobuf::FieldDescriptor::TYPE_UINT32: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddUInt32(msg, fieldDesc, strTo<uint32_t>(arrayIter->atom)); - arrayIter++; - } - } else { - reflect->SetUInt32(msg, fieldDesc, strTo<uint32_t>(data.compound[key].atom)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_FIXED64: - case google::protobuf::FieldDescriptor::TYPE_UINT64: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddUInt64(msg, fieldDesc, strTo<uint64_t>(arrayIter->atom)); - arrayIter++; - } - } else { - reflect->SetUInt64(msg, fieldDesc, strTo<uint64_t>(data.compound[key].atom)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_FLOAT: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddFloat(msg, fieldDesc, strTo<float>(arrayIter->atom)); - arrayIter++; - } - } else { - reflect->SetFloat(msg, fieldDesc, strTo<float>(data.compound[key].atom)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_GROUP: - LOG(ERROR) << "TYPE_GROUP is unimplemented" << std::endl; - break; - case google::protobuf::FieldDescriptor::TYPE_INT32: - case google::protobuf::FieldDescriptor::TYPE_SINT32: - case google::protobuf::FieldDescriptor::TYPE_SFIXED32: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddInt32(msg, fieldDesc, strTo<int32_t>(arrayIter->atom)); - arrayIter++; - } - } else { - reflect->SetInt32(msg, fieldDesc, strTo<int32_t>(data.compound[key].atom)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_INT64: - case google::protobuf::FieldDescriptor::TYPE_SINT64: - case google::protobuf::FieldDescriptor::TYPE_SFIXED64: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddInt64(msg, fieldDesc, strTo<int64_t>(arrayIter->atom)); - arrayIter++; - } - } else { - reflect->SetInt64(msg, fieldDesc, strTo<int64_t>(data.compound[key].atom)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_MESSAGE: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - dataToProtobuf(reflect->AddMessage(msg, fieldDesc), *arrayIter); - arrayIter++; - } - } else { - dataToProtobuf(reflect->MutableMessage(msg, fieldDesc), data.compound[key]); - } - break; - } - } - return true; + const google::protobuf::Descriptor* desc = msg->GetDescriptor(); + const google::protobuf::Reflection* reflect = msg->GetReflection(); + + for (int i = 0; i < desc->field_count(); i++) { + const google::protobuf::FieldDescriptor* fieldDesc = desc->field(i); + std::string key = fieldDesc->name(); + + if (data.compound.find(key) == data.compound.end()) { + if (fieldDesc->is_required()) { + LOG(ERROR) << "required field " << key << " not given in JSON"; + return false; + } + continue; + } + + std::list<Data>::iterator arrayIter = data.compound[key].array.begin(); + + switch(fieldDesc->type()) { + case google::protobuf::FieldDescriptor::TYPE_BOOL: + if (fieldDesc->is_repeated()) { + while(arrayIter != data.compound[key].array.end()) { + reflect->AddBool(msg, fieldDesc, arrayIter->atom.compare("false") == 0 ? false : true); + arrayIter++; + } + } else { + reflect->SetBool(msg, fieldDesc, (data.compound[key].atom.compare("false") == 0 ? false : true)); + } + break; + case google::protobuf::FieldDescriptor::TYPE_BYTES: + case google::protobuf::FieldDescriptor::TYPE_STRING: + if (fieldDesc->is_repeated()) { + while(arrayIter != data.compound[key].array.end()) { + reflect->AddString(msg, fieldDesc, arrayIter->atom); + arrayIter++; + } + } else { + reflect->SetString(msg, fieldDesc, data.compound[key].atom); + } + break; + case google::protobuf::FieldDescriptor::TYPE_DOUBLE: + if (fieldDesc->is_repeated()) { + while(arrayIter != data.compound[key].array.end()) { + reflect->AddDouble(msg, fieldDesc, strTo<double>(arrayIter->atom)); + arrayIter++; + } + } else { + reflect->SetDouble(msg, fieldDesc, strTo<double>(data.compound[key].atom)); + } + break; + case google::protobuf::FieldDescriptor::TYPE_ENUM: + LOG(ERROR) << "TYPE_ENUM is unimplemented" << std::endl; + break; + case google::protobuf::FieldDescriptor::TYPE_FIXED32: + case google::protobuf::FieldDescriptor::TYPE_UINT32: + if (fieldDesc->is_repeated()) { + while(arrayIter != data.compound[key].array.end()) { + reflect->AddUInt32(msg, fieldDesc, strTo<uint32_t>(arrayIter->atom)); + arrayIter++; + } + } else { + reflect->SetUInt32(msg, fieldDesc, strTo<uint32_t>(data.compound[key].atom)); + } + break; + case google::protobuf::FieldDescriptor::TYPE_FIXED64: + case google::protobuf::FieldDescriptor::TYPE_UINT64: + if (fieldDesc->is_repeated()) { + while(arrayIter != data.compound[key].array.end()) { + reflect->AddUInt64(msg, fieldDesc, strTo<uint64_t>(arrayIter->atom)); + arrayIter++; + } + } else { + reflect->SetUInt64(msg, fieldDesc, strTo<uint64_t>(data.compound[key].atom)); + } + break; + case google::protobuf::FieldDescriptor::TYPE_FLOAT: + if (fieldDesc->is_repeated()) { + while(arrayIter != data.compound[key].array.end()) { + reflect->AddFloat(msg, fieldDesc, strTo<float>(arrayIter->atom)); + arrayIter++; + } + } else { + reflect->SetFloat(msg, fieldDesc, strTo<float>(data.compound[key].atom)); + } + break; + case google::protobuf::FieldDescriptor::TYPE_GROUP: + LOG(ERROR) << "TYPE_GROUP is unimplemented" << std::endl; + break; + case google::protobuf::FieldDescriptor::TYPE_INT32: + case google::protobuf::FieldDescriptor::TYPE_SINT32: + case google::protobuf::FieldDescriptor::TYPE_SFIXED32: + if (fieldDesc->is_repeated()) { + while(arrayIter != data.compound[key].array.end()) { + reflect->AddInt32(msg, fieldDesc, strTo<int32_t>(arrayIter->atom)); + arrayIter++; + } + } else { + reflect->SetInt32(msg, fieldDesc, strTo<int32_t>(data.compound[key].atom)); + } + break; + case google::protobuf::FieldDescriptor::TYPE_INT64: + case google::protobuf::FieldDescriptor::TYPE_SINT64: + case google::protobuf::FieldDescriptor::TYPE_SFIXED64: + if (fieldDesc->is_repeated()) { + while(arrayIter != data.compound[key].array.end()) { + reflect->AddInt64(msg, fieldDesc, strTo<int64_t>(arrayIter->atom)); + arrayIter++; + } + } else { + reflect->SetInt64(msg, fieldDesc, strTo<int64_t>(data.compound[key].atom)); + } + break; + case google::protobuf::FieldDescriptor::TYPE_MESSAGE: + if (fieldDesc->is_repeated()) { + while(arrayIter != data.compound[key].array.end()) { + dataToProtobuf(reflect->AddMessage(msg, fieldDesc), *arrayIter); + arrayIter++; + } + } else { + dataToProtobuf(reflect->MutableMessage(msg, fieldDesc), data.compound[key]); + } + break; + } + } + return true; } }
\ No newline at end of file diff --git a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h index 36a6217..72fcc9b 100644 --- a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h +++ b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h @@ -5,6 +5,7 @@ #include <umundo/s11n.h> #include <umundo/rpc.h> #include <umundo/s11n/protobuf/PBSerializer.h> +#include <uscxml/Interpreter.h> #include <google/protobuf/message.h> #ifdef BUILD_AS_PLUGINS @@ -18,46 +19,46 @@ class Interpreter; class UmundoInvoker : public Invoker, public umundo::TypedReceiver, public umundo::ResultSet<umundo::ServiceDescription> { public: UmundoInvoker(); - virtual ~UmundoInvoker(); - virtual Invoker* create(Interpreter* interpreter); + virtual ~UmundoInvoker(); + virtual Invoker* create(Interpreter* interpreter); - virtual std::set<std::string> getNames() { + virtual std::set<std::string> getNames() { std::set<std::string> names; names.insert("umundo"); names.insert("http://umundo.tk.informatik.tu-darmstadt.de/"); names.insert("http://umundo.tk.informatik.tu-darmstadt.de"); return names; } - - virtual Data getDataModelVariables(); - virtual void send(SendRequest& req); - virtual void cancel(const std::string sendId); - virtual void invoke(InvokeRequest& req); - virtual void sendToParent(SendRequest& req); - virtual void receive(void* object, umundo::Message* msg); + virtual Data getDataModelVariables(); + virtual void send(SendRequest& req); + virtual void cancel(const std::string sendId); + virtual void invoke(InvokeRequest& req); + virtual void sendToParent(SendRequest& req); - virtual void added(umundo::ServiceDescription); + virtual void receive(void* object, umundo::Message* msg); + + virtual void added(umundo::ServiceDescription); virtual void removed(umundo::ServiceDescription); virtual void changed(umundo::ServiceDescription); - + protected: - std::string _invokeId; - bool _isService; - - bool dataToProtobuf(google::protobuf::Message* msg, Data& data); - bool protobufToData(Data& data, const google::protobuf::Message& msg); - - umundo::TypedPublisher _pub; - umundo::TypedSubscriber _sub; - umundo::Node _node; - - umundo::ServiceFilter _svcFilter; - umundo::ServiceManager _svcMgr; - std::map<umundo::ServiceDescription, umundo::ServiceStub*> _svcs; - - static std::map<std::string, umundo::Node> _nodes; - static umundo::Node getNode(Interpreter* interpreter); + std::string _invokeId; + bool _isService; + + bool dataToProtobuf(google::protobuf::Message* msg, Data& data); + bool protobufToData(Data& data, const google::protobuf::Message& msg); + + umundo::TypedPublisher _pub; + umundo::TypedSubscriber _sub; + umundo::Node _node; + + umundo::ServiceFilter _svcFilter; + umundo::ServiceManager _svcMgr; + std::map<umundo::ServiceDescription, umundo::ServiceStub*> _svcs; + + static std::map<std::string, umundo::Node> _nodes; + static umundo::Node getNode(Interpreter* interpreter); }; #ifdef BUILD_AS_PLUGINS diff --git a/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp index 44c89ae..bed9f98 100644 --- a/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp @@ -28,9 +28,9 @@ namespace uscxml { #ifdef BUILD_AS_PLUGINS PLUMA_CONNECTOR -bool connect(pluma::Host& host){ - host.add( new EventIOProcessorProvider() ); - return true; +bool connect(pluma::Host& host) { + host.add( new EventIOProcessorProvider() ); + return true; } #endif @@ -40,199 +40,227 @@ EventIOProcessor::EventIOProcessor() { } EventIOProcessor::~EventIOProcessor() { - _asyncQueue.stop(); - evdns_base_free(_dns, 1); - EventIOServer* httpServer = EventIOServer::getInstance(); - httpServer->unregisterProcessor(this); + _asyncQueue.stop(); + evdns_base_free(_dns, 1); + EventIOServer* httpServer = EventIOServer::getInstance(); + httpServer->unregisterProcessor(this); } IOProcessor* EventIOProcessor::create(Interpreter* interpreter) { - EventIOProcessor* io = new EventIOProcessor(); - io->_interpreter = interpreter; - - io->_dns = evdns_base_new(io->_asyncQueue._eventLoop, 1); - assert(io->_dns); - assert(evdns_base_count_nameservers(io->_dns) > 0); - - // register at http server - EventIOServer* httpServer = EventIOServer::getInstance(); - httpServer->registerProcessor(io); - - io->start(); - return io; + EventIOProcessor* io = new EventIOProcessor(); + io->_interpreter = interpreter; + + io->_dns = evdns_base_new(io->_asyncQueue._eventLoop, 1); + assert(io->_dns); + assert(evdns_base_count_nameservers(io->_dns) > 0); + + // register at http server + EventIOServer* httpServer = EventIOServer::getInstance(); + httpServer->registerProcessor(io); + + io->start(); + return io; } void EventIOProcessor::start() { - _asyncQueue.start(); + _asyncQueue.start(); } Data EventIOProcessor::getDataModelVariables() { Data data; - assert(_url.length() > 0); - data.compound["location"] = Data(_url, Data::VERBATIM); + assert(_url.length() > 0); + data.compound["location"] = Data(_url, Data::VERBATIM); return data; } void EventIOProcessor::send(SendRequest& req) { - // I cant figure out how to copy the reference into the struct :( - _sendData[req.sendid].req = req; - _sendData[req.sendid].ioProcessor = this; - - int err = 0; - char uriBuf[1024]; - - struct evhttp_uri* targetURI = evhttp_uri_parse(_sendData[req.sendid].req.target.c_str()); - if (evhttp_uri_get_port(targetURI) == 0) - evhttp_uri_set_port(targetURI, 80); - const char* hostName = evhttp_uri_get_host(targetURI); - - // use synchronous dns resolving for multicast dns - if(hostName && strlen(hostName) >= strlen(".local")) { - if(strcmp(hostName + strlen(hostName) - strlen(".local"), ".local") == 0) { - evhttp_uri_set_host(targetURI, EventIOServer::syncResolve(hostName).c_str()); - } - } - evhttp_uri_join(targetURI, uriBuf, 1024); - - LOG(INFO) << "URI for send request: " << uriBuf << std::endl; - - std::stringstream ssEndPoint; - ssEndPoint << evhttp_uri_get_host(targetURI) << ":" << evhttp_uri_get_port(targetURI); - std::string endPoint = ssEndPoint.str(); - - std::stringstream ssLocalURI; - ssLocalURI << evhttp_uri_get_path(targetURI) << evhttp_uri_get_fragment(targetURI); - std::string localURI = ssLocalURI.str(); - - if (_httpConnections.find(endPoint) == _httpConnections.end()) - _httpConnections[endPoint] = evhttp_connection_base_new(_asyncQueue._eventLoop, _dns, evhttp_uri_get_host(targetURI), evhttp_uri_get_port(targetURI)); - - struct evhttp_connection* httpConn = _httpConnections[endPoint]; - struct evhttp_request* httpReq = evhttp_request_new(EventIOProcessor::httpSendReqDone, this); - + // I cant figure out how to copy the reference into the struct :( + _sendData[req.sendid].req = req; + _sendData[req.sendid].ioProcessor = this; + + int err = 0; + char uriBuf[1024]; + + struct evhttp_uri* targetURI = evhttp_uri_parse(_sendData[req.sendid].req.target.c_str()); + if (evhttp_uri_get_port(targetURI) == 0) + evhttp_uri_set_port(targetURI, 80); + const char* hostName = evhttp_uri_get_host(targetURI); + + // use synchronous dns resolving for multicast dns + if(hostName && strlen(hostName) >= strlen(".local")) { + if(strcmp(hostName + strlen(hostName) - strlen(".local"), ".local") == 0) { + evhttp_uri_set_host(targetURI, EventIOServer::syncResolve(hostName).c_str()); + } + } + evhttp_uri_join(targetURI, uriBuf, 1024); + + LOG(INFO) << "URI for send request: " << uriBuf << std::endl; + + int port = evhttp_uri_get_port(targetURI); + if (port <= 0) + port = 80; + + std::stringstream ssEndPoint; + ssEndPoint << evhttp_uri_get_host(targetURI) << ":" << port; + std::string endPoint = ssEndPoint.str(); + + std::stringstream ssLocalURI; + ssLocalURI << evhttp_uri_get_path(targetURI) << evhttp_uri_get_fragment(targetURI); + std::string localURI = ssLocalURI.str(); + + if (_httpConnections.find(endPoint) == _httpConnections.end()) + _httpConnections[endPoint] = evhttp_connection_base_new(_asyncQueue._eventLoop, _dns, evhttp_uri_get_host(targetURI), evhttp_uri_get_port(targetURI)); + + struct evhttp_connection* httpConn = _httpConnections[endPoint]; + struct evhttp_request* httpReq = evhttp_request_new(EventIOProcessor::httpSendReqDone, this); + + // event name + if (req.name.size() > 0) { + evhttp_add_header(evhttp_request_get_output_headers(httpReq), "_scxmleventname", evhttp_encode_uri(req.name.c_str())); + } + + // event namelist + if (req.namelist.size() > 0) { + std::map<std::string, std::string>::iterator namelistIter = req.namelist.begin(); + while (namelistIter != req.namelist.end()) { + evhttp_add_header(evhttp_request_get_output_headers(httpReq), + namelistIter->first.c_str(), + evhttp_encode_uri(namelistIter->second.c_str())); + namelistIter++; + } + } + + // event params + if (req.params.size() > 0) { + std::multimap<std::string, std::string>::iterator paramIter = req.params.begin(); + while (paramIter != req.params.end()) { + evhttp_add_header(evhttp_request_get_output_headers(httpReq), + paramIter->first.c_str(), + evhttp_encode_uri(paramIter->second.c_str())); + paramIter++; + } + } + + // content + if (req.content.size() > 0) + evbuffer_add(evhttp_request_get_output_buffer(httpReq), req.content.c_str(), req.content.size()); + #if 0 - // event name - if (sendData->req.event.size() > 0) { - evhttp_add_header(evhttp_request_get_output_headers(httpReq), "_scxmleventname", evhttp_encode_uri(sendData->req.event.c_str())); - } - - // event namelist - if (sendData->req.namelist.size() > 0) { - std::map<std::string, std::string>::iterator namelistIter = sendData->req.namelist.begin(); - while (namelistIter != sendData->req.namelist.end()) { - evhttp_add_header(evhttp_request_get_output_headers(httpReq), - namelistIter->first.c_str(), - evhttp_encode_uri(namelistIter->second.c_str())); - namelistIter++; - } - } - - // event params - if (sendData->req.params.size() > 0) { - std::map<std::string, std::string>::iterator paramIter = sendData->req.params.begin(); - while (paramIter != sendData->req.params.end()) { - evhttp_add_header(evhttp_request_get_output_headers(httpReq), - paramIter->first.c_str(), - evhttp_encode_uri(paramIter->second.c_str())); - paramIter++; - } - } - - // content - if (sendData->req.content.size() > 0) - evbuffer_add(evhttp_request_get_output_buffer(httpReq), sendData->req.content.c_str(), sendData->req.content.size()); + evhttp_add_header(evhttp_request_get_output_headers(httpReq), "_scxmleventstruct", evhttp_encode_uri(req.toXMLString().c_str())); #endif - - evhttp_add_header(evhttp_request_get_output_headers(httpReq), "_scxmleventstruct", evhttp_encode_uri(req.toXMLString().c_str())); - - - _httpRequests[req.sendid] = httpReq; - err = evhttp_make_request(httpConn, - httpReq, - EVHTTP_REQ_POST, localURI.c_str()); - if (err) { - LOG(ERROR) << "Could not make http request to " << req.target; - } + // required as per http 1.1 RFC2616 section 14.23 + evhttp_add_header(evhttp_request_get_output_headers(httpReq), "Host", evhttp_uri_get_host(targetURI)); + + _httpRequests[req.sendid] = httpReq; + err = evhttp_make_request(httpConn, + httpReq, + EVHTTP_REQ_POST, localURI.c_str()); + if (err) { + LOG(ERROR) << "Could not make http request to " << req.target; + } } void EventIOProcessor::httpRecvReq(struct evhttp_request *req, void *arg) { - + const char *cmdtype; struct evkeyvalq *headers; struct evkeyval *header; struct evbuffer *buf; - switch (evhttp_request_get_command(req)) { - case EVHTTP_REQ_GET: cmdtype = "GET"; break; - case EVHTTP_REQ_POST: cmdtype = "POST"; break; - case EVHTTP_REQ_HEAD: cmdtype = "HEAD"; break; - case EVHTTP_REQ_PUT: cmdtype = "PUT"; break; - case EVHTTP_REQ_DELETE: cmdtype = "DELETE"; break; - case EVHTTP_REQ_OPTIONS: cmdtype = "OPTIONS"; break; - case EVHTTP_REQ_TRACE: cmdtype = "TRACE"; break; - case EVHTTP_REQ_CONNECT: cmdtype = "CONNECT"; break; - case EVHTTP_REQ_PATCH: cmdtype = "PATCH"; break; - default: cmdtype = "unknown"; break; + switch (evhttp_request_get_command(req)) { + case EVHTTP_REQ_GET: + cmdtype = "GET"; + break; + case EVHTTP_REQ_POST: + cmdtype = "POST"; + break; + case EVHTTP_REQ_HEAD: + cmdtype = "HEAD"; + break; + case EVHTTP_REQ_PUT: + cmdtype = "PUT"; + break; + case EVHTTP_REQ_DELETE: + cmdtype = "DELETE"; + break; + case EVHTTP_REQ_OPTIONS: + cmdtype = "OPTIONS"; + break; + case EVHTTP_REQ_TRACE: + cmdtype = "TRACE"; + break; + case EVHTTP_REQ_CONNECT: + cmdtype = "CONNECT"; + break; + case EVHTTP_REQ_PATCH: + cmdtype = "PATCH"; + break; + default: + cmdtype = "unknown"; + break; } - Event reqEvent; - reqEvent.type = Event::EXTERNAL; - bool scxmlStructFound = false; - - // map headers to event structure - headers = evhttp_request_get_input_headers(req); + Event reqEvent; + reqEvent.type = Event::EXTERNAL; + bool scxmlStructFound = false; + + // map headers to event structure + headers = evhttp_request_get_input_headers(req); for (header = headers->tqh_first; header; - header = header->next.tqe_next) { + header = header->next.tqe_next) { // std::cout << "Header: " << header->key << std::endl; // std::cout << "Value: " << evhttp_decode_uri(header->value) << std::endl; - if (boost::iequals("_scxmleventstruct", header->key)) { - reqEvent = Event::fromXML(evhttp_decode_uri(header->value)); - scxmlStructFound = true; - break; - } else if (boost::iequals("_scxmleventname", header->key)) { - reqEvent.name = evhttp_decode_uri(header->value); - } else { - reqEvent.compound[header->key] = Data(evhttp_decode_uri(header->value), Data::VERBATIM); - } + if (boost::iequals("_scxmleventstruct", header->key)) { + reqEvent = Event::fromXML(evhttp_decode_uri(header->value)); + scxmlStructFound = true; + break; + } else if (boost::iequals("_scxmleventname", header->key)) { + reqEvent.name = evhttp_decode_uri(header->value); + } else { + reqEvent.compound[header->key] = Data(evhttp_decode_uri(header->value), Data::VERBATIM); + } } - if (!scxmlStructFound) { - // get content into event - std::string content; - buf = evhttp_request_get_input_buffer(req); - while (evbuffer_get_length(buf)) { - int n; - char cbuf[128]; - n = evbuffer_remove(buf, cbuf, sizeof(buf)-1); - if (n > 0) { - content.append(cbuf, n); - } - } - reqEvent.compound["content"] = Data(content, Data::VERBATIM); - } - - EventIOProcessor* INSTANCE = (EventIOProcessor*)arg; - INSTANCE->_interpreter->receive(reqEvent); - + if (reqEvent.name.length() == 0) + reqEvent.name = cmdtype; + + if (!scxmlStructFound) { + // get content into event + std::string content; + buf = evhttp_request_get_input_buffer(req); + while (evbuffer_get_length(buf)) { + int n; + char cbuf[128]; + n = evbuffer_remove(buf, cbuf, sizeof(buf)-1); + if (n > 0) { + content.append(cbuf, n); + } + } + reqEvent.compound["content"] = Data(content, Data::VERBATIM); + } + + EventIOProcessor* INSTANCE = (EventIOProcessor*)arg; + INSTANCE->_interpreter->receive(reqEvent); + evhttp_send_reply(req, 200, "OK", NULL); } void EventIOProcessor::httpSendReqDone(struct evhttp_request *req, void *cb_arg) { - if (req) { - LOG(INFO) << "got return code " << evhttp_request_get_response_code(req) << std::endl; - } + if (req) { + LOG(INFO) << "got return code " << evhttp_request_get_response_code(req) << std::endl; + } } EventIOServer::EventIOServer(unsigned short port) { - _port = port; - _base = event_base_new(); - _http = evhttp_new(_base); - _handle = NULL; - while((_handle = evhttp_bind_socket_with_handle(_http, INADDR_ANY, _port)) == NULL) { - _port++; - } - determineAddress(); + _port = port; + _base = event_base_new(); + _http = evhttp_new(_base); + _handle = NULL; + while((_handle = evhttp_bind_socket_with_handle(_http, INADDR_ANY, _port)) == NULL) { + _port++; + } + determineAddress(); } EventIOServer::~EventIOServer() { @@ -242,128 +270,128 @@ EventIOServer* EventIOServer::_instance = NULL; tthread::recursive_mutex EventIOServer::_instanceMutex; EventIOServer* EventIOServer::getInstance() { - tthread::lock_guard<tthread::recursive_mutex> lock(_instanceMutex); - if (_instance == NULL) { - _instance = new EventIOServer(8080); - _instance->start(); - } - return _instance; + tthread::lock_guard<tthread::recursive_mutex> lock(_instanceMutex); + if (_instance == NULL) { + _instance = new EventIOServer(8080); + _instance->start(); + } + return _instance; } void EventIOServer::registerProcessor(EventIOProcessor* processor) { - EventIOServer* INSTANCE = getInstance(); - tthread::lock_guard<tthread::recursive_mutex> lock(INSTANCE->_mutex); - - /** - * Determine path for interpreter. - * - * If the interpreter has a name and it is not yet taken, choose it as the path - * for requests. If the interpreters name path is already taken, append digits - * until we have an available path. - * - * If the interpreter does not specify a name, take its sessionid. - */ - - std::string path = processor->_interpreter->getName(); - if (path.size() == 0) { - path = processor->_interpreter->getSessionId(); - } - assert(path.size() > 0); - - std::stringstream actualPath(path); - int i = 1; - while(INSTANCE->_processors.find(actualPath.str()) != INSTANCE->_processors.end()) { - actualPath.str(std::string()); - actualPath.clear(); - actualPath << path << ++i; - } - - std::stringstream processorURL; - processorURL << "http://" << INSTANCE->_address << ":" << INSTANCE->_port << "/" << actualPath.str(); - - INSTANCE->_processors[actualPath.str()] = processor; - processor->setURL(processorURL.str()); - - evhttp_set_cb(INSTANCE->_http, ("/" + actualPath.str()).c_str(), EventIOProcessor::httpRecvReq, processor); + EventIOServer* INSTANCE = getInstance(); + tthread::lock_guard<tthread::recursive_mutex> lock(INSTANCE->_mutex); + + /** + * Determine path for interpreter. + * + * If the interpreter has a name and it is not yet taken, choose it as the path + * for requests. If the interpreters name path is already taken, append digits + * until we have an available path. + * + * If the interpreter does not specify a name, take its sessionid. + */ + + std::string path = processor->_interpreter->getName(); + if (path.size() == 0) { + path = processor->_interpreter->getSessionId(); + } + assert(path.size() > 0); + + std::stringstream actualPath(path); + int i = 1; + while(INSTANCE->_processors.find(actualPath.str()) != INSTANCE->_processors.end()) { + actualPath.str(std::string()); + actualPath.clear(); + actualPath << path << ++i; + } + + std::stringstream processorURL; + processorURL << "http://" << INSTANCE->_address << ":" << INSTANCE->_port << "/" << actualPath.str(); + + INSTANCE->_processors[actualPath.str()] = processor; + processor->setURL(processorURL.str()); + + evhttp_set_cb(INSTANCE->_http, ("/" + actualPath.str()).c_str(), EventIOProcessor::httpRecvReq, processor); // evhttp_set_cb(THIS->_http, "/", EventIOProcessor::httpRecvReq, processor); // evhttp_set_gencb(THIS->_http, EventIOProcessor::httpRecvReq, NULL); } void EventIOServer::unregisterProcessor(EventIOProcessor* processor) { - EventIOServer* INSTANCE = getInstance(); - tthread::lock_guard<tthread::recursive_mutex> lock(INSTANCE->_mutex); - evhttp_del_cb(INSTANCE->_http, processor->_url.c_str()); + EventIOServer* INSTANCE = getInstance(); + tthread::lock_guard<tthread::recursive_mutex> lock(INSTANCE->_mutex); + evhttp_del_cb(INSTANCE->_http, processor->_url.c_str()); } - + void EventIOServer::start() { - _isRunning = true; - _thread = new tthread::thread(EventIOServer::run, this); + _isRunning = true; + _thread = new tthread::thread(EventIOServer::run, this); } void EventIOServer::run(void* instance) { - EventIOServer* INSTANCE = (EventIOServer*)instance; - while(INSTANCE->_isRunning) { - LOG(INFO) << "Dispatching HTTP Server" << std::endl; - event_base_dispatch(INSTANCE->_base); - } - LOG(INFO) << "HTTP Server stopped" << std::endl; + EventIOServer* INSTANCE = (EventIOServer*)instance; + while(INSTANCE->_isRunning) { + LOG(INFO) << "Dispatching HTTP Server" << std::endl; + event_base_dispatch(INSTANCE->_base); + } + LOG(INFO) << "HTTP Server stopped" << std::endl; } std::string EventIOServer::syncResolve(const std::string& hostname) { - struct hostent *he; - struct in_addr **addr_list; - int i; - - if ( (he = gethostbyname( hostname.c_str() ) ) != NULL) { - addr_list = (struct in_addr **) he->h_addr_list; - for(i = 0; addr_list[i] != NULL; i++) { - return std::string(inet_ntoa(*addr_list[i])); - } - } - return ""; + struct hostent *he; + struct in_addr **addr_list; + int i; + + if ( (he = gethostbyname( hostname.c_str() ) ) != NULL) { + addr_list = (struct in_addr **) he->h_addr_list; + for(i = 0; addr_list[i] != NULL; i++) { + return std::string(inet_ntoa(*addr_list[i])); + } + } + return ""; } - + void EventIOServer::determineAddress() { - char hostname[1024]; - gethostname(hostname, 1024); - _address = std::string(hostname); - + char hostname[1024]; + gethostname(hostname, 1024); + _address = std::string(hostname); + #if 0 - struct sockaddr_storage ss; - evutil_socket_t fd; - ev_socklen_t socklen = sizeof(ss); - char addrbuf[128]; - - void *inaddr; - const char *addr; - int got_port = -1; - fd = evhttp_bound_socket_get_fd(_handle); - memset(&ss, 0, sizeof(ss)); - if (getsockname(fd, (struct sockaddr *)&ss, &socklen)) { - perror("getsockname() failed"); - return; - } - - if (ss.ss_family == AF_INET) { - got_port = ntohs(((struct sockaddr_in*)&ss)->sin_port); - inaddr = &((struct sockaddr_in*)&ss)->sin_addr; - } else if (ss.ss_family == AF_INET6) { - got_port = ntohs(((struct sockaddr_in6*)&ss)->sin6_port); - inaddr = &((struct sockaddr_in6*)&ss)->sin6_addr; - } else { - fprintf(stderr, "Weird address family %d\n", - ss.ss_family); - return; - } - addr = evutil_inet_ntop(ss.ss_family, inaddr, addrbuf, - sizeof(addrbuf)); - if (addr) { - _address = std::string(addr); - } else { - fprintf(stderr, "evutil_inet_ntop failed\n"); - return; - } + struct sockaddr_storage ss; + evutil_socket_t fd; + ev_socklen_t socklen = sizeof(ss); + char addrbuf[128]; + + void *inaddr; + const char *addr; + int got_port = -1; + fd = evhttp_bound_socket_get_fd(_handle); + memset(&ss, 0, sizeof(ss)); + if (getsockname(fd, (struct sockaddr *)&ss, &socklen)) { + perror("getsockname() failed"); + return; + } + + if (ss.ss_family == AF_INET) { + got_port = ntohs(((struct sockaddr_in*)&ss)->sin_port); + inaddr = &((struct sockaddr_in*)&ss)->sin_addr; + } else if (ss.ss_family == AF_INET6) { + got_port = ntohs(((struct sockaddr_in6*)&ss)->sin6_port); + inaddr = &((struct sockaddr_in6*)&ss)->sin6_addr; + } else { + fprintf(stderr, "Weird address family %d\n", + ss.ss_family); + return; + } + addr = evutil_inet_ntop(ss.ss_family, inaddr, addrbuf, + sizeof(addrbuf)); + if (addr) { + _address = std::string(addr); + } else { + fprintf(stderr, "evutil_inet_ntop failed\n"); + return; + } #endif } diff --git a/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h b/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h index af7aac7..f0228e9 100644 --- a/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h +++ b/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h @@ -18,84 +18,86 @@ namespace uscxml { class EventIOServer; - + class EventIOProcessor : public uscxml::IOProcessor { public: - struct SendData { - EventIOProcessor* ioProcessor; - uscxml::SendRequest req; - }; - - EventIOProcessor(); - virtual ~EventIOProcessor(); - virtual IOProcessor* create(uscxml::Interpreter* interpreter); - - virtual std::set<std::string> getNames() { + struct SendData { + EventIOProcessor* ioProcessor; + uscxml::SendRequest req; + }; + + EventIOProcessor(); + virtual ~EventIOProcessor(); + virtual IOProcessor* create(uscxml::Interpreter* interpreter); + + virtual std::set<std::string> getNames() { std::set<std::string> names; names.insert("basichttp"); names.insert("http://www.w3.org/TR/scxml/#SCXMLEventProcessor"); return names; } - virtual void send(uscxml::SendRequest& req); + virtual void send(uscxml::SendRequest& req); Data getDataModelVariables(); - void setURL(const std::string& url) { _url = url; } - - void start(); - static void run(void* instance); + void setURL(const std::string& url) { + _url = url; + } + + void start(); + static void run(void* instance); - static void httpMakeSendReq(void* userdata, std::string eventName); - static void httpSendReqDone(struct evhttp_request *req, void *cb_arg); - static void httpRecvReq(struct evhttp_request *req, void *arg); + static void httpMakeSendReq(void* userdata, std::string eventName); + static void httpSendReqDone(struct evhttp_request *req, void *cb_arg); + static void httpRecvReq(struct evhttp_request *req, void *arg); protected: - std::map<std::string, SendData> _sendData; - - std::string _url; - - uscxml::DelayedEventQueue _asyncQueue; - uscxml::Interpreter* _interpreter; - std::map<std::string, struct evhttp_connection*> _httpConnections; - std::map<std::string, struct evhttp_request*> _httpRequests; - struct evdns_base* _dns; - - friend class EventIOServer; + std::map<std::string, SendData> _sendData; + + std::string _url; + + uscxml::DelayedEventQueue _asyncQueue; + uscxml::Interpreter* _interpreter; + std::map<std::string, struct evhttp_connection*> _httpConnections; + std::map<std::string, struct evhttp_request*> _httpRequests; + struct evdns_base* _dns; + + friend class EventIOServer; }; class EventIOServer { private: - static EventIOServer* getInstance(); - EventIOServer(unsigned short port); - ~EventIOServer(); - - void start(); - void stop(); - static void run(void* instance); - - void determineAddress(); - static std::string syncResolve(const std::string& hostname); - - static void registerProcessor(EventIOProcessor* processor); - static void unregisterProcessor(EventIOProcessor* processor); - - - std::map<std::string, EventIOProcessor*> _processors; - - struct event_base* _base; - struct evhttp* _http; - struct evhttp_bound_socket* _handle; - - unsigned short _port; - std::string _address; - - static EventIOServer* _instance; - static tthread::recursive_mutex _instanceMutex; - tthread::thread* _thread; - tthread::recursive_mutex _mutex; - bool _isRunning; - - friend class EventIOProcessor; + static EventIOServer* getInstance(); + EventIOServer(unsigned short port); + ~EventIOServer(); + + void start(); + void stop(); + static void run(void* instance); + + void determineAddress(); + static std::string syncResolve(const std::string& hostname); + + static void registerProcessor(EventIOProcessor* processor); + static void unregisterProcessor(EventIOProcessor* processor); + + + std::map<std::string, EventIOProcessor*> _processors; + + struct event_base* _base; + struct evhttp* _http; + struct evhttp_bound_socket* _handle; + + unsigned short _port; + std::string _address; + + static EventIOServer* _instance; + static tthread::recursive_mutex _instanceMutex; + tthread::thread* _thread; + tthread::recursive_mutex _mutex; + bool _isRunning; + + friend class EventIOProcessor; }; #ifdef BUILD_AS_PLUGINS |