summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2012-12-20 21:34:09 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2012-12-20 21:34:09 (GMT)
commit498f6f80e9ca01236ca1491596875ab7eb4cd8c3 (patch)
treee627ae19475bb93a98dfa50db1950f6e3403f569
parentd779abe6ff76a78f92d229fcf1f006f5cf1f9295 (diff)
downloaduscxml-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
-rw-r--r--CMakeLists.txt93
-rw-r--r--apps/mmi-browser.cpp33
-rw-r--r--config.h.in1
-rw-r--r--contrib/cmake/FindArabica.cmake4
-rw-r--r--contrib/cmake/FindGMP.cmake42
-rw-r--r--contrib/cmake/FindSWI.cmake86
-rwxr-xr-xcontrib/local/beautifyCode.sh29
-rwxr-xr-xcontrib/local/compress_and_upload_deps.sh8
-rw-r--r--contrib/prebuilt/uscxml-prebuilt-windows-x86-0.0.1.tgzbin3652287 -> 0 bytes
-rw-r--r--src/uscxml/Factory.cpp297
-rw-r--r--src/uscxml/Factory.h189
-rw-r--r--src/uscxml/Interpreter.cpp3411
-rw-r--r--src/uscxml/Interpreter.h655
-rw-r--r--src/uscxml/Message.cpp474
-rw-r--r--src/uscxml/Message.h155
-rw-r--r--src/uscxml/URL.cpp673
-rw-r--r--src/uscxml/URL.h31
-rw-r--r--src/uscxml/concurrency/BlockingQueue.h30
-rw-r--r--src/uscxml/concurrency/eventqueue/DelayedEventQueue.cpp157
-rw-r--r--src/uscxml/concurrency/eventqueue/DelayedEventQueue.h37
-rw-r--r--src/uscxml/concurrency/tinythread.cpp294
-rw-r--r--src/uscxml/concurrency/tinythread.h773
-rw-r--r--src/uscxml/debug/SCXMLDotWriter.h50
-rw-r--r--src/uscxml/plugins/Plugins.cpp2
-rw-r--r--[-rwxr-xr-x]src/uscxml/plugins/Pluma/DLibrary.cpp105
-rw-r--r--[-rwxr-xr-x]src/uscxml/plugins/Pluma/Dir.cpp114
-rw-r--r--[-rwxr-xr-x]src/uscxml/plugins/Pluma/Host.cpp186
-rw-r--r--[-rwxr-xr-x]src/uscxml/plugins/Pluma/PluginManager.cpp214
-rw-r--r--[-rwxr-xr-x]src/uscxml/plugins/Pluma/Provider.cpp22
-rw-r--r--[-rwxr-xr-x]src/uscxml/plugins/Pluma/uce-dirent.h746
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp566
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h94
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLDOM.cpp398
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLDOM.h68
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp103
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h66
-rw-r--r--src/uscxml/plugins/invoker/modality/MMIComponent.cpp28
-rw-r--r--src/uscxml/plugins/invoker/modality/MMIComponent.h52
-rw-r--r--src/uscxml/plugins/invoker/modality/UmundoComponent.cpp44
-rw-r--r--src/uscxml/plugins/invoker/modality/UmundoComponent.h26
-rw-r--r--src/uscxml/plugins/invoker/modality/miles/SpatialAudio.cpp280
-rw-r--r--src/uscxml/plugins/invoker/modality/miles/SpatialAudio.h46
-rw-r--r--src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp51
-rw-r--r--src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h26
-rw-r--r--src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp847
-rw-r--r--src/uscxml/plugins/invoker/umundo/UmundoInvoker.h57
-rw-r--r--src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp546
-rw-r--r--src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h124
-rw-r--r--test/CMakeLists.txt17
-rw-r--r--test/samples/uscxml/test-ecmascript.scxml8
-rw-r--r--test/samples/uscxml/test-prolog.scxml15
-rw-r--r--test/src/test-apache-commons.cpp138
-rw-r--r--test/src/test-communication.cpp38
-rw-r--r--test/src/test-completion.cpp20
-rw-r--r--test/src/test-ecmascript-v8.cpp34
-rw-r--r--test/src/test-eventdelay.cpp26
-rw-r--r--test/src/test-execution.cpp24
-rw-r--r--test/src/test-predicates.cpp108
-rw-r--r--test/src/test-prolog-swi.cpp25
59 files changed, 6613 insertions, 6173 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 370e217..db87084 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -82,17 +82,17 @@ else ()
endif()
endif()
-SET(USCXML_LIBRARY_HOST_URL_PREFIX "http://umundo.tk.informatik.tu-darmstadt.de/uscxml/prebuilt" CACHE STRING "The root path of an URL where to look for prebuilt libraries.")
+SET(USCXML_LIBRARY_HOST_URL_PREFIX "http://uscxml.tk.informatik.tu-darmstadt.de/prebuilt" CACHE STRING "The root path of an URL where to look for prebuilt libraries.")
if (WIN32 AND 64BIT_HOST)
- SET(USCXML_LIBRARY_ARCHIVE_NAME uscxml-prebuilt-${CMAKE_SYSTEM_NAME_LC}-${CMAKE_SYSTEM_PROCESSOR}_64-${USCXML_VERSION}.tgz)
+ SET(USCXML_LIBRARY_ARCHIVE_NAME uscxml-prebuilt-${CMAKE_SYSTEM_NAME_LC}-${CMAKE_SYSTEM_PROCESSOR}_64.tgz)
else()
- SET(USCXML_LIBRARY_ARCHIVE_NAME uscxml-prebuilt-${CMAKE_SYSTEM_NAME_LC}-${CMAKE_SYSTEM_PROCESSOR}-${USCXML_VERSION}.tgz)
+ SET(USCXML_LIBRARY_ARCHIVE_NAME uscxml-prebuilt-${CMAKE_SYSTEM_NAME_LC}-${CMAKE_SYSTEM_PROCESSOR}.tgz)
endif()
if (NOT EXISTS ${USCXML_PREBUILT_LIBRARY_PATH})
- message(STATUS "Downloading prebuilt libraries: ${USCXML_LIBRARY_HOST_URL_PREFIX}/${USCXML_LIBRARY_ARCHIVE_NAME}")
- file(DOWNLOAD ${USCXML_LIBRARY_HOST_URL_PREFIX}/${USCXML_LIBRARY_ARCHIVE_NAME}
+ message(STATUS "Downloading prebuilt libraries: ${USCXML_LIBRARY_HOST_URL_PREFIX}/${USCXML_VERSION}/${USCXML_LIBRARY_ARCHIVE_NAME}")
+ file(DOWNLOAD ${USCXML_LIBRARY_HOST_URL_PREFIX}/${USCXML_VERSION}/${USCXML_LIBRARY_ARCHIVE_NAME}
${PROJECT_SOURCE_DIR}/contrib/prebuilt/${USCXML_LIBRARY_ARCHIVE_NAME}
INACTIVITY_TIMEOUT 60 STATUS DOWNLOAD_STATUS SHOW_PROGRESS)
list(GET DOWNLOAD_STATUS 0 STATUS_CODE)
@@ -215,6 +215,8 @@ elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
add_definitions("-Wno-parentheses-equality")
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-fPIC")
+ # set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -read_only_relocs suppress")
+ # set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -read_only_relocs suppress")
else()
message(FATAL_ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}")
endif()
@@ -376,10 +378,7 @@ list (APPEND USCXML_FILES ${USCXML_CORE})
include_directories(src)
-#################################################
-# optional libraries we can build as plugins
-
-OPTION(BUILD_AS_PLUGINS "Build invokers, ioprocessors and datamodels as plugins" ON)
+OPTION(BUILD_AS_PLUGINS "Build invokers, ioprocessors and datamodels as plugins" OFF)
if (BUILD_AS_PLUGINS)
include_directories(${PROJECT_SOURCE_DIR}/src/uscxml/plugins)
file(GLOB PLUMA
@@ -392,6 +391,12 @@ if (BUILD_AS_PLUGINS)
add_definitions("-DBUILD_AS_PLUGINS")
endif()
+if (BUILD_AS_PLUGINS)
+ add_library(uscxml ${USCXML_FILES})
+endif()
+
+#################################################
+# optional libraries we can build as plugins
# LIBEVENT basichttp ioprocessor - this one is already required above
@@ -404,11 +409,8 @@ file(GLOB_RECURSE LIBEVENT_IOPROCESSOR
if (BUILD_AS_PLUGINS)
add_library(
ioprocessor_basichttp SHARED
- ${LIBEVENT_IOPROCESSOR}
- ${PLUMA}
- ${USCXML_FILES})
- target_link_libraries(ioprocessor_basichttp
- ${USCXML_CORE_LIBS})
+ ${LIBEVENT_IOPROCESSOR})
+ target_link_libraries(ioprocessor_basichttp uscxml)
set_target_properties(ioprocessor_basichttp PROPERTIES FOLDER "Plugin IOProcessor")
else()
list (APPEND USCXML_FILES ${LIBEVENT_IOPROCESSOR})
@@ -428,11 +430,9 @@ if (V8_FOUND)
if (BUILD_AS_PLUGINS)
add_library(
datamodel_v8 SHARED
- ${V8_DATAMODEL}
- ${PLUMA}
- ${USCXML_FILES})
+ ${V8_DATAMODEL})
target_link_libraries(datamodel_v8
- ${USCXML_CORE_LIBS}
+ uscxml
${V8_LIBRARY})
set_target_properties(datamodel_v8 PROPERTIES FOLDER "Plugin DataModel")
else()
@@ -442,6 +442,37 @@ if (V8_FOUND)
endif()
+# SWI PROLOG datamodel
+
+# set(ENV{V8_SRC} ${CMAKE_SOURCE_DIR}/../v8)
+find_package(SWI)
+#find_package(GMP)
+#find_package(CURSES)
+if (SWI_FOUND)
+ include_directories(${SWI_INCLUDE_DIR})
+# include_directories(${GMP_INCLUDE_DIR})
+# include_directories(${CURSES_INCLUDE_DIR})
+ file(GLOB_RECURSE SWI_DATAMODEL
+ src/uscxml/plugins/datamodel/prolog/swi/*.cpp
+ src/uscxml/plugins/datamodel/prolog/swi/*.h
+ )
+ if (BUILD_AS_PLUGINS)
+ add_library(
+ datamodel_swi SHARED
+ ${SWI_DATAMODEL})
+ target_link_libraries(datamodel_swi
+ uscxml
+# ${GMP_LIBRARY}
+# ${CURSES_LIBRARIES}
+ ${SWI_LIBRARY})
+ set_target_properties(datamodel_swi PROPERTIES FOLDER "Plugin DataModel")
+ else()
+ list (APPEND USCXML_FILES ${SWI_DATAMODEL})
+ list (APPEND USCXML_OPT_LIBS ${SWI_LIBRARY}) # ${GMP_LIBRARY} ${CURSES_LIBRARIES})
+ endif()
+endif()
+
+
# UMUNDO invoker
if (WIN32)
@@ -457,11 +488,9 @@ if (UMUNDO_FOUND)
if (BUILD_AS_PLUGINS)
add_library(
invoker_umundo SHARED
- ${UMUNDO_INVOKER}
- ${PLUMA}
- ${USCXML_FILES})
+ ${UMUNDO_INVOKER})
target_link_libraries(invoker_umundo
- ${USCXML_CORE_LIBS}
+ uscxml
${UMUNDO_LIBRARIES})
set_target_properties(invoker_umundo PROPERTIES FOLDER "Plugin Invoker")
else()
@@ -480,11 +509,9 @@ file(GLOB_RECURSE USCXML_INVOKER
if (BUILD_AS_PLUGINS)
add_library(
invoker_uscxml SHARED
- ${USCXML_INVOKER}
- ${PLUMA}
- ${USCXML_FILES})
+ ${USCXML_INVOKER})
target_link_libraries(invoker_uscxml
- ${USCXML_CORE_LIBS})
+ uscxml)
set_target_properties(invoker_uscxml PROPERTIES FOLDER "Plugin Invoker")
else()
list (APPEND USCXML_FILES ${USCXML_INVOKER})
@@ -493,8 +520,8 @@ endif()
# MILES modality components
-find_package(MILES COMPONENTS core audio debug)
-if (MILES_FOUND)
+#find_package(MILES COMPONENTS core audio debug)
+if (MILES_FOUND AND OFF)
include_directories(${MILES_INCLUDE_DIR})
# openal is only needed for miles
@@ -505,13 +532,11 @@ if (MILES_FOUND)
if (BUILD_AS_PLUGINS)
add_library(
invoker_miles SHARED
- ${MILES_INVOKER}
- ${PLUMA}
- ${USCXML_FILES})
+ ${MILES_INVOKER})
target_link_libraries(invoker_miles
${MILES_LIBRARIES}
${OPENAL_LIBRARY}
- ${USCXML_CORE_LIBS})
+ uscxml)
set_target_properties(invoker_miles PROPERTIES FOLDER "Plugin Invoker")
else()
list (APPEND USCXML_FILES ${MILES_INVOKER})
@@ -532,7 +557,9 @@ endif()
############################################################
# build library
-add_library(uscxml ${USCXML_FILES})
+if (NOT BUILD_AS_PLUGINS)
+ add_library(uscxml ${USCXML_FILES})
+endif()
target_link_libraries(uscxml ${USCXML_OPT_LIBS} ${USCXML_CORE_LIBS})
add_executable(mmi-browser apps/mmi-browser.cpp ${PROJECT_SOURCE_DIR}/contrib/snippets/XGetopt.cpp)
diff --git a/apps/mmi-browser.cpp b/apps/mmi-browser.cpp
index e651448..97e0c96 100644
--- a/apps/mmi-browser.cpp
+++ b/apps/mmi-browser.cpp
@@ -9,7 +9,11 @@
void printUsageAndExit() {
printf("mmi-browser version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n");
printf("Usage\n");
- printf("\tmmi-browser [-p pluginPath] URL\n");
+ printf("\tmmi-browser");
+#ifdef BUILD_AS_PLUGINS
+ printf(" [-p pluginPath]");
+#endif
+ printf(" URL\n");
printf("\n");
// printf("Options\n");
// printf("\t-l loglevel : loglevel to use\n");
@@ -17,34 +21,35 @@ void printUsageAndExit() {
}
int main(int argc, char** argv) {
- using namespace uscxml;
+ using namespace uscxml;
- if (argc < 2) {
+ if (argc < 2) {
printUsageAndExit();
- }
+ }
- char* loglevel = NULL;
int option;
while ((option = getopt(argc, argv, "l:p:")) != -1) {
switch(option) {
case 'l':
- loglevel = optarg;
+ google::InitGoogleLogging(optarg);
+ break;
+ case 'p':
+ uscxml::Factory::pluginPath = optarg;
break;
- case 'p':
- uscxml::Factory::pluginPath = optarg;
- break;
default:
printUsageAndExit();
break;
}
}
-
+
+// for (int i = 0; i < argc; i++)
+// std::cout << argv[i] << std::endl;
+
Factory::getInstance();
- google::InitGoogleLogging(argv[0]);
- Interpreter* interpreter = Interpreter::fromURI(argv[1]);
+ Interpreter* interpreter = Interpreter::fromURI(argv[argc - 1]);
interpreter->interpret();
-
-
+
+
return EXIT_SUCCESS;
} \ No newline at end of file
diff --git a/config.h.in b/config.h.in
index b4036d0..6525c61 100644
--- a/config.h.in
+++ b/config.h.in
@@ -53,5 +53,6 @@
#cmakedefine UMUNDO_FOUND
#cmakedefine MILES_FOUND
#cmakedefine V8_FOUND
+#cmakedefine SWI_FOUND
#endif \ No newline at end of file
diff --git a/contrib/cmake/FindArabica.cmake b/contrib/cmake/FindArabica.cmake
index fb5423d..7ed0c7d 100644
--- a/contrib/cmake/FindArabica.cmake
+++ b/contrib/cmake/FindArabica.cmake
@@ -9,7 +9,7 @@ FIND_PATH(ARABICA_INCLUDE_DIR Arabica/getparam.hpp
/opt
HINTS $ENV{ARABICA_SRC}
)
-
+set(ARABICA_LIBRARY)
FIND_LIBRARY(ARABICA_LIBRARY_RELEASE
NAMES arabica
HINTS $ENV{ARABICA_SRC}/src/.libs/
@@ -31,4 +31,4 @@ endif()
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Arabica DEFAULT_MSG ARABICA_LIBRARY ARABICA_INCLUDE_DIR)
-MARK_AS_ADVANCED(ARABICA_LIBRARY ARABICA_INCLUDE_DIR)
+MARK_AS_ADVANCED(ARABICA_LIBRARY_RELEASE ARABICA_LIBRARY_DEBUG)
diff --git a/contrib/cmake/FindGMP.cmake b/contrib/cmake/FindGMP.cmake
new file mode 100644
index 0000000..2926a98
--- /dev/null
+++ b/contrib/cmake/FindGMP.cmake
@@ -0,0 +1,42 @@
+FIND_PATH(GMP_INCLUDE_DIR gmp.h
+ PATH_SUFFIXES include
+ PATHS
+ /usr/local
+ /usr
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+ HINTS $ENV{GMP_SRC}
+)
+
+FIND_LIBRARY(GMP_LIBRARY_RELEASE
+ NAMES gmp
+ PATHS
+ /usr/local
+ /usr
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+ HINTS $ENV{GMP_SRC}/.libs/
+)
+if (GMP_LIBRARY_RELEASE)
+ list(APPEND GMP_LIBRARY optimized ${GMP_LIBRARY_RELEASE})
+endif()
+
+FIND_LIBRARY(GMP_LIBRARY_DEBUG
+ NAMES GMP libGMP_static_d
+ HINTS $ENV{GMP_SRC}/.libs/
+)
+if (GMP_LIBRARY_DEBUG)
+ list(APPEND GMP_LIBRARY debug ${GMP_LIBRARY_DEBUG})
+else()
+ if (UNIX)
+ list(APPEND GMP_LIBRARY debug ${GMP_LIBRARY_RELEASE})
+ endif()
+endif()
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMP DEFAULT_MSG GMP_LIBRARY GMP_INCLUDE_DIR)
+MARK_AS_ADVANCED(GMP_LIBRARY GMP_INCLUDE_DIR)
diff --git a/contrib/cmake/FindSWI.cmake b/contrib/cmake/FindSWI.cmake
new file mode 100644
index 0000000..9fbdc77
--- /dev/null
+++ b/contrib/cmake/FindSWI.cmake
@@ -0,0 +1,86 @@
+set (SWI_SEARCH_PATHS $ENV{SWI_DIR})
+list (APPEND SWI_SEARCH_PATHS
+ ${CMAKE_FIND_ROOT_PATH}
+ "/usr/lib/swi-prolog/"
+ "/opt/local/"
+ "C:/Program Files (x86)/swipl"
+ "C:/Program Files/swipl"
+)
+
+set(64BIT_HOST OFF)
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(64BIT_HOST ON)
+endif()
+
+set (SWI_HOME)
+set (LOOP_DONE 0)
+foreach(SWI_SEARCH_PATH ${SWI_SEARCH_PATHS})
+ if(NOT LOOP_DONE)
+ file(GLOB SWI_VERSIONS ${SWI_SEARCH_PATH}/lib/swipl*)
+ if (SWI_VERSIONS)
+ set(LOOP_DONE 1)
+ list(SORT SWI_VERSIONS)
+ list(REVERSE SWI_VERSIONS)
+ list(GET SWI_VERSIONS 0 SWI_HOME)
+ endif()
+ endif()
+endforeach()
+
+set (SWI_PLATFORM_PATH)
+set (LOOP_DONE 0)
+if (SWI_HOME)
+
+ set(SWI_CPU_SUFFIX ${CMAKE_SYSTEM_PROCESSOR})
+ if (APPLE)
+ if (64BIT_HOST)
+ set(SWI_CPU_SUFFIX "x86_64")
+ endif()
+ endif()
+
+ file(GLOB SWI_PLATFORMS ${SWI_HOME}/lib/*)
+ foreach(SWI_PLATFORM ${SWI_PLATFORMS})
+ STRING(REGEX REPLACE "${SWI_HOME}/lib/" "" REL_SWI_PLATFORM ${SWI_PLATFORM})
+ if(NOT LOOP_DONE)
+ if (REL_SWI_PLATFORM MATCHES ".*${SWI_CPU_SUFFIX}.*")
+ set (SWI_PLATFORM_PATH ${SWI_PLATFORM})
+ set(LOOP_DONE 1)
+ endif()
+ endif()
+ endforeach()
+endif()
+
+#message(STATUS "SWI_PLATFORM_PATH: ${SWI_PLATFORM_PATH}, SWI_HOME: ${SWI_HOME}")
+
+if (SWI_PLATFORM_PATH)
+ FIND_PATH(SWI_INCLUDE_DIR SWI-Prolog.h
+ PATH_SUFFIXES include
+ PATHS ${SWI_HOME}
+ )
+
+ FIND_LIBRARY(SWI_LIBRARY_RELEASE
+ NAMES libswipl swipl
+ PATHS ${SWI_PLATFORM_PATH}
+ )
+
+ if (SWI_LIBRARY_RELEASE)
+ list(APPEND SWI_LIBRARY optimized ${SWI_LIBRARY_RELEASE})
+ add_definitions("-DSWI_LIBRARY_PATH=\"${SWI_PLATFORM_PATH}\"")
+ endif()
+
+
+ FIND_LIBRARY(SWI_LIBRARY_DEBUG
+ NAMES libswipl_d swipl_d
+ PATHS ${SWI_PLATFORM_PATH}
+ )
+ if (SWI_LIBRARY_DEBUG)
+ list(APPEND SWI_LIBRARY debug ${SWI_LIBRARY_DEBUG})
+ elseif(UNIX)
+ list(APPEND SWI_LIBRARY debug ${SWI_LIBRARY_RELEASE})
+ else()
+ message(FATAL_ERROR "Cannot find debug version of SWI")
+ endif()
+endif()
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SWI DEFAULT_MSG SWI_LIBRARY SWI_INCLUDE_DIR)
+MARK_AS_ADVANCED(SWI_LIBRARY SWI_INCLUDE_DIR)
diff --git a/contrib/local/beautifyCode.sh b/contrib/local/beautifyCode.sh
new file mode 100755
index 0000000..d6f4c11
--- /dev/null
+++ b/contrib/local/beautifyCode.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# see http://astyle.sourceforge.net/astyle.html
+# run from project root as sh ./contrib/tidy_source.sh
+
+set -e
+
+ME=`basename $0`
+DIR="$( cd "$( dirname "$0" )" && pwd )"
+CWD=`pwd`
+
+astyle \
+ --style=java \
+ --indent=tab \
+ --recursive "${DIR}/../../src/*.cpp" "${DIR}/../../src/*.h"
+find ${DIR}/../../src/ -iname '*.orig' -exec rm {} \;
+
+astyle \
+ --style=java \
+ --indent=tab \
+ --recursive "${DIR}/../../test/*.cpp"
+find ${DIR}/../../test/ -iname '*.orig' -exec rm {} \;
+
+astyle \
+ --style=java \
+ --indent=tab \
+ --recursive "${DIR}/../../apps/*.cpp"
+find ${DIR}/../../apps/ -iname '*.orig' -exec rm {} \;
+
diff --git a/contrib/local/compress_and_upload_deps.sh b/contrib/local/compress_and_upload_deps.sh
index c96ff0b..641219d 100755
--- a/contrib/local/compress_and_upload_deps.sh
+++ b/contrib/local/compress_and_upload_deps.sh
@@ -9,7 +9,7 @@ CWD=`pwd`
cd $DIR
if [ "$UMUNDO_PREBUILT_HOST" == "" ]; then
- UMUNDO_PREBUILT_HOST="admin@umundo.tk.informatik.tu-darmstadt.de:/var/www/html/uscxml/prebuilt"
+ UMUNDO_PREBUILT_HOST="admin@uscxml.tk.informatik.tu-darmstadt.de:/var/www/html/uscxml/prebuilt"
fi
if [ "$1" == "" ] || [ "$2" == "" ]; then
@@ -27,6 +27,6 @@ VERSION=$2
cd ../prebuilt
-tar cvzf uscxml-prebuilt-${PLATFORM}-${VERSION}.tgz ${PLATFORM}
-scp uscxml-prebuilt-${PLATFORM}-${VERSION}.tgz ${UMUNDO_PREBUILT_HOST}/
-rm uscxml-prebuilt-${PLATFORM}-${VERSION}.tgz \ No newline at end of file
+tar cvzf uscxml-prebuilt-${PLATFORM}.tgz ${PLATFORM}
+scp uscxml-prebuilt-${PLATFORM}.tgz ${UMUNDO_PREBUILT_HOST}/${VERSION}
+rm uscxml-prebuilt-${PLATFORM}.tgz \ No newline at end of file
diff --git a/contrib/prebuilt/uscxml-prebuilt-windows-x86-0.0.1.tgz b/contrib/prebuilt/uscxml-prebuilt-windows-x86-0.0.1.tgz
deleted file mode 100644
index 835bb7a..0000000
--- a/contrib/prebuilt/uscxml-prebuilt-windows-x86-0.0.1.tgz
+++ /dev/null
Binary files differ
diff --git a/src/uscxml/Factory.cpp b/src/uscxml/Factory.cpp
index 9f16503..0745f74 100644
--- a/src/uscxml/Factory.cpp
+++ b/src/uscxml/Factory.cpp
@@ -2,154 +2,185 @@
#include "uscxml/config.h"
#include "uscxml/Factory.h"
-#include "uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h"
-#include "uscxml/plugins/invoker/scxml/USCXMLInvoker.h"
+#include "uscxml/Message.h"
-#ifdef UMUNDO_FOUND
-#include "uscxml/plugins/invoker/umundo/UmundoInvoker.h"
-#endif
+#ifdef BUILD_AS_PLUGINS
+# include "uscxml/plugins/Plugins.h"
+#else
-#ifdef MILES_FOUND
-#include "uscxml/plugins/invoker/modality/miles/SpatialAudio.h"
-#endif
+# include "uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h"
+# include "uscxml/plugins/invoker/scxml/USCXMLInvoker.h"
+
+# ifdef UMUNDO_FOUND
+# include "uscxml/plugins/invoker/umundo/UmundoInvoker.h"
+# endif
+
+# ifdef MILES_FOUND
+# include "uscxml/plugins/invoker/modality/miles/SpatialAudio.h"
+# endif
+
+# ifdef V8_FOUND
+# include "uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h"
+# endif
+
+# ifdef SWI_FOUND
+# include "uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h"
+# endif
-#ifdef V8_FOUND
-#include "uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h"
#endif
namespace uscxml {
-
- Factory::Factory() {
+
+Factory::Factory() {
#ifdef BUILD_AS_PLUGINS
- if (pluginPath.length() > 0) {
- pluma.acceptProviderType<InvokerProvider>();
- pluma.acceptProviderType<IOProcessorProvider>();
- pluma.acceptProviderType<DataModelProvider>();
- pluma.loadFromFolder(pluginPath);
-
- std::vector<InvokerProvider*> invokerProviders;
- pluma.getProviders(invokerProviders);
- for (std::vector<InvokerProvider*>::iterator it = invokerProviders.begin() ; it != invokerProviders.end() ; ++it) {
- Invoker* invoker = (*it)->create();
- registerInvoker(invoker);
- }
-
- std::vector<IOProcessorProvider*> ioProcessorProviders;
- pluma.getProviders(ioProcessorProviders);
- for (std::vector<IOProcessorProvider*>::iterator it = ioProcessorProviders.begin() ; it != ioProcessorProviders.end() ; ++it) {
- IOProcessor* ioProcessor = (*it)->create();
- registerIOProcessor(ioProcessor);
- }
-
- std::vector<DataModelProvider*> dataModelProviders;
- pluma.getProviders(dataModelProviders);
- for (std::vector<DataModelProvider*>::iterator it = dataModelProviders.begin() ; it != dataModelProviders.end() ; ++it) {
- DataModel* dataModel = (*it)->create();
- registerDataModel(dataModel);
- }
-
- pluma.unloadAll();
- }
-#else
-#ifdef UMUNDO_FOUND
- {
- UmundoInvoker* invoker = new UmundoInvoker();
+ if (pluginPath.length() == 0) {
+ // try to read USCXML_PLUGIN_PATH environment variable
+ pluginPath = (getenv("USCXML_PLUGIN_PATH") != NULL ? getenv("USCXML_PLUGIN_PATH") : "");
+ }
+ if (pluginPath.length() > 0) {
+ pluma.acceptProviderType<InvokerProvider>();
+ pluma.acceptProviderType<IOProcessorProvider>();
+ pluma.acceptProviderType<DataModelProvider>();
+ pluma.loadFromFolder(pluginPath);
+
+ std::vector<InvokerProvider*> invokerProviders;
+ pluma.getProviders(invokerProviders);
+ for (std::vector<InvokerProvider*>::iterator it = invokerProviders.begin() ; it != invokerProviders.end() ; ++it) {
+ Invoker* invoker = (*it)->create();
registerInvoker(invoker);
}
+
+ std::vector<IOProcessorProvider*> ioProcessorProviders;
+ pluma.getProviders(ioProcessorProviders);
+ for (std::vector<IOProcessorProvider*>::iterator it = ioProcessorProviders.begin() ; it != ioProcessorProviders.end() ; ++it) {
+ IOProcessor* ioProcessor = (*it)->create();
+ registerIOProcessor(ioProcessor);
+ }
+
+ std::vector<DataModelProvider*> dataModelProviders;
+ pluma.getProviders(dataModelProviders);
+ for (std::vector<DataModelProvider*>::iterator it = dataModelProviders.begin() ; it != dataModelProviders.end() ; ++it) {
+ DataModel* dataModel = (*it)->create();
+ registerDataModel(dataModel);
+ }
+ }
+#else
+#ifdef UMUNDO_FOUND
+ {
+ UmundoInvoker* invoker = new UmundoInvoker();
+ registerInvoker(invoker);
+ }
#endif
#ifdef MILES_FOUND
- {
- SpatialAudio* invoker = new SpatialAudio();
- registerInvoker(invoker);
- }
+ {
+ SpatialAudio* invoker = new SpatialAudio();
+ registerInvoker(invoker);
+ }
#endif
#ifdef V8_FOUND
- {
- V8DataModel* dataModel = new V8DataModel();
- registerDataModel(dataModel);
- }
+ {
+ V8DataModel* dataModel = new V8DataModel();
+ registerDataModel(dataModel);
+ }
#endif
- // these are always available
- {
- USCXMLInvoker* invoker = new USCXMLInvoker();
- registerInvoker(invoker);
- }
- {
- EventIOProcessor* ioProcessor = new EventIOProcessor();
- registerIOProcessor(ioProcessor);
- }
-#endif
- }
-
- void Factory::registerIOProcessor(IOProcessor* ioProcessor) {
- std::set<std::string> names = ioProcessor->getNames();
- std::set<std::string>::iterator nameIter = names.begin();
- while(nameIter != names.end()) {
- _ioProcessors[*nameIter] = ioProcessor;
- nameIter++;
- }
- }
-
- void Factory::registerDataModel(DataModel* dataModel) {
- std::set<std::string> names = dataModel->getNames();
- std::set<std::string>::iterator nameIter = names.begin();
- while(nameIter != names.end()) {
- _dataModels[*nameIter] = dataModel;
- nameIter++;
- }
- }
-
- void Factory::registerInvoker(Invoker* invoker) {
- std::set<std::string> names = invoker->getNames();
- std::set<std::string>::iterator nameIter = names.begin();
- while(nameIter != names.end()) {
- _invokers[*nameIter] = invoker;
- nameIter++;
- }
- }
-
- void Factory::registerExecutableContent(const std::string tag, ExecutableContent* executableContent) {
- _executableContent[tag] = executableContent;
- }
-
- Invoker* Factory::getInvoker(const std::string type, Interpreter* interpreter) {
- if (Factory::getInstance()->_invokers.find(type) != getInstance()->_invokers.end()) {
- return (Invoker*)getInstance()->_invokers[type]->create(interpreter);
- }
- return NULL;
- }
-
- DataModel* Factory::getDataModel(const std::string type, Interpreter* interpreter) {
- if (Factory::getInstance()->_dataModels.find(type) != getInstance()->_dataModels.end()) {
- return getInstance()->_dataModels[type]->create(interpreter);
- }
- return NULL;
- }
-
- IOProcessor* Factory::getIOProcessor(const std::string type, Interpreter* interpreter) {
- if (getInstance()->_ioProcessors.find(type) != getInstance()->_ioProcessors.end()) {
- return getInstance()->_ioProcessors[type]->create(interpreter);
- }
- return NULL;
- }
-
- ExecutableContent* Factory::getExecutableContent(const std::string tag, Interpreter* interpreter) {
- if (getInstance()->_executableContent.find(tag) != getInstance()->_executableContent.end()) {
- return getInstance()->_executableContent[tag]->create(interpreter);
- }
- return NULL;
- }
-
- Factory* Factory::getInstance() {
- if (_instance == NULL) {
- _instance = new Factory();
- }
- return _instance;
- }
-
- Factory* Factory::_instance = NULL;
- std::string Factory::pluginPath;
+#ifdef SWI_FOUND
+ {
+ SWIDataModel* dataModel = new SWIDataModel();
+ registerDataModel(dataModel);
+ }
+#endif
+
+ // these are always available
+ {
+ USCXMLInvoker* invoker = new USCXMLInvoker();
+ registerInvoker(invoker);
+ }
+ {
+ EventIOProcessor* ioProcessor = new EventIOProcessor();
+ registerIOProcessor(ioProcessor);
+ }
+#endif
+}
+
+Factory::~Factory() {
+#ifdef BUILD_AS_PLUGINS
+ pluma.unloadAll();
+#endif
+}
+
+void Factory::registerIOProcessor(IOProcessor* ioProcessor) {
+ std::set<std::string> names = ioProcessor->getNames();
+ std::set<std::string>::iterator nameIter = names.begin();
+ while(nameIter != names.end()) {
+ _ioProcessors[*nameIter] = ioProcessor;
+ nameIter++;
+ }
+}
+
+void Factory::registerDataModel(DataModel* dataModel) {
+ std::set<std::string> names = dataModel->getNames();
+ std::set<std::string>::iterator nameIter = names.begin();
+ while(nameIter != names.end()) {
+ _dataModels[*nameIter] = dataModel;
+ nameIter++;
+ }
+}
+
+void Factory::registerInvoker(Invoker* invoker) {
+ std::set<std::string> names = invoker->getNames();
+ std::set<std::string>::iterator nameIter = names.begin();
+ while(nameIter != names.end()) {
+ _invokers[*nameIter] = invoker;
+ nameIter++;
+ }
+}
+
+void Factory::registerExecutableContent(const std::string tag, ExecutableContent* executableContent) {
+ _executableContent[tag] = executableContent;
+}
+
+Invoker* Factory::getInvoker(const std::string type, Interpreter* interpreter) {
+ Factory* factory = getInstance();
+ if (factory->_invokers.find(type) != factory->_invokers.end()) {
+ return (Invoker*)factory->_invokers[type]->create(interpreter);
+ }
+ return NULL;
+}
+
+DataModel* Factory::getDataModel(const std::string type, Interpreter* interpreter) {
+ Factory* factory = getInstance();
+ if (factory->_dataModels.find(type) != factory->_dataModels.end()) {
+ return factory->_dataModels[type]->create(interpreter);
+ }
+ return NULL;
+}
+
+IOProcessor* Factory::getIOProcessor(const std::string type, Interpreter* interpreter) {
+ Factory* factory = getInstance();
+ if (factory->_ioProcessors.find(type) != factory->_ioProcessors.end()) {
+ return factory->_ioProcessors[type]->create(interpreter);
+ }
+ return NULL;
+}
+
+ExecutableContent* Factory::getExecutableContent(const std::string tag, Interpreter* interpreter) {
+ Factory* factory = getInstance();
+ if (factory->_executableContent.find(tag) != factory->_executableContent.end()) {
+ return factory->_executableContent[tag]->create(interpreter);
+ }
+ return NULL;
+}
+
+Factory* Factory::getInstance() {
+ if (_instance == NULL) {
+ _instance = new Factory();
+ }
+ return _instance;
+}
+
+Factory* Factory::_instance = NULL;
+std::string Factory::pluginPath;
} \ No newline at end of file
diff --git a/src/uscxml/Factory.h b/src/uscxml/Factory.h
index fcd907e..6385ba7 100644
--- a/src/uscxml/Factory.h
+++ b/src/uscxml/Factory.h
@@ -11,101 +11,106 @@
#include <set>
namespace uscxml {
-
- // see http://stackoverflow.com/questions/228005/alternative-to-itoa-for-converting-integer-to-string-c
- template <typename T> std::string toStr(T tmp) {
- std::ostringstream out;
- out << tmp;
- return out.str();
- }
-
- template <typename T> T strTo(std::string tmp) {
- T output;
- std::istringstream in(tmp);
- in >> output;
- return output;
- }
-
- class Interpreter;
-
- class ExecutableContent {
- public:
- ExecutableContent() {};
- virtual ExecutableContent* create(Interpreter* interpreter) = 0;
- };
-
- class IOProcessor {
- public:
- IOProcessor() {};
- virtual ~IOProcessor() {};
- virtual IOProcessor* create(Interpreter* interpreter) = 0;
- virtual std::set<std::string> getNames() = 0;
-
- virtual void setInterpreter(Interpreter* interpreter) { _interpreter = interpreter; }
- virtual Data getDataModelVariables() = 0;
- virtual void send(SendRequest& req) = 0;
- protected:
- Interpreter* _interpreter;
- };
-
- class Invoker : public IOProcessor {
- public:
- virtual void invoke(InvokeRequest& req) = 0;
- virtual void sendToParent(SendRequest& req) = 0;
- };
-
- class DataModel {
- public:
- virtual ~DataModel() {}
- virtual DataModel* create(Interpreter* interpreter) = 0;
- virtual std::set<std::string> getNames() = 0;
-
- virtual bool validate(const std::string& location, const std::string& schema) = 0;
- virtual void setEvent(const Event& event) = 0;
- virtual Data getStringAsData(const std::string& content) = 0;
-
- // foreach
- virtual uint32_t getLength(const std::string& expr) = 0;
- virtual void pushContext() = 0;
- virtual void popContext() = 0;
-
- virtual void eval(const std::string& expr) = 0;
- virtual std::string evalAsString(const std::string& expr) = 0;
- virtual bool evalAsBool(const std::string& expr) = 0;
- virtual void assign(const std::string& location, const std::string& expr) = 0;
- virtual void assign(const std::string& location, const Data& data) = 0;
- };
-
- class Factory {
- public:
- void registerIOProcessor(IOProcessor* ioProcessor);
- void registerDataModel(DataModel* dataModel);
- void registerInvoker(Invoker* invoker);
- void registerExecutableContent(const std::string tag, ExecutableContent* executableContent);
-
- static DataModel* getDataModel(const std::string type, Interpreter* interpreter);
- static IOProcessor* getIOProcessor(const std::string type, Interpreter* interpreter);
- static ExecutableContent* getExecutableContent(const std::string tag, Interpreter* interpreter);
- static Invoker* getInvoker(const std::string type, Interpreter* interpreter);
-
- static Factory* getInstance();
-
- std::map<std::string, DataModel*> _dataModels;
- std::map<std::string, IOProcessor*> _ioProcessors;
- std::map<std::string, Invoker*> _invokers;
- std::map<std::string, ExecutableContent*> _executableContent;
-
- static std::string pluginPath;
-
- protected:
+
+// see http://stackoverflow.com/questions/228005/alternative-to-itoa-for-converting-integer-to-string-c
+template <typename T> std::string toStr(T tmp) {
+ std::ostringstream out;
+ out << tmp;
+ return out.str();
+}
+
+template <typename T> T strTo(std::string tmp) {
+ T output;
+ std::istringstream in(tmp);
+ in >> output;
+ return output;
+}
+
+class Interpreter;
+
+class ExecutableContent {
+public:
+ ExecutableContent() {};
+ virtual ExecutableContent* create(Interpreter* interpreter) = 0;
+};
+
+class IOProcessor {
+public:
+ IOProcessor() {};
+ virtual ~IOProcessor() {};
+ virtual IOProcessor* create(Interpreter* interpreter) = 0;
+ virtual std::set<std::string> getNames() = 0;
+
+ virtual void setInterpreter(Interpreter* interpreter) {
+ _interpreter = interpreter;
+ }
+ virtual Data getDataModelVariables() = 0;
+ virtual void send(SendRequest& req) = 0;
+protected:
+ Interpreter* _interpreter;
+};
+
+class Invoker : public IOProcessor {
+public:
+ virtual void invoke(InvokeRequest& req) = 0;
+ virtual void sendToParent(SendRequest& req) = 0;
+};
+
+class DataModel {
+public:
+ virtual ~DataModel() {}
+ virtual DataModel* create(Interpreter* interpreter) = 0;
+ virtual std::set<std::string> getNames() = 0;
+
+ virtual bool validate(const std::string& location, const std::string& schema) = 0;
+ virtual void setEvent(const Event& event) = 0;
+ virtual Data getStringAsData(const std::string& content) = 0;
+
+ virtual void registerIOProcessor(const std::string& name, IOProcessor* ioprocessor) = 0;
+
+ // foreach
+ virtual uint32_t getLength(const std::string& expr) = 0;
+ virtual void pushContext() = 0;
+ virtual void popContext() = 0;
+
+ virtual void eval(const std::string& expr) = 0;
+ virtual std::string evalAsString(const std::string& expr) = 0;
+ virtual bool evalAsBool(const std::string& expr) = 0;
+ virtual void assign(const std::string& location, const std::string& expr) = 0;
+ virtual void assign(const std::string& location, const Data& data) = 0;
+};
+
+class Factory {
+public:
+ void registerIOProcessor(IOProcessor* ioProcessor);
+ void registerDataModel(DataModel* dataModel);
+ void registerInvoker(Invoker* invoker);
+ void registerExecutableContent(const std::string tag, ExecutableContent* executableContent);
+
+ static DataModel* getDataModel(const std::string type, Interpreter* interpreter);
+ static IOProcessor* getIOProcessor(const std::string type, Interpreter* interpreter);
+ static ExecutableContent* getExecutableContent(const std::string tag, Interpreter* interpreter);
+ static Invoker* getInvoker(const std::string type, Interpreter* interpreter);
+
+ static Factory* getInstance();
+
+ std::map<std::string, DataModel*> _dataModels;
+ std::map<std::string, IOProcessor*> _ioProcessors;
+ std::map<std::string, Invoker*> _invokers;
+ std::map<std::string, ExecutableContent*> _executableContent;
+
+ static std::string pluginPath;
+
+protected:
#ifdef BUILD_AS_PLUGINS
- pluma::Pluma pluma;
+ pluma::Pluma pluma;
#endif
-
- Factory();
- static Factory* _instance;
- };
+ Factory();
+ ~Factory();
+ static Factory* _instance;
+
+};
}
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index 17d499a..604921a 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -25,7 +25,7 @@ using namespace Arabica::DOM;
boost::uuids::random_generator Interpreter::uuidGen;
const std::string Interpreter::getUUID() {
- return boost::lexical_cast<std::string>(uuidGen());
+ return boost::lexical_cast<std::string>(uuidGen());
}
Interpreter::Interpreter() {
@@ -34,1166 +34,1171 @@ Interpreter::Interpreter() {
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
}
-
+
Interpreter* Interpreter::fromDOM(const Arabica::DOM::Node<std::string>& node) {
- Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
- Interpreter* interpreter = new Interpreter();
- interpreter->_doc = domFactory.createDocument("http://www.w3.org/2005/07/scxml", "scxml", 0);
- interpreter->_doc.appendChild(node);
- interpreter->init();
+ Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
+ Interpreter* interpreter = new Interpreter();
+ interpreter->_doc = domFactory.createDocument("http://www.w3.org/2005/07/scxml", "scxml", 0);
+ interpreter->_doc.appendChild(node);
+ interpreter->init();
- return interpreter;
+ return interpreter;
}
Interpreter* Interpreter::fromXML(const std::string& xml) {
- std::istringstream is(xml);
- Arabica::SAX::InputSource<std::string> inputSource;
- return fromInputSource(inputSource);
+ std::istringstream is(xml);
+ Arabica::SAX::InputSource<std::string> inputSource;
+ return fromInputSource(inputSource);
}
Interpreter* Interpreter::fromURI(const std::string& uri) {
- Arabica::SAX::InputSource<std::string> inputSource(uri);
- Interpreter* interpreter = fromInputSource(inputSource);
+ Arabica::SAX::InputSource<std::string> inputSource(uri);
+ Interpreter* interpreter = fromInputSource(inputSource);
- // try to establish URI root for relative src attributes in document
- interpreter->_baseURI = toBaseURI(Arabica::io::URI(uri));
- return interpreter;
+ // try to establish URI root for relative src attributes in document
+ interpreter->_baseURI = toBaseURI(Arabica::io::URI(uri));
+ return interpreter;
}
Arabica::io::URI Interpreter::toBaseURI(const Arabica::io::URI& uri) {
- std::stringstream ssBaseURI;
- if (uri.scheme().size() > 0) {
- ssBaseURI << uri.scheme() << "://";
- } else {
- ssBaseURI << "file://";
- }
- if (uri.host().size() > 0) {
- ssBaseURI << uri.host();
- if (!boost::iequals(uri.port(), "0"))
- ssBaseURI << ":" << uri.port();
- }
- if (uri.path().size() > 0) {
- std::string uriPath = uri.path();
- uriPath = uriPath.substr(0, uriPath.find_last_of("/\\"));
- ssBaseURI << uriPath;
- }
- return Arabica::io::URI(ssBaseURI.str());
+ std::stringstream ssBaseURI;
+ if (uri.scheme().size() > 0) {
+ ssBaseURI << uri.scheme() << "://";
+ } else {
+ ssBaseURI << "file://";
+ }
+ if (uri.host().size() > 0) {
+ ssBaseURI << uri.host();
+ if (!boost::iequals(uri.port(), "0"))
+ ssBaseURI << ":" << uri.port();
+ }
+ if (uri.path().size() > 0) {
+ std::string uriPath = uri.path();
+ uriPath = uriPath.substr(0, uriPath.find_last_of("/\\"));
+ ssBaseURI << uriPath;
+ }
+ return Arabica::io::URI(ssBaseURI.str());
}
bool Interpreter::makeAbsolute(Arabica::io::URI& uri) {
- if (uri.is_absolute())
- return true;
-
- if (_baseURI.as_string().size() > 0) {
- std::stringstream ssAbsoluteURI;
- if (_baseURI.scheme().size() > 0)
- ssAbsoluteURI << _baseURI.scheme() << "://";
- if (_baseURI.host().size() > 0) {
- ssAbsoluteURI << _baseURI.host();
- if (!boost::iequals(_baseURI.port(), "0"))
- ssAbsoluteURI << ":" << _baseURI.port();
- }
- if (_baseURI.path().size() > 0) {
- ssAbsoluteURI << _baseURI.path() << "/" << uri.path();
- }
- uri = Arabica::io::URI(ssAbsoluteURI.str());
- return true;
- }
- return false;
+ if (uri.is_absolute())
+ return true;
+
+ if (_baseURI.as_string().size() > 0) {
+ std::stringstream ssAbsoluteURI;
+ if (_baseURI.scheme().size() > 0)
+ ssAbsoluteURI << _baseURI.scheme() << "://";
+ if (_baseURI.host().size() > 0) {
+ ssAbsoluteURI << _baseURI.host();
+ if (!boost::iequals(_baseURI.port(), "0"))
+ ssAbsoluteURI << ":" << _baseURI.port();
+ }
+ if (_baseURI.path().size() > 0) {
+ ssAbsoluteURI << _baseURI.path() << "/" << uri.path();
+ }
+ uri = Arabica::io::URI(ssAbsoluteURI.str());
+ return true;
+ }
+ return false;
}
Interpreter* Interpreter::fromInputSource(Arabica::SAX::InputSource<std::string>& source) {
- Interpreter* interpreter = new Interpreter();
-
- Arabica::SAX2DOM::Parser<std::string> domParser;
- Arabica::SAX::CatchErrorHandler<std::string> errorHandler;
- domParser.setErrorHandler(errorHandler);
- if(!domParser.parse(source) || !domParser.getDocument().hasChildNodes()) {
- LOG(INFO) << "could not parse input:";
- if(errorHandler.errorsReported()) {
- LOG(ERROR) << errorHandler.errors() << std::endl;
- } else {
- Arabica::SAX::InputSourceResolver resolver(source, Arabica::default_string_adaptor<std::string>());
- if (!resolver.resolve()) {
- LOG(ERROR) << "no such file";
- }
- }
- } else {
- interpreter->_doc = domParser.getDocument();
- }
- interpreter->init();
- return interpreter;
+ Interpreter* interpreter = new Interpreter();
+
+ Arabica::SAX2DOM::Parser<std::string> domParser;
+ Arabica::SAX::CatchErrorHandler<std::string> errorHandler;
+ domParser.setErrorHandler(errorHandler);
+ if(!domParser.parse(source) || !domParser.getDocument().hasChildNodes()) {
+ LOG(INFO) << "could not parse input:";
+ if(errorHandler.errorsReported()) {
+ LOG(ERROR) << errorHandler.errors() << std::endl;
+ } else {
+ Arabica::SAX::InputSourceResolver resolver(source, Arabica::default_string_adaptor<std::string>());
+ if (!resolver.resolve()) {
+ LOG(ERROR) << "no such file";
+ }
+ }
+ } else {
+ interpreter->_doc = domParser.getDocument();
+ }
+ interpreter->init();
+ return interpreter;
}
void Interpreter::init() {
_thread = NULL;
- _dataModel = NULL;
- _invoker = NULL;
- _running = false;
- _sendQueue = new DelayedEventQueue();
- _sendQueue->start();
- if (_doc) {
- // do we have a xmlns attribute?
- std::string ns = _doc.getDocumentElement().getNamespaceURI();
- if(ns.size() > 0) {
- _nsContext.addNamespaceDeclaration(ns, "sc");
- _xpath.setNamespaceContext(_nsContext);
- _nsPrefix = "sc:";
- }
- NodeList<std::string> scxmls = _doc.getElementsByTagName("scxml");
- if (scxmls.getLength() > 0) {
- _scxml = (Arabica::DOM::Element<std::string>)scxmls.item(0);
- normalize(_doc);
- _name = (HAS_ATTR(_scxml, "name") ? ATTR(_scxml, "name") : getUUID());
- } else {
- LOG(ERROR) << "Cannot find SCXML element" << std::endl;
- }
- }
+ _dataModel = NULL;
+ _invoker = NULL;
+ _running = false;
+ _sendQueue = new DelayedEventQueue();
+ _sendQueue->start();
+ if (_doc) {
+ // do we have a xmlns attribute?
+ std::string ns = _doc.getDocumentElement().getNamespaceURI();
+ if(ns.size() > 0) {
+ _nsContext.addNamespaceDeclaration(ns, "sc");
+ _xpath.setNamespaceContext(_nsContext);
+ _nsPrefix = "sc:";
+ }
+ NodeList<std::string> scxmls = _doc.getElementsByTagName("scxml");
+ if (scxmls.getLength() > 0) {
+ _scxml = (Arabica::DOM::Element<std::string>)scxmls.item(0);
+ normalize(_doc);
+ _name = (HAS_ATTR(_scxml, "name") ? ATTR(_scxml, "name") : getUUID());
+ } else {
+ LOG(ERROR) << "Cannot find SCXML element" << std::endl;
+ }
+ }
}
Interpreter::~Interpreter() {
- std::map<std::string, IOProcessor*>::iterator ioProcessorIter = _ioProcessors.begin();
- while(ioProcessorIter != _ioProcessors.end()) {
- delete ioProcessorIter->second;
- ioProcessorIter++;
- }
+ std::map<std::string, IOProcessor*>::iterator ioProcessorIter = _ioProcessors.begin();
+ while(ioProcessorIter != _ioProcessors.end()) {
+ delete ioProcessorIter->second;
+ ioProcessorIter++;
+ }
if (_thread) {
- _running = false;
- _externalQueue.push(Event());
- _thread->join();
+ _running = false;
+ _externalQueue.push(Event());
+ _thread->join();
delete(_thread);
}
- delete _dataModel;
- delete _sendQueue;
+ delete _dataModel;
+ delete _sendQueue;
}
void Interpreter::start() {
- _thread = new tthread::thread(Interpreter::run, this);
+ _thread = new tthread::thread(Interpreter::run, this);
}
-
+
void Interpreter::run(void* instance) {
((Interpreter*)instance)->interpret();
}
void Interpreter::waitForStabilization() {
- tthread::lock_guard<tthread::mutex> lock(_mutex);
- _stabilized.wait(_mutex);
+ tthread::lock_guard<tthread::mutex> lock(_mutex);
+ _stabilized.wait(_mutex);
}
-
+
// see: http://www.w3.org/TR/scxml/#AlgorithmforSCXMLInterpretation
void Interpreter::interpret() {
- if (!_scxml)
- return;
+ if (!_scxml)
+ return;
// dump();
- _sessionId = getUUID();
-
- if(HAS_ATTR(_scxml, "datamodel")) {
+ _sessionId = getUUID();
+
+ if(HAS_ATTR(_scxml, "datamodel")) {
_dataModel = Factory::getDataModel(ATTR(_scxml, "datamodel"), this);
if(_dataModel == NULL) {
- LOG(ERROR) << "No datamodel for " << ATTR(_scxml, "datamodel") << " registered";
- return;
- }
- }
+ LOG(ERROR) << "No datamodel for " << ATTR(_scxml, "datamodel") << " registered";
+ return;
+ }
+ }
- setupIOProcessors();
+ setupIOProcessors();
- // executeGlobalScriptElements
- NodeSet<std::string> globalScriptElems = _xpath.evaluate("/" + _nsPrefix + "scxml/" + _nsPrefix + "script", _doc).asNodeSet();
- for (unsigned int i = 0; i < globalScriptElems.size(); i++) {
+ // executeGlobalScriptElements
+ NodeSet<std::string> globalScriptElems = _xpath.evaluate("/" + _nsPrefix + "scxml/" + _nsPrefix + "script", _doc).asNodeSet();
+ for (unsigned int i = 0; i < globalScriptElems.size(); i++) {
// std::cout << globalScriptElems[i].getFirstChild().getNodeValue() << std::endl;
- if (_dataModel)
- executeContent(globalScriptElems[i]);
- }
-
- _running = true;
-
- std::string binding = _xpath.evaluate("/" + _nsPrefix + "scxml/@binding", _doc).asString();
- _binding = (boost::iequals(binding, "late") ? LATE : EARLY);
-
- // initialize all data elements
- if (_dataModel && _binding == EARLY) {
- NodeSet<std::string> dataElems = _xpath.evaluate("//" + _nsPrefix + "data", _doc).asNodeSet();
- for (unsigned int i = 0; i < dataElems.size(); i++) {
- initializeData(dataElems[i]);
- }
- } else if(_dataModel) {
- NodeSet<std::string> topDataElems = _xpath.evaluate("/" + _nsPrefix + "scxml/" + _nsPrefix + "datamodel/" + _nsPrefix + "data", _doc).asNodeSet();
- for (unsigned int i = 0; i < topDataElems.size(); i++) {
- initializeData(topDataElems[i]);
- }
- }
-
- // we made sure during normalization that this element exists
- NodeSet<std::string> initialTransitions = _xpath.evaluate("/" + _nsPrefix + "scxml/" + _nsPrefix + "initial/" + _nsPrefix + "transition", _doc).asNodeSet();
- assert(initialTransitions.size() > 0);
- initialTransitions.push_back(initialTransitions[0]);
- enterStates(initialTransitions);
-
- mainEventLoop();
+ if (_dataModel)
+ executeContent(globalScriptElems[i]);
+ }
+
+ _running = true;
+
+ std::string binding = _xpath.evaluate("/" + _nsPrefix + "scxml/@binding", _doc).asString();
+ _binding = (boost::iequals(binding, "late") ? LATE : EARLY);
+
+ // initialize all data elements
+ if (_dataModel && _binding == EARLY) {
+ NodeSet<std::string> dataElems = _xpath.evaluate("//" + _nsPrefix + "data", _doc).asNodeSet();
+ for (unsigned int i = 0; i < dataElems.size(); i++) {
+ initializeData(dataElems[i]);
+ }
+ } else if(_dataModel) {
+ NodeSet<std::string> topDataElems = _xpath.evaluate("/" + _nsPrefix + "scxml/" + _nsPrefix + "datamodel/" + _nsPrefix + "data", _doc).asNodeSet();
+ for (unsigned int i = 0; i < topDataElems.size(); i++) {
+ initializeData(topDataElems[i]);
+ }
+ }
+
+ // we made sure during normalization that this element exists
+ NodeSet<std::string> initialTransitions = _xpath.evaluate("/" + _nsPrefix + "scxml/" + _nsPrefix + "initial/" + _nsPrefix + "transition", _doc).asNodeSet();
+ assert(initialTransitions.size() > 0);
+ initialTransitions.push_back(initialTransitions[0]);
+ enterStates(initialTransitions);
+
+ mainEventLoop();
}
/**
* Called with a single data element from the topmost datamodel element.
*/
void Interpreter::initializeData(const Arabica::DOM::Node<std::string>& data) {
- if (!_dataModel) {
- LOG(ERROR) << "Cannot initialize data when no datamodel is given!";
- return;
- }
- try {
- if (!HAS_ATTR(data, "id"))
- return;
-
- if (HAS_ATTR(data, "expr")) {
- std::string value = ATTR(data, "expr");
- _dataModel->assign(ATTR(data, "id"), value);
- } else if (HAS_ATTR(data, "src")) {
- Arabica::SAX::InputSourceResolver resolver(Arabica::SAX::InputSource<std::string>(ATTR(data, "src")),
- Arabica::default_string_adaptor<std::string>());
- std::string value = std::string(std::istreambuf_iterator<char>(*resolver.resolve()), std::istreambuf_iterator<char>());
- _dataModel->assign(ATTR(data, "id"), value);
- } else if (data.hasChildNodes()) {
- // search for the text node with the actual script
- NodeList<std::string> dataChilds = data.getChildNodes();
- for (int i = 0; i < dataChilds.getLength(); i++) {
- if (dataChilds.item(i).getNodeType() == Node_base::TEXT_NODE) {
- Data value = Data(dataChilds.item(i).getNodeValue());
- _dataModel->assign(ATTR(data, "id"), value);
- break;
- }
- }
+ if (!_dataModel) {
+ LOG(ERROR) << "Cannot initialize data when no datamodel is given!";
+ return;
+ }
+ try {
+ if (!HAS_ATTR(data, "id"))
+ return;
+
+ if (HAS_ATTR(data, "expr")) {
+ std::string value = ATTR(data, "expr");
+ _dataModel->assign(ATTR(data, "id"), value);
+ } else if (HAS_ATTR(data, "src")) {
+ Arabica::SAX::InputSourceResolver resolver(Arabica::SAX::InputSource<std::string>(ATTR(data, "src")),
+ Arabica::default_string_adaptor<std::string>());
+ std::string value = std::string(std::istreambuf_iterator<char>(*resolver.resolve()), std::istreambuf_iterator<char>());
+ _dataModel->assign(ATTR(data, "id"), value);
+ } else if (data.hasChildNodes()) {
+ // search for the text node with the actual script
+ NodeList<std::string> dataChilds = data.getChildNodes();
+ for (int i = 0; i < dataChilds.getLength(); i++) {
+ if (dataChilds.item(i).getNodeType() == Node_base::TEXT_NODE) {
+ Data value = Data(dataChilds.item(i).getNodeValue());
+ _dataModel->assign(ATTR(data, "id"), value);
+ break;
+ }
+ }
// std::cout << value << std::endl;
- }
-
- } catch (Event e) {
- LOG(ERROR) << "Syntax error in send element:" << std::endl << e << std::endl;
- }
+ }
+
+ } catch (Event e) {
+ LOG(ERROR) << "Syntax error in send element:" << std::endl << e << std::endl;
+ }
}
void Interpreter::normalize(const Arabica::DOM::Document<std::string>& node) {
- // make sure every state has an id and set isFirstEntry to true
- Arabica::XPath::NodeSet<std::string> states = _xpath.evaluate("//" + _nsPrefix + "state", _doc).asNodeSet();
- for (int i = 0; i < states.size(); i++) {
- Arabica::DOM::Element<std::string> stateElem = Arabica::DOM::Element<std::string>(states[i]);
- stateElem.setAttribute("isFirstEntry", "true");
- if (!stateElem.hasAttribute("id")) {
- stateElem.setAttribute("id", getUUID());
- }
- }
-
- // make sure every invoke has an idlocation or id
- Arabica::XPath::NodeSet<std::string> invokes = _xpath.evaluate("//" + _nsPrefix + "invoke", _doc).asNodeSet();
- for (int i = 0; i < invokes.size(); i++) {
- Arabica::DOM::Element<std::string> invokeElem = Arabica::DOM::Element<std::string>(invokes[i]);
- if (!invokeElem.hasAttribute("id") && !invokeElem.hasAttribute("idlocation")) {
- invokeElem.setAttribute("id", getUUID());
- }
+ // make sure every state has an id and set isFirstEntry to true
+ Arabica::XPath::NodeSet<std::string> states = _xpath.evaluate("//" + _nsPrefix + "state", _doc).asNodeSet();
+ for (int i = 0; i < states.size(); i++) {
+ Arabica::DOM::Element<std::string> stateElem = Arabica::DOM::Element<std::string>(states[i]);
+ stateElem.setAttribute("isFirstEntry", "true");
+ if (!stateElem.hasAttribute("id")) {
+ stateElem.setAttribute("id", getUUID());
+ }
+ }
+
+ // make sure every invoke has an idlocation or id
+ Arabica::XPath::NodeSet<std::string> invokes = _xpath.evaluate("//" + _nsPrefix + "invoke", _doc).asNodeSet();
+ for (int i = 0; i < invokes.size(); i++) {
+ Arabica::DOM::Element<std::string> invokeElem = Arabica::DOM::Element<std::string>(invokes[i]);
+ if (!invokeElem.hasAttribute("id") && !invokeElem.hasAttribute("idlocation")) {
+ invokeElem.setAttribute("id", getUUID());
+ }
// // make sure every finalize element contained has the invoke id as an attribute
// Arabica::XPath::NodeSet<std::string> finalizes = _xpath.evaluate("" + _nsPrefix + "finalize", invokeElem).asNodeSet();
// for (int j = 0; j < finalizes.size(); j++) {
// Arabica::DOM::Element<std::string> finalizeElem = Arabica::DOM::Element<std::string>(finalizes[j]);
// finalizeElem.setAttribute("invokeid", invokeElem.getAttribute("id"));
// }
- }
-
- Arabica::XPath::NodeSet<std::string> finals = _xpath.evaluate("//" + _nsPrefix + "final", _doc).asNodeSet();
- for (int i = 0; i < finals.size(); i++) {
- Arabica::DOM::Element<std::string> finalElem = Arabica::DOM::Element<std::string>(finals[i]);
- finalElem.setAttribute("isFirstEntry", "true");
- if (!finalElem.hasAttribute("id")) {
- finalElem.setAttribute("id", getUUID());
- }
- }
-
- Arabica::XPath::NodeSet<std::string> histories = _xpath.evaluate("//" + _nsPrefix + "history", _doc).asNodeSet();
- for (int i = 0; i < histories.size(); i++) {
- Arabica::DOM::Element<std::string> historyElem = Arabica::DOM::Element<std::string>(histories[i]);
- if (!historyElem.hasAttribute("id")) {
- historyElem.setAttribute("id", getUUID());
- }
- }
-
- Arabica::XPath::NodeSet<std::string> scxml = _xpath.evaluate("/" + _nsPrefix + "scxml", _doc).asNodeSet();
- if (!((Arabica::DOM::Element<std::string>)scxml[0]).hasAttribute("id")) {
- ((Arabica::DOM::Element<std::string>)scxml[0]).setAttribute("id", getUUID());
- }
-
- // create a pseudo initial and transition element
- Arabica::DOM::Element<std::string> initialState = (Arabica::DOM::Element<std::string>)getInitialState();
- Arabica::DOM::Element<std::string> initialElem = _doc.createElement("initial");
- Arabica::DOM::Element<std::string> transitionElem = _doc.createElement("transition");
- transitionElem.setAttribute("target", initialState.getAttribute("id"));
- initialElem.appendChild(transitionElem);
- _scxml.appendChild(initialElem);
-
-}
-
+ }
+
+ Arabica::XPath::NodeSet<std::string> finals = _xpath.evaluate("//" + _nsPrefix + "final", _doc).asNodeSet();
+ for (int i = 0; i < finals.size(); i++) {
+ Arabica::DOM::Element<std::string> finalElem = Arabica::DOM::Element<std::string>(finals[i]);
+ finalElem.setAttribute("isFirstEntry", "true");
+ if (!finalElem.hasAttribute("id")) {
+ finalElem.setAttribute("id", getUUID());
+ }
+ }
+
+ Arabica::XPath::NodeSet<std::string> histories = _xpath.evaluate("//" + _nsPrefix + "history", _doc).asNodeSet();
+ for (int i = 0; i < histories.size(); i++) {
+ Arabica::DOM::Element<std::string> historyElem = Arabica::DOM::Element<std::string>(histories[i]);
+ if (!historyElem.hasAttribute("id")) {
+ historyElem.setAttribute("id", getUUID());
+ }
+ }
+
+ Arabica::XPath::NodeSet<std::string> scxml = _xpath.evaluate("/" + _nsPrefix + "scxml", _doc).asNodeSet();
+ if (!((Arabica::DOM::Element<std::string>)scxml[0]).hasAttribute("id")) {
+ ((Arabica::DOM::Element<std::string>)scxml[0]).setAttribute("id", getUUID());
+ }
+
+ // create a pseudo initial and transition element
+ Arabica::DOM::Element<std::string> initialState = (Arabica::DOM::Element<std::string>)getInitialState();
+ Arabica::DOM::Element<std::string> initialElem = _doc.createElement("initial");
+ Arabica::DOM::Element<std::string> transitionElem = _doc.createElement("transition");
+ transitionElem.setAttribute("target", initialState.getAttribute("id"));
+ initialElem.appendChild(transitionElem);
+ _scxml.appendChild(initialElem);
+
+}
+
void Interpreter::mainEventLoop() {
- while(_running) {
- NodeSet<std::string> enabledTransitions;
- _stable = false;
+ while(_running) {
+ NodeSet<std::string> enabledTransitions;
+ _stable = false;
- // Here we handle eventless transitions and transitions
- // triggered by internal events until machine is stable
- while(_running && !_stable) {
+ // Here we handle eventless transitions and transitions
+ // triggered by internal events until machine is stable
+ while(_running && !_stable) {
#if 0
- std::cout << "Configuration: ";
- for (int i = 0; i < _configuration.size(); i++) {
- std::cout << ((Arabica::DOM::Element<std::string>)_configuration[i]).getAttribute("id") << ", ";
- }
- std::cout << std::endl;
+ std::cout << "Configuration: ";
+ for (int i = 0; i < _configuration.size(); i++) {
+ std::cout << ((Arabica::DOM::Element<std::string>)_configuration[i]).getAttribute("id") << ", ";
+ }
+ std::cout << std::endl;
#endif
- enabledTransitions = selectEventlessTransitions();
- if (enabledTransitions.size() == 0) {
- if (_internalQueue.size() == 0) {
- _stable = true;
- } else {
- Event internalEvent = _internalQueue.front();
- _internalQueue.pop_front();
+ enabledTransitions = selectEventlessTransitions();
+ if (enabledTransitions.size() == 0) {
+ if (_internalQueue.size() == 0) {
+ _stable = true;
+ } else {
+ Event internalEvent = _internalQueue.front();
+ _internalQueue.pop_front();
#if 0
- std::cout << "Received internal event " << internalEvent.name << std::endl;
+ std::cout << "Received internal event " << internalEvent.name << std::endl;
#endif
- if (_dataModel)
- _dataModel->setEvent(internalEvent);
- enabledTransitions = selectTransitions(internalEvent.name);
- }
- }
- if (!enabledTransitions.empty())
- microstep(enabledTransitions);
- }
-
- for (unsigned int i = 0; i < _statesToInvoke.size(); i++) {
- NodeSet<std::string> invokes = _xpath.evaluate("" + _nsPrefix + "invoke", _statesToInvoke[i]).asNodeSet();
- for (unsigned int j = 0; j < invokes.size(); j++) {
- invoke(invokes[j]);
- }
- }
-
- _statesToInvoke = NodeSet<std::string>();
- if (!_internalQueue.empty())
- continue;
-
- {
- tthread::lock_guard<tthread::mutex> lock(_mutex);
- _stabilized.notify_all();
- }
-
- Event externalEvent = _externalQueue.pop();
- if (!_running)
- exitInterpreter();
-
- if (_dataModel && boost::iequals(externalEvent.name, "cancel.invoke." + _sessionId))
- break;
-
- if (_dataModel)
- try {
- _dataModel->setEvent(externalEvent);
- } catch (Event e) {
- LOG(ERROR) << "Syntax error while setting external event:" << std::endl << e << std::endl;
- }
- for (unsigned int i = 0; i < _configuration.size(); i++) {
- NodeSet<std::string> invokes = _xpath.evaluate("" + _nsPrefix + "invoke", _configuration[i]).asNodeSet();
- for (unsigned int j = 0; j < invokes.size(); j++) {
- Arabica::DOM::Element<std::string> invokeElem = (Arabica::DOM::Element<std::string>)invokes[j];
- std::string invokeId = invokeElem.getAttribute("id");
- std::string autoForward = invokeElem.getAttribute("autoforward");
- if (boost::iequals(invokeId, externalEvent.invokeid)) {
-
- Arabica::XPath::NodeSet<std::string> finalizes = _xpath.evaluate("" + _nsPrefix + "finalize", invokeElem).asNodeSet();
- for (int k = 0; k < finalizes.size(); k++) {
- Arabica::DOM::Element<std::string> finalizeElem = Arabica::DOM::Element<std::string>(finalizes[k]);
- executeContent(finalizeElem);
- }
-
-
- }
- if (autoForward.length() > 0) {
- // @TODO
+ if (_dataModel)
+ _dataModel->setEvent(internalEvent);
+ enabledTransitions = selectTransitions(internalEvent.name);
+ }
+ }
+ if (!enabledTransitions.empty())
+ microstep(enabledTransitions);
+ }
+
+ for (unsigned int i = 0; i < _statesToInvoke.size(); i++) {
+ NodeSet<std::string> invokes = _xpath.evaluate("" + _nsPrefix + "invoke", _statesToInvoke[i]).asNodeSet();
+ for (unsigned int j = 0; j < invokes.size(); j++) {
+ invoke(invokes[j]);
+ }
+ }
+
+ _statesToInvoke = NodeSet<std::string>();
+ if (!_internalQueue.empty())
+ continue;
+
+ {
+ tthread::lock_guard<tthread::mutex> lock(_mutex);
+ _stabilized.notify_all();
+ }
+
+ Event externalEvent = _externalQueue.pop();
+ if (!_running)
+ exitInterpreter();
+
+ if (_dataModel && boost::iequals(externalEvent.name, "cancel.invoke." + _sessionId))
+ break;
+
+ if (_dataModel)
+ try {
+ _dataModel->setEvent(externalEvent);
+ } catch (Event e) {
+ LOG(ERROR) << "Syntax error while setting external event:" << std::endl << e << std::endl;
+ }
+ for (unsigned int i = 0; i < _configuration.size(); i++) {
+ NodeSet<std::string> invokes = _xpath.evaluate("" + _nsPrefix + "invoke", _configuration[i]).asNodeSet();
+ for (unsigned int j = 0; j < invokes.size(); j++) {
+ Arabica::DOM::Element<std::string> invokeElem = (Arabica::DOM::Element<std::string>)invokes[j];
+ std::string invokeId = invokeElem.getAttribute("id");
+ std::string autoForward = invokeElem.getAttribute("autoforward");
+ if (boost::iequals(invokeId, externalEvent.invokeid)) {
+
+ Arabica::XPath::NodeSet<std::string> finalizes = _xpath.evaluate("" + _nsPrefix + "finalize", invokeElem).asNodeSet();
+ for (int k = 0; k < finalizes.size(); k++) {
+ Arabica::DOM::Element<std::string> finalizeElem = Arabica::DOM::Element<std::string>(finalizes[k]);
+ executeContent(finalizeElem);
+ }
+
+
+ }
+ if (autoForward.length() > 0) {
+ // @TODO
// send(invokeId, externalEvent);
- }
- }
- }
- enabledTransitions = selectTransitions(externalEvent.name);
- if (!enabledTransitions.empty())
- microstep(enabledTransitions);
- }
- exitInterpreter();
+ }
+ }
+ }
+ enabledTransitions = selectTransitions(externalEvent.name);
+ if (!enabledTransitions.empty())
+ microstep(enabledTransitions);
+ }
+ exitInterpreter();
}
void Interpreter::internalDoneSend(const Arabica::DOM::Node<std::string>& state) {
- if (!isState(state))
- return;
-
- Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)state;
- Arabica::DOM::Element<std::string> parent = (Arabica::DOM::Element<std::string>)stateElem.getParentNode();
- Event event;
-
- Arabica::XPath::NodeSet<std::string> doneDatas = _xpath.evaluate("" + _nsPrefix + "donedata", stateElem).asNodeSet();
- if (doneDatas.size() > 0) {
- // only process first donedata element
- Arabica::DOM::Node<std::string> doneData = doneDatas[0];
- NodeList<std::string> doneChilds = doneData.getChildNodes();
- for (int i = 0; i < doneChilds.getLength(); i++) {
- if (!doneChilds.item(i).getNodeType() == Node_base::ELEMENT_NODE)
- continue;
- if (boost::iequals(TAGNAME(doneChilds.item(i)), "param")) {
- if (!HAS_ATTR(doneChilds.item(i), "name")) {
- LOG(ERROR) << "param element is missing name attribut";
- continue;
- }
- std::string paramValue;
- if (HAS_ATTR(doneChilds.item(i), "expr") && _dataModel) {
- std::string location = _dataModel->evalAsString(ATTR(doneChilds.item(i), "expr"));
- paramValue = _dataModel->evalAsString(location);
- } else if(HAS_ATTR(doneChilds.item(i), "location") && _dataModel) {
- paramValue = _dataModel->evalAsString(ATTR(doneChilds.item(i), "location"));
- } else {
- LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
- continue;
- }
- event.compound[ATTR(doneChilds.item(i), "name")] = paramValue;
- }
- if (boost::iequals(TAGNAME(doneChilds.item(i)), "content")) {
- if (HAS_ATTR(doneChilds.item(i), "expr")) {
- if (_dataModel) {
- event.compound["content"] = Data(_dataModel->evalAsString(ATTR(doneChilds.item(i), "expr")), Data::VERBATIM);
- } else {
- LOG(ERROR) << "content element has expr attribute but no datamodel is specified.";
- }
- } else if (doneChilds.item(i).hasChildNodes()) {
- event.compound["content"] = Data(doneChilds.item(i).getFirstChild().getNodeValue(), Data::VERBATIM);
- } else {
- LOG(ERROR) << "content element does not specify any content.";
- }
-
- }
- }
- }
-
- event.name = "done.state." + parent.getAttribute("id");
- _internalQueue.push_back(event);
-
-}
-
+ if (!isState(state))
+ return;
+
+ Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)state;
+ Arabica::DOM::Element<std::string> parent = (Arabica::DOM::Element<std::string>)stateElem.getParentNode();
+ Event event;
+
+ Arabica::XPath::NodeSet<std::string> doneDatas = _xpath.evaluate("" + _nsPrefix + "donedata", stateElem).asNodeSet();
+ if (doneDatas.size() > 0) {
+ // only process first donedata element
+ Arabica::DOM::Node<std::string> doneData = doneDatas[0];
+ NodeList<std::string> doneChilds = doneData.getChildNodes();
+ for (int i = 0; i < doneChilds.getLength(); i++) {
+ if (!doneChilds.item(i).getNodeType() == Node_base::ELEMENT_NODE)
+ continue;
+ if (boost::iequals(TAGNAME(doneChilds.item(i)), "param")) {
+ if (!HAS_ATTR(doneChilds.item(i), "name")) {
+ LOG(ERROR) << "param element is missing name attribut";
+ continue;
+ }
+ std::string paramValue;
+ if (HAS_ATTR(doneChilds.item(i), "expr") && _dataModel) {
+ std::string location = _dataModel->evalAsString(ATTR(doneChilds.item(i), "expr"));
+ paramValue = _dataModel->evalAsString(location);
+ } else if(HAS_ATTR(doneChilds.item(i), "location") && _dataModel) {
+ paramValue = _dataModel->evalAsString(ATTR(doneChilds.item(i), "location"));
+ } else {
+ LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
+ continue;
+ }
+ event.compound[ATTR(doneChilds.item(i), "name")] = paramValue;
+ }
+ if (boost::iequals(TAGNAME(doneChilds.item(i)), "content")) {
+ if (HAS_ATTR(doneChilds.item(i), "expr")) {
+ if (_dataModel) {
+ event.compound["content"] = Data(_dataModel->evalAsString(ATTR(doneChilds.item(i), "expr")), Data::VERBATIM);
+ } else {
+ LOG(ERROR) << "content element has expr attribute but no datamodel is specified.";
+ }
+ } else if (doneChilds.item(i).hasChildNodes()) {
+ event.compound["content"] = Data(doneChilds.item(i).getFirstChild().getNodeValue(), Data::VERBATIM);
+ } else {
+ LOG(ERROR) << "content element does not specify any content.";
+ }
+
+ }
+ }
+ }
+
+ event.name = "done.state." + parent.getAttribute("id");
+ _internalQueue.push_back(event);
+
+}
+
void Interpreter::send(const Arabica::DOM::Node<std::string>& element) {
- SendRequest sendReq;
- try {
- // event
- if (HAS_ATTR(element, "eventexpr") && _dataModel) {
- sendReq.name = _dataModel->evalAsString(ATTR(element, "eventexpr"));
- } else if (HAS_ATTR(element, "event")) {
- sendReq.name = ATTR(element, "event");
- }
- // target
- if (HAS_ATTR(element, "targetexpr") && _dataModel) {
- sendReq.target = _dataModel->evalAsString(ATTR(element, "targetexpr"));
- } else if (HAS_ATTR(element, "target")) {
- sendReq.target = ATTR(element, "target");
- }
- // type
- if (HAS_ATTR(element, "typeexpr") && _dataModel) {
- sendReq.type = _dataModel->evalAsString(ATTR(element, "typeexpr"));
- } else if (HAS_ATTR(element, "type")) {
- sendReq.type = ATTR(element, "type");
- } else {
- sendReq.type = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor";
- }
- // id
- if (HAS_ATTR(element, "idlocation") && _dataModel) {
- sendReq.sendid = _dataModel->evalAsString(ATTR(element, "idlocation"));
- } else if (HAS_ATTR(element, "id")) {
- sendReq.sendid = ATTR(element, "id");
- } else {
- /*
- * The ids for <send> and <invoke> are subtly different. In a conformant
- * SCXML document, they must be unique within the session, but in the case
- * where the author does not provide them, the processor must generate a
- * new unique ID not at load time but each time the element is executed.
- * Furthermore the attribute 'idlocation' can be used to capture this
- * automatically generated id. Finally note that the automatically generated
- * id for <invoke> has a special format. See 6.4.1 Attribute Details for
- * details. The SCXML processor may generate all other ids in any format,
- * as long as they are unique.
- */
- sendReq.sendid = getUUID();
- }
- /** @TODO:
- *
- * If 'idlocation' is present, the SCXML Processor must generate an id when
- * the parent <send> element is evaluated and store it in this location.
- * See 3.14 IDs for details.
- *
- */
-
- // delay
- std::string delay;
- sendReq.delayMs = 0;
- if (HAS_ATTR(element, "delayexpr") && _dataModel) {
- delay = _dataModel->evalAsString(ATTR(element, "delayexpr"));
- } else if (HAS_ATTR(element, "delay")) {
- delay = ATTR(element, "delay");
- }
- if (delay.size() > 0) {
- boost::trim(delay);
- std::stringstream delayTime;
- if (delay.size() > 2 && boost::iequals("ms", delay.substr(delay.length() - 2, 2))) {
- delayTime << delay.substr(0, delay.size() - 2);
- delayTime >> sendReq.delayMs;
- } else if (delay.size() > 1 && boost::iequals("s", delay.substr(delay.length() - 1, 1))) {
- delayTime << delay.substr(0, delay.size() - 1);
- delayTime >> sendReq.delayMs;
- sendReq.delayMs *= 1000;
- } else {
- LOG(ERROR) << "Cannot make sense of delay value " << delay << ": does not end in 's' or 'ms'";
- }
- }
- // namelist
- if (HAS_ATTR(element, "namelist")) {
- std::vector<std::string> names = tokenizeIdRefs(ATTR(element, "namelist"));
- for (int i = 0; i < names.size(); i++) {
- sendReq.namelist[names[i]] = _dataModel->evalAsString(names[i]);
- }
- }
-
- // params
- NodeSet<std::string> params = _xpath.evaluate("" + _nsPrefix + "param", element).asNodeSet();
- for (int i = 0; i < params.size(); i++) {
- if (!HAS_ATTR(params[i], "name")) {
- LOG(ERROR) << "param element is missing name attribut";
- continue;
- }
- std::string paramValue;
- if (HAS_ATTR(params[i], "expr") && _dataModel) {
- paramValue = _dataModel->evalAsString(ATTR(params[i], "expr"));
- } else if(HAS_ATTR(params[i], "location") && _dataModel) {
- paramValue = _dataModel->evalAsString(ATTR(params[i], "location"));
- } else {
- LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
- continue;
- }
- sendReq.params[ATTR(params[i], "name")].push_back(paramValue);
- }
-
- // content
- NodeSet<std::string> contents = _xpath.evaluate("" + _nsPrefix + "content", element).asNodeSet();
- if (contents.size() > 1)
- LOG(ERROR) << "Only a single content element is allowed for send elements - using first one";
- if (contents.size() > 0) {
- if (HAS_ATTR(contents[0], "expr")) {
- if (_dataModel) {
- sendReq.content = _dataModel->evalAsString(ATTR(contents[0], "expr"));
- } else {
- LOG(ERROR) << "content element has expr attribute but no datamodel is specified.";
- }
- } else if (contents[0].hasChildNodes()) {
- sendReq.content = contents[0].getFirstChild().getNodeValue();
- } else {
- LOG(ERROR) << "content element does not specify any content.";
- }
- }
-
- assert(_sendIds.find(sendReq.sendid) == _sendIds.end());
- _sendIds[sendReq.sendid] = std::make_pair(this, sendReq);
- if (sendReq.delayMs > 0) {
- _sendQueue->addEvent(sendReq.sendid, Interpreter::delayedSend, sendReq.delayMs, &_sendIds[sendReq.sendid]);
- } else {
- delayedSend(&_sendIds[sendReq.sendid], sendReq.name);
- }
-
- } catch (Event e) {
- LOG(ERROR) << "Syntax error in send element:" << std::endl << e << std::endl;
- }
+ SendRequest sendReq;
+ try {
+ // event
+ if (HAS_ATTR(element, "eventexpr") && _dataModel) {
+ sendReq.name = _dataModel->evalAsString(ATTR(element, "eventexpr"));
+ } else if (HAS_ATTR(element, "event")) {
+ sendReq.name = ATTR(element, "event");
+ }
+ // target
+ if (HAS_ATTR(element, "targetexpr") && _dataModel) {
+ sendReq.target = _dataModel->evalAsString(ATTR(element, "targetexpr"));
+ } else if (HAS_ATTR(element, "target")) {
+ sendReq.target = ATTR(element, "target");
+ }
+ // type
+ if (HAS_ATTR(element, "typeexpr") && _dataModel) {
+ sendReq.type = _dataModel->evalAsString(ATTR(element, "typeexpr"));
+ } else if (HAS_ATTR(element, "type")) {
+ sendReq.type = ATTR(element, "type");
+ } else {
+ sendReq.type = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor";
+ }
+ // id
+ if (HAS_ATTR(element, "idlocation") && _dataModel) {
+ sendReq.sendid = _dataModel->evalAsString(ATTR(element, "idlocation"));
+ } else if (HAS_ATTR(element, "id")) {
+ sendReq.sendid = ATTR(element, "id");
+ } else {
+ /*
+ * The ids for <send> and <invoke> are subtly different. In a conformant
+ * SCXML document, they must be unique within the session, but in the case
+ * where the author does not provide them, the processor must generate a
+ * new unique ID not at load time but each time the element is executed.
+ * Furthermore the attribute 'idlocation' can be used to capture this
+ * automatically generated id. Finally note that the automatically generated
+ * id for <invoke> has a special format. See 6.4.1 Attribute Details for
+ * details. The SCXML processor may generate all other ids in any format,
+ * as long as they are unique.
+ */
+ sendReq.sendid = getUUID();
+ }
+ /** @TODO:
+ *
+ * If 'idlocation' is present, the SCXML Processor must generate an id when
+ * the parent <send> element is evaluated and store it in this location.
+ * See 3.14 IDs for details.
+ *
+ */
+
+ // delay
+ std::string delay;
+ sendReq.delayMs = 0;
+ if (HAS_ATTR(element, "delayexpr") && _dataModel) {
+ delay = _dataModel->evalAsString(ATTR(element, "delayexpr"));
+ } else if (HAS_ATTR(element, "delay")) {
+ delay = ATTR(element, "delay");
+ }
+ if (delay.size() > 0) {
+ boost::trim(delay);
+ std::stringstream delayTime;
+ if (delay.size() > 2 && boost::iequals("ms", delay.substr(delay.length() - 2, 2))) {
+ delayTime << delay.substr(0, delay.size() - 2);
+ delayTime >> sendReq.delayMs;
+ } else if (delay.size() > 1 && boost::iequals("s", delay.substr(delay.length() - 1, 1))) {
+ delayTime << delay.substr(0, delay.size() - 1);
+ delayTime >> sendReq.delayMs;
+ sendReq.delayMs *= 1000;
+ } else {
+ LOG(ERROR) << "Cannot make sense of delay value " << delay << ": does not end in 's' or 'ms'";
+ }
+ }
+ // namelist
+ if (HAS_ATTR(element, "namelist")) {
+ std::vector<std::string> names = tokenizeIdRefs(ATTR(element, "namelist"));
+ for (int i = 0; i < names.size(); i++) {
+ sendReq.namelist[names[i]] = _dataModel->evalAsString(names[i]);
+ }
+ }
+
+ // params
+ NodeSet<std::string> params = _xpath.evaluate("" + _nsPrefix + "param", element).asNodeSet();
+ for (int i = 0; i < params.size(); i++) {
+ if (!HAS_ATTR(params[i], "name")) {
+ LOG(ERROR) << "param element is missing name attribut";
+ continue;
+ }
+ std::string paramValue;
+ if (HAS_ATTR(params[i], "expr") && _dataModel) {
+ paramValue = _dataModel->evalAsString(ATTR(params[i], "expr"));
+ } else if(HAS_ATTR(params[i], "location") && _dataModel) {
+ paramValue = _dataModel->evalAsString(ATTR(params[i], "location"));
+ } else {
+ LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
+ continue;
+ }
+ sendReq.params.insert(std::make_pair(ATTR(params[i], "name"), paramValue));
+ }
+
+ // content
+ NodeSet<std::string> contents = _xpath.evaluate("" + _nsPrefix + "content", element).asNodeSet();
+ if (contents.size() > 1)
+ LOG(ERROR) << "Only a single content element is allowed for send elements - using first one";
+ if (contents.size() > 0) {
+ if (HAS_ATTR(contents[0], "expr")) {
+ if (_dataModel) {
+ sendReq.content = _dataModel->evalAsString(ATTR(contents[0], "expr"));
+ } else {
+ LOG(ERROR) << "content element has expr attribute but no datamodel is specified.";
+ }
+ } else if (contents[0].hasChildNodes()) {
+ sendReq.content = contents[0].getFirstChild().getNodeValue();
+ } else {
+ LOG(ERROR) << "content element does not specify any content.";
+ }
+ }
+
+ assert(_sendIds.find(sendReq.sendid) == _sendIds.end());
+ _sendIds[sendReq.sendid] = std::make_pair(this, sendReq);
+ if (sendReq.delayMs > 0) {
+ _sendQueue->addEvent(sendReq.sendid, Interpreter::delayedSend, sendReq.delayMs, &_sendIds[sendReq.sendid]);
+ } else {
+ delayedSend(&_sendIds[sendReq.sendid], sendReq.name);
+ }
+
+ } catch (Event e) {
+ LOG(ERROR) << "Syntax error in send element:" << std::endl << e << std::endl;
+ }
}
void Interpreter::delayedSend(void* userdata, std::string eventName) {
- std::pair<Interpreter*, SendRequest>* data = (std::pair<Interpreter*, SendRequest>*)(userdata);
-
- Interpreter* INSTANCE = data->first;
- SendRequest sendReq = data->second;
-
- if (boost::iequals(sendReq.target, "#_parent")) {
- // send to parent scxml session
- if (INSTANCE->_invoker != NULL) {
- INSTANCE->_invoker->sendToParent(sendReq);
- } else {
- LOG(ERROR) << "Can not send to parent, we were not invoked" << std::endl;
- }
- } else if (sendReq.target.find_first_of("#_") == 0) {
- // send to invoker
- std::string invokeId = sendReq.target.substr(2, sendReq.target.length() - 2);
- if (INSTANCE->_invokerIds.find(invokeId) != INSTANCE->_invokerIds.end()) {
- INSTANCE->_invokerIds[invokeId]->send(sendReq);
- } else {
- LOG(ERROR) << "Can not send to invoked component " << invokeId << ", no such invokeId" << std::endl;
- }
- } else if (sendReq.target.length() == 0) {
- INSTANCE->receive(sendReq);
- } else {
- IOProcessor* ioProc = INSTANCE->getIOProcessor(sendReq.type);
- if (ioProc != NULL) {
- ioProc->send(sendReq);
- }
- }
- assert(INSTANCE->_sendIds.find(sendReq.sendid) != INSTANCE->_sendIds.end());
- INSTANCE->_sendIds.erase(sendReq.sendid);
-}
-
+ std::pair<Interpreter*, SendRequest>* data = (std::pair<Interpreter*, SendRequest>*)(userdata);
+
+ Interpreter* INSTANCE = data->first;
+ SendRequest sendReq = data->second;
+
+ if (boost::iequals(sendReq.target, "#_parent")) {
+ // send to parent scxml session
+ if (INSTANCE->_invoker != NULL) {
+ INSTANCE->_invoker->sendToParent(sendReq);
+ } else {
+ LOG(ERROR) << "Can not send to parent, we were not invoked" << std::endl;
+ }
+ } else if (sendReq.target.find_first_of("#_") == 0) {
+ // send to invoker
+ std::string invokeId = sendReq.target.substr(2, sendReq.target.length() - 2);
+ if (INSTANCE->_invokerIds.find(invokeId) != INSTANCE->_invokerIds.end()) {
+ INSTANCE->_invokerIds[invokeId]->send(sendReq);
+ } else {
+ LOG(ERROR) << "Can not send to invoked component " << invokeId << ", no such invokeId" << std::endl;
+ }
+ } else if (sendReq.target.length() == 0) {
+ INSTANCE->receive(sendReq);
+ } else {
+ IOProcessor* ioProc = INSTANCE->getIOProcessor(sendReq.type);
+ if (ioProc != NULL) {
+ ioProc->send(sendReq);
+ }
+ }
+ assert(INSTANCE->_sendIds.find(sendReq.sendid) != INSTANCE->_sendIds.end());
+ INSTANCE->_sendIds.erase(sendReq.sendid);
+}
+
void Interpreter::invoke(const Arabica::DOM::Node<std::string>& element) {
- InvokeRequest invokeReq;
- try {
- // type
- if (HAS_ATTR(element, "typeexpr") && _dataModel) {
- invokeReq.type = _dataModel->evalAsString(ATTR(element, "typeexpr"));
- } else if (HAS_ATTR(element, "type")) {
- invokeReq.type = ATTR(element, "type");
- } else {
- LOG(ERROR) << "invoke element is missing expr or typeexpr or no datamodel is specified";
- }
-
- // src
- std::string source;
- if (HAS_ATTR(element, "srcexpr") && _dataModel) {
- source = _dataModel->evalAsString(ATTR(element, "srcexpr"));
- } else if (HAS_ATTR(element, "src")) {
- source = ATTR(element, "src");
- }
- if (source.length() > 0) {
- Arabica::io::URI srcURI(source);
- if (!makeAbsolute(srcURI)) {
- LOG(ERROR) << "invoke element has relative src URI with no baseURI set.";
- return;
- }
- invokeReq.src = srcURI.as_string();
- }
-
- // id
- if (HAS_ATTR(element, "idlocation") && _dataModel) {
- invokeReq.invokeid = _dataModel->evalAsString(ATTR(element, "idlocation"));
- } else if (HAS_ATTR(element, "id")) {
- invokeReq.invokeid = ATTR(element, "id");
- } else {
- assert(false);
- }
-
- // namelist
- if (HAS_ATTR(element, "namelist")) {
- invokeReq.namelist = ATTR(element, "namelist");
- }
-
- // autoforward
- if (HAS_ATTR(element, "autoforward")) {
- if (boost::iequals(ATTR(element, "autoforward"), "true")) {
- invokeReq.autoForward = true;
- }
- } else {
- invokeReq.autoForward = false;
- }
-
- // params
- NodeSet<std::string> params = _xpath.evaluate("" + _nsPrefix + "param", element).asNodeSet();
- for (int i = 0; i < params.size(); i++) {
- if (!HAS_ATTR(params[i], "name")) {
- LOG(ERROR) << "param element is missing name attribut";
- continue;
- }
- std::string paramValue;
- if (HAS_ATTR(params[i], "expr")) {
- if (_dataModel) {
- paramValue = _dataModel->evalAsString(ATTR(params[i], "expr"));
- } else {
- paramValue = ATTR(params[i], "expr");
- }
- } else if(HAS_ATTR(params[i], "location") && _dataModel) {
- paramValue = _dataModel->evalAsString(ATTR(params[i], "location"));
- } else {
- LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
- continue;
- }
- invokeReq.params[ATTR(params[i], "name")].push_back(paramValue);
- }
-
- // content
- NodeSet<std::string> contents = _xpath.evaluate("" + _nsPrefix + "content", element).asNodeSet();
- if (contents.size() > 1)
- LOG(ERROR) << "Only a single content element is allowed for send elements - using first one";
- if (contents.size() > 0) {
- invokeReq.content = contents[0].getNodeValue();
- }
-
- Invoker* invoker = Factory::getInvoker(invokeReq.type, this);
- if (invoker != NULL) {
- _invokerIds[invokeReq.invokeid] = invoker;
- LOG(INFO) << "Added " << invokeReq.type << " at " << invokeReq.invokeid;
- invoker->invoke(invokeReq);
- } else {
- LOG(ERROR) << "No invoker known for type " << invokeReq.type;
- }
-
- } catch (Event e) {
- LOG(ERROR) << "Syntax error in invoke element:" << std::endl << e << std::endl;
- }
-}
-
+ InvokeRequest invokeReq;
+ try {
+ // type
+ if (HAS_ATTR(element, "typeexpr") && _dataModel) {
+ invokeReq.type = _dataModel->evalAsString(ATTR(element, "typeexpr"));
+ } else if (HAS_ATTR(element, "type")) {
+ invokeReq.type = ATTR(element, "type");
+ } else {
+ LOG(ERROR) << "invoke element is missing expr or typeexpr or no datamodel is specified";
+ }
+
+ // src
+ std::string source;
+ if (HAS_ATTR(element, "srcexpr") && _dataModel) {
+ source = _dataModel->evalAsString(ATTR(element, "srcexpr"));
+ } else if (HAS_ATTR(element, "src")) {
+ source = ATTR(element, "src");
+ }
+ if (source.length() > 0) {
+ Arabica::io::URI srcURI(source);
+ if (!makeAbsolute(srcURI)) {
+ LOG(ERROR) << "invoke element has relative src URI with no baseURI set.";
+ return;
+ }
+ invokeReq.src = srcURI.as_string();
+ }
+
+ // id
+ if (HAS_ATTR(element, "idlocation") && _dataModel) {
+ invokeReq.invokeid = _dataModel->evalAsString(ATTR(element, "idlocation"));
+ } else if (HAS_ATTR(element, "id")) {
+ invokeReq.invokeid = ATTR(element, "id");
+ } else {
+ assert(false);
+ }
+
+ // namelist
+ if (HAS_ATTR(element, "namelist")) {
+ invokeReq.namelist = ATTR(element, "namelist");
+ }
+
+ // autoforward
+ if (HAS_ATTR(element, "autoforward")) {
+ if (boost::iequals(ATTR(element, "autoforward"), "true")) {
+ invokeReq.autoForward = true;
+ }
+ } else {
+ invokeReq.autoForward = false;
+ }
+
+ // params
+ NodeSet<std::string> params = _xpath.evaluate("" + _nsPrefix + "param", element).asNodeSet();
+ for (int i = 0; i < params.size(); i++) {
+ if (!HAS_ATTR(params[i], "name")) {
+ LOG(ERROR) << "param element is missing name attribut";
+ continue;
+ }
+ std::string paramValue;
+ if (HAS_ATTR(params[i], "expr")) {
+ if (_dataModel) {
+ paramValue = _dataModel->evalAsString(ATTR(params[i], "expr"));
+ } else {
+ paramValue = ATTR(params[i], "expr");
+ }
+ } else if(HAS_ATTR(params[i], "location") && _dataModel) {
+ paramValue = _dataModel->evalAsString(ATTR(params[i], "location"));
+ } else {
+ LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
+ continue;
+ }
+// invokeReq.params[ATTR(params[i], "name")].push_back(paramValue);
+ invokeReq.params.insert(std::make_pair(ATTR(params[i], "name"), paramValue));
+
+ }
+
+ // content
+ NodeSet<std::string> contents = _xpath.evaluate("" + _nsPrefix + "content", element).asNodeSet();
+ if (contents.size() > 1)
+ LOG(ERROR) << "Only a single content element is allowed for send elements - using first one";
+ if (contents.size() > 0) {
+ invokeReq.content = contents[0].getNodeValue();
+ }
+
+ Invoker* invoker = Factory::getInvoker(invokeReq.type, this);
+ if (invoker != NULL) {
+ _invokerIds[invokeReq.invokeid] = invoker;
+ LOG(INFO) << "Added " << invokeReq.type << " at " << invokeReq.invokeid;
+ invoker->invoke(invokeReq);
+ } else {
+ LOG(ERROR) << "No invoker known for type " << invokeReq.type;
+ }
+
+ } catch (Event e) {
+ LOG(ERROR) << "Syntax error in invoke element:" << std::endl << e << std::endl;
+ }
+}
+
void Interpreter::cancelInvoke(const Arabica::DOM::Node<std::string>& element) {
- std::string invokeId;
- if (HAS_ATTR(element, "idlocation") && _dataModel) {
- invokeId = _dataModel->evalAsString(ATTR(element, "idlocation"));
- } else if (HAS_ATTR(element, "id")) {
- invokeId = ATTR(element, "id");
- } else {
- assert(false);
- }
- if (_invokerIds.find(invokeId) != _invokerIds.end()) {
- LOG(INFO) << "Removed invoker at " << invokeId;
- delete (_invokerIds[invokeId]);
- _invokerIds.erase(invokeId);
- } else {
- LOG(ERROR) << "Cannot cancel invoke for id " << invokeId << ": no soch invokation";
- }
+ std::string invokeId;
+ if (HAS_ATTR(element, "idlocation") && _dataModel) {
+ invokeId = _dataModel->evalAsString(ATTR(element, "idlocation"));
+ } else if (HAS_ATTR(element, "id")) {
+ invokeId = ATTR(element, "id");
+ } else {
+ assert(false);
+ }
+ if (_invokerIds.find(invokeId) != _invokerIds.end()) {
+ LOG(INFO) << "Removed invoker at " << invokeId;
+ delete (_invokerIds[invokeId]);
+ _invokerIds.erase(invokeId);
+ } else {
+ LOG(ERROR) << "Cannot cancel invoke for id " << invokeId << ": no soch invokation";
+ }
}
Arabica::XPath::NodeSet<std::string> Interpreter::selectTransitions(const std::string& event) {
- Arabica::XPath::NodeSet<std::string> enabledTransitions;
-
- NodeSet<std::string> atomicStates;
- for (unsigned int i = 0; i < _configuration.size(); i++) {
- if (isAtomic(_configuration[i]))
- atomicStates.push_back(_configuration[i]);
- }
- atomicStates.to_document_order();
-
- for (unsigned int i = 0; i < atomicStates.size(); i++) {
- NodeSet<std::string> ancestors = getProperAncestors(atomicStates[i], Arabica::DOM::Node<std::string>());
- ancestors.push_back(atomicStates[i]);
- for (unsigned int j = 0; j < ancestors.size(); j++) {
- NodeSet<std::string> transitions = _xpath.evaluate("" + _nsPrefix + "transition", ancestors[j]).asNodeSet();
- for (unsigned int k = 0; k < transitions.size(); k++) {
- if (((Arabica::DOM::Element<std::string>)transitions[k]).hasAttribute("event") &&
- nameMatch(((Arabica::DOM::Element<std::string>)transitions[k]).getAttribute("event"), event) &&
- hasConditionMatch(transitions[k])) {
- enabledTransitions.push_back(transitions[k]);
- goto LOOP;
- }
- }
- }
- LOOP:;
- }
- return enabledTransitions;
+ Arabica::XPath::NodeSet<std::string> enabledTransitions;
+
+ NodeSet<std::string> atomicStates;
+ for (unsigned int i = 0; i < _configuration.size(); i++) {
+ if (isAtomic(_configuration[i]))
+ atomicStates.push_back(_configuration[i]);
+ }
+ atomicStates.to_document_order();
+
+ for (unsigned int i = 0; i < atomicStates.size(); i++) {
+ NodeSet<std::string> ancestors = getProperAncestors(atomicStates[i], Arabica::DOM::Node<std::string>());
+ ancestors.push_back(atomicStates[i]);
+ for (unsigned int j = 0; j < ancestors.size(); j++) {
+ NodeSet<std::string> transitions = _xpath.evaluate("" + _nsPrefix + "transition", ancestors[j]).asNodeSet();
+ for (unsigned int k = 0; k < transitions.size(); k++) {
+ if (((Arabica::DOM::Element<std::string>)transitions[k]).hasAttribute("event") &&
+ nameMatch(((Arabica::DOM::Element<std::string>)transitions[k]).getAttribute("event"), event) &&
+ hasConditionMatch(transitions[k])) {
+ enabledTransitions.push_back(transitions[k]);
+ goto LOOP;
+ }
+ }
+ }
+LOOP:
+ ;
+ }
+ return enabledTransitions;
}
// see: http://www.w3.org/TR/scxml/#EventDescriptors
bool Interpreter::nameMatch(const std::string& transitionEvent, const std::string& event) {
- assert(transitionEvent.size() > 0);
- assert(event.size() > 0);
-
- // naive case of single descriptor and exact match
- if (boost::equals(transitionEvent, event))
- return true;
-
- boost::char_separator<char> sep(" ");
- boost::tokenizer<boost::char_separator<char> > tokens(transitionEvent, sep);
- boost::tokenizer<boost::char_separator<char> >::iterator tokenIter = tokens.begin();
-
- while(tokenIter != tokens.end()) {
- std::string eventDesc(*tokenIter++);
-
- // remove optional trailing .* for CCXML compatibility
- if (eventDesc.find("*", eventDesc.size() - 1) != std::string::npos)
- eventDesc = eventDesc.substr(0, eventDesc.size() - 1);
- if (eventDesc.find(".", eventDesc.size() - 1) != std::string::npos)
- eventDesc = eventDesc.substr(0, eventDesc.size() - 1);
-
- // was eventDesc the * wildcard
- if (eventDesc.size() == 0)
- return true;
-
- // are they already equal?
- if (boost::equals(eventDesc, event))
- return true;
-
- // eventDesc has to be a real prefix of event now and therefore shorter
- if (eventDesc.size() >= event.size())
- continue;
-
- // it is a prefix of the event name and event continues with .something
- if (eventDesc.compare(event.substr(0, eventDesc.size())) == 0)
- if (event.find(".", eventDesc.size()) == eventDesc.size())
- return true;
- }
- return false;
-}
-
+ assert(transitionEvent.size() > 0);
+ assert(event.size() > 0);
+
+ // naive case of single descriptor and exact match
+ if (boost::equals(transitionEvent, event))
+ return true;
+
+ boost::char_separator<char> sep(" ");
+ boost::tokenizer<boost::char_separator<char> > tokens(transitionEvent, sep);
+ boost::tokenizer<boost::char_separator<char> >::iterator tokenIter = tokens.begin();
+
+ while(tokenIter != tokens.end()) {
+ std::string eventDesc(*tokenIter++);
+
+ // remove optional trailing .* for CCXML compatibility
+ if (eventDesc.find("*", eventDesc.size() - 1) != std::string::npos)
+ eventDesc = eventDesc.substr(0, eventDesc.size() - 1);
+ if (eventDesc.find(".", eventDesc.size() - 1) != std::string::npos)
+ eventDesc = eventDesc.substr(0, eventDesc.size() - 1);
+
+ // was eventDesc the * wildcard
+ if (eventDesc.size() == 0)
+ return true;
+
+ // are they already equal?
+ if (boost::equals(eventDesc, event))
+ return true;
+
+ // eventDesc has to be a real prefix of event now and therefore shorter
+ if (eventDesc.size() >= event.size())
+ continue;
+
+ // it is a prefix of the event name and event continues with .something
+ if (eventDesc.compare(event.substr(0, eventDesc.size())) == 0)
+ if (event.find(".", eventDesc.size()) == eventDesc.size())
+ return true;
+ }
+ return false;
+}
+
Arabica::XPath::NodeSet<std::string> Interpreter::selectEventlessTransitions() {
- Arabica::XPath::NodeSet<std::string> enabledTransitions;
-
- NodeSet<std::string> atomicStates;
- for (unsigned int i = 0; i < _configuration.size(); i++) {
- if (isAtomic(_configuration[i]))
- atomicStates.push_back(_configuration[i]);
- }
- atomicStates.to_document_order();
-
- for (unsigned int i = 0; i < atomicStates.size(); i++) {
- NodeSet<std::string> ancestors = getProperAncestors(atomicStates[i], Arabica::DOM::Node<std::string>());
- ancestors.push_back(atomicStates[i]);
- for (unsigned int j = 0; j < ancestors.size(); j++) {
- NodeSet<std::string> transitions = _xpath.evaluate("" + _nsPrefix + "transition", ancestors[j]).asNodeSet();
- for (unsigned int k = 0; k < transitions.size(); k++) {
- if (!((Arabica::DOM::Element<std::string>)transitions[k]).hasAttribute("event") && hasConditionMatch(transitions[k])) {
- enabledTransitions.push_back(transitions[k]);
- goto LOOP;
- }
- }
- }
- LOOP:;
- }
-
- enabledTransitions = filterPreempted(enabledTransitions);
- return enabledTransitions;
+ Arabica::XPath::NodeSet<std::string> enabledTransitions;
+
+ NodeSet<std::string> atomicStates;
+ for (unsigned int i = 0; i < _configuration.size(); i++) {
+ if (isAtomic(_configuration[i]))
+ atomicStates.push_back(_configuration[i]);
+ }
+ atomicStates.to_document_order();
+
+ for (unsigned int i = 0; i < atomicStates.size(); i++) {
+ NodeSet<std::string> ancestors = getProperAncestors(atomicStates[i], Arabica::DOM::Node<std::string>());
+ ancestors.push_back(atomicStates[i]);
+ for (unsigned int j = 0; j < ancestors.size(); j++) {
+ NodeSet<std::string> transitions = _xpath.evaluate("" + _nsPrefix + "transition", ancestors[j]).asNodeSet();
+ for (unsigned int k = 0; k < transitions.size(); k++) {
+ if (!((Arabica::DOM::Element<std::string>)transitions[k]).hasAttribute("event") && hasConditionMatch(transitions[k])) {
+ enabledTransitions.push_back(transitions[k]);
+ goto LOOP;
+ }
+ }
+ }
+LOOP:
+ ;
+ }
+
+ enabledTransitions = filterPreempted(enabledTransitions);
+ return enabledTransitions;
}
bool Interpreter::hasConditionMatch(const Arabica::DOM::Node<std::string>& conditional) {
- try {
- if (_dataModel && HAS_ATTR(conditional, "cond"))
- return _dataModel->evalAsBool(ATTR(conditional, "cond"));
- } catch (Event e) {
- LOG(ERROR) << "Syntax error in cond attribute of " << TAGNAME(conditional) << " element:" << std::endl << e << std::endl;
- return false;
- }
- return true; // no condition is always true
+ try {
+ if (_dataModel && HAS_ATTR(conditional, "cond"))
+ return _dataModel->evalAsBool(ATTR(conditional, "cond"));
+ } catch (Event e) {
+ LOG(ERROR) << "Syntax error in cond attribute of " << TAGNAME(conditional) << " element:" << std::endl << e << std::endl;
+ return false;
+ }
+ return true; // no condition is always true
}
Arabica::XPath::NodeSet<std::string> Interpreter::filterPreempted(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
- Arabica::XPath::NodeSet<std::string> filteredTransitions;
- for (unsigned int i = 0; i < enabledTransitions.size(); i++) {
- Arabica::DOM::Node<std::string> t = enabledTransitions[i];
- for (unsigned int j = i+1; j < enabledTransitions.size(); j++) {
- Arabica::DOM::Node<std::string> t2 = enabledTransitions[j];
- if (isPreemptingTransition(t2, t))
- goto LOOP;
- }
- filteredTransitions.push_back(t);
- LOOP:;
- }
- return filteredTransitions;
+ Arabica::XPath::NodeSet<std::string> filteredTransitions;
+ for (unsigned int i = 0; i < enabledTransitions.size(); i++) {
+ Arabica::DOM::Node<std::string> t = enabledTransitions[i];
+ for (unsigned int j = i+1; j < enabledTransitions.size(); j++) {
+ Arabica::DOM::Node<std::string> t2 = enabledTransitions[j];
+ if (isPreemptingTransition(t2, t))
+ goto LOOP;
+ }
+ filteredTransitions.push_back(t);
+LOOP:
+ ;
+ }
+ return filteredTransitions;
}
bool Interpreter::isPreemptingTransition(const Arabica::DOM::Node<std::string>& t1, const Arabica::DOM::Node<std::string>& t2) {
- if (t1 == t2)
- return false;
- if (isWithinSameChild(t1) && (!isTargetless(t2) && !isWithinSameChild(t2)))
- return true;
- if (!isTargetless(t1) && !isWithinSameChild(t1))
- return true;
- return false;
+ if (t1 == t2)
+ return false;
+ if (isWithinSameChild(t1) && (!isTargetless(t2) && !isWithinSameChild(t2)))
+ return true;
+ if (!isTargetless(t1) && !isWithinSameChild(t1))
+ return true;
+ return false;
}
void Interpreter::microstep(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
#if 0
- std::cout << "Transitions: ";
- for (int i = 0; i < enabledTransitions.size(); i++) {
- std::cout << ((Arabica::DOM::Element<std::string>)getSourceState(enabledTransitions[i])).getAttribute("id") << " -> " << std::endl;
- NodeSet<std::string> targetSet = getTargetStates(enabledTransitions[i]);
- for (int j = 0; j < targetSet.size(); j++) {
- std::cout << " " << ((Arabica::DOM::Element<std::string>)targetSet[j]).getAttribute("id") << std::endl;
- }
- }
- std::cout << std::endl;
+ std::cout << "Transitions: ";
+ for (int i = 0; i < enabledTransitions.size(); i++) {
+ std::cout << ((Arabica::DOM::Element<std::string>)getSourceState(enabledTransitions[i])).getAttribute("id") << " -> " << std::endl;
+ NodeSet<std::string> targetSet = getTargetStates(enabledTransitions[i]);
+ for (int j = 0; j < targetSet.size(); j++) {
+ std::cout << " " << ((Arabica::DOM::Element<std::string>)targetSet[j]).getAttribute("id") << std::endl;
+ }
+ }
+ std::cout << std::endl;
#endif
- exitStates(enabledTransitions);
- executeTransitionContent(enabledTransitions);
- enterStates(enabledTransitions);
+ exitStates(enabledTransitions);
+ executeTransitionContent(enabledTransitions);
+ enterStates(enabledTransitions);
}
void Interpreter::exitInterpreter() {
- NodeSet<std::string> statesToExit = _configuration;
- statesToExit.to_document_order();
- statesToExit.reverse();
-
- for (int i = 0; i < statesToExit.size(); i++) {
- Arabica::XPath::NodeSet<std::string> onExitElems = _xpath.evaluate("" + _nsPrefix + "onexit", statesToExit[i]).asNodeSet();
- for (int j = 0; j < onExitElems.size(); j++) {
- executeContent(onExitElems[j]);
- }
- Arabica::XPath::NodeSet<std::string> invokeElems = _xpath.evaluate("" + _nsPrefix + "invoke", statesToExit[i]).asNodeSet();
- for (int j = 0; j < invokeElems.size(); j++) {
- cancelInvoke(invokeElems[j]);
- }
- if (isFinal(statesToExit[i]) && parentIsScxmlState(statesToExit[i])) {
- returnDoneEvent(statesToExit[i]);
- }
- }
- _configuration = NodeSet<std::string>();
+ NodeSet<std::string> statesToExit = _configuration;
+ statesToExit.to_document_order();
+ statesToExit.reverse();
+
+ for (int i = 0; i < statesToExit.size(); i++) {
+ Arabica::XPath::NodeSet<std::string> onExitElems = _xpath.evaluate("" + _nsPrefix + "onexit", statesToExit[i]).asNodeSet();
+ for (int j = 0; j < onExitElems.size(); j++) {
+ executeContent(onExitElems[j]);
+ }
+ Arabica::XPath::NodeSet<std::string> invokeElems = _xpath.evaluate("" + _nsPrefix + "invoke", statesToExit[i]).asNodeSet();
+ for (int j = 0; j < invokeElems.size(); j++) {
+ cancelInvoke(invokeElems[j]);
+ }
+ if (isFinal(statesToExit[i]) && parentIsScxmlState(statesToExit[i])) {
+ returnDoneEvent(statesToExit[i]);
+ }
+ }
+ _configuration = NodeSet<std::string>();
}
void Interpreter::executeTransitionContent(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
- for (int i = 0; i < enabledTransitions.size(); i++) {
- executeContent(enabledTransitions[i]);
- }
+ for (int i = 0; i < enabledTransitions.size(); i++) {
+ executeContent(enabledTransitions[i]);
+ }
}
void Interpreter::executeContent(const NodeList<std::string>& content) {
- for (unsigned int i = 0; i < content.getLength(); i++) {
- if (content.item(i).getNodeType() != Node_base::ELEMENT_NODE)
- continue;
- executeContent(content.item(i));
- }
+ for (unsigned int i = 0; i < content.getLength(); i++) {
+ if (content.item(i).getNodeType() != Node_base::ELEMENT_NODE)
+ continue;
+ executeContent(content.item(i));
+ }
}
-
+
void Interpreter::executeContent(const Arabica::DOM::Node<std::string>& content) {
- if (content.getNodeType() != Node_base::ELEMENT_NODE)
- return;
-
- if (false) {
- } else if (boost::iequals(TAGNAME(content), "raise")) {
- // --- RAISE --------------------------
- if (HAS_ATTR(content, "event")) {
- Event event;
- event.name = ATTR(content, "event");
- _internalQueue.push_back(event);
- }
- } else if (boost::iequals(TAGNAME(content), "if")) {
- // --- IF / ELSEIF / ELSE --------------
- Arabica::DOM::Element<std::string> ifElem = (Arabica::DOM::Element<std::string>)content;
- if(hasConditionMatch(ifElem)) {
- // condition is true, execute all content up to an elseif, else or end
- if (ifElem.hasChildNodes()) {
- NodeList<std::string> childs = ifElem.getChildNodes();
- for (unsigned int i = 0; i < childs.getLength(); i++) {
- if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE)
- continue;
- if (boost::iequals(TAGNAME(childs.item(i)), "elsif") ||
- boost::iequals(TAGNAME(childs.item(i)), "else"))
- break;
- executeContent(childs.item(i));
- }
- }
- } else {
- // condition does not match - do we have an elsif?
- if (ifElem.hasChildNodes()) {
- NodeList<std::string> elseifElem = ifElem.getElementsByTagName("elseif");
- for (unsigned int i = 0; i < elseifElem.getLength(); i++) {
- if (hasConditionMatch(elseifElem.item(i))) {
- executeContent(elseifElem.item(i).getChildNodes());
- goto ELSIF_ELEM_MATCH;
- }
- }
- NodeList<std::string> elseElem = ifElem.getElementsByTagName("else");
- if (elseElem.getLength() > 0)
- executeContent(elseElem.item(0).getChildNodes());
- }
- }
- ELSIF_ELEM_MATCH:;
- } else if (boost::iequals(TAGNAME(content), "elseif")) {
- std::cerr << "Found single elsif to evaluate!" << std::endl;
- } else if (boost::iequals(TAGNAME(content), "else")) {
- std::cerr << "Found single else to evaluate!" << std::endl;
- } else if (boost::iequals(TAGNAME(content), "foreach")) {
- // --- FOREACH --------------------------
- if (_dataModel) {
- if (HAS_ATTR(content, "array") && HAS_ATTR(content, "item")) {
- std::string array = ATTR(content, "array");
- std::string item = ATTR(content, "item");
- std::string index = (HAS_ATTR(content, "index") ? ATTR(content, "index") : "");
- uint32_t iterations = _dataModel->getLength(array);
- _dataModel->pushContext(); // copy old and enter new context
- for (uint32_t iteration = 0; iteration < iterations; iteration++) {
- {
- // assign array element to item
- std::stringstream ss;
- ss << array << "[" << iteration << "]";
- _dataModel->assign(item, ss.str());
- }
- if (index.length() > 0) {
- // assign iteration element to index
- std::stringstream ss;
- ss << iteration;
- _dataModel->assign(index,ss.str());
- }
- if (content.hasChildNodes())
- executeContent(content.getChildNodes());
- }
- _dataModel->popContext(); // leave stacked context
- } else {
- LOG(ERROR) << "Expected array and item attributes with foreach element!" << std::endl;
- }
- }
- } else if (boost::iequals(TAGNAME(content), "log")) {
- // --- LOG --------------------------
- Arabica::DOM::Element<std::string> logElem = (Arabica::DOM::Element<std::string>)content;
- if (logElem.hasAttribute("expr")) {
- if (_dataModel) {
- try {
- std::cout << _dataModel->evalAsString(logElem.getAttribute("expr")) << std::endl;
- } catch (Event e) {
- LOG(ERROR) << "Syntax error in expr attribute of log element:" << std::endl << e << std::endl;
- }
- } else {
- std::cout << logElem.getAttribute("expr") << std::endl;
- }
- }
- } else if (boost::iequals(TAGNAME(content), "assign")) {
- // --- ASSIGN --------------------------
- if (_dataModel && HAS_ATTR(content, "location") && HAS_ATTR(content, "expr")) {
- try {
- _dataModel->assign(ATTR(content, "location"), ATTR(content, "expr"));
- } catch (Event e) {
- LOG(ERROR) << "Syntax error in attributes of assign element:" << std::endl << e << std::endl;
- }
- }
- } else if (boost::iequals(TAGNAME(content), "validate")) {
- // --- VALIDATE --------------------------
- if (_dataModel) {
- std::string location = (HAS_ATTR(content, "location") ? ATTR(content, "location") : "");
- std::string schema = (HAS_ATTR(content, "schema") ? ATTR(content, "schema") : "");
- _dataModel->validate(location, schema);
- }
- } else if (boost::iequals(TAGNAME(content), "script")) {
- // --- SCRIPT --------------------------
- if (_dataModel) {
- if (HAS_ATTR(content, "src")) {
- Arabica::io::URI url(ATTR(content, "src"));
- if (!makeAbsolute(url)) {
- LOG(ERROR) << "script element has relative URI " << ATTR(content, "src") << " with no base URI set for interpreter";
- return;
- }
-
- std::stringstream srcContent;
- URL scriptUrl(url.as_string());
- srcContent << scriptUrl;
-
- try {
- _dataModel->eval(srcContent.str());
- } catch (Event e) {
- LOG(ERROR) << "Syntax error while executing script element from '" << ATTR(content, "src") << "':" << std::endl << e << std::endl;
- }
- } else {
- if (content.hasChildNodes()) {
- // search for the text node with the actual script
- if (content.getFirstChild().getNodeType() == Node_base::TEXT_NODE) {
- try {
- _dataModel->eval(content.getFirstChild().getNodeValue());
- } catch (Event e) {
- LOG(ERROR) << "Syntax error while executing script element" << std::endl << e << std::endl;
- }
- }
- }
- }
- }
- } else if (boost::iequals(TAGNAME(content), "send")) {
- // --- SEND --------------------------
- send(content);
- } else if (boost::iequals(TAGNAME(content), "cancel")) {
- // --- CANCEL --------------------------
- std::string sendId;
- try {
- if (HAS_ATTR(content, "sendidexpr")) {
- sendId = _dataModel->evalAsString(ATTR(content, "sendidexpr"));
- } else if(HAS_ATTR(content, "sendid")) {
- sendId = ATTR(content, "sendid");
- } else {
- LOG(ERROR) << "Expected sendidexpr or sendid attribute in cancel element";
- return;
- }
- _sendQueue->cancelEvent(sendId);
-
- } catch (Event e) {
- LOG(ERROR) << "Syntax error while executing cancel element" << std::endl << e << std::endl;
- }
-
- } else if (boost::iequals(TAGNAME(content), "invoke")) {
- // --- INVOKE --------------------------
- } else {
- NodeList<std::string> executable = content.getChildNodes();
- for (int i = 0; i < executable.getLength(); i++) {
- executeContent(executable.item(i));
- }
- }
+ if (content.getNodeType() != Node_base::ELEMENT_NODE)
+ return;
+
+ if (false) {
+ } else if (boost::iequals(TAGNAME(content), "raise")) {
+ // --- RAISE --------------------------
+ if (HAS_ATTR(content, "event")) {
+ Event event;
+ event.name = ATTR(content, "event");
+ _internalQueue.push_back(event);
+ }
+ } else if (boost::iequals(TAGNAME(content), "if")) {
+ // --- IF / ELSEIF / ELSE --------------
+ Arabica::DOM::Element<std::string> ifElem = (Arabica::DOM::Element<std::string>)content;
+ if(hasConditionMatch(ifElem)) {
+ // condition is true, execute all content up to an elseif, else or end
+ if (ifElem.hasChildNodes()) {
+ NodeList<std::string> childs = ifElem.getChildNodes();
+ for (unsigned int i = 0; i < childs.getLength(); i++) {
+ if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE)
+ continue;
+ if (boost::iequals(TAGNAME(childs.item(i)), "elsif") ||
+ boost::iequals(TAGNAME(childs.item(i)), "else"))
+ break;
+ executeContent(childs.item(i));
+ }
+ }
+ } else {
+ // condition does not match - do we have an elsif?
+ if (ifElem.hasChildNodes()) {
+ NodeList<std::string> elseifElem = ifElem.getElementsByTagName("elseif");
+ for (unsigned int i = 0; i < elseifElem.getLength(); i++) {
+ if (hasConditionMatch(elseifElem.item(i))) {
+ executeContent(elseifElem.item(i).getChildNodes());
+ goto ELSIF_ELEM_MATCH;
+ }
+ }
+ NodeList<std::string> elseElem = ifElem.getElementsByTagName("else");
+ if (elseElem.getLength() > 0)
+ executeContent(elseElem.item(0).getChildNodes());
+ }
+ }
+ELSIF_ELEM_MATCH:
+ ;
+ } else if (boost::iequals(TAGNAME(content), "elseif")) {
+ std::cerr << "Found single elsif to evaluate!" << std::endl;
+ } else if (boost::iequals(TAGNAME(content), "else")) {
+ std::cerr << "Found single else to evaluate!" << std::endl;
+ } else if (boost::iequals(TAGNAME(content), "foreach")) {
+ // --- FOREACH --------------------------
+ if (_dataModel) {
+ if (HAS_ATTR(content, "array") && HAS_ATTR(content, "item")) {
+ std::string array = ATTR(content, "array");
+ std::string item = ATTR(content, "item");
+ std::string index = (HAS_ATTR(content, "index") ? ATTR(content, "index") : "");
+ uint32_t iterations = _dataModel->getLength(array);
+ _dataModel->pushContext(); // copy old and enter new context
+ for (uint32_t iteration = 0; iteration < iterations; iteration++) {
+ {
+ // assign array element to item
+ std::stringstream ss;
+ ss << array << "[" << iteration << "]";
+ _dataModel->assign(item, ss.str());
+ }
+ if (index.length() > 0) {
+ // assign iteration element to index
+ std::stringstream ss;
+ ss << iteration;
+ _dataModel->assign(index,ss.str());
+ }
+ if (content.hasChildNodes())
+ executeContent(content.getChildNodes());
+ }
+ _dataModel->popContext(); // leave stacked context
+ } else {
+ LOG(ERROR) << "Expected array and item attributes with foreach element!" << std::endl;
+ }
+ }
+ } else if (boost::iequals(TAGNAME(content), "log")) {
+ // --- LOG --------------------------
+ Arabica::DOM::Element<std::string> logElem = (Arabica::DOM::Element<std::string>)content;
+ if (logElem.hasAttribute("expr")) {
+ if (_dataModel) {
+ try {
+ std::cout << _dataModel->evalAsString(logElem.getAttribute("expr")) << std::endl;
+ } catch (Event e) {
+ LOG(ERROR) << "Syntax error in expr attribute of log element:" << std::endl << e << std::endl;
+ }
+ } else {
+ std::cout << logElem.getAttribute("expr") << std::endl;
+ }
+ }
+ } else if (boost::iequals(TAGNAME(content), "assign")) {
+ // --- ASSIGN --------------------------
+ if (_dataModel && HAS_ATTR(content, "location") && HAS_ATTR(content, "expr")) {
+ try {
+ _dataModel->assign(ATTR(content, "location"), ATTR(content, "expr"));
+ } catch (Event e) {
+ LOG(ERROR) << "Syntax error in attributes of assign element:" << std::endl << e << std::endl;
+ }
+ }
+ } else if (boost::iequals(TAGNAME(content), "validate")) {
+ // --- VALIDATE --------------------------
+ if (_dataModel) {
+ std::string location = (HAS_ATTR(content, "location") ? ATTR(content, "location") : "");
+ std::string schema = (HAS_ATTR(content, "schema") ? ATTR(content, "schema") : "");
+ _dataModel->validate(location, schema);
+ }
+ } else if (boost::iequals(TAGNAME(content), "script")) {
+ // --- SCRIPT --------------------------
+ if (_dataModel) {
+ if (HAS_ATTR(content, "src")) {
+ Arabica::io::URI url(ATTR(content, "src"));
+ if (!makeAbsolute(url)) {
+ LOG(ERROR) << "script element has relative URI " << ATTR(content, "src") << " with no base URI set for interpreter";
+ return;
+ }
+
+ std::stringstream srcContent;
+ URL scriptUrl(url.as_string());
+ srcContent << scriptUrl;
+
+ try {
+ _dataModel->eval(srcContent.str());
+ } catch (Event e) {
+ LOG(ERROR) << "Syntax error while executing script element from '" << ATTR(content, "src") << "':" << std::endl << e << std::endl;
+ }
+ } else {
+ if (content.hasChildNodes()) {
+ // search for the text node with the actual script
+ if (content.getFirstChild().getNodeType() == Node_base::TEXT_NODE) {
+ try {
+ _dataModel->eval(content.getFirstChild().getNodeValue());
+ } catch (Event e) {
+ LOG(ERROR) << "Syntax error while executing script element" << std::endl << e << std::endl;
+ }
+ }
+ }
+ }
+ }
+ } else if (boost::iequals(TAGNAME(content), "send")) {
+ // --- SEND --------------------------
+ send(content);
+ } else if (boost::iequals(TAGNAME(content), "cancel")) {
+ // --- CANCEL --------------------------
+ std::string sendId;
+ try {
+ if (HAS_ATTR(content, "sendidexpr")) {
+ sendId = _dataModel->evalAsString(ATTR(content, "sendidexpr"));
+ } else if(HAS_ATTR(content, "sendid")) {
+ sendId = ATTR(content, "sendid");
+ } else {
+ LOG(ERROR) << "Expected sendidexpr or sendid attribute in cancel element";
+ return;
+ }
+ _sendQueue->cancelEvent(sendId);
+
+ } catch (Event e) {
+ LOG(ERROR) << "Syntax error while executing cancel element" << std::endl << e << std::endl;
+ }
+
+ } else if (boost::iequals(TAGNAME(content), "invoke")) {
+ // --- INVOKE --------------------------
+ } else {
+ NodeList<std::string> executable = content.getChildNodes();
+ for (int i = 0; i < executable.getLength(); i++) {
+ executeContent(executable.item(i));
+ }
+ }
}
void Interpreter::returnDoneEvent(const Arabica::DOM::Node<std::string>& state) {
}
void Interpreter::exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
- NodeSet<std::string> statesToExit;
- for (int i = 0; i < enabledTransitions.size(); i++) {
- Arabica::DOM::Element<std::string> transition = ((Arabica::DOM::Element<std::string>)enabledTransitions[i]);
- if (!isTargetless(transition)) {
- std::string transitionType = (boost::iequals(transition.getAttribute("type"), "internal") ? "internal" : "external");
- NodeSet<std::string> tStates = getTargetStates(transition);
- Arabica::DOM::Node<std::string> ancestor;
- Arabica::DOM::Node<std::string> source = getSourceState(transition);
-
- bool allDescendants = true;
- for (int j = 0; j < tStates.size(); j++) {
- if (!isDescendant(tStates[j], source)) {
- allDescendants = false;
- break;
- }
- }
- if (boost::iequals(transitionType, "internal") &&
- isCompound(source) &&
- allDescendants)
- {
- ancestor = source;
- } else {
- NodeSet<std::string> tmpStates;
- tmpStates.push_back(source);
- tmpStates.insert(tmpStates.end(), tStates.begin(), tStates.end());
-
- ancestor = findLCCA(tmpStates);
- }
-
- for (int j = 0; j < _configuration.size(); j++) {
- if (isDescendant(_configuration[j], ancestor))
- statesToExit.push_back(_configuration[j]);
- }
- }
- }
- // remove statesToExit from _statesToInvoke
- std::list<Arabica::DOM::Node<std::string> > tmp;
- for (int i = 0; i < _statesToInvoke.size(); i++) {
- if (!isMember(_statesToInvoke[i], statesToExit)) {
- tmp.push_back(_statesToInvoke[i]);
- }
- }
- _statesToInvoke = NodeSet<std::string>();
- _statesToInvoke.insert(_statesToInvoke.end(), tmp.begin(), tmp.end());
-
- statesToExit.to_document_order();
- statesToExit.reverse();
-
- for (int i = 0; i < statesToExit.size(); i++) {
- NodeSet<std::string> historyElems = _xpath.evaluate("" + _nsPrefix + "history", statesToExit[i]).asNodeSet();
- for (int j = 0; j < historyElems.size(); j++) {
- Arabica::DOM::Element<std::string> historyElem = (Arabica::DOM::Element<std::string>)historyElems[j];
- std::string historyType = (historyElem.hasAttribute("type") ? historyElem.getAttribute("type") : "shallow");
- NodeSet<std::string> historyNodes;
- for (int k = 0; k < _configuration.size(); k++) {
- if (boost::iequals(historyType, "deep")) {
- if (isAtomic(_configuration[k]) && isDescendant(_configuration[k], statesToExit[i]))
- historyNodes.push_back(_configuration[k]);
- } else {
- if (_configuration[k].getParentNode() == statesToExit[i])
- historyNodes.push_back(_configuration[k]);
- }
- }
- _historyValue[historyElem.getAttribute("id")] = historyNodes;
- }
- }
-
- for (int i = 0; i < statesToExit.size(); i++) {
- Arabica::XPath::NodeSet<std::string> onExitElems = _xpath.evaluate("" + _nsPrefix + "onexit", statesToExit[i]).asNodeSet();
- for (int j = 0; j < onExitElems.size(); j++) {
- executeContent(onExitElems[j]);
- }
- Arabica::XPath::NodeSet<std::string> invokeElems = _xpath.evaluate("" + _nsPrefix + "invoke", statesToExit[i]).asNodeSet();
- for (int j = 0; j < invokeElems.size(); j++) {
- cancelInvoke(invokeElems[j]);
- }
- }
+ NodeSet<std::string> statesToExit;
+ for (int i = 0; i < enabledTransitions.size(); i++) {
+ Arabica::DOM::Element<std::string> transition = ((Arabica::DOM::Element<std::string>)enabledTransitions[i]);
+ if (!isTargetless(transition)) {
+ std::string transitionType = (boost::iequals(transition.getAttribute("type"), "internal") ? "internal" : "external");
+ NodeSet<std::string> tStates = getTargetStates(transition);
+ Arabica::DOM::Node<std::string> ancestor;
+ Arabica::DOM::Node<std::string> source = getSourceState(transition);
+
+ bool allDescendants = true;
+ for (int j = 0; j < tStates.size(); j++) {
+ if (!isDescendant(tStates[j], source)) {
+ allDescendants = false;
+ break;
+ }
+ }
+ if (boost::iequals(transitionType, "internal") &&
+ isCompound(source) &&
+ allDescendants) {
+ ancestor = source;
+ } else {
+ NodeSet<std::string> tmpStates;
+ tmpStates.push_back(source);
+ tmpStates.insert(tmpStates.end(), tStates.begin(), tStates.end());
+
+ ancestor = findLCCA(tmpStates);
+ }
+
+ for (int j = 0; j < _configuration.size(); j++) {
+ if (isDescendant(_configuration[j], ancestor))
+ statesToExit.push_back(_configuration[j]);
+ }
+ }
+ }
+ // remove statesToExit from _statesToInvoke
+ std::list<Arabica::DOM::Node<std::string> > tmp;
+ for (int i = 0; i < _statesToInvoke.size(); i++) {
+ if (!isMember(_statesToInvoke[i], statesToExit)) {
+ tmp.push_back(_statesToInvoke[i]);
+ }
+ }
+ _statesToInvoke = NodeSet<std::string>();
+ _statesToInvoke.insert(_statesToInvoke.end(), tmp.begin(), tmp.end());
+
+ statesToExit.to_document_order();
+ statesToExit.reverse();
+
+ for (int i = 0; i < statesToExit.size(); i++) {
+ NodeSet<std::string> historyElems = _xpath.evaluate("" + _nsPrefix + "history", statesToExit[i]).asNodeSet();
+ for (int j = 0; j < historyElems.size(); j++) {
+ Arabica::DOM::Element<std::string> historyElem = (Arabica::DOM::Element<std::string>)historyElems[j];
+ std::string historyType = (historyElem.hasAttribute("type") ? historyElem.getAttribute("type") : "shallow");
+ NodeSet<std::string> historyNodes;
+ for (int k = 0; k < _configuration.size(); k++) {
+ if (boost::iequals(historyType, "deep")) {
+ if (isAtomic(_configuration[k]) && isDescendant(_configuration[k], statesToExit[i]))
+ historyNodes.push_back(_configuration[k]);
+ } else {
+ if (_configuration[k].getParentNode() == statesToExit[i])
+ historyNodes.push_back(_configuration[k]);
+ }
+ }
+ _historyValue[historyElem.getAttribute("id")] = historyNodes;
+ }
+ }
+
+ for (int i = 0; i < statesToExit.size(); i++) {
+ Arabica::XPath::NodeSet<std::string> onExitElems = _xpath.evaluate("" + _nsPrefix + "onexit", statesToExit[i]).asNodeSet();
+ for (int j = 0; j < onExitElems.size(); j++) {
+ executeContent(onExitElems[j]);
+ }
+ Arabica::XPath::NodeSet<std::string> invokeElems = _xpath.evaluate("" + _nsPrefix + "invoke", statesToExit[i]).asNodeSet();
+ for (int j = 0; j < invokeElems.size(); j++) {
+ cancelInvoke(invokeElems[j]);
+ }
+ }
// std::cout << "States to Exit: ";
// for (int i = 0; i < statesToExit.size(); i++) {
@@ -1201,533 +1206,531 @@ void Interpreter::exitStates(const Arabica::XPath::NodeSet<std::string>& enabled
// }
// std::cout << std::endl;
- // remove statesToExit from _configuration
- tmp.clear();
- for (int i = 0; i < _configuration.size(); i++) {
- if (!isMember(_configuration[i], statesToExit)) {
- tmp.push_back(_configuration[i]);
- }
- }
- _configuration = NodeSet<std::string>();
- _configuration.insert(_configuration.end(), tmp.begin(), tmp.end());
+ // remove statesToExit from _configuration
+ tmp.clear();
+ for (int i = 0; i < _configuration.size(); i++) {
+ if (!isMember(_configuration[i], statesToExit)) {
+ tmp.push_back(_configuration[i]);
+ }
+ }
+ _configuration = NodeSet<std::string>();
+ _configuration.insert(_configuration.end(), tmp.begin(), tmp.end());
+
-
}
void Interpreter::enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
- NodeSet<std::string> statesToEnter;
- NodeSet<std::string> statesForDefaultEntry;
-
- for (int i = 0; i < enabledTransitions.size(); i++) {
- Arabica::DOM::Element<std::string> transition = ((Arabica::DOM::Element<std::string>)enabledTransitions[i]);
- if (!isTargetless(transition)) {
- std::string transitionType = (boost::iequals(transition.getAttribute("type"), "internal") ? "internal" : "external");
- NodeSet<std::string> tStates = getTargetStates(transition);
- Arabica::DOM::Node<std::string> ancestor;
- Arabica::DOM::Node<std::string> source = getSourceState(transition);
- assert(source);
-
- bool allDescendants = true;
- for (int j = 0; j < tStates.size(); j++) {
- if (!isDescendant(tStates[j], source)) {
- allDescendants = false;
- break;
- }
- }
- if (boost::iequals(transitionType, "internal") &&
- isCompound(source) &&
- allDescendants)
- {
- ancestor = source;
- } else {
- NodeSet<std::string> tmpStates;
- tmpStates.push_back(source);
- tmpStates.insert(tmpStates.end(), tStates.begin(), tStates.end());
-
- ancestor = findLCCA(tmpStates);
- }
-
- for (int j = 0; j < tStates.size(); j++) {
- addStatesToEnter(tStates[j], statesToEnter, statesForDefaultEntry);
- }
-
- for (int j = 0; j < tStates.size(); j++) {
- NodeSet<std::string> ancestors = getProperAncestors(tStates[j], ancestor);
- for (int k = 0; k < ancestors.size(); k++) {
- statesToEnter.push_back(ancestors[k]);
- if(isParallel(ancestors[k])) {
- NodeSet<std::string> childs = getChildStates(ancestors[k]);
- for (int l = 0; l < childs.size(); l++) {
- bool someIsDescendant = false;
- for (int m = 0; m < statesToEnter.size(); m++) {
- if (isDescendant(statesToEnter[m], childs[l])) {
- someIsDescendant = true;
- break;
- }
- }
- if (!someIsDescendant) {
- addStatesToEnter(childs[l], statesToEnter, statesForDefaultEntry);
- }
- }
- }
- }
- }
- }
- }
- statesToEnter.to_document_order();
- for (int i = 0; i < statesToEnter.size(); i++) {
- Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)statesToEnter[i];
- _configuration.push_back(stateElem);
- _statesToInvoke.push_back(stateElem);
- if (_binding == LATE && stateElem.getAttribute("isFirstEntry").size() > 0) {
- Arabica::XPath::NodeSet<std::string> dataModelElems = _xpath.evaluate("" + _nsPrefix + "datamodel", stateElem).asNodeSet();
- if(dataModelElems.size() > 0 && _dataModel) {
- Arabica::XPath::NodeSet<std::string> dataElems = _xpath.evaluate("" + _nsPrefix + "data", dataModelElems[0]).asNodeSet();
- for (int j = 0; j < dataElems.size(); j++) {
- initializeData(dataElems[j]);
- }
- }
- stateElem.setAttribute("isFirstEntry", "");
- }
- // execute onentry executable content
- Arabica::XPath::NodeSet<std::string> onEntryElems = _xpath.evaluate("" + _nsPrefix + "onentry", stateElem).asNodeSet();
- for (int j = 0; j < onEntryElems.size(); j++) {
- executeContent(onEntryElems[j]);
- }
- if (isMember(stateElem, statesForDefaultEntry)) {
- // execute initial transition content for compund states
- Arabica::XPath::NodeSet<std::string> transitions = _xpath.evaluate("" + _nsPrefix + "initial/" + _nsPrefix + "transition", stateElem).asNodeSet();
- for (int j = 0; j < transitions.size(); j++) {
- executeContent(transitions[j]);
- }
- }
-
- if (isFinal(stateElem)) {
- internalDoneSend(stateElem);
- Arabica::DOM::Element<std::string> parent = (Arabica::DOM::Element<std::string>)stateElem.getParentNode();
-
- if (isParallel(parent.getParentNode())) {
- Arabica::DOM::Element<std::string> grandParent = (Arabica::DOM::Element<std::string>)parent.getParentNode();
-
- Arabica::XPath::NodeSet<std::string> childs = getChildStates(grandParent);
- bool inFinalState = true;
- for (int j = 0; j < childs.size(); j++) {
- if (!isInFinalState(childs[j])) {
- inFinalState = false;
- break;
- }
- }
- if (inFinalState) {
- internalDoneSend(parent);
- }
- }
- }
- }
- for (int i = 0; i < _configuration.size(); i++) {
- Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)_configuration[i];
- if (isFinal(stateElem) && parentIsScxmlState(stateElem))
- _running = false;
- }
+ NodeSet<std::string> statesToEnter;
+ NodeSet<std::string> statesForDefaultEntry;
+
+ for (int i = 0; i < enabledTransitions.size(); i++) {
+ Arabica::DOM::Element<std::string> transition = ((Arabica::DOM::Element<std::string>)enabledTransitions[i]);
+ if (!isTargetless(transition)) {
+ std::string transitionType = (boost::iequals(transition.getAttribute("type"), "internal") ? "internal" : "external");
+ NodeSet<std::string> tStates = getTargetStates(transition);
+ Arabica::DOM::Node<std::string> ancestor;
+ Arabica::DOM::Node<std::string> source = getSourceState(transition);
+ assert(source);
+
+ bool allDescendants = true;
+ for (int j = 0; j < tStates.size(); j++) {
+ if (!isDescendant(tStates[j], source)) {
+ allDescendants = false;
+ break;
+ }
+ }
+ if (boost::iequals(transitionType, "internal") &&
+ isCompound(source) &&
+ allDescendants) {
+ ancestor = source;
+ } else {
+ NodeSet<std::string> tmpStates;
+ tmpStates.push_back(source);
+ tmpStates.insert(tmpStates.end(), tStates.begin(), tStates.end());
+
+ ancestor = findLCCA(tmpStates);
+ }
+
+ for (int j = 0; j < tStates.size(); j++) {
+ addStatesToEnter(tStates[j], statesToEnter, statesForDefaultEntry);
+ }
+
+ for (int j = 0; j < tStates.size(); j++) {
+ NodeSet<std::string> ancestors = getProperAncestors(tStates[j], ancestor);
+ for (int k = 0; k < ancestors.size(); k++) {
+ statesToEnter.push_back(ancestors[k]);
+ if(isParallel(ancestors[k])) {
+ NodeSet<std::string> childs = getChildStates(ancestors[k]);
+ for (int l = 0; l < childs.size(); l++) {
+ bool someIsDescendant = false;
+ for (int m = 0; m < statesToEnter.size(); m++) {
+ if (isDescendant(statesToEnter[m], childs[l])) {
+ someIsDescendant = true;
+ break;
+ }
+ }
+ if (!someIsDescendant) {
+ addStatesToEnter(childs[l], statesToEnter, statesForDefaultEntry);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ statesToEnter.to_document_order();
+ for (int i = 0; i < statesToEnter.size(); i++) {
+ Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)statesToEnter[i];
+ _configuration.push_back(stateElem);
+ _statesToInvoke.push_back(stateElem);
+ if (_binding == LATE && stateElem.getAttribute("isFirstEntry").size() > 0) {
+ Arabica::XPath::NodeSet<std::string> dataModelElems = _xpath.evaluate("" + _nsPrefix + "datamodel", stateElem).asNodeSet();
+ if(dataModelElems.size() > 0 && _dataModel) {
+ Arabica::XPath::NodeSet<std::string> dataElems = _xpath.evaluate("" + _nsPrefix + "data", dataModelElems[0]).asNodeSet();
+ for (int j = 0; j < dataElems.size(); j++) {
+ initializeData(dataElems[j]);
+ }
+ }
+ stateElem.setAttribute("isFirstEntry", "");
+ }
+ // execute onentry executable content
+ Arabica::XPath::NodeSet<std::string> onEntryElems = _xpath.evaluate("" + _nsPrefix + "onentry", stateElem).asNodeSet();
+ for (int j = 0; j < onEntryElems.size(); j++) {
+ executeContent(onEntryElems[j]);
+ }
+ if (isMember(stateElem, statesForDefaultEntry)) {
+ // execute initial transition content for compund states
+ Arabica::XPath::NodeSet<std::string> transitions = _xpath.evaluate("" + _nsPrefix + "initial/" + _nsPrefix + "transition", stateElem).asNodeSet();
+ for (int j = 0; j < transitions.size(); j++) {
+ executeContent(transitions[j]);
+ }
+ }
+
+ if (isFinal(stateElem)) {
+ internalDoneSend(stateElem);
+ Arabica::DOM::Element<std::string> parent = (Arabica::DOM::Element<std::string>)stateElem.getParentNode();
+
+ if (isParallel(parent.getParentNode())) {
+ Arabica::DOM::Element<std::string> grandParent = (Arabica::DOM::Element<std::string>)parent.getParentNode();
+
+ Arabica::XPath::NodeSet<std::string> childs = getChildStates(grandParent);
+ bool inFinalState = true;
+ for (int j = 0; j < childs.size(); j++) {
+ if (!isInFinalState(childs[j])) {
+ inFinalState = false;
+ break;
+ }
+ }
+ if (inFinalState) {
+ internalDoneSend(parent);
+ }
+ }
+ }
+ }
+ for (int i = 0; i < _configuration.size(); i++) {
+ Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)_configuration[i];
+ if (isFinal(stateElem) && parentIsScxmlState(stateElem))
+ _running = false;
+ }
}
bool Interpreter::parentIsScxmlState(Arabica::DOM::Node<std::string> state) {
- Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)state;
- Arabica::DOM::Element<std::string> parentElem = (Arabica::DOM::Element<std::string>)state.getParentNode();
- if (boost::iequals(parentElem.getTagName(), "scxml"))
- return true;
- return false;
+ Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)state;
+ Arabica::DOM::Element<std::string> parentElem = (Arabica::DOM::Element<std::string>)state.getParentNode();
+ if (boost::iequals(parentElem.getTagName(), "scxml"))
+ return true;
+ return false;
}
-
+
bool Interpreter::isInFinalState(const Arabica::DOM::Node<std::string>& state) {
// std::cout << ATTR(state, "id") << std::endl;
- if (isCompound(state)) {
- Arabica::XPath::NodeSet<std::string> childs = getChildStates(state);
- for (int i = 0; i < childs.size(); i++) {
- if (isFinal(childs[i]) && isMember(childs[i], _configuration))
- return true;
- }
- } else if (isParallel(state)) {
- Arabica::XPath::NodeSet<std::string> childs = getChildStates(state);
- for (int i = 0; i < childs.size(); i++) {
- if (!isInFinalState(childs[i]))
- return false;
- }
- return true;
- }
- return false;
+ if (isCompound(state)) {
+ Arabica::XPath::NodeSet<std::string> childs = getChildStates(state);
+ for (int i = 0; i < childs.size(); i++) {
+ if (isFinal(childs[i]) && isMember(childs[i], _configuration))
+ return true;
+ }
+ } else if (isParallel(state)) {
+ Arabica::XPath::NodeSet<std::string> childs = getChildStates(state);
+ for (int i = 0; i < childs.size(); i++) {
+ if (!isInFinalState(childs[i]))
+ return false;
+ }
+ return true;
+ }
+ return false;
}
bool Interpreter::isMember(const Arabica::DOM::Node<std::string>& node, const Arabica::XPath::NodeSet<std::string>& set) {
- for (int i = 0; i < set.size(); i++) {
- if (set[i] == node)
- return true;
- }
- return false;
+ for (int i = 0; i < set.size(); i++) {
+ if (set[i] == node)
+ return true;
+ }
+ return false;
}
-
+
void Interpreter::addStatesToEnter(const Arabica::DOM::Node<std::string>& state,
- Arabica::XPath::NodeSet<std::string>& statesToEnter,
- Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry) {
- std::string stateId = ((Arabica::DOM::Element<std::string>)state).getAttribute("id");
- if (isHistory(state)) {
- if (_historyValue.find(stateId) != _historyValue.end()) {
- Arabica::XPath::NodeSet<std::string> historyValue = _historyValue[stateId];
- for (int i = 0; i < historyValue.size(); i++) {
- addStatesToEnter(historyValue[i], statesToEnter, statesForDefaultEntry);
- NodeSet<std::string> ancestors = getProperAncestors(historyValue[i], state);
- for (int j = 0; j < ancestors.size(); j++) {
- statesToEnter.push_back(ancestors[j]);
- }
- }
- } else {
- NodeSet<std::string> transitions = _xpath.evaluate("" + _nsPrefix + "transition", state).asNodeSet();
- for (int i = 0; i < transitions.size(); i++) {
- NodeSet<std::string> targets = getTargetStates(transitions[i]);
- for (int j = 0; j < targets.size(); j++) {
- addStatesToEnter(targets[j], statesToEnter, statesForDefaultEntry);
- }
- }
- }
- } else {
- statesToEnter.push_back(state);
- if (isCompound(state)) {
- statesForDefaultEntry.push_back(state);
+ Arabica::XPath::NodeSet<std::string>& statesToEnter,
+ Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry) {
+ std::string stateId = ((Arabica::DOM::Element<std::string>)state).getAttribute("id");
+ if (isHistory(state)) {
+ if (_historyValue.find(stateId) != _historyValue.end()) {
+ Arabica::XPath::NodeSet<std::string> historyValue = _historyValue[stateId];
+ for (int i = 0; i < historyValue.size(); i++) {
+ addStatesToEnter(historyValue[i], statesToEnter, statesForDefaultEntry);
+ NodeSet<std::string> ancestors = getProperAncestors(historyValue[i], state);
+ for (int j = 0; j < ancestors.size(); j++) {
+ statesToEnter.push_back(ancestors[j]);
+ }
+ }
+ } else {
+ NodeSet<std::string> transitions = _xpath.evaluate("" + _nsPrefix + "transition", state).asNodeSet();
+ for (int i = 0; i < transitions.size(); i++) {
+ NodeSet<std::string> targets = getTargetStates(transitions[i]);
+ for (int j = 0; j < targets.size(); j++) {
+ addStatesToEnter(targets[j], statesToEnter, statesForDefaultEntry);
+ }
+ }
+ }
+ } else {
+ statesToEnter.push_back(state);
+ if (isCompound(state)) {
+ statesForDefaultEntry.push_back(state);
#if 0
- NodeSet<std::string> tStates = getTargetStates(getInitialState(state));
- for (int i = 0; i < tStates.size(); i++) {
- addStatesToEnter(tStates[i], statesToEnter, statesForDefaultEntry);
- }
+ NodeSet<std::string> tStates = getTargetStates(getInitialState(state));
+ for (int i = 0; i < tStates.size(); i++) {
+ addStatesToEnter(tStates[i], statesToEnter, statesForDefaultEntry);
+ }
#endif
- addStatesToEnter(getInitialState(state), statesToEnter, statesForDefaultEntry);
+ addStatesToEnter(getInitialState(state), statesToEnter, statesForDefaultEntry);
// NodeSet<std::string> tStates = getTargetStates(getInitialState(state));
- } else if(isParallel(state)) {
- NodeSet<std::string> childStates = getChildStates(state);
- for (int i = 0; i < childStates.size(); i++) {
- addStatesToEnter(childStates[i], statesToEnter, statesForDefaultEntry);
- }
- }
- }
+ } else if(isParallel(state)) {
+ NodeSet<std::string> childStates = getChildStates(state);
+ for (int i = 0; i < childStates.size(); i++) {
+ addStatesToEnter(childStates[i], statesToEnter, statesForDefaultEntry);
+ }
+ }
+ }
}
Arabica::XPath::NodeSet<std::string> Interpreter::getChildStates(const Arabica::DOM::Node<std::string>& state) {
- Arabica::XPath::NodeSet<std::string> childs;
-
- Arabica::DOM::NodeList<std::string> childElems = state.getChildNodes();
- for (int i = 0; i < childElems.getLength(); i++) {
- if (isState(childElems.item(i))) {
- childs.push_back(childElems.item(i));
- }
- }
- return childs;
-}
-
+ Arabica::XPath::NodeSet<std::string> childs;
+
+ Arabica::DOM::NodeList<std::string> childElems = state.getChildNodes();
+ for (int i = 0; i < childElems.getLength(); i++) {
+ if (isState(childElems.item(i))) {
+ childs.push_back(childElems.item(i));
+ }
+ }
+ return childs;
+}
+
Arabica::DOM::Node<std::string> Interpreter::findLCCA(const Arabica::XPath::NodeSet<std::string>& states) {
// std::cout << "findLCCA: ";
// for (int i = 0; i < states.size(); i++) {
// std::cout << ((Arabica::DOM::Element<std::string>)states[i]).getAttribute("id") << " - " << states[i].getLocalName() << ", ";
// }
// std::cout << std::flush;
-
- Arabica::XPath::NodeSet<std::string> ancestors = getProperAncestors(states[0], Arabica::DOM::Node<std::string>());
- ancestors.push_back(states[0]); // state[0] may already be the ancestor - bug in W3C spec?
- Arabica::DOM::Node<std::string> ancestor;
- for (int i = 0; i < ancestors.size(); i++) {
- for (int j = 0; j < states.size(); j++) {
+
+ Arabica::XPath::NodeSet<std::string> ancestors = getProperAncestors(states[0], Arabica::DOM::Node<std::string>());
+ ancestors.push_back(states[0]); // state[0] may already be the ancestor - bug in W3C spec?
+ Arabica::DOM::Node<std::string> ancestor;
+ for (int i = 0; i < ancestors.size(); i++) {
+ for (int j = 0; j < states.size(); j++) {
// std::cout << "Checking " << TAGNAME(state) << " and " << TAGNAME(ancestors[i]) << std::endl;
- if (!isDescendant(states[j], ancestors[i]) && (states[j] != ancestors[i]))
- goto NEXT_ANCESTOR;
- }
- ancestor = ancestors[i];
- break;
- NEXT_ANCESTOR:;
- }
- assert(ancestor);
+ if (!isDescendant(states[j], ancestors[i]) && (states[j] != ancestors[i]))
+ goto NEXT_ANCESTOR;
+ }
+ ancestor = ancestors[i];
+ break;
+NEXT_ANCESTOR:
+ ;
+ }
+ assert(ancestor);
// std::cout << " -> " << ((Arabica::DOM::Element<std::string>)ancestor).getAttribute("id") << " " << ancestor.getLocalName() << std::endl;
- return ancestor;
+ return ancestor;
}
Arabica::DOM::Node<std::string> Interpreter::getState(const std::string& stateId) {
- // first try atomic and compund states
+ // first try atomic and compund states
// std::cout << _nsPrefix << stateId << std::endl;
- NodeSet<std::string> target = _xpath.evaluate("//" + _nsPrefix + "state[@id='" + stateId + "']", _doc).asNodeSet();
- if (target.size() > 0)
- goto FOUND;
+ NodeSet<std::string> target = _xpath.evaluate("//" + _nsPrefix + "state[@id='" + stateId + "']", _doc).asNodeSet();
+ if (target.size() > 0)
+ goto FOUND;
- // now parallel states
- target = _xpath.evaluate("//" + _nsPrefix + "parallel[@id='" + stateId + "']", _doc).asNodeSet();
- if (target.size() > 0)
- goto FOUND;
+ // now parallel states
+ target = _xpath.evaluate("//" + _nsPrefix + "parallel[@id='" + stateId + "']", _doc).asNodeSet();
+ if (target.size() > 0)
+ goto FOUND;
- // now final states
- target = _xpath.evaluate("//" + _nsPrefix + "final[@id='" + stateId + "']", _doc).asNodeSet();
- if (target.size() > 0)
- goto FOUND;
+ // now final states
+ target = _xpath.evaluate("//" + _nsPrefix + "final[@id='" + stateId + "']", _doc).asNodeSet();
+ if (target.size() > 0)
+ goto FOUND;
FOUND:
- if (target.size() > 0) {
- assert(target.size() == 1);
- return target[0];
- }
- // return the empty node
- return Arabica::DOM::Node<std::string>();
+ if (target.size() > 0) {
+ assert(target.size() == 1);
+ return target[0];
+ }
+ // return the empty node
+ return Arabica::DOM::Node<std::string>();
}
Arabica::DOM::Node<std::string> Interpreter::getSourceState(const Arabica::DOM::Node<std::string>& transition) {
- if (boost::iequals(TAGNAME(transition.getParentNode()), "initial"))
- return transition.getParentNode().getParentNode();
- return transition.getParentNode();
-}
-
- /**
- * In a conformant SCXML document, a compound state may specify either an "initial"
- * attribute or an <initial> element, but not both. See 3.6 <initial> for a
- * discussion of the difference between the two notations. If neither the "initial"
- * attribute nor an <initial> element is specified, the SCXML Processor must use
- * the first child state in document order as the default initial state.
- */
+ if (boost::iequals(TAGNAME(transition.getParentNode()), "initial"))
+ return transition.getParentNode().getParentNode();
+ return transition.getParentNode();
+}
+
+/**
+ * In a conformant SCXML document, a compound state may specify either an "initial"
+ * attribute or an <initial> element, but not both. See 3.6 <initial> for a
+ * discussion of the difference between the two notations. If neither the "initial"
+ * attribute nor an <initial> element is specified, the SCXML Processor must use
+ * the first child state in document order as the default initial state.
+ */
Arabica::DOM::Node<std::string> Interpreter::getInitialState(Arabica::DOM::Node<std::string> state) {
- if (!state) {
- state = _doc.getFirstChild();
- while(!isState(state))
- state = state.getNextSibling();
- }
-
- assert(isCompound(state) || isParallel(state));
-
- // initial attribute at element
- Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)state;
- if (stateElem.hasAttribute("initial")) {
- return getState(stateElem.getAttribute("initial"));
- }
-
- // initial element as child
- NodeSet<std::string> initialStates = _xpath.evaluate("" + _nsPrefix + "initial", state).asNodeSet();
- if(initialStates.size() == 1)
- return initialStates[0];
-
- // first child state
- NodeList<std::string> childs = state.getChildNodes();
- for (int i = 0; i < childs.getLength(); i++) {
- if (isState(childs.item(i)))
- return childs.item(i);
- }
- // nothing found
- return Arabica::DOM::Node<std::string>();
+ if (!state) {
+ state = _doc.getFirstChild();
+ while(!isState(state))
+ state = state.getNextSibling();
+ }
+
+ assert(isCompound(state) || isParallel(state));
+
+ // initial attribute at element
+ Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)state;
+ if (stateElem.hasAttribute("initial")) {
+ return getState(stateElem.getAttribute("initial"));
+ }
+
+ // initial element as child
+ NodeSet<std::string> initialStates = _xpath.evaluate("" + _nsPrefix + "initial", state).asNodeSet();
+ if(initialStates.size() == 1)
+ return initialStates[0];
+
+ // first child state
+ NodeList<std::string> childs = state.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ if (isState(childs.item(i)))
+ return childs.item(i);
+ }
+ // nothing found
+ return Arabica::DOM::Node<std::string>();
}
NodeSet<std::string> Interpreter::getTargetStates(const Arabica::DOM::Node<std::string>& transition) {
- NodeSet<std::string> targetStates;
-
- // if we are called with a state, process all its transitions
- if (isState(transition)) {
- NodeList<std::string> childs = transition.getChildNodes();
- for (int i = 0; i < childs.getLength(); i++) {
- if (childs.item(i).getNodeType() == Node_base::ELEMENT_NODE && boost::iequals(TAGNAME(childs.item(i)), "transition")) {
- targetStates.push_back(getTargetStates(childs.item(i)));
- }
- }
- return targetStates;
- }
-
- std::string targetId = ((Arabica::DOM::Element<std::string>)transition).getAttribute("target");
-
- std::vector<std::string> targetIds = Interpreter::tokenizeIdRefs(ATTR(transition, "target"));
- for (int i = 0; i < targetIds.size(); i++) {
- Arabica::DOM::Node<std::string> state = getState(targetIds[i]);
- assert(HAS_ATTR(state, "id"));
- targetStates.push_back(state);
- }
- return targetStates;
+ NodeSet<std::string> targetStates;
+
+ // if we are called with a state, process all its transitions
+ if (isState(transition)) {
+ NodeList<std::string> childs = transition.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ if (childs.item(i).getNodeType() == Node_base::ELEMENT_NODE && boost::iequals(TAGNAME(childs.item(i)), "transition")) {
+ targetStates.push_back(getTargetStates(childs.item(i)));
+ }
+ }
+ return targetStates;
+ }
+
+ std::string targetId = ((Arabica::DOM::Element<std::string>)transition).getAttribute("target");
+
+ std::vector<std::string> targetIds = Interpreter::tokenizeIdRefs(ATTR(transition, "target"));
+ for (int i = 0; i < targetIds.size(); i++) {
+ Arabica::DOM::Node<std::string> state = getState(targetIds[i]);
+ assert(HAS_ATTR(state, "id"));
+ targetStates.push_back(state);
+ }
+ return targetStates;
}
std::vector<std::string> Interpreter::tokenizeIdRefs(const std::string& idRefs) {
- std::vector<std::string> ids;
-
- if (idRefs.length() > 0) {
- std::istringstream iss(idRefs);
-
- std::copy(std::istream_iterator<std::string>(iss),
- std::istream_iterator<std::string>(),
- std::back_inserter<std::vector<std::string> >(ids));
- }
-
- return ids;
-}
-
+ std::vector<std::string> ids;
+
+ if (idRefs.length() > 0) {
+ std::istringstream iss(idRefs);
+
+ std::copy(std::istream_iterator<std::string>(iss),
+ std::istream_iterator<std::string>(),
+ std::back_inserter<std::vector<std::string> >(ids));
+ }
+
+ return ids;
+}
+
NodeSet<std::string> Interpreter::getProperAncestors(const Arabica::DOM::Node<std::string>& s1,
- const Arabica::DOM::Node<std::string>& s2) {
- NodeSet<std::string> ancestors;
- if (isState(s1)) {
- Arabica::DOM::Node<std::string> node = s1;
- while((node = node.getParentNode())) {
- if (!isState(node))
- break;
- if (!boost::iequals(TAGNAME(node), "parallel") && !boost::iequals(TAGNAME(node), "state") && !boost::iequals(TAGNAME(node), "scxml"))
- break;
- if (node == s2)
- break;
- ancestors.push_back(node);
- }
- }
- return ancestors;
+ const Arabica::DOM::Node<std::string>& s2) {
+ NodeSet<std::string> ancestors;
+ if (isState(s1)) {
+ Arabica::DOM::Node<std::string> node = s1;
+ while((node = node.getParentNode())) {
+ if (!isState(node))
+ break;
+ if (!boost::iequals(TAGNAME(node), "parallel") && !boost::iequals(TAGNAME(node), "state") && !boost::iequals(TAGNAME(node), "scxml"))
+ break;
+ if (node == s2)
+ break;
+ ancestors.push_back(node);
+ }
+ }
+ return ancestors;
}
bool Interpreter::isDescendant(const Arabica::DOM::Node<std::string>& s1,
- const Arabica::DOM::Node<std::string>& s2) {
- Arabica::DOM::Node<std::string> parent = s1.getParentNode();
- while(parent) {
- if (s2 == parent)
- return true;
- parent = parent.getParentNode();
- }
- return false;
-}
-
+ const Arabica::DOM::Node<std::string>& s2) {
+ Arabica::DOM::Node<std::string> parent = s1.getParentNode();
+ while(parent) {
+ if (s2 == parent)
+ return true;
+ parent = parent.getParentNode();
+ }
+ return false;
+}
+
bool Interpreter::isTargetless(const Arabica::DOM::Node<std::string>& transition) {
- if (transition.hasAttributes()) {
- if (((Arabica::DOM::Element<std::string>)transition).hasAttribute("target"))
- return false;
- }
- return true;
+ if (transition.hasAttributes()) {
+ if (((Arabica::DOM::Element<std::string>)transition).hasAttribute("target"))
+ return false;
+ }
+ return true;
}
bool Interpreter::isWithinSameChild(const Arabica::DOM::Node<std::string>& transition) {
- if (!isTargetless(transition)) {
- std::string target = ((Arabica::DOM::Element<std::string>)transition).getAttribute("target");
- Arabica::XPath::XPath<std::string> xpath;
- // @todo: do we need to look at parallel as well?
- if (xpath.evaluate("" + _nsPrefix + "state[id=\"" + target + "\"]", transition.getParentNode()).asNodeSet().size() > 0)
- return true;
- }
- return false;
+ if (!isTargetless(transition)) {
+ std::string target = ((Arabica::DOM::Element<std::string>)transition).getAttribute("target");
+ Arabica::XPath::XPath<std::string> xpath;
+ // @todo: do we need to look at parallel as well?
+ if (xpath.evaluate("" + _nsPrefix + "state[id=\"" + target + "\"]", transition.getParentNode()).asNodeSet().size() > 0)
+ return true;
+ }
+ return false;
}
bool Interpreter::isState(const Arabica::DOM::Node<std::string>& state) {
- if (!state)
- return false;
- if (state.getNodeType() != Arabica::DOM::Node_base::ELEMENT_NODE)
- return false;
-
- std::string tagName = TAGNAME(state);
- if (boost::iequals("state", tagName))
- return true;
- if (boost::iequals("scxml", tagName))
- return true;
- if (boost::iequals("parallel", tagName))
- return true;
- if (boost::iequals("final", tagName))
- return true;
- return false;
+ if (!state)
+ return false;
+ if (state.getNodeType() != Arabica::DOM::Node_base::ELEMENT_NODE)
+ return false;
+
+ std::string tagName = TAGNAME(state);
+ if (boost::iequals("state", tagName))
+ return true;
+ if (boost::iequals("scxml", tagName))
+ return true;
+ if (boost::iequals("parallel", tagName))
+ return true;
+ if (boost::iequals("final", tagName))
+ return true;
+ return false;
}
bool Interpreter::isFinal(const Arabica::DOM::Node<std::string>& state) {
- std::string tagName = TAGNAME(state);
- if (boost::iequals("final", tagName))
- return true;
- if (HAS_ATTR(state, "final") && boost::iequals("true", ATTR(state, "final")))
- return true;
- return false;
+ std::string tagName = TAGNAME(state);
+ if (boost::iequals("final", tagName))
+ return true;
+ if (HAS_ATTR(state, "final") && boost::iequals("true", ATTR(state, "final")))
+ return true;
+ return false;
}
bool Interpreter::isInitial(const Arabica::DOM::Node<std::string>& state) {
- if (!isState(state))
- return false;
-
- Arabica::DOM::Node<std::string> parent = state.getParentNode();
- if (!isState(parent))
- return true; // scxml element
-
- if (getInitialState(parent) == state)
- return true; // every nested node
-
- return false;
+ if (!isState(state))
+ return false;
+
+ Arabica::DOM::Node<std::string> parent = state.getParentNode();
+ if (!isState(parent))
+ return true; // scxml element
+
+ if (getInitialState(parent) == state)
+ return true; // every nested node
+
+ return false;
}
bool Interpreter::isPseudoState(const Arabica::DOM::Node<std::string>& state) {
- std::string tagName = TAGNAME(state);
- if (boost::iequals("initial", tagName))
- return true;
- if (boost::iequals("history", tagName))
- return true;
- return false;
+ std::string tagName = TAGNAME(state);
+ if (boost::iequals("initial", tagName))
+ return true;
+ if (boost::iequals("history", tagName))
+ return true;
+ return false;
}
bool Interpreter::isTransitionTarget(const Arabica::DOM::Node<std::string>& elem) {
- return (isState(elem) || boost::iequals(TAGNAME(elem), "history"));
+ return (isState(elem) || boost::iequals(TAGNAME(elem), "history"));
}
bool Interpreter::isAtomic(const Arabica::DOM::Node<std::string>& state) {
- if (boost::iequals("final", TAGNAME(state)))
- return true;
-
- // I will assume that parallel states are not meant to be atomic.
- if (boost::iequals("parallel", TAGNAME(state)))
- return false;
+ if (boost::iequals("final", TAGNAME(state)))
+ return true;
- Arabica::DOM::NodeList<std::string> childs = state.getChildNodes();
- for (unsigned int i = 0; i < childs.getLength(); i++) {
- if (isState(childs.item(i)))
- return false;
- }
- return true;
+ // I will assume that parallel states are not meant to be atomic.
+ if (boost::iequals("parallel", TAGNAME(state)))
+ return false;
+
+ Arabica::DOM::NodeList<std::string> childs = state.getChildNodes();
+ for (unsigned int i = 0; i < childs.getLength(); i++) {
+ if (isState(childs.item(i)))
+ return false;
+ }
+ return true;
}
bool Interpreter::isHistory(const Arabica::DOM::Node<std::string>& state) {
- if (boost::iequals("history", TAGNAME(state)))
- return true;
- return false;
+ if (boost::iequals("history", TAGNAME(state)))
+ return true;
+ return false;
}
bool Interpreter::isParallel(const Arabica::DOM::Node<std::string>& state) {
- if (!isState(state))
- return false;
- if (boost::iequals("parallel", TAGNAME(state)))
- return true;
- return false;
+ if (!isState(state))
+ return false;
+ if (boost::iequals("parallel", TAGNAME(state)))
+ return true;
+ return false;
}
-
+
bool Interpreter::isCompound(const Arabica::DOM::Node<std::string>& state) {
- if (!isState(state))
- return false;
+ if (!isState(state))
+ return false;
+
+ if (boost::iequals(TAGNAME(state), "parallel"))
+ return false;
- if (boost::iequals(TAGNAME(state), "parallel"))
- return false;
-
- Arabica::DOM::NodeList<std::string> childs = state.getChildNodes();
- for (unsigned int i = 0; i < childs.getLength(); i++) {
- if (isState(childs.item(i)))
- return true;
- }
- return false;
+ Arabica::DOM::NodeList<std::string> childs = state.getChildNodes();
+ for (unsigned int i = 0; i < childs.getLength(); i++) {
+ if (isState(childs.item(i)))
+ return true;
+ }
+ return false;
}
void Interpreter::setupIOProcessors() {
- std::map<std::string, IOProcessor*>::iterator ioProcIter = Factory::getInstance()->_ioProcessors.begin();
- while(ioProcIter != Factory::getInstance()->_ioProcessors.end()) {
- _ioProcessors[ioProcIter->first] = Factory::getIOProcessor(ioProcIter->first, this);
- if (_dataModel) {
- try {
-// _dataModel->setData("_ioprocessors", ioProcIter->first, _ioProcessors[ioProcIter->first]->getDataModelVariables());
- _dataModel->assign("_ioprocessors['" + ioProcIter->first + "']", _ioProcessors[ioProcIter->first]->getDataModelVariables());
-// std::cout << _dataModel->evalAsString("_ioprocessors['basichttp'].location") << std::endl;
- } catch (Event e) {
- LOG(ERROR) << "Syntax error when setting _ioprocessors:" << std::endl << e << std::endl;
- }
- } else {
- LOG(INFO) << "Not registering " << ioProcIter->first << " at _ioprocessors in datamodel, no datamodel specified";
- }
- ioProcIter++;
- }
+ std::map<std::string, IOProcessor*>::iterator ioProcIter = Factory::getInstance()->_ioProcessors.begin();
+ while(ioProcIter != Factory::getInstance()->_ioProcessors.end()) {
+ _ioProcessors[ioProcIter->first] = Factory::getIOProcessor(ioProcIter->first, this);
+ if (_dataModel) {
+ try {
+ _dataModel->registerIOProcessor(ioProcIter->first, _ioProcessors[ioProcIter->first]);
+ } catch (Event e) {
+ LOG(ERROR) << "Syntax error when setting _ioprocessors:" << std::endl << e << std::endl;
+ }
+ } else {
+ LOG(INFO) << "Not registering " << ioProcIter->first << " at _ioprocessors in datamodel, no datamodel specified";
+ }
+ ioProcIter++;
+ }
}
IOProcessor* Interpreter::getIOProcessor(const std::string& type) {
- if (_ioProcessors.find(type) == _ioProcessors.end()) {
- LOG(ERROR) << "No ioProcessor known for type " << type;
- return NULL;
- }
- return _ioProcessors[type];
+ if (_ioProcessors.find(type) == _ioProcessors.end()) {
+ LOG(ERROR) << "No ioProcessor known for type " << type;
+ return NULL;
+ }
+ return _ioProcessors[type];
}
//IOProcessor* Interpreter::getIOProcessorForId(const std::string& sendId) {
@@ -1737,237 +1740,237 @@ IOProcessor* Interpreter::getIOProcessor(const std::string& type) {
// }
// return _ioProcessorsIds[sendId];
//}
-
+
bool Interpreter::validate() {
- bool validationErrors = false;
-
- if (!_doc) {
- LOG(ERROR) << "Document " << _baseURI.as_string() << " was not parsed successfully" << std::endl;
- return false;
- }
-
- // semantic issues ------------
- if ((_xpath.evaluate("/" + _nsPrefix + "scxml/@datamodel", _doc).asNodeSet().size() == 0) &&
- _xpath.evaluate("/" + _nsPrefix + "scxml/" + _nsPrefix + "script", _doc).asNodeSet().size() > 0) {
- LOG(ERROR) << "Script elements used, but no datamodel specified" << std::endl;
- }
-
- // element issues ------------
- Arabica::XPath::NodeSet<std::string> scxmlElems = _xpath.evaluate(_nsPrefix + "scxml", _doc).asNodeSet();
- if (scxmlElems.size() > 0)
- LOG(ERROR) << "More than one scxml element found" << std::endl;
- for (unsigned int i = 0; i < scxmlElems.size(); i++) {
- if (!HAS_ATTR(scxmlElems[i], "xmlns"))
- LOG(ERROR) << "scxml element has no xmlns attribute" << std::endl;
- if (!HAS_ATTR(scxmlElems[i], "version"))
- LOG(ERROR) << "scxml element has no version attribute" << std::endl;
- NodeList<std::string> childs = scxmlElems[i].getChildNodes();
- for (unsigned int j = 0; j < childs.getLength(); j++) {
- if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
- continue;
- if (boost::iequals(TAGNAME(childs.item(j)), "state") ||
- boost::iequals(TAGNAME(childs.item(j)), "parallel") ||
- boost::iequals(TAGNAME(childs.item(j)), "final") ||
- boost::iequals(TAGNAME(childs.item(j)), "datamodel") ||
- boost::iequals(TAGNAME(childs.item(j)), "script")) {
- LOG(ERROR) << "scxml element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
- }
- }
- }
-
- Arabica::XPath::NodeSet<std::string> stateElems = _xpath.evaluate(_nsPrefix + "state", _doc).asNodeSet();
- for (unsigned int i = 0; i < stateElems.size(); i++) {
- NodeList<std::string> childs = stateElems[i].getChildNodes();
- for (unsigned int j = 0; j < childs.getLength(); j++) {
- if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
- continue;
- if (boost::iequals(TAGNAME(childs.item(j)), "onentry") ||
- boost::iequals(TAGNAME(childs.item(j)), "onexit") ||
- boost::iequals(TAGNAME(childs.item(j)), "transition") ||
- boost::iequals(TAGNAME(childs.item(j)), "initial") ||
- boost::iequals(TAGNAME(childs.item(j)), "state") ||
- boost::iequals(TAGNAME(childs.item(j)), "parallel") ||
- boost::iequals(TAGNAME(childs.item(j)), "final") ||
- boost::iequals(TAGNAME(childs.item(j)), "history") ||
- boost::iequals(TAGNAME(childs.item(j)), "datamodel") ||
- boost::iequals(TAGNAME(childs.item(j)), "invoke")) {
- LOG(ERROR) << "state element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
- }
- }
- }
-
- Arabica::XPath::NodeSet<std::string> parallelElems = _xpath.evaluate(_nsPrefix + "parallel", _doc).asNodeSet();
- for (unsigned int i = 0; i < parallelElems.size(); i++) {
- NodeList<std::string> childs = parallelElems[i].getChildNodes();
- for (unsigned int j = 0; j < childs.getLength(); j++) {
- if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
- continue;
- if (boost::iequals(TAGNAME(childs.item(j)), "onentry") ||
- boost::iequals(TAGNAME(childs.item(j)), "onexit") ||
- boost::iequals(TAGNAME(childs.item(j)), "transition") ||
- boost::iequals(TAGNAME(childs.item(j)), "state") ||
- boost::iequals(TAGNAME(childs.item(j)), "parallel") ||
- boost::iequals(TAGNAME(childs.item(j)), "history") ||
- boost::iequals(TAGNAME(childs.item(j)), "datamodel") ||
- boost::iequals(TAGNAME(childs.item(j)), "invoke")) {
- LOG(ERROR) << "parallel element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
- }
- }
- }
-
- Arabica::XPath::NodeSet<std::string> transitionElems = _xpath.evaluate(_nsPrefix + "transition", _doc).asNodeSet();
- for (unsigned int i = 0; i < transitionElems.size(); i++) {
- if (HAS_ATTR(transitionElems[i], "cond") &&
- !HAS_ATTR(transitionElems[i], "event")) {
- LOG(ERROR) << "transition element with cond attribute but without event attribute not allowed" << std::endl;
- }
- NodeList<std::string> childs = scxmlElems[i].getChildNodes();
- for (unsigned int j = 0; j < childs.getLength(); j++) {
- if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
- continue;
- }
- }
-
- Arabica::XPath::NodeSet<std::string> initialElems = _xpath.evaluate(_nsPrefix + "initial", _doc).asNodeSet();
- for (unsigned int i = 0; i < initialElems.size(); i++) {
- NodeList<std::string> childs = initialElems[i].getChildNodes();
- for (unsigned int j = 0; j < childs.getLength(); j++) {
- if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
- continue;
- if (boost::iequals(TAGNAME(childs.item(j)), "transition")) {
- LOG(ERROR) << "initial element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
- }
- }
- }
-
- Arabica::XPath::NodeSet<std::string> finalElems = _xpath.evaluate(_nsPrefix + "final", _doc).asNodeSet();
- for (unsigned int i = 0; i < finalElems.size(); i++) {
- NodeList<std::string> childs = finalElems[i].getChildNodes();
- for (unsigned int j = 0; j < childs.getLength(); j++) {
- if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
- continue;
- if (!boost::iequals(TAGNAME(childs.item(j)), "onentry") ||
- !boost::iequals(TAGNAME(childs.item(j)), "onexit") ||
- !boost::iequals(TAGNAME(childs.item(j)), "donedata")) {
- LOG(ERROR) << "parallel element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
- }
- }
- }
-
- Arabica::XPath::NodeSet<std::string> historyElems = _xpath.evaluate(_nsPrefix + "history", _doc).asNodeSet();
- for (unsigned int i = 0; i < historyElems.size(); i++) {
- NodeList<std::string> childs = historyElems[i].getChildNodes();
- for (unsigned int j = 0; j < childs.getLength(); j++) {
- if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
- continue;
- if (boost::iequals(TAGNAME(childs.item(j)), "transition")) {
- LOG(ERROR) << "history element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
- }
- }
- }
-
- Arabica::XPath::NodeSet<std::string> datamodelElems = _xpath.evaluate(_nsPrefix + "datamodel", _doc).asNodeSet();
- for (unsigned int i = 0; i < datamodelElems.size(); i++) {
- NodeList<std::string> childs = datamodelElems[i].getChildNodes();
- for (unsigned int j = 0; j < childs.getLength(); j++) {
- if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
- continue;
- if (!boost::iequals(TAGNAME(childs.item(j)), "data")) {
- LOG(ERROR) << "datamodel element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
- }
- }
- }
-
- Arabica::XPath::NodeSet<std::string> dataElems = _xpath.evaluate(_nsPrefix + "data", _doc).asNodeSet();
- for (unsigned int i = 0; i < dataElems.size(); i++) {
- if (!HAS_ATTR(dataElems[i], "id"))
- LOG(ERROR) << "data element has no id attribute" << std::endl;
- }
-
- return validationErrors;
-}
-
+ bool validationErrors = false;
+
+ if (!_doc) {
+ LOG(ERROR) << "Document " << _baseURI.as_string() << " was not parsed successfully" << std::endl;
+ return false;
+ }
+
+ // semantic issues ------------
+ if ((_xpath.evaluate("/" + _nsPrefix + "scxml/@datamodel", _doc).asNodeSet().size() == 0) &&
+ _xpath.evaluate("/" + _nsPrefix + "scxml/" + _nsPrefix + "script", _doc).asNodeSet().size() > 0) {
+ LOG(ERROR) << "Script elements used, but no datamodel specified" << std::endl;
+ }
+
+ // element issues ------------
+ Arabica::XPath::NodeSet<std::string> scxmlElems = _xpath.evaluate(_nsPrefix + "scxml", _doc).asNodeSet();
+ if (scxmlElems.size() > 0)
+ LOG(ERROR) << "More than one scxml element found" << std::endl;
+ for (unsigned int i = 0; i < scxmlElems.size(); i++) {
+ if (!HAS_ATTR(scxmlElems[i], "xmlns"))
+ LOG(ERROR) << "scxml element has no xmlns attribute" << std::endl;
+ if (!HAS_ATTR(scxmlElems[i], "version"))
+ LOG(ERROR) << "scxml element has no version attribute" << std::endl;
+ NodeList<std::string> childs = scxmlElems[i].getChildNodes();
+ for (unsigned int j = 0; j < childs.getLength(); j++) {
+ if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
+ continue;
+ if (boost::iequals(TAGNAME(childs.item(j)), "state") ||
+ boost::iequals(TAGNAME(childs.item(j)), "parallel") ||
+ boost::iequals(TAGNAME(childs.item(j)), "final") ||
+ boost::iequals(TAGNAME(childs.item(j)), "datamodel") ||
+ boost::iequals(TAGNAME(childs.item(j)), "script")) {
+ LOG(ERROR) << "scxml element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
+ }
+ }
+ }
+
+ Arabica::XPath::NodeSet<std::string> stateElems = _xpath.evaluate(_nsPrefix + "state", _doc).asNodeSet();
+ for (unsigned int i = 0; i < stateElems.size(); i++) {
+ NodeList<std::string> childs = stateElems[i].getChildNodes();
+ for (unsigned int j = 0; j < childs.getLength(); j++) {
+ if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
+ continue;
+ if (boost::iequals(TAGNAME(childs.item(j)), "onentry") ||
+ boost::iequals(TAGNAME(childs.item(j)), "onexit") ||
+ boost::iequals(TAGNAME(childs.item(j)), "transition") ||
+ boost::iequals(TAGNAME(childs.item(j)), "initial") ||
+ boost::iequals(TAGNAME(childs.item(j)), "state") ||
+ boost::iequals(TAGNAME(childs.item(j)), "parallel") ||
+ boost::iequals(TAGNAME(childs.item(j)), "final") ||
+ boost::iequals(TAGNAME(childs.item(j)), "history") ||
+ boost::iequals(TAGNAME(childs.item(j)), "datamodel") ||
+ boost::iequals(TAGNAME(childs.item(j)), "invoke")) {
+ LOG(ERROR) << "state element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
+ }
+ }
+ }
+
+ Arabica::XPath::NodeSet<std::string> parallelElems = _xpath.evaluate(_nsPrefix + "parallel", _doc).asNodeSet();
+ for (unsigned int i = 0; i < parallelElems.size(); i++) {
+ NodeList<std::string> childs = parallelElems[i].getChildNodes();
+ for (unsigned int j = 0; j < childs.getLength(); j++) {
+ if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
+ continue;
+ if (boost::iequals(TAGNAME(childs.item(j)), "onentry") ||
+ boost::iequals(TAGNAME(childs.item(j)), "onexit") ||
+ boost::iequals(TAGNAME(childs.item(j)), "transition") ||
+ boost::iequals(TAGNAME(childs.item(j)), "state") ||
+ boost::iequals(TAGNAME(childs.item(j)), "parallel") ||
+ boost::iequals(TAGNAME(childs.item(j)), "history") ||
+ boost::iequals(TAGNAME(childs.item(j)), "datamodel") ||
+ boost::iequals(TAGNAME(childs.item(j)), "invoke")) {
+ LOG(ERROR) << "parallel element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
+ }
+ }
+ }
+
+ Arabica::XPath::NodeSet<std::string> transitionElems = _xpath.evaluate(_nsPrefix + "transition", _doc).asNodeSet();
+ for (unsigned int i = 0; i < transitionElems.size(); i++) {
+ if (HAS_ATTR(transitionElems[i], "cond") &&
+ !HAS_ATTR(transitionElems[i], "event")) {
+ LOG(ERROR) << "transition element with cond attribute but without event attribute not allowed" << std::endl;
+ }
+ NodeList<std::string> childs = scxmlElems[i].getChildNodes();
+ for (unsigned int j = 0; j < childs.getLength(); j++) {
+ if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
+ continue;
+ }
+ }
+
+ Arabica::XPath::NodeSet<std::string> initialElems = _xpath.evaluate(_nsPrefix + "initial", _doc).asNodeSet();
+ for (unsigned int i = 0; i < initialElems.size(); i++) {
+ NodeList<std::string> childs = initialElems[i].getChildNodes();
+ for (unsigned int j = 0; j < childs.getLength(); j++) {
+ if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
+ continue;
+ if (boost::iequals(TAGNAME(childs.item(j)), "transition")) {
+ LOG(ERROR) << "initial element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
+ }
+ }
+ }
+
+ Arabica::XPath::NodeSet<std::string> finalElems = _xpath.evaluate(_nsPrefix + "final", _doc).asNodeSet();
+ for (unsigned int i = 0; i < finalElems.size(); i++) {
+ NodeList<std::string> childs = finalElems[i].getChildNodes();
+ for (unsigned int j = 0; j < childs.getLength(); j++) {
+ if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
+ continue;
+ if (!boost::iequals(TAGNAME(childs.item(j)), "onentry") ||
+ !boost::iequals(TAGNAME(childs.item(j)), "onexit") ||
+ !boost::iequals(TAGNAME(childs.item(j)), "donedata")) {
+ LOG(ERROR) << "parallel element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
+ }
+ }
+ }
+
+ Arabica::XPath::NodeSet<std::string> historyElems = _xpath.evaluate(_nsPrefix + "history", _doc).asNodeSet();
+ for (unsigned int i = 0; i < historyElems.size(); i++) {
+ NodeList<std::string> childs = historyElems[i].getChildNodes();
+ for (unsigned int j = 0; j < childs.getLength(); j++) {
+ if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
+ continue;
+ if (boost::iequals(TAGNAME(childs.item(j)), "transition")) {
+ LOG(ERROR) << "history element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
+ }
+ }
+ }
+
+ Arabica::XPath::NodeSet<std::string> datamodelElems = _xpath.evaluate(_nsPrefix + "datamodel", _doc).asNodeSet();
+ for (unsigned int i = 0; i < datamodelElems.size(); i++) {
+ NodeList<std::string> childs = datamodelElems[i].getChildNodes();
+ for (unsigned int j = 0; j < childs.getLength(); j++) {
+ if (childs.item(j).getNodeType() != Node_base::ELEMENT_NODE)
+ continue;
+ if (!boost::iequals(TAGNAME(childs.item(j)), "data")) {
+ LOG(ERROR) << "datamodel element has unspecified child " << TAGNAME(childs.item(j)) << std::endl;
+ }
+ }
+ }
+
+ Arabica::XPath::NodeSet<std::string> dataElems = _xpath.evaluate(_nsPrefix + "data", _doc).asNodeSet();
+ for (unsigned int i = 0; i < dataElems.size(); i++) {
+ if (!HAS_ATTR(dataElems[i], "id"))
+ LOG(ERROR) << "data element has no id attribute" << std::endl;
+ }
+
+ return validationErrors;
+}
+
void Interpreter::dump() {
- if (!_doc)
- return;
- dump(_doc);
+ if (!_doc)
+ return;
+ dump(_doc);
}
void Interpreter::dump(const Arabica::DOM::Node<std::string>& node, int lvl) {
- if (!node)
- return;
-
- std::string indent = "";
- for (unsigned int i = 0; i < lvl; i++)
- indent += " ";
-
- std::cout << indent;
- switch(node.getNodeType()) {
- case Arabica::DOM::Node_base::ELEMENT_NODE: {
- std::cout << "ELEMENT_NODE: ";
- Arabica::DOM::Element<std::string> elem = (Arabica::DOM::Element<std::string>)node;
- break;
- }
- case Arabica::DOM::Node_base::ATTRIBUTE_NODE:
- std::cout << "ATTRIBUTE_NODE: ";
- break;
- case Arabica::DOM::Node_base::TEXT_NODE:
- std::cout << "TEXT_NODE: ";
- break;
- case Arabica::DOM::Node_base::CDATA_SECTION_NODE:
- std::cout << "CDATA_SECTION_NODE: ";
- break;
- case Arabica::DOM::Node_base::ENTITY_REFERENCE_NODE:
- std::cout << "ENTITY_REFERENCE_NODE: ";
- break;
- case Arabica::DOM::Node_base::ENTITY_NODE:
- std::cout << "ENTITY_NODE: ";
- break;
- case Arabica::DOM::Node_base::PROCESSING_INSTRUCTION_NODE:
- std::cout << "PROCESSING_INSTRUCTION_NODE: ";
- break;
- case Arabica::DOM::Node_base::COMMENT_NODE:
- std::cout << "COMMENT_NODE: ";
- break;
- case Arabica::DOM::Node_base::DOCUMENT_NODE:
- std::cout << "DOCUMENT_NODE: ";
- break;
- case Arabica::DOM::Node_base::DOCUMENT_TYPE_NODE:
- std::cout << "DOCUMENT_TYPE_NODE: ";
- break;
- case Arabica::DOM::Node_base::DOCUMENT_FRAGMENT_NODE:
- std::cout << "DOCUMENT_FRAGMENT_NODE: ";
- break;
- case Arabica::DOM::Node_base::NOTATION_NODE:
- std::cout << "NOTATION_NODE: ";
- break;
- case Arabica::DOM::Node_base::MAX_TYPE:
- std::cout << "MAX_TYPE: ";
- break;
- }
- std::cout << node.getNamespaceURI() << " " << node.getNodeName() << std::endl;
-
- if (node.getNodeValue().length() > 0 && node.getNodeValue().find_first_not_of(" \t\n") != std::string::npos)
- std::cout << indent << "Value: '" << node.getNodeValue() << "'" << std::endl;
-
-
- if (node.hasAttributes()) {
- Arabica::DOM::NamedNodeMap<std::string> attrs = node.getAttributes();
- for (unsigned int i = 0; i < attrs.getLength(); i++) {
- std::cout << indent << " " << attrs.item(i).getLocalName() << " = " << attrs.item(i).getNodeValue() << " (" << std::endl;
- std::cout << indent << " namespace: " << attrs.item(i).getNamespaceURI() << std::endl;
- std::cout << indent << " nodeName: " << attrs.item(i).getNodeName() << std::endl;
- std::cout << indent << " prefix: " << attrs.item(i).getPrefix() << std::endl;
- std::cout << indent << " )" << std::endl;
- }
- }
-
- if (node.hasChildNodes()) {
- Arabica::DOM::NodeList<std::string> childs = node.getChildNodes();
- for (unsigned int i = 0; i < childs.getLength(); i++) {
- dump(childs.item(i), lvl+1);
- }
- }
+ if (!node)
+ return;
+
+ std::string indent = "";
+ for (unsigned int i = 0; i < lvl; i++)
+ indent += " ";
+
+ std::cout << indent;
+ switch(node.getNodeType()) {
+ case Arabica::DOM::Node_base::ELEMENT_NODE: {
+ std::cout << "ELEMENT_NODE: ";
+ Arabica::DOM::Element<std::string> elem = (Arabica::DOM::Element<std::string>)node;
+ break;
+ }
+ case Arabica::DOM::Node_base::ATTRIBUTE_NODE:
+ std::cout << "ATTRIBUTE_NODE: ";
+ break;
+ case Arabica::DOM::Node_base::TEXT_NODE:
+ std::cout << "TEXT_NODE: ";
+ break;
+ case Arabica::DOM::Node_base::CDATA_SECTION_NODE:
+ std::cout << "CDATA_SECTION_NODE: ";
+ break;
+ case Arabica::DOM::Node_base::ENTITY_REFERENCE_NODE:
+ std::cout << "ENTITY_REFERENCE_NODE: ";
+ break;
+ case Arabica::DOM::Node_base::ENTITY_NODE:
+ std::cout << "ENTITY_NODE: ";
+ break;
+ case Arabica::DOM::Node_base::PROCESSING_INSTRUCTION_NODE:
+ std::cout << "PROCESSING_INSTRUCTION_NODE: ";
+ break;
+ case Arabica::DOM::Node_base::COMMENT_NODE:
+ std::cout << "COMMENT_NODE: ";
+ break;
+ case Arabica::DOM::Node_base::DOCUMENT_NODE:
+ std::cout << "DOCUMENT_NODE: ";
+ break;
+ case Arabica::DOM::Node_base::DOCUMENT_TYPE_NODE:
+ std::cout << "DOCUMENT_TYPE_NODE: ";
+ break;
+ case Arabica::DOM::Node_base::DOCUMENT_FRAGMENT_NODE:
+ std::cout << "DOCUMENT_FRAGMENT_NODE: ";
+ break;
+ case Arabica::DOM::Node_base::NOTATION_NODE:
+ std::cout << "NOTATION_NODE: ";
+ break;
+ case Arabica::DOM::Node_base::MAX_TYPE:
+ std::cout << "MAX_TYPE: ";
+ break;
+ }
+ std::cout << node.getNamespaceURI() << " " << node.getNodeName() << std::endl;
+
+ if (node.getNodeValue().length() > 0 && node.getNodeValue().find_first_not_of(" \t\n") != std::string::npos)
+ std::cout << indent << "Value: '" << node.getNodeValue() << "'" << std::endl;
+
+
+ if (node.hasAttributes()) {
+ Arabica::DOM::NamedNodeMap<std::string> attrs = node.getAttributes();
+ for (unsigned int i = 0; i < attrs.getLength(); i++) {
+ std::cout << indent << " " << attrs.item(i).getLocalName() << " = " << attrs.item(i).getNodeValue() << " (" << std::endl;
+ std::cout << indent << " namespace: " << attrs.item(i).getNamespaceURI() << std::endl;
+ std::cout << indent << " nodeName: " << attrs.item(i).getNodeName() << std::endl;
+ std::cout << indent << " prefix: " << attrs.item(i).getPrefix() << std::endl;
+ std::cout << indent << " )" << std::endl;
+ }
+ }
+
+ if (node.hasChildNodes()) {
+ Arabica::DOM::NodeList<std::string> childs = node.getChildNodes();
+ for (unsigned int i = 0; i < childs.getLength(); i++) {
+ dump(childs.item(i), lvl+1);
+ }
+ }
}
} \ No newline at end of file
diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h
index 6890baf..58b2a51 100644
--- a/src/uscxml/Interpreter.h
+++ b/src/uscxml/Interpreter.h
@@ -25,320 +25,351 @@
namespace uscxml {
- class Interpreter {
- public:
- enum Binding {
- EARLY = 0,
- LATE = 1
- };
-
- virtual ~Interpreter();
-
- static Interpreter* fromDOM(const Arabica::DOM::Node<std::string>& node);
- static Interpreter* fromXML(const std::string& xml);
- static Interpreter* fromURI(const std::string& uri);
- static Interpreter* fromInputSource(Arabica::SAX::InputSource<std::string>& source);
-
- void start();
- static void run(void*);
- void join() { if (_thread != NULL) _thread->join(); };
-
- void interpret();
- bool validate();
-
- void setBaseURI(std::string baseURI) { _baseURI = Arabica::io::URI(baseURI); }
- Arabica::io::URI getBaseURI() { return _baseURI; }
- bool makeAbsolute(Arabica::io::URI& uri);
-
- DataModel* getDataModel() { return _dataModel; }
- Invoker* getInvoker() { return _invoker; }
- void setInvoker(Invoker* invoker) { _invoker = invoker; }
- std::string getNSPrefix() { return _nsPrefix; }
- Arabica::XPath::XPath<std::string>& getXPath() { return _xpath; }
-
- void waitForStabilization();
-
- void receive(Event& event) { _externalQueue.push(event); }
- void receiveInternal(Event& event) { _internalQueue.push_back(event); }
- Arabica::XPath::NodeSet<std::string> getConfiguration() { return _configuration; }
- Arabica::DOM::Node<std::string> getState(const std::string& stateId);
- Arabica::DOM::Document<std::string>& getDocument() { return _doc; }
-
- const std::string& getName() { return _name; }
- const std::string& getSessionId() { return _sessionId; }
-
- static bool isMember(const Arabica::DOM::Node<std::string>& node, const Arabica::XPath::NodeSet<std::string>& set);
-
- void dump();
- static void dump(const Arabica::DOM::Node<std::string>& node, int lvl = 0);
-
- static bool isState(const Arabica::DOM::Node<std::string>& state);
- static bool isPseudoState(const Arabica::DOM::Node<std::string>& state);
- static bool isTransitionTarget(const Arabica::DOM::Node<std::string>& elem);
- static bool isTargetless(const Arabica::DOM::Node<std::string>& transition);
- static bool isAtomic(const Arabica::DOM::Node<std::string>& state);
- static bool isFinal(const Arabica::DOM::Node<std::string>& state);
- static bool isHistory(const Arabica::DOM::Node<std::string>& state);
- static bool isParallel(const Arabica::DOM::Node<std::string>& state);
- static bool isCompound(const Arabica::DOM::Node<std::string>& state);
- static bool isDescendant(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2);
-
- bool isInitial(const Arabica::DOM::Node<std::string>& state);
- Arabica::DOM::Node<std::string> getInitialState(Arabica::DOM::Node<std::string> state = Arabica::DOM::Node<std::string>());
- static Arabica::XPath::NodeSet<std::string> getChildStates(const Arabica::DOM::Node<std::string>& state);
- Arabica::XPath::NodeSet<std::string> getTargetStates(const Arabica::DOM::Node<std::string>& transition);
-
- protected:
- Interpreter();
- void init();
-
- void normalize(const Arabica::DOM::Document<std::string>& node);
- void setupIOProcessors();
-
- void mainEventLoop();
-
- bool _stable;
- tthread::thread* _thread;
- tthread::mutex _mutex;
- tthread::condition_variable _stabilized;
-
- Arabica::io::URI _baseURI;
- Arabica::DOM::Document<std::string> _doc;
- Arabica::DOM::Element<std::string> _scxml;
- Arabica::XPath::XPath<std::string> _xpath;
- Arabica::XPath::StandardNamespaceContext<std::string> _nsContext;
- std::string _nsPrefix;
-
- bool _running;
- Binding _binding;
- Arabica::XPath::NodeSet<std::string> _configuration;
- Arabica::XPath::NodeSet<std::string> _statesToInvoke;
-
- DataModel* _dataModel;
- std::map<std::string, Arabica::XPath::NodeSet<std::string> > _historyValue;
-
- std::list<Event > _internalQueue;
- uscxml::concurrency::BlockingQueue<Event> _externalQueue;
- DelayedEventQueue* _sendQueue;
- Invoker* _invoker;
-
- static Arabica::io::URI toBaseURI(const Arabica::io::URI& uri);
-
- void microstep(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
- void exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
- void enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
- void executeTransitionContent(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
- void executeContent(const Arabica::DOM::Node<std::string>& content);
- void executeContent(const Arabica::DOM::NodeList<std::string>& content);
- void initializeData(const Arabica::DOM::Node<std::string>& data);
- void exitInterpreter();
-
- void addStatesToEnter(const Arabica::DOM::Node<std::string>& state,
- Arabica::XPath::NodeSet<std::string>& statesToEnter,
- Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry);
-
- Arabica::XPath::NodeSet<std::string> selectEventlessTransitions();
- Arabica::XPath::NodeSet<std::string> selectTransitions(const std::string& event);
- Arabica::DOM::Node<std::string> getSourceState(const Arabica::DOM::Node<std::string>& transition);
- Arabica::DOM::Node<std::string> findLCCA(const Arabica::XPath::NodeSet<std::string>& states);
- static Arabica::XPath::NodeSet<std::string> getProperAncestors(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2);
-
-
- void send(const Arabica::DOM::Node<std::string>& element);
- void invoke(const Arabica::DOM::Node<std::string>& element);
- void cancelInvoke(const Arabica::DOM::Node<std::string>& element);
- void returnDoneEvent(const Arabica::DOM::Node<std::string>& state);
- void internalDoneSend(const Arabica::DOM::Node<std::string>& state);
- static void delayedSend(void* userdata, std::string eventName);
-
- static bool nameMatch(const std::string& transitionEvent, const std::string& event);
- Arabica::XPath::NodeSet<std::string> filterPreempted(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
- bool hasConditionMatch(const Arabica::DOM::Node<std::string>& conditional);
- bool isPreemptingTransition(const Arabica::DOM::Node<std::string>& t1, const Arabica::DOM::Node<std::string>& t2);
- bool isInFinalState(const Arabica::DOM::Node<std::string>& state);
- bool isWithinSameChild(const Arabica::DOM::Node<std::string>& transition);
- bool parentIsScxmlState(Arabica::DOM::Node<std::string> state);
-
- static std::vector<std::string> tokenizeIdRefs(const std::string& idRefs);
-
- static boost::uuids::random_generator uuidGen;
- static const std::string getUUID();
-
- std::string _name;
- std::string _sessionId;
-
- IOProcessor* getIOProcessor(const std::string& type);
+class Interpreter {
+public:
+ enum Binding {
+ EARLY = 0,
+ LATE = 1
+ };
+
+ virtual ~Interpreter();
+
+ static Interpreter* fromDOM(const Arabica::DOM::Node<std::string>& node);
+ static Interpreter* fromXML(const std::string& xml);
+ static Interpreter* fromURI(const std::string& uri);
+ static Interpreter* fromInputSource(Arabica::SAX::InputSource<std::string>& source);
+
+ void start();
+ static void run(void*);
+ void join() {
+ if (_thread != NULL) _thread->join();
+ };
+
+ void interpret();
+ bool validate();
+
+ void setBaseURI(std::string baseURI) {
+ _baseURI = Arabica::io::URI(baseURI);
+ }
+ Arabica::io::URI getBaseURI() {
+ return _baseURI;
+ }
+ bool makeAbsolute(Arabica::io::URI& uri);
+
+ DataModel* getDataModel() {
+ return _dataModel;
+ }
+ Invoker* getInvoker() {
+ return _invoker;
+ }
+ void setInvoker(Invoker* invoker) {
+ _invoker = invoker;
+ }
+ std::string getNSPrefix() {
+ return _nsPrefix;
+ }
+ Arabica::XPath::XPath<std::string>& getXPath() {
+ return _xpath;
+ }
+
+ void waitForStabilization();
+
+ void receive(Event& event) {
+ _externalQueue.push(event);
+ }
+ void receiveInternal(Event& event) {
+ _internalQueue.push_back(event);
+ }
+ Arabica::XPath::NodeSet<std::string> getConfiguration() {
+ return _configuration;
+ }
+ Arabica::DOM::Node<std::string> getState(const std::string& stateId);
+ Arabica::DOM::Document<std::string>& getDocument() {
+ return _doc;
+ }
+
+ const std::string& getName() {
+ return _name;
+ }
+ const std::string& getSessionId() {
+ return _sessionId;
+ }
+
+ static bool isMember(const Arabica::DOM::Node<std::string>& node, const Arabica::XPath::NodeSet<std::string>& set);
+
+ void dump();
+ static void dump(const Arabica::DOM::Node<std::string>& node, int lvl = 0);
+
+ static bool isState(const Arabica::DOM::Node<std::string>& state);
+ static bool isPseudoState(const Arabica::DOM::Node<std::string>& state);
+ static bool isTransitionTarget(const Arabica::DOM::Node<std::string>& elem);
+ static bool isTargetless(const Arabica::DOM::Node<std::string>& transition);
+ static bool isAtomic(const Arabica::DOM::Node<std::string>& state);
+ static bool isFinal(const Arabica::DOM::Node<std::string>& state);
+ static bool isHistory(const Arabica::DOM::Node<std::string>& state);
+ static bool isParallel(const Arabica::DOM::Node<std::string>& state);
+ static bool isCompound(const Arabica::DOM::Node<std::string>& state);
+ static bool isDescendant(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2);
+
+ bool isInitial(const Arabica::DOM::Node<std::string>& state);
+ Arabica::DOM::Node<std::string> getInitialState(Arabica::DOM::Node<std::string> state = Arabica::DOM::Node<std::string>());
+ static Arabica::XPath::NodeSet<std::string> getChildStates(const Arabica::DOM::Node<std::string>& state);
+ Arabica::XPath::NodeSet<std::string> getTargetStates(const Arabica::DOM::Node<std::string>& transition);
+
+protected:
+ Interpreter();
+ void init();
+
+ void normalize(const Arabica::DOM::Document<std::string>& node);
+ void setupIOProcessors();
+
+ void mainEventLoop();
+
+ bool _stable;
+ tthread::thread* _thread;
+ tthread::mutex _mutex;
+ tthread::condition_variable _stabilized;
+
+ Arabica::io::URI _baseURI;
+ Arabica::DOM::Document<std::string> _doc;
+ Arabica::DOM::Element<std::string> _scxml;
+ Arabica::XPath::XPath<std::string> _xpath;
+ Arabica::XPath::StandardNamespaceContext<std::string> _nsContext;
+ std::string _nsPrefix;
+
+ bool _running;
+ Binding _binding;
+ Arabica::XPath::NodeSet<std::string> _configuration;
+ Arabica::XPath::NodeSet<std::string> _statesToInvoke;
+
+ DataModel* _dataModel;
+ std::map<std::string, Arabica::XPath::NodeSet<std::string> > _historyValue;
+
+ std::list<Event > _internalQueue;
+ uscxml::concurrency::BlockingQueue<Event> _externalQueue;
+ DelayedEventQueue* _sendQueue;
+ Invoker* _invoker;
+
+ static Arabica::io::URI toBaseURI(const Arabica::io::URI& uri);
+
+ void microstep(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
+ void exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
+ void enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
+ void executeTransitionContent(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
+ void executeContent(const Arabica::DOM::Node<std::string>& content);
+ void executeContent(const Arabica::DOM::NodeList<std::string>& content);
+ void initializeData(const Arabica::DOM::Node<std::string>& data);
+ void exitInterpreter();
+
+ void addStatesToEnter(const Arabica::DOM::Node<std::string>& state,
+ Arabica::XPath::NodeSet<std::string>& statesToEnter,
+ Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry);
+
+ Arabica::XPath::NodeSet<std::string> selectEventlessTransitions();
+ Arabica::XPath::NodeSet<std::string> selectTransitions(const std::string& event);
+ Arabica::DOM::Node<std::string> getSourceState(const Arabica::DOM::Node<std::string>& transition);
+ Arabica::DOM::Node<std::string> findLCCA(const Arabica::XPath::NodeSet<std::string>& states);
+ static Arabica::XPath::NodeSet<std::string> getProperAncestors(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2);
+
+
+ void send(const Arabica::DOM::Node<std::string>& element);
+ void invoke(const Arabica::DOM::Node<std::string>& element);
+ void cancelInvoke(const Arabica::DOM::Node<std::string>& element);
+ void returnDoneEvent(const Arabica::DOM::Node<std::string>& state);
+ void internalDoneSend(const Arabica::DOM::Node<std::string>& state);
+ static void delayedSend(void* userdata, std::string eventName);
+
+ static bool nameMatch(const std::string& transitionEvent, const std::string& event);
+ Arabica::XPath::NodeSet<std::string> filterPreempted(const Arabica::XPath::NodeSet<std::string>& enabledTransitions);
+ bool hasConditionMatch(const Arabica::DOM::Node<std::string>& conditional);
+ bool isPreemptingTransition(const Arabica::DOM::Node<std::string>& t1, const Arabica::DOM::Node<std::string>& t2);
+ bool isInFinalState(const Arabica::DOM::Node<std::string>& state);
+ bool isWithinSameChild(const Arabica::DOM::Node<std::string>& transition);
+ bool parentIsScxmlState(Arabica::DOM::Node<std::string> state);
+
+ static std::vector<std::string> tokenizeIdRefs(const std::string& idRefs);
+
+ static boost::uuids::random_generator uuidGen;
+ static const std::string getUUID();
+
+ std::string _name;
+ std::string _sessionId;
+
+ IOProcessor* getIOProcessor(const std::string& type);
// IOProcessor* getIOProcessorForId(const std::string& sendId);
-
- std::map<std::string, IOProcessor*> _ioProcessors;
- std::map<std::string, std::pair<Interpreter*, SendRequest> > _sendIds;
- std::map<std::string, Invoker*> _invokerIds;
- std::map<std::string, Invoker*> _invokers;
-
- };
-
+
+ std::map<std::string, IOProcessor*> _ioProcessors;
+ std::map<std::string, std::pair<Interpreter*, SendRequest> > _sendIds;
+ std::map<std::string, Invoker*> _invokerIds;
+ std::map<std::string, Invoker*> _invokers;
+
+};
+
#if 0
- class SCXMLParseHandler :
- public Arabica::SAX::EntityResolver<std::string>,
- public Arabica::SAX::DTDHandler<std::string>,
- public Arabica::SAX::ContentHandler<std::string>,
- public Arabica::SAX::CatchErrorHandler<std::string>,
- public Arabica::SAX::LexicalHandler<std::string>,
- public Arabica::SAX::DeclHandler<std::string>
- {
- public:
- SCXMLParseHandler() { }
- virtual ~SCXMLParseHandler() { }
-
- // EntityResolver
- virtual InputSourceT resolveEntity(const std::string& publicId , const std::string& systemId) {
- return InputSourceT();
- }
-
- // DTDHandler
- virtual void notationDecl(const std::string& name,
- const std::string& publicId,
- const std::string& systemId) {
- std::cout << "notationDecl" << std::endl;
- std::cout << " name:" << name << std::endl;
- std::cout << " publicId:" << publicId << std::endl;
- std::cout << " systemId:" << systemId << std::endl;
- }
- virtual void unparsedEntityDecl(const std::string& name,
- const std::string& publicId,
- const std::string& systemId,
- const std::string& notationName) {
- std::cout << "unparsedEntityDecl" << std::endl;
- std::cout << " name:" << name << std::endl;
- std::cout << " publicId:" << publicId << std::endl;
- std::cout << " systemId:" << systemId << std::endl;
- std::cout << " notationName:" << notationName << std::endl;
- }
-
- // ContentHandler
- virtual void setDocumentLocator(const LocatorT& locator) {
- std::cout << "setDocumentLocator" << std::endl;
- }
- virtual void startDocument() {
- std::cout << "startDocument" << std::endl;
- }
- virtual void endDocument() {
- std::cout << "endDocument" << std::endl;
- }
- virtual void startPrefixMapping(const std::string& prefix, const std::string& uri) {
- std::cout << "startPrefixMapping" << std::endl;
- std::cout << " prefix:" << prefix << std::endl;
- std::cout << " uri:" << uri << std::endl;
- }
- virtual void endPrefixMapping(const std::string& prefix) {
- std::cout << "endPrefixMapping" << std::endl;
- std::cout << " prefix:" << prefix << std::endl;
- }
- virtual void startElement(const std::string& namespaceURI, const std::string& localName,
- const std::string& qName, const AttributesT& atts) {
- std::cout << "startElement" << std::endl;
- std::cout << " namespaceURI:" << namespaceURI << std::endl;
- std::cout << " localName:" << localName << std::endl;
- std::cout << " qName:" << qName << std::endl;
- std::cout << " atts:" << atts.getLength() << std::endl;
- }
- virtual void endElement(const std::string& namespaceURI, const std::string& localName,
- const std::string& qName) {
- std::cout << "endElement" << std::endl;
- std::cout << " namespaceURI:" << namespaceURI << std::endl;
- std::cout << " localName:" << localName << std::endl;
- std::cout << " qName:" << qName << std::endl;
- }
- virtual void characters(const std::string& ch) {
- std::cout << "characters" << std::endl;
- std::cout << " ch:" << ch << std::endl;
- }
- virtual void ignorableWhitespace(const std::string& ch) {
- std::cout << "ignorableWhitespace" << std::endl;
- std::cout << " ch:" << ch << std::endl;
- }
- virtual void processingInstruction(const std::string& target, const std::string& data) {
- std::cout << "processingInstruction" << std::endl;
- std::cout << " target:" << target << std::endl;
- std::cout << " data:" << data << std::endl;
- }
- virtual void skippedEntity(const std::string& name) {
- std::cout << "skippedEntity" << std::endl;
- std::cout << " name:" << name << std::endl;
- }
-
- // ErrorHandler
- virtual void warning(const SAXParseExceptionT& e) { Arabica::SAX::CatchErrorHandler<std::string>::warning(e); }
- virtual void error(const SAXParseExceptionT& e) { Arabica::SAX::CatchErrorHandler<std::string>::error(e); }
- virtual void fatalError(const SAXParseExceptionT& e) {
- Arabica::SAX::CatchErrorHandler<std::string>::fatalError(e);
- }
-
- // LexicalHandler
- virtual void startDTD(const std::string& name,
- const std::string& publicId,
- const std::string& systemId) {
- std::cout << "startDTD" << std::endl;
- std::cout << " name:" << name << std::endl;
- std::cout << " publicId:" << publicId << std::endl;
- std::cout << " systemId:" << systemId << std::endl;
- }
-
- virtual void endDTD() {
- std::cout << "endDTD" << std::endl;
- }
- virtual void startEntity(const std::string& name) {
- std::cout << "startEntity" << std::endl;
- std::cout << " name:" << name << std::endl;
- }
- virtual void endEntity(const std::string& name) {
- std::cout << "endEntity" << std::endl;
- std::cout << " name:" << name << std::endl;
- }
- virtual void startCDATA() {
- std::cout << "startCDATA" << std::endl;
- }
- virtual void endCDATA() {
- std::cout << "endCDATA" << std::endl;
- }
- virtual void comment(const std::string& text) {
- std::cout << "comment" << std::endl;
- std::cout << " text:" << text << std::endl;
- }
-
- // DeclHandler
- virtual void elementDecl(const std::string& name, const std::string& model) {
- std::cout << "elementDecl" << std::endl;
- std::cout << " name:" << name << std::endl;
- std::cout << " model:" << model << std::endl;
- }
- virtual void attributeDecl(const std::string& elementName,
- const std::string& attributeName,
- const std::string& type,
- const std::string& valueDefault,
- const std::string& value) {
- std::cout << "attributeDecl" << std::endl;
- std::cout << " elementName:" << elementName << std::endl;
- std::cout << " attributeName:" << attributeName << std::endl;
- std::cout << " type:" << type << std::endl;
- std::cout << " valueDefault:" << valueDefault << std::endl;
- std::cout << " value:" << value << std::endl;
- }
- virtual void internalEntityDecl(const std::string& name, const std::string& value) {
- std::cout << "internalEntityDecl" << std::endl;
- std::cout << " name:" << name << std::endl;
- std::cout << " value:" << value << std::endl;
- }
- virtual void externalEntityDecl(const std::string& name,
- const std::string& publicId,
- const std::string& systemId) {
- std::cout << "externalEntityDecl" << std::endl;
- std::cout << " name:" << name << std::endl;
- std::cout << " publicId:" << publicId << std::endl;
- std::cout << " systemId:" << systemId << std::endl;
- }
-
- };
+class SCXMLParseHandler :
+ public Arabica::SAX::EntityResolver<std::string>,
+ public Arabica::SAX::DTDHandler<std::string>,
+ public Arabica::SAX::ContentHandler<std::string>,
+ public Arabica::SAX::CatchErrorHandler<std::string>,
+ public Arabica::SAX::LexicalHandler<std::string>,
+ public Arabica::SAX::DeclHandler<std::string> {
+public:
+ SCXMLParseHandler() { }
+ virtual ~SCXMLParseHandler() { }
+
+ // EntityResolver
+ virtual InputSourceT resolveEntity(const std::string& publicId , const std::string& systemId) {
+ return InputSourceT();
+ }
+
+ // DTDHandler
+ virtual void notationDecl(const std::string& name,
+ const std::string& publicId,
+ const std::string& systemId) {
+ std::cout << "notationDecl" << std::endl;
+ std::cout << " name:" << name << std::endl;
+ std::cout << " publicId:" << publicId << std::endl;
+ std::cout << " systemId:" << systemId << std::endl;
+ }
+ virtual void unparsedEntityDecl(const std::string& name,
+ const std::string& publicId,
+ const std::string& systemId,
+ const std::string& notationName) {
+ std::cout << "unparsedEntityDecl" << std::endl;
+ std::cout << " name:" << name << std::endl;
+ std::cout << " publicId:" << publicId << std::endl;
+ std::cout << " systemId:" << systemId << std::endl;
+ std::cout << " notationName:" << notationName << std::endl;
+ }
+
+ // ContentHandler
+ virtual void setDocumentLocator(const LocatorT& locator) {
+ std::cout << "setDocumentLocator" << std::endl;
+ }
+ virtual void startDocument() {
+ std::cout << "startDocument" << std::endl;
+ }
+ virtual void endDocument() {
+ std::cout << "endDocument" << std::endl;
+ }
+ virtual void startPrefixMapping(const std::string& prefix, const std::string& uri) {
+ std::cout << "startPrefixMapping" << std::endl;
+ std::cout << " prefix:" << prefix << std::endl;
+ std::cout << " uri:" << uri << std::endl;
+ }
+ virtual void endPrefixMapping(const std::string& prefix) {
+ std::cout << "endPrefixMapping" << std::endl;
+ std::cout << " prefix:" << prefix << std::endl;
+ }
+ virtual void startElement(const std::string& namespaceURI, const std::string& localName,
+ const std::string& qName, const AttributesT& atts) {
+ std::cout << "startElement" << std::endl;
+ std::cout << " namespaceURI:" << namespaceURI << std::endl;
+ std::cout << " localName:" << localName << std::endl;
+ std::cout << " qName:" << qName << std::endl;
+ std::cout << " atts:" << atts.getLength() << std::endl;
+ }
+ virtual void endElement(const std::string& namespaceURI, const std::string& localName,
+ const std::string& qName) {
+ std::cout << "endElement" << std::endl;
+ std::cout << " namespaceURI:" << namespaceURI << std::endl;
+ std::cout << " localName:" << localName << std::endl;
+ std::cout << " qName:" << qName << std::endl;
+ }
+ virtual void characters(const std::string& ch) {
+ std::cout << "characters" << std::endl;
+ std::cout << " ch:" << ch << std::endl;
+ }
+ virtual void ignorableWhitespace(const std::string& ch) {
+ std::cout << "ignorableWhitespace" << std::endl;
+ std::cout << " ch:" << ch << std::endl;
+ }
+ virtual void processingInstruction(const std::string& target, const std::string& data) {
+ std::cout << "processingInstruction" << std::endl;
+ std::cout << " target:" << target << std::endl;
+ std::cout << " data:" << data << std::endl;
+ }
+ virtual void skippedEntity(const std::string& name) {
+ std::cout << "skippedEntity" << std::endl;
+ std::cout << " name:" << name << std::endl;
+ }
+
+ // ErrorHandler
+ virtual void warning(const SAXParseExceptionT& e) {
+ Arabica::SAX::CatchErrorHandler<std::string>::warning(e);
+ }
+ virtual void error(const SAXParseExceptionT& e) {
+ Arabica::SAX::CatchErrorHandler<std::string>::error(e);
+ }
+ virtual void fatalError(const SAXParseExceptionT& e) {
+ Arabica::SAX::CatchErrorHandler<std::string>::fatalError(e);
+ }
+
+ // LexicalHandler
+ virtual void startDTD(const std::string& name,
+ const std::string& publicId,
+ const std::string& systemId) {
+ std::cout << "startDTD" << std::endl;
+ std::cout << " name:" << name << std::endl;
+ std::cout << " publicId:" << publicId << std::endl;
+ std::cout << " systemId:" << systemId << std::endl;
+ }
+
+ virtual void endDTD() {
+ std::cout << "endDTD" << std::endl;
+ }
+ virtual void startEntity(const std::string& name) {
+ std::cout << "startEntity" << std::endl;
+ std::cout << " name:" << name << std::endl;
+ }
+ virtual void endEntity(const std::string& name) {
+ std::cout << "endEntity" << std::endl;
+ std::cout << " name:" << name << std::endl;
+ }
+ virtual void startCDATA() {
+ std::cout << "startCDATA" << std::endl;
+ }
+ virtual void endCDATA() {
+ std::cout << "endCDATA" << std::endl;
+ }
+ virtual void comment(const std::string& text) {
+ std::cout << "comment" << std::endl;
+ std::cout << " text:" << text << std::endl;
+ }
+
+ // DeclHandler
+ virtual void elementDecl(const std::string& name, const std::string& model) {
+ std::cout << "elementDecl" << std::endl;
+ std::cout << " name:" << name << std::endl;
+ std::cout << " model:" << model << std::endl;
+ }
+ virtual void attributeDecl(const std::string& elementName,
+ const std::string& attributeName,
+ const std::string& type,
+ const std::string& valueDefault,
+ const std::string& value) {
+ std::cout << "attributeDecl" << std::endl;
+ std::cout << " elementName:" << elementName << std::endl;
+ std::cout << " attributeName:" << attributeName << std::endl;
+ std::cout << " type:" << type << std::endl;
+ std::cout << " valueDefault:" << valueDefault << std::endl;
+ std::cout << " value:" << value << std::endl;
+ }
+ virtual void internalEntityDecl(const std::string& name, const std::string& value) {
+ std::cout << "internalEntityDecl" << std::endl;
+ std::cout << " name:" << name << std::endl;
+ std::cout << " value:" << value << std::endl;
+ }
+ virtual void externalEntityDecl(const std::string& name,
+ const std::string& publicId,
+ const std::string& systemId) {
+ std::cout << "externalEntityDecl" << std::endl;
+ std::cout << " name:" << name << std::endl;
+ std::cout << " publicId:" << publicId << std::endl;
+ std::cout << " systemId:" << systemId << std::endl;
+ }
+
+};
#endif
}
diff --git a/src/uscxml/Message.cpp b/src/uscxml/Message.cpp
index 1b2c9e8..09676bf 100644
--- a/src/uscxml/Message.cpp
+++ b/src/uscxml/Message.cpp
@@ -9,211 +9,207 @@ namespace uscxml {
static int _dataIndentation = 1;
Data::Data(const Arabica::DOM::Node<std::string>& dom) {
- // we may need to convert some keys to arrays if we have the same name as an element
- std::map<std::string, std::list<Data> > arrays;
+ // we may need to convert some keys to arrays if we have the same name as an element
+ std::map<std::string, std::list<Data> > arrays;
// Interpreter::dump(dom);
- if (dom.hasAttributes()) {
- Arabica::DOM::NamedNodeMap<std::string> attributes = dom.getAttributes();
- for (int i = 0; i < attributes.getLength(); i++) {
- Arabica::DOM::Node<std::string> attribute = attributes.item(i);
+ if (dom.hasAttributes()) {
+ Arabica::DOM::NamedNodeMap<std::string> attributes = dom.getAttributes();
+ for (int i = 0; i < attributes.getLength(); i++) {
+ Arabica::DOM::Node<std::string> attribute = attributes.item(i);
// Interpreter::dump(attribute);
- assert(attribute.getNodeType() == Arabica::DOM::Node_base::ATTRIBUTE_NODE);
- std::string key = attribute.getLocalName();
- std::string value = attribute.getNodeValue();
- compound[key] = Data(value, VERBATIM);
- }
- }
-
- if (dom.hasChildNodes()) {
- Arabica::DOM::NodeList<std::string> children = dom.getChildNodes();
- for (int i = 0; i < children.getLength(); i++) {
- Arabica::DOM::Node<std::string> child = children.item(i);
+ assert(attribute.getNodeType() == Arabica::DOM::Node_base::ATTRIBUTE_NODE);
+ std::string key = attribute.getLocalName();
+ std::string value = attribute.getNodeValue();
+ compound[key] = Data(value, VERBATIM);
+ }
+ }
+
+ if (dom.hasChildNodes()) {
+ Arabica::DOM::NodeList<std::string> children = dom.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Arabica::DOM::Node<std::string> child = children.item(i);
// Interpreter::dump(child);
- std::string key;
- switch (child.getNodeType()) {
- case Arabica::DOM::Node_base::ELEMENT_NODE:
- key = TAGNAME(child);
- break;
- case Arabica::DOM::Node_base::ATTRIBUTE_NODE:
- key = ((Arabica::DOM::Attr<std::string>)child).getName();
- break;
- case Arabica::DOM::Node_base::TEXT_NODE:
- default:
- break;
- }
- if (key.length() == 0)
- continue;
-
- if (compound.find(key) != compound.end()) {
- // we already have such a key .. make it an array after we processed all children
- arrays[key].push_back(Data(child));
- } else {
- compound[key] = Data(child);
- }
- }
- } else {
- atom = dom.getNodeValue();
- type = VERBATIM;
- }
-
- std::map<std::string, std::list<Data> >::iterator arrayIter = arrays.begin();
- while(arrayIter != arrays.end()) {
- assert(compound.find(arrayIter->first) != compound.end());
- Data arrayData;
- arrays[arrayIter->first].push_front(compound[arrayIter->first]);
- arrayData.array = arrays[arrayIter->first];
- compound[arrayIter->first] = arrayData;
- }
+ std::string key;
+ switch (child.getNodeType()) {
+ case Arabica::DOM::Node_base::ELEMENT_NODE:
+ key = TAGNAME(child);
+ break;
+ case Arabica::DOM::Node_base::ATTRIBUTE_NODE:
+ key = ((Arabica::DOM::Attr<std::string>)child).getName();
+ break;
+ case Arabica::DOM::Node_base::TEXT_NODE:
+ default:
+ break;
+ }
+ if (key.length() == 0)
+ continue;
+
+ if (compound.find(key) != compound.end()) {
+ // we already have such a key .. make it an array after we processed all children
+ arrays[key].push_back(Data(child));
+ } else {
+ compound[key] = Data(child);
+ }
+ }
+ } else {
+ atom = dom.getNodeValue();
+ type = VERBATIM;
+ }
+
+ std::map<std::string, std::list<Data> >::iterator arrayIter = arrays.begin();
+ while(arrayIter != arrays.end()) {
+ assert(compound.find(arrayIter->first) != compound.end());
+ Data arrayData;
+ arrays[arrayIter->first].push_front(compound[arrayIter->first]);
+ arrayData.array = arrays[arrayIter->first];
+ compound[arrayIter->first] = arrayData;
+ }
}
Arabica::DOM::Document<std::string> Data::toDocument() {
- Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
- Arabica::DOM::Document<std::string> document = domFactory.createDocument("http://www.w3.org/2005/07/scxml", "message", 0);
- Arabica::DOM::Element<std::string> scxmlMsg = document.getDocumentElement();
- scxmlMsg.setPrefix("scxml");
- scxmlMsg.setAttribute("version", "1.0");
-
- if (compound.size() > 0 || array.size() > 0) {
- Arabica::DOM::Element<std::string> payloadElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:payload");
- scxmlMsg.appendChild(payloadElem);
-
- // we do not support nested attibutes
- if (compound.size() > 0) {
- std::map<std::string, Data>::iterator compoundIter = compound.begin();
- while(compoundIter != compound.end()) {
- if (compoundIter->second.atom.size() > 0) {
- Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:property");
- propertyElem.setAttribute("name", compoundIter->first);
- Arabica::DOM::Text<std::string> textElem = document.createTextNode(compoundIter->second.atom);
- propertyElem.appendChild(textElem);
- payloadElem.appendChild(propertyElem);
- }
- compoundIter++;
- }
- }
- }
- return document;
+ Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
+ Arabica::DOM::Document<std::string> document = domFactory.createDocument("http://www.w3.org/2005/07/scxml", "message", 0);
+ Arabica::DOM::Element<std::string> scxmlMsg = document.getDocumentElement();
+ scxmlMsg.setPrefix("scxml");
+ scxmlMsg.setAttribute("version", "1.0");
+
+ if (compound.size() > 0 || array.size() > 0) {
+ Arabica::DOM::Element<std::string> payloadElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:payload");
+ scxmlMsg.appendChild(payloadElem);
+
+ // we do not support nested attibutes
+ if (compound.size() > 0) {
+ std::map<std::string, Data>::iterator compoundIter = compound.begin();
+ while(compoundIter != compound.end()) {
+ if (compoundIter->second.atom.size() > 0) {
+ Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:property");
+ propertyElem.setAttribute("name", compoundIter->first);
+ Arabica::DOM::Text<std::string> textElem = document.createTextNode(compoundIter->second.atom);
+ propertyElem.appendChild(textElem);
+ payloadElem.appendChild(propertyElem);
+ }
+ compoundIter++;
+ }
+ }
+ }
+ return document;
}
Arabica::DOM::Document<std::string> Event::toDocument() {
- Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
- Arabica::DOM::Document<std::string> document = Data::toDocument();
- Arabica::DOM::Element<std::string> scxmlMsg = document.getDocumentElement();
-
-
- scxmlMsg.setAttribute("source", origin);
- scxmlMsg.setAttribute("name", name);
-
- return document;
+ Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
+ Arabica::DOM::Document<std::string> document = Data::toDocument();
+ Arabica::DOM::Element<std::string> scxmlMsg = document.getDocumentElement();
+
+
+ scxmlMsg.setAttribute("source", origin);
+ scxmlMsg.setAttribute("name", name);
+
+ return document;
}
Arabica::DOM::Document<std::string> SendRequest::toDocument() {
- Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
- Arabica::DOM::Document<std::string> document = Event::toDocument();
- Arabica::DOM::Element<std::string> scxmlMsg = document.getDocumentElement();
-
- // add params and namelist
- if (params.size() > 0 || namelist.size() > 0) {
- Arabica::DOM::NodeList<std::string> payload = scxmlMsg.getElementsByTagName("scxml:payload");
- if (payload.getLength() == 0) {
- Arabica::DOM::Element<std::string> payloadElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:payload");
- scxmlMsg.appendChild(payloadElem);
- }
- Arabica::DOM::Node<std::string> payloadElem = scxmlMsg.getElementsByTagName("scxml:payload").item(0);
-
- // add parameters
- std::map<std::string, std::list<std::string> >::iterator paramsIter = params.begin();
- while(paramsIter != params.end()) {
- std::list<std::string>::iterator paramIter = paramsIter->second.begin();
- while(paramIter != paramsIter->second.end()) {
- Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:property");
- propertyElem.setAttribute("name", paramsIter->first);
- Arabica::DOM::Text<std::string> textElem = document.createTextNode(*paramIter);
- propertyElem.appendChild(textElem);
- payloadElem.appendChild(propertyElem);
- paramIter++;
- }
- paramsIter++;
- }
-
- // add namelist elements
- std::map<std::string, std::string>::iterator namelistIter = namelist.begin();
- while(namelistIter != namelist.end()) {
- Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:property");
- propertyElem.setAttribute("name", namelistIter->first);
- Arabica::DOM::Text<std::string> textElem = document.createTextNode(namelistIter->second);
- propertyElem.appendChild(textElem);
- payloadElem.appendChild(propertyElem);
- namelistIter++;
- }
-
- }
-
-
- scxmlMsg.setAttribute("sendid", sendid);
-
- return document;
+ Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
+ Arabica::DOM::Document<std::string> document = Event::toDocument();
+ Arabica::DOM::Element<std::string> scxmlMsg = document.getDocumentElement();
+
+ // add params and namelist
+ if (params.size() > 0 || namelist.size() > 0) {
+ Arabica::DOM::NodeList<std::string> payload = scxmlMsg.getElementsByTagName("scxml:payload");
+ if (payload.getLength() == 0) {
+ Arabica::DOM::Element<std::string> payloadElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:payload");
+ scxmlMsg.appendChild(payloadElem);
+ }
+ Arabica::DOM::Node<std::string> payloadElem = scxmlMsg.getElementsByTagName("scxml:payload").item(0);
+
+ // add parameters
+ std::multimap<std::string, std::string>::iterator paramIter = params.begin();
+ while(paramIter != params.end()) {
+ Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:property");
+ propertyElem.setAttribute("name", paramIter->first);
+ Arabica::DOM::Text<std::string> textElem = document.createTextNode(paramIter->second);
+ propertyElem.appendChild(textElem);
+ payloadElem.appendChild(propertyElem);
+ paramIter++;
+ }
+
+ // add namelist elements
+ std::map<std::string, std::string>::iterator namelistIter = namelist.begin();
+ while(namelistIter != namelist.end()) {
+ Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:property");
+ propertyElem.setAttribute("name", namelistIter->first);
+ Arabica::DOM::Text<std::string> textElem = document.createTextNode(namelistIter->second);
+ propertyElem.appendChild(textElem);
+ payloadElem.appendChild(propertyElem);
+ namelistIter++;
+ }
+
+ }
+
+
+ scxmlMsg.setAttribute("sendid", sendid);
+
+ return document;
}
Arabica::DOM::Document<std::string> InvokeRequest::toDocument() {
- Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
- Arabica::DOM::Document<std::string> document = Event::toDocument();
- Arabica::DOM::Element<std::string> scxmlMsg = document.getDocumentElement();
-
- scxmlMsg.setAttribute("invokeid", invokeid);
-
- return document;
+ Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
+ Arabica::DOM::Document<std::string> document = Event::toDocument();
+ Arabica::DOM::Element<std::string> scxmlMsg = document.getDocumentElement();
+
+ scxmlMsg.setAttribute("invokeid", invokeid);
+
+ return document;
}
Data Data::fromXML(const std::string& xmlString) {
return Data();
}
-
+
Event Event::fromXML(const std::string& xmlString) {
- Arabica::SAX2DOM::Parser<std::string> eventParser;
- Arabica::SAX::CatchErrorHandler<std::string> errorHandler;
- eventParser.setErrorHandler(errorHandler);
-
- std::istringstream is(xmlString);
- Arabica::SAX::InputSource<std::string> inputSource;
- inputSource.setByteStream(is);
-
- Event event;
- if(eventParser.parse(inputSource) && eventParser.getDocument().hasChildNodes()) {
- Arabica::DOM::Element<std::string> scxmlMsg = eventParser.getDocument().getDocumentElement();
- if (HAS_ATTR(scxmlMsg, "name"))
- event.name = ATTR(scxmlMsg, "name");
- if (HAS_ATTR(scxmlMsg, "sendid"))
- event.sendid = ATTR(scxmlMsg, "sendid");
-
- Arabica::DOM::NodeList<std::string> payloads = scxmlMsg.getElementsByTagName("scxml:payload");
- if (payloads.getLength() > 0) {
- Arabica::DOM::Node<std::string> payload = payloads.item(0);
- if (payload.getNodeType() == Arabica::DOM::Node_base::ELEMENT_NODE) {
- Arabica::DOM::Element<std::string> payloadElem = (Arabica::DOM::Element<std::string>)payload;
- Arabica::DOM::NodeList<std::string> properties = payloadElem.getElementsByTagName("scxml:property");
- if (properties.getLength() > 0) {
- for (int i = 0; i < properties.getLength(); i++) {
- if (HAS_ATTR(properties.item(i), "name")) {
- std::string key = ATTR(properties.item(i), "name");
- std::string value;
- Arabica::DOM::NodeList<std::string> childs = properties.item(i).getChildNodes();
- for (int j = 0; j < childs.getLength(); j++) {
- if (childs.item(j).getNodeType() == Arabica::DOM::Node_base::TEXT_NODE) {
- value = childs.item(j).getNodeValue();
- break;
- }
- }
- event.compound[key] = Data(value, VERBATIM);
- }
- }
- }
- }
- }
- }
- return event;
+ Arabica::SAX2DOM::Parser<std::string> eventParser;
+ Arabica::SAX::CatchErrorHandler<std::string> errorHandler;
+ eventParser.setErrorHandler(errorHandler);
+
+ std::istringstream is(xmlString);
+ Arabica::SAX::InputSource<std::string> inputSource;
+ inputSource.setByteStream(is);
+
+ Event event;
+ if(eventParser.parse(inputSource) && eventParser.getDocument().hasChildNodes()) {
+ Arabica::DOM::Element<std::string> scxmlMsg = eventParser.getDocument().getDocumentElement();
+ if (HAS_ATTR(scxmlMsg, "name"))
+ event.name = ATTR(scxmlMsg, "name");
+ if (HAS_ATTR(scxmlMsg, "sendid"))
+ event.sendid = ATTR(scxmlMsg, "sendid");
+
+ Arabica::DOM::NodeList<std::string> payloads = scxmlMsg.getElementsByTagName("scxml:payload");
+ if (payloads.getLength() > 0) {
+ Arabica::DOM::Node<std::string> payload = payloads.item(0);
+ if (payload.getNodeType() == Arabica::DOM::Node_base::ELEMENT_NODE) {
+ Arabica::DOM::Element<std::string> payloadElem = (Arabica::DOM::Element<std::string>)payload;
+ Arabica::DOM::NodeList<std::string> properties = payloadElem.getElementsByTagName("scxml:property");
+ if (properties.getLength() > 0) {
+ for (int i = 0; i < properties.getLength(); i++) {
+ if (HAS_ATTR(properties.item(i), "name")) {
+ std::string key = ATTR(properties.item(i), "name");
+ std::string value;
+ Arabica::DOM::NodeList<std::string> childs = properties.item(i).getChildNodes();
+ for (int j = 0; j < childs.getLength(); j++) {
+ if (childs.item(j).getNodeType() == Arabica::DOM::Node_base::TEXT_NODE) {
+ value = childs.item(j).getNodeValue();
+ break;
+ }
+ }
+ event.compound[key] = Data(value, VERBATIM);
+ }
+ }
+ }
+ }
+ }
+ }
+ return event;
}
SendRequest SendRequest::fromXML(const std::string& xmlString) {
@@ -228,68 +224,68 @@ InvokeRequest InvokeRequest::fromXML(const std::string& xmlString) {
#ifndef SWIGJAVA
std::ostream& operator<< (std::ostream& os, const Event& event) {
- os << (event.type == Event::EXTERNAL ? "External" : "Internal") << " Event " /* << (event.dom ? "with DOM attached" : "")*/ << std::endl;
-
- if (event.name.size() > 0)
- os << " name: " << event.name << std::endl;
- if (event.origin.size() > 0)
- os << " origin: " << event.origin << std::endl;
- if (event.origintype.size() > 0)
- os << " origintype: " << event.origintype << std::endl;
- _dataIndentation++;
- os << " data: " << (Data)event << std::endl;
- _dataIndentation--;
- return os;
+ os << (event.type == Event::EXTERNAL ? "External" : "Internal") << " Event " /* << (event.dom ? "with DOM attached" : "")*/ << std::endl;
+
+ if (event.name.size() > 0)
+ os << " name: " << event.name << std::endl;
+ if (event.origin.size() > 0)
+ os << " origin: " << event.origin << std::endl;
+ if (event.origintype.size() > 0)
+ os << " origintype: " << event.origintype << std::endl;
+ _dataIndentation++;
+ os << " data: " << (Data)event << std::endl;
+ _dataIndentation--;
+ return os;
}
#endif
#ifndef SWIGJAVA
std::ostream& operator<< (std::ostream& os, const Data& data) {
- std::string indent;
- for (int i = 0; i < _dataIndentation; i++) {
- indent += " ";
- }
- if (false) {
- } else if (data.compound.size() > 0) {
- int longestKey = 0;
- std::map<std::string, Data>::const_iterator compoundIter = data.compound.begin();
- while(compoundIter != data.compound.end()) {
- if (compoundIter->first.size() > longestKey)
- longestKey = compoundIter->first.size();
- compoundIter++;
- }
- std::string keyPadding;
- for (unsigned int i = 0; i < longestKey; i++)
- keyPadding += " ";
-
- os << "{" << std::endl;
- compoundIter = data.compound.begin();
- while(compoundIter != data.compound.end()) {
- os << indent << " \"" << compoundIter->first << "\" " << keyPadding.substr(0, longestKey - compoundIter->first.size()) << ": ";
- _dataIndentation += 2;
- os << compoundIter->second << "," << std::endl;
- _dataIndentation -= 2;
- compoundIter++;
- }
- os << indent << "}" << std::endl;
- } else if (data.array.size() > 0) {
- os << "[" << std::endl;
- std::map<std::string, Data>::const_iterator compoundIter = data.compound.begin();
- while(compoundIter != data.compound.end()) {
- _dataIndentation += 2;
- os << indent << " " << compoundIter->second << "," << std::endl;
- _dataIndentation -= 2;
- compoundIter++;
- }
- os << indent << "]" << std::endl;
- } else if (data.atom.size() > 0) {
- if (data.type == Data::VERBATIM) {
- os << indent << "\"" << data.atom << "\"";
- } else {
- os << indent << data.atom;
- }
- }
- return os;
+ std::string indent;
+ for (int i = 0; i < _dataIndentation; i++) {
+ indent += " ";
+ }
+ if (false) {
+ } else if (data.compound.size() > 0) {
+ int longestKey = 0;
+ std::map<std::string, Data>::const_iterator compoundIter = data.compound.begin();
+ while(compoundIter != data.compound.end()) {
+ if (compoundIter->first.size() > longestKey)
+ longestKey = compoundIter->first.size();
+ compoundIter++;
+ }
+ std::string keyPadding;
+ for (unsigned int i = 0; i < longestKey; i++)
+ keyPadding += " ";
+
+ os << "{" << std::endl;
+ compoundIter = data.compound.begin();
+ while(compoundIter != data.compound.end()) {
+ os << indent << " \"" << compoundIter->first << "\" " << keyPadding.substr(0, longestKey - compoundIter->first.size()) << ": ";
+ _dataIndentation += 2;
+ os << compoundIter->second << "," << std::endl;
+ _dataIndentation -= 2;
+ compoundIter++;
+ }
+ os << indent << "}" << std::endl;
+ } else if (data.array.size() > 0) {
+ os << "[" << std::endl;
+ std::map<std::string, Data>::const_iterator compoundIter = data.compound.begin();
+ while(compoundIter != data.compound.end()) {
+ _dataIndentation += 2;
+ os << indent << " " << compoundIter->second << "," << std::endl;
+ _dataIndentation -= 2;
+ compoundIter++;
+ }
+ os << indent << "]" << std::endl;
+ } else if (data.atom.size() > 0) {
+ if (data.type == Data::VERBATIM) {
+ os << indent << "\"" << data.atom << "\"";
+ } else {
+ os << indent << data.atom;
+ }
+ }
+ return os;
}
#endif
diff --git a/src/uscxml/Message.h b/src/uscxml/Message.h
index ecd2bf0..1644869 100644
--- a/src/uscxml/Message.h
+++ b/src/uscxml/Message.h
@@ -19,105 +19,110 @@ namespace uscxml {
class Data {
public:
- enum Type {
- VERBATIM,
- INTERPRETED
- };
-
- Data() {}
- Data(const std::string& atom_, Type type_ = INTERPRETED) : atom(atom_), type(type_) {}
- Data(const Arabica::DOM::Node<std::string>& dom);
- virtual ~Data() {}
-
- static Data fromXML(const std::string& xmlString);
- Arabica::DOM::Document<std::string> toDocument();
- std::string toXMLString() {
- std::stringstream ss;
- ss << toDocument();
- return ss.str();
- }
-
- std::map<std::string, Data> compound;
- std::list<Data> array;
- std::string atom;
- Type type;
+ enum Type {
+ VERBATIM,
+ INTERPRETED
+ };
+
+ Data() {}
+ Data(const std::string& atom_, Type type_ = INTERPRETED) : atom(atom_), type(type_) {}
+ Data(const Arabica::DOM::Node<std::string>& dom);
+ virtual ~Data() {}
+
+ static Data fromXML(const std::string& xmlString);
+ Arabica::DOM::Document<std::string> toDocument();
+ std::string toXMLString() {
+ std::stringstream ss;
+ ss << toDocument();
+ return ss.str();
+ }
+
+ std::map<std::string, Data> compound;
+ std::list<Data> array;
+ std::string atom;
+ Type type;
protected:
- Arabica::DOM::Document<std::string> toNode(const Arabica::DOM::Document<std::string>& factory, const Data& data);
+ Arabica::DOM::Document<std::string> toNode(const Arabica::DOM::Document<std::string>& factory, const Data& data);
#ifndef SWIGJAVA
- friend std::ostream& operator<< (std::ostream& os, const Data& data);
+ friend std::ostream& operator<< (std::ostream& os, const Data& data);
#endif
};
class Event : public Data {
public:
- enum Type {
- PLATFORM,
- INTERNAL,
- EXTERNAL
- };
-
- Event() : type(INTERNAL) {}
- Event(const Arabica::DOM::Node<std::string>& xmlString) : type(INTERNAL) {};
-
- std::string name;
- Type type;
- std::string origin;
- std::string origintype;
+ enum Type {
+ PLATFORM,
+ INTERNAL,
+ EXTERNAL
+ };
+
+ Event() : type(INTERNAL) {}
+ Event(const Arabica::DOM::Node<std::string>& xmlString) : type(INTERNAL) {};
+
+ std::string name;
+ Type type;
+ std::string origin;
+ std::string origintype;
// Arabica::DOM::Node<std::string> dom;
- std::string sendid;
- std::string invokeid;
+ std::string sendid;
+ std::string invokeid;
- static Event fromXML(const std::string& xmlString);
- Arabica::DOM::Document<std::string> toDocument();
- std::string toXMLString() {
- std::stringstream ss;
- ss << toDocument();
- return ss.str();
- }
+ static Event fromXML(const std::string& xmlString);
+ Arabica::DOM::Document<std::string> toDocument();
+ std::string toXMLString() {
+ std::stringstream ss;
+ ss << toDocument();
+ return ss.str();
+ }
#ifndef SWIGJAVA
- friend std::ostream& operator<< (std::ostream& os, const Event& event);
+ friend std::ostream& operator<< (std::ostream& os, const Event& event);
#endif
};
class InvokeRequest : public Event {
public:
- std::string type;
- std::string src;
- std::string namelist;
- bool autoForward;
- std::map<std::string, std::list<std::string> > params;
- std::string content;
-
- static InvokeRequest fromXML(const std::string& xmlString);
- Arabica::DOM::Document<std::string> toDocument();
- std::string toXMLString() {
- std::stringstream ss;
- ss << toDocument();
- return ss.str();
- }
+ std::string type;
+ std::string src;
+ std::string namelist;
+ typedef std::map<std::string, std::string> namelist_t;
+ bool autoForward;
+ std::multimap<std::string, std::string> params;
+ typedef std::multimap<std::string, std::string> params_t;
+
+ std::string content;
+
+ static InvokeRequest fromXML(const std::string& xmlString);
+ Arabica::DOM::Document<std::string> toDocument();
+ std::string toXMLString() {
+ std::stringstream ss;
+ ss << toDocument();
+ return ss.str();
+ }
};
class SendRequest : public Event {
public:
- std::string target;
- std::string type;
- uint32_t delayMs;
- std::map<std::string, std::string> namelist;
- std::map<std::string, std::list<std::string> > params;
- std::string content;
-
- static SendRequest fromXML(const std::string& xmlString);
- Arabica::DOM::Document<std::string> toDocument();
- std::string toXMLString() {
- std::stringstream ss;
- ss << toDocument();
+ std::string target;
+ std::string type;
+ uint32_t delayMs;
+ std::map<std::string, std::string> namelist;
+ typedef std::map<std::string, std::string> namelist_t;
+ std::multimap<std::string, std::string> params;
+ typedef std::multimap<std::string, std::string> params_t;
+ std::string content;
+
+ static SendRequest fromXML(const std::string& xmlString);
+ Arabica::DOM::Document<std::string> toDocument();
+ std::string toXMLString() {
+ std::stringstream ss;
+ ss << toDocument();
// std::cout << ss.str() << std::endl;
- return ss.str();
- }
+ return ss.str();
+ }
};
diff --git a/src/uscxml/URL.cpp b/src/uscxml/URL.cpp
index 991c875..8631b52 100644
--- a/src/uscxml/URL.cpp
+++ b/src/uscxml/URL.cpp
@@ -13,7 +13,7 @@
#include "URL.h"
namespace uscxml {
-
+
std::ostream & operator<<(std::ostream & stream, const URL& url) {
std::string urlString = url._urlString;
@@ -30,366 +30,355 @@ std::ostream & operator<<(std::ostream & stream, const URL& url) {
LOG(ERROR) << "Trying to open " << urlString;
URL_FILE *handle = url_fopen(urlString.c_str(), "r");
- if(!handle) {
- LOG(ERROR) << "Cannot open URL " << url._urlString;
+ if(!handle) {
+ LOG(ERROR) << "Cannot open URL " << url._urlString;
return stream;
- }
-
+ }
+
int nread;
- char buffer[256];
+ char buffer[256];
- do {
- nread = url_fread(buffer, 1,sizeof(buffer), handle);
- stream.write(buffer, nread);
- } while(nread);
+ do {
+ nread = url_fread(buffer, 1,sizeof(buffer), handle);
+ stream.write(buffer, nread);
+ } while(nread);
- url_fclose(handle);
+ url_fclose(handle);
return stream;
}
-
-/* we use a global one for convenience */
+
+/* we use a global one for convenience */
CURLM *multi_handle;
-/* curl calls this routine to get more data */
+/* curl calls this routine to get more data */
static size_t write_callback(char *buffer,
size_t size,
size_t nitems,
- void *userp)
-{
- char *newbuff;
- size_t rembuff;
-
- URL_FILE *url = (URL_FILE *)userp;
- size *= nitems;
-
- rembuff=url->buffer_len - url->buffer_pos; /* remaining space in buffer */
-
- if(size > rembuff) {
- /* not enough space in buffer */
- newbuff=(char*)realloc(url->buffer,url->buffer_len + (size - rembuff));
- if(newbuff==NULL) {
- fprintf(stderr,"callback buffer grow failed\n");
- size=rembuff;
- }
- else {
- /* realloc suceeded increase buffer size*/
- url->buffer_len+=size - rembuff;
- url->buffer=newbuff;
- }
- }
-
- memcpy(&url->buffer[url->buffer_pos], buffer, size);
- url->buffer_pos += size;
-
- return size;
+ void *userp) {
+ char *newbuff;
+ size_t rembuff;
+
+ URL_FILE *url = (URL_FILE *)userp;
+ size *= nitems;
+
+ rembuff=url->buffer_len - url->buffer_pos; /* remaining space in buffer */
+
+ if(size > rembuff) {
+ /* not enough space in buffer */
+ newbuff=(char*)realloc(url->buffer,url->buffer_len + (size - rembuff));
+ if(newbuff==NULL) {
+ fprintf(stderr,"callback buffer grow failed\n");
+ size=rembuff;
+ } else {
+ /* realloc suceeded increase buffer size*/
+ url->buffer_len+=size - rembuff;
+ url->buffer=newbuff;
+ }
+ }
+
+ memcpy(&url->buffer[url->buffer_pos], buffer, size);
+ url->buffer_pos += size;
+
+ return size;
}
-
-/* use to attempt to fill the read buffer up to requested number of bytes */
-static int fill_buffer(URL_FILE *file, size_t want)
-{
- fd_set fdread;
- fd_set fdwrite;
- fd_set fdexcep;
- struct timeval timeout;
- int rc;
-
- /* only attempt to fill buffer if transactions still running and buffer
- * doesnt exceed required size already
- */
- if((!file->still_running) || (file->buffer_pos > want))
- return 0;
-
- /* attempt to fill buffer */
- do {
- int maxfd = -1;
- long curl_timeo = -1;
-
- FD_ZERO(&fdread);
- FD_ZERO(&fdwrite);
- FD_ZERO(&fdexcep);
-
- /* set a suitable timeout to fail on */
- timeout.tv_sec = 60; /* 1 minute */
- timeout.tv_usec = 0;
-
- curl_multi_timeout(multi_handle, &curl_timeo);
- if(curl_timeo >= 0) {
- timeout.tv_sec = curl_timeo / 1000;
- if(timeout.tv_sec > 1)
- timeout.tv_sec = 1;
- else
- timeout.tv_usec = (curl_timeo % 1000) * 1000;
- }
-
- /* get file descriptors from the transfers */
- curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
-
- /* In a real-world program you OF COURSE check the return code of the
- function calls. On success, the value of maxfd is guaranteed to be
- greater or equal than -1. We call select(maxfd + 1, ...), specially
- in case of (maxfd == -1), we call select(0, ...), which is basically
- equal to sleep. */
-
- rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
-
- switch(rc) {
- case -1:
- /* select error */
- break;
-
- case 0:
- default:
- /* timeout or readable/writable sockets */
- curl_multi_perform(multi_handle, &file->still_running);
- break;
- }
- } while(file->still_running && (file->buffer_pos < want));
- return 1;
+
+/* use to attempt to fill the read buffer up to requested number of bytes */
+static int fill_buffer(URL_FILE *file, size_t want) {
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ struct timeval timeout;
+ int rc;
+
+ /* only attempt to fill buffer if transactions still running and buffer
+ * doesnt exceed required size already
+ */
+ if((!file->still_running) || (file->buffer_pos > want))
+ return 0;
+
+ /* attempt to fill buffer */
+ do {
+ int maxfd = -1;
+ long curl_timeo = -1;
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ /* set a suitable timeout to fail on */
+ timeout.tv_sec = 60; /* 1 minute */
+ timeout.tv_usec = 0;
+
+ curl_multi_timeout(multi_handle, &curl_timeo);
+ if(curl_timeo >= 0) {
+ timeout.tv_sec = curl_timeo / 1000;
+ if(timeout.tv_sec > 1)
+ timeout.tv_sec = 1;
+ else
+ timeout.tv_usec = (curl_timeo % 1000) * 1000;
+ }
+
+ /* get file descriptors from the transfers */
+ curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* In a real-world program you OF COURSE check the return code of the
+ function calls. On success, the value of maxfd is guaranteed to be
+ greater or equal than -1. We call select(maxfd + 1, ...), specially
+ in case of (maxfd == -1), we call select(0, ...), which is basically
+ equal to sleep. */
+
+ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ switch(rc) {
+ case -1:
+ /* select error */
+ break;
+
+ case 0:
+ default:
+ /* timeout or readable/writable sockets */
+ curl_multi_perform(multi_handle, &file->still_running);
+ break;
+ }
+ } while(file->still_running && (file->buffer_pos < want));
+ return 1;
}
-
-/* use to remove want bytes from the front of a files buffer */
-static int use_buffer(URL_FILE *file,int want)
-{
- /* sort out buffer */
- if((file->buffer_pos - want) <=0) {
- /* ditch buffer - write will recreate */
- if(file->buffer)
- free(file->buffer);
-
- file->buffer=NULL;
- file->buffer_pos=0;
- file->buffer_len=0;
- }
- else {
- /* move rest down make it available for later */
- memmove(file->buffer,
- &file->buffer[want],
- (file->buffer_pos - want));
-
- file->buffer_pos -= want;
- }
- return 0;
+
+/* use to remove want bytes from the front of a files buffer */
+static int use_buffer(URL_FILE *file,int want) {
+ /* sort out buffer */
+ if((file->buffer_pos - want) <=0) {
+ /* ditch buffer - write will recreate */
+ if(file->buffer)
+ free(file->buffer);
+
+ file->buffer=NULL;
+ file->buffer_pos=0;
+ file->buffer_len=0;
+ } else {
+ /* move rest down make it available for later */
+ memmove(file->buffer,
+ &file->buffer[want],
+ (file->buffer_pos - want));
+
+ file->buffer_pos -= want;
+ }
+ return 0;
}
-
-URL_FILE *url_fopen(const char *url,const char *operation)
-{
- /* this code could check for URLs or types in the 'url' and
- basicly use the real fopen() for standard files */
-
- URL_FILE *file;
- (void)operation;
-
- file = (URL_FILE*)malloc(sizeof(URL_FILE));
- if(!file)
- return NULL;
-
- memset(file, 0, sizeof(URL_FILE));
-
- if((file->handle.file=fopen(url,operation)))
- file->type = CFTYPE_FILE; /* marked as URL */
-
- else {
- file->type = CFTYPE_CURL; /* marked as URL */
- file->handle.curl = curl_easy_init();
-
- curl_easy_setopt(file->handle.curl, CURLOPT_URL, url);
- curl_easy_setopt(file->handle.curl, CURLOPT_WRITEDATA, file);
- curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE, 0L);
- curl_easy_setopt(file->handle.curl, CURLOPT_WRITEFUNCTION, write_callback);
-
- if(!multi_handle)
- multi_handle = curl_multi_init();
-
- curl_multi_add_handle(multi_handle, file->handle.curl);
-
- /* lets start the fetch */
- curl_multi_perform(multi_handle, &file->still_running);
-
- if((file->buffer_pos == 0) && (!file->still_running)) {
- /* if still_running is 0 now, we should return NULL */
-
- /* make sure the easy handle is not in the multi handle anymore */
- curl_multi_remove_handle(multi_handle, file->handle.curl);
-
- /* cleanup */
- curl_easy_cleanup(file->handle.curl);
-
- free(file);
-
- file = NULL;
- }
- }
- return file;
+
+URL_FILE *url_fopen(const char *url,const char *operation) {
+ /* this code could check for URLs or types in the 'url' and
+ basicly use the real fopen() for standard files */
+
+ URL_FILE *file;
+ (void)operation;
+
+ file = (URL_FILE*)malloc(sizeof(URL_FILE));
+ if(!file)
+ return NULL;
+
+ memset(file, 0, sizeof(URL_FILE));
+
+ if((file->handle.file=fopen(url,operation)))
+ file->type = CFTYPE_FILE; /* marked as URL */
+
+ else {
+ file->type = CFTYPE_CURL; /* marked as URL */
+ file->handle.curl = curl_easy_init();
+
+ curl_easy_setopt(file->handle.curl, CURLOPT_URL, url);
+ curl_easy_setopt(file->handle.curl, CURLOPT_WRITEDATA, file);
+ curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE, 0L);
+ curl_easy_setopt(file->handle.curl, CURLOPT_WRITEFUNCTION, write_callback);
+
+ if(!multi_handle)
+ multi_handle = curl_multi_init();
+
+ curl_multi_add_handle(multi_handle, file->handle.curl);
+
+ /* lets start the fetch */
+ curl_multi_perform(multi_handle, &file->still_running);
+
+ if((file->buffer_pos == 0) && (!file->still_running)) {
+ /* if still_running is 0 now, we should return NULL */
+
+ /* make sure the easy handle is not in the multi handle anymore */
+ curl_multi_remove_handle(multi_handle, file->handle.curl);
+
+ /* cleanup */
+ curl_easy_cleanup(file->handle.curl);
+
+ free(file);
+
+ file = NULL;
+ }
+ }
+ return file;
}
-
-int url_fclose(URL_FILE *file)
-{
- int ret=0;/* default is good return */
-
- switch(file->type) {
- case CFTYPE_FILE:
- ret=fclose(file->handle.file); /* passthrough */
- break;
-
- case CFTYPE_CURL:
- /* make sure the easy handle is not in the multi handle anymore */
- curl_multi_remove_handle(multi_handle, file->handle.curl);
-
- /* cleanup */
- curl_easy_cleanup(file->handle.curl);
- break;
-
- default: /* unknown or supported type - oh dear */
- ret=EOF;
- errno=EBADF;
- break;
- }
-
- if(file->buffer)
- free(file->buffer);/* free any allocated buffer space */
-
- free(file);
-
- return ret;
+
+int url_fclose(URL_FILE *file) {
+ int ret=0;/* default is good return */
+
+ switch(file->type) {
+ case CFTYPE_FILE:
+ ret=fclose(file->handle.file); /* passthrough */
+ break;
+
+ case CFTYPE_CURL:
+ /* make sure the easy handle is not in the multi handle anymore */
+ curl_multi_remove_handle(multi_handle, file->handle.curl);
+
+ /* cleanup */
+ curl_easy_cleanup(file->handle.curl);
+ break;
+
+ default: /* unknown or supported type - oh dear */
+ ret=EOF;
+ errno=EBADF;
+ break;
+ }
+
+ if(file->buffer)
+ free(file->buffer);/* free any allocated buffer space */
+
+ free(file);
+
+ return ret;
}
-
-int url_feof(URL_FILE *file)
-{
- int ret=0;
-
- switch(file->type) {
- case CFTYPE_FILE:
- ret=feof(file->handle.file);
- break;
-
- case CFTYPE_CURL:
- if((file->buffer_pos == 0) && (!file->still_running))
- ret = 1;
- break;
-
- default: /* unknown or supported type - oh dear */
- ret=-1;
- errno=EBADF;
- break;
- }
- return ret;
+
+int url_feof(URL_FILE *file) {
+ int ret=0;
+
+ switch(file->type) {
+ case CFTYPE_FILE:
+ ret=feof(file->handle.file);
+ break;
+
+ case CFTYPE_CURL:
+ if((file->buffer_pos == 0) && (!file->still_running))
+ ret = 1;
+ break;
+
+ default: /* unknown or supported type - oh dear */
+ ret=-1;
+ errno=EBADF;
+ break;
+ }
+ return ret;
}
-
-size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
-{
- size_t want;
-
- switch(file->type) {
- case CFTYPE_FILE:
- want=fread(ptr,size,nmemb,file->handle.file);
- break;
-
- case CFTYPE_CURL:
- want = nmemb * size;
-
- fill_buffer(file,want);
-
- /* check if theres data in the buffer - if not fill_buffer()
- * either errored or EOF */
- if(!file->buffer_pos)
- return 0;
-
- /* ensure only available data is considered */
- if(file->buffer_pos < want)
- want = file->buffer_pos;
-
- /* xfer data to caller */
- memcpy(ptr, file->buffer, want);
-
- use_buffer(file,want);
-
- want = want / size; /* number of items */
- break;
-
- default: /* unknown or supported type - oh dear */
- want=0;
- errno=EBADF;
- break;
-
- }
- return want;
+
+size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file) {
+ size_t want;
+
+ switch(file->type) {
+ case CFTYPE_FILE:
+ want=fread(ptr,size,nmemb,file->handle.file);
+ break;
+
+ case CFTYPE_CURL:
+ want = nmemb * size;
+
+ fill_buffer(file,want);
+
+ /* check if theres data in the buffer - if not fill_buffer()
+ * either errored or EOF */
+ if(!file->buffer_pos)
+ return 0;
+
+ /* ensure only available data is considered */
+ if(file->buffer_pos < want)
+ want = file->buffer_pos;
+
+ /* xfer data to caller */
+ memcpy(ptr, file->buffer, want);
+
+ use_buffer(file,want);
+
+ want = want / size; /* number of items */
+ break;
+
+ default: /* unknown or supported type - oh dear */
+ want=0;
+ errno=EBADF;
+ break;
+
+ }
+ return want;
}
-
-char *url_fgets(char *ptr, size_t size, URL_FILE *file)
-{
- size_t want = size - 1;/* always need to leave room for zero termination */
- size_t loop;
-
- switch(file->type) {
- case CFTYPE_FILE:
- ptr = fgets(ptr,size,file->handle.file);
- break;
-
- case CFTYPE_CURL:
- fill_buffer(file,want);
-
- /* check if theres data in the buffer - if not fill either errored or
- * EOF */
- if(!file->buffer_pos)
- return NULL;
-
- /* ensure only available data is considered */
- if(file->buffer_pos < want)
- want = file->buffer_pos;
-
- /*buffer contains data */
- /* look for newline or eof */
- for(loop=0;loop < want;loop++) {
- if(file->buffer[loop] == '\n') {
- want=loop+1;/* include newline */
- break;
- }
- }
-
- /* xfer data to caller */
- memcpy(ptr, file->buffer, want);
- ptr[want]=0;/* allways null terminate */
-
- use_buffer(file,want);
-
- break;
-
- default: /* unknown or supported type - oh dear */
- ptr=NULL;
- errno=EBADF;
- break;
- }
-
- return ptr;/*success */
+
+char *url_fgets(char *ptr, size_t size, URL_FILE *file) {
+ size_t want = size - 1;/* always need to leave room for zero termination */
+ size_t loop;
+
+ switch(file->type) {
+ case CFTYPE_FILE:
+ ptr = fgets(ptr,size,file->handle.file);
+ break;
+
+ case CFTYPE_CURL:
+ fill_buffer(file,want);
+
+ /* check if theres data in the buffer - if not fill either errored or
+ * EOF */
+ if(!file->buffer_pos)
+ return NULL;
+
+ /* ensure only available data is considered */
+ if(file->buffer_pos < want)
+ want = file->buffer_pos;
+
+ /*buffer contains data */
+ /* look for newline or eof */
+ for(loop=0; loop < want; loop++) {
+ if(file->buffer[loop] == '\n') {
+ want=loop+1;/* include newline */
+ break;
+ }
+ }
+
+ /* xfer data to caller */
+ memcpy(ptr, file->buffer, want);
+ ptr[want]=0;/* allways null terminate */
+
+ use_buffer(file,want);
+
+ break;
+
+ default: /* unknown or supported type - oh dear */
+ ptr=NULL;
+ errno=EBADF;
+ break;
+ }
+
+ return ptr;/*success */
}
-
-void url_rewind(URL_FILE *file)
-{
- switch(file->type) {
- case CFTYPE_FILE:
- rewind(file->handle.file); /* passthrough */
- break;
-
- case CFTYPE_CURL:
- /* halt transaction */
- curl_multi_remove_handle(multi_handle, file->handle.curl);
-
- /* restart */
- curl_multi_add_handle(multi_handle, file->handle.curl);
-
- /* ditch buffer - write will recreate - resets stream pos*/
- if(file->buffer)
- free(file->buffer);
-
- file->buffer=NULL;
- file->buffer_pos=0;
- file->buffer_len=0;
-
- break;
-
- default: /* unknown or supported type - oh dear */
- break;
- }
+
+void url_rewind(URL_FILE *file) {
+ switch(file->type) {
+ case CFTYPE_FILE:
+ rewind(file->handle.file); /* passthrough */
+ break;
+
+ case CFTYPE_CURL:
+ /* halt transaction */
+ curl_multi_remove_handle(multi_handle, file->handle.curl);
+
+ /* restart */
+ curl_multi_add_handle(multi_handle, file->handle.curl);
+
+ /* ditch buffer - write will recreate - resets stream pos*/
+ if(file->buffer)
+ free(file->buffer);
+
+ file->buffer=NULL;
+ file->buffer_pos=0;
+ file->buffer_len=0;
+
+ break;
+
+ default: /* unknown or supported type - oh dear */
+ break;
+ }
}
} \ No newline at end of file
diff --git a/src/uscxml/URL.h b/src/uscxml/URL.h
index 8438d3a..705fdb4 100644
--- a/src/uscxml/URL.h
+++ b/src/uscxml/URL.h
@@ -8,23 +8,22 @@
namespace uscxml {
enum fcurl_type_e {
- CFTYPE_NONE=0,
- CFTYPE_FILE=1,
- CFTYPE_CURL=2
+ CFTYPE_NONE=0,
+ CFTYPE_FILE=1,
+ CFTYPE_CURL=2
};
-struct fcurl_data
-{
- enum fcurl_type_e type; /* type of handle */
- union {
- CURL *curl;
- FILE *file;
- } handle; /* handle */
-
- char *buffer; /* buffer to store cached data*/
- size_t buffer_len; /* currently allocated buffers length */
- size_t buffer_pos; /* end of data in buffer*/
- int still_running; /* Is background url fetch still in progress */
+struct fcurl_data {
+ enum fcurl_type_e type; /* type of handle */
+ union {
+ CURL *curl;
+ FILE *file;
+ } handle; /* handle */
+
+ char *buffer; /* buffer to store cached data*/
+ size_t buffer_len; /* currently allocated buffers length */
+ size_t buffer_pos; /* end of data in buffer*/
+ int still_running; /* Is background url fetch still in progress */
};
typedef struct fcurl_data URL_FILE;
@@ -42,7 +41,7 @@ public:
private:
std::string _urlString;
- friend std::ostream & operator<<(std::ostream &stream, const URL& p);
+ friend std::ostream & operator<<(std::ostream &stream, const URL& p);
};
std::ostream & operator<<(std::ostream &stream, const URL& url);
diff --git a/src/uscxml/concurrency/BlockingQueue.h b/src/uscxml/concurrency/BlockingQueue.h
index 90094bf..16c23d4 100644
--- a/src/uscxml/concurrency/BlockingQueue.h
+++ b/src/uscxml/concurrency/BlockingQueue.h
@@ -12,26 +12,26 @@ class BlockingQueue {
public:
BlockingQueue() {}
virtual ~BlockingQueue() {
- }
+ }
void push(T elem) {
- tthread::lock_guard<tthread::mutex> lock(_mutex);
- _queue.push_back(elem);
- _cond.notify_all();
- }
-
+ tthread::lock_guard<tthread::mutex> lock(_mutex);
+ _queue.push_back(elem);
+ _cond.notify_all();
+ }
+
T pop() {
- tthread::lock_guard<tthread::mutex> lock(_mutex);
- while (_queue.empty()) {
- _cond.wait(_mutex);
- }
- T ret = _queue.front();
- _queue.pop_front();
- return ret;
- }
+ tthread::lock_guard<tthread::mutex> lock(_mutex);
+ while (_queue.empty()) {
+ _cond.wait(_mutex);
+ }
+ T ret = _queue.front();
+ _queue.pop_front();
+ return ret;
+ }
tthread::mutex _mutex;
- tthread::condition_variable _cond;
+ tthread::condition_variable _cond;
std::list<T> _queue;
};
diff --git a/src/uscxml/concurrency/eventqueue/DelayedEventQueue.cpp b/src/uscxml/concurrency/eventqueue/DelayedEventQueue.cpp
index e2a89b2..e582c13 100644
--- a/src/uscxml/concurrency/eventqueue/DelayedEventQueue.cpp
+++ b/src/uscxml/concurrency/eventqueue/DelayedEventQueue.cpp
@@ -4,88 +4,89 @@
namespace uscxml {
- DelayedEventQueue::DelayedEventQueue() {
+DelayedEventQueue::DelayedEventQueue() {
#ifndef _WIN32
- evthread_use_pthreads();
+ evthread_use_pthreads();
#else
- evthread_use_windows_threads();
+ evthread_use_windows_threads();
#endif
- _eventLoop = event_base_new();
- _thread = NULL;
- }
+ _eventLoop = event_base_new();
+ _thread = NULL;
+}
- DelayedEventQueue::~DelayedEventQueue() {
+DelayedEventQueue::~DelayedEventQueue() {
// std::cout << "Deleting DelayedEventQueue" << std::endl;
- stop();
- if (_thread)
- _thread->join();
- if(_eventLoop)
- event_base_free(_eventLoop);
- }
-
- void DelayedEventQueue::run(void* instance) {
- DelayedEventQueue* THIS = (DelayedEventQueue*)instance;
- int result;
- while(THIS->_isStarted) {
- {
- //result = event_base_dispatch(THIS->_eventLoop);
- result = event_base_loop(THIS->_eventLoop, EVLOOP_NO_EXIT_ON_EMPTY);
- }
- }
- }
-
- void DelayedEventQueue::addEvent(std::string eventId, void (*callback)(void*, const std::string eventId), uint32_t delayMs, void* userData) {
- if(_callbackData.find(eventId) != _callbackData.end()) {
- cancelEvent(eventId);
- }
-
- struct timeval delay = {delayMs / 1000, (delayMs % 1000) * 1000};
- struct event* event = event_new(_eventLoop, -1, 0, DelayedEventQueue::timerCallback, &_callbackData[eventId]);
-
- _callbackData[eventId].eventId = eventId;
- _callbackData[eventId].userData = userData;
- _callbackData[eventId].eventQueue = this;
- _callbackData[eventId].callback = callback;
- _callbackData[eventId].event = event;
-
- event_add(event, &delay);
- }
-
- void DelayedEventQueue::cancelEvent(std::string eventId) {
- tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
-
- if(_callbackData.find(eventId) != _callbackData.end()) {
- event_del(_callbackData[eventId].event);
- event_free(_callbackData[eventId].event);
- _callbackData.erase(eventId);
- }
- }
-
- void DelayedEventQueue::start() {
- _isStarted = true;
- _thread = new tthread::thread(DelayedEventQueue::run, this);
- }
-
- void DelayedEventQueue::stop() {
- if (_isStarted) {
- _isStarted = false;
- event_base_loopbreak(_eventLoop);
- _thread->join();
- delete _thread;
- }
- }
-
- void DelayedEventQueue::dummyCallback(evutil_socket_t fd, short what, void *arg) {
- }
-
- void DelayedEventQueue::timerCallback(evutil_socket_t fd, short what, void *arg) {
- struct callbackData *data = (struct callbackData*)arg;
- tthread::lock_guard<tthread::recursive_mutex> lock(data->eventQueue->_mutex);
-
- std::string eventId = data->eventId; // copy eventId
- event_free(data->event);
- data->callback(data->userData, eventId);
- data->eventQueue->_callbackData.erase(data->eventId);
- }
+ stop();
+ if (_thread)
+ _thread->join();
+ if(_eventLoop)
+ event_base_free(_eventLoop);
+}
+
+void DelayedEventQueue::run(void* instance) {
+ DelayedEventQueue* THIS = (DelayedEventQueue*)instance;
+ int result;
+ while(THIS->_isStarted) {
+ {
+ //result = event_base_dispatch(THIS->_eventLoop);
+ result = event_base_loop(THIS->_eventLoop, EVLOOP_NO_EXIT_ON_EMPTY);
+ (void)result;
+ }
+ }
+}
+
+void DelayedEventQueue::addEvent(std::string eventId, void (*callback)(void*, const std::string eventId), uint32_t delayMs, void* userData) {
+ if(_callbackData.find(eventId) != _callbackData.end()) {
+ cancelEvent(eventId);
+ }
+
+ struct timeval delay = {delayMs / 1000, (delayMs % 1000) * 1000};
+ struct event* event = event_new(_eventLoop, -1, 0, DelayedEventQueue::timerCallback, &_callbackData[eventId]);
+
+ _callbackData[eventId].eventId = eventId;
+ _callbackData[eventId].userData = userData;
+ _callbackData[eventId].eventQueue = this;
+ _callbackData[eventId].callback = callback;
+ _callbackData[eventId].event = event;
+
+ event_add(event, &delay);
+}
+
+void DelayedEventQueue::cancelEvent(std::string eventId) {
+ tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
+
+ if(_callbackData.find(eventId) != _callbackData.end()) {
+ event_del(_callbackData[eventId].event);
+ event_free(_callbackData[eventId].event);
+ _callbackData.erase(eventId);
+ }
+}
+
+void DelayedEventQueue::start() {
+ _isStarted = true;
+ _thread = new tthread::thread(DelayedEventQueue::run, this);
+}
+
+void DelayedEventQueue::stop() {
+ if (_isStarted) {
+ _isStarted = false;
+ event_base_loopbreak(_eventLoop);
+ _thread->join();
+ delete _thread;
+ }
+}
+
+void DelayedEventQueue::dummyCallback(evutil_socket_t fd, short what, void *arg) {
+}
+
+void DelayedEventQueue::timerCallback(evutil_socket_t fd, short what, void *arg) {
+ struct callbackData *data = (struct callbackData*)arg;
+ tthread::lock_guard<tthread::recursive_mutex> lock(data->eventQueue->_mutex);
+
+ std::string eventId = data->eventId; // copy eventId
+ event_free(data->event);
+ data->callback(data->userData, eventId);
+ data->eventQueue->_callbackData.erase(data->eventId);
+}
} \ No newline at end of file
diff --git a/src/uscxml/concurrency/eventqueue/DelayedEventQueue.h b/src/uscxml/concurrency/eventqueue/DelayedEventQueue.h
index 024e353..8825c27 100644
--- a/src/uscxml/concurrency/eventqueue/DelayedEventQueue.h
+++ b/src/uscxml/concurrency/eventqueue/DelayedEventQueue.h
@@ -17,37 +17,36 @@ namespace uscxml {
class DelayedEventQueue {
public:
-
- struct callbackData
- {
- void *userData;
- void (*callback)(void*, const std::string eventId);
- std::string eventId;
- struct event *event;
- DelayedEventQueue* eventQueue;
- };
+
+ struct callbackData {
+ void *userData;
+ void (*callback)(void*, const std::string eventId);
+ std::string eventId;
+ struct event *event;
+ DelayedEventQueue* eventQueue;
+ };
DelayedEventQueue();
virtual ~DelayedEventQueue();
-
+
void addEvent(std::string eventId, void (*callback)(void*, const std::string eventId), uint32_t delayMs, void* userData);
void cancelEvent(std::string eventId);
-
+
void start();
void stop();
static void run(void*);
- static void timerCallback(evutil_socket_t fd, short what, void *arg);
- static void dummyCallback(evutil_socket_t fd, short what, void *arg);
+ static void timerCallback(evutil_socket_t fd, short what, void *arg);
+ static void dummyCallback(evutil_socket_t fd, short what, void *arg);
- bool _isStarted;
- tthread::thread* _thread;
- tthread::recursive_mutex _mutex;
-
- std::map<std::string, callbackData> _callbackData;
+ bool _isStarted;
+ tthread::thread* _thread;
+ tthread::recursive_mutex _mutex;
+
+ std::map<std::string, callbackData> _callbackData;
struct event_base* _eventLoop;
};
-
+
}
diff --git a/src/uscxml/concurrency/tinythread.cpp b/src/uscxml/concurrency/tinythread.cpp
index 690ecee..c4bab68 100644
--- a/src/uscxml/concurrency/tinythread.cpp
+++ b/src/uscxml/concurrency/tinythread.cpp
@@ -25,10 +25,10 @@ freely, subject to the following restrictions:
#include "tinythread.h"
#if defined(_TTHREAD_POSIX_)
- #include <unistd.h>
- #include <map>
+#include <unistd.h>
+#include <map>
#elif defined(_TTHREAD_WIN32_)
- #include <process.h>
+#include <process.h>
#endif
@@ -49,73 +49,68 @@ namespace tthread {
//------------------------------------------------------------------------------
#if defined(_TTHREAD_WIN32_)
- #define _CONDITION_EVENT_ONE 0
- #define _CONDITION_EVENT_ALL 1
+#define _CONDITION_EVENT_ONE 0
+#define _CONDITION_EVENT_ALL 1
#endif
#if defined(_TTHREAD_WIN32_)
-condition_variable::condition_variable() : mWaitersCount(0)
-{
- mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL);
- mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL);
- InitializeCriticalSection(&mWaitersCountLock);
+condition_variable::condition_variable() : mWaitersCount(0) {
+ mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL);
+ mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL);
+ InitializeCriticalSection(&mWaitersCountLock);
}
#endif
#if defined(_TTHREAD_WIN32_)
-condition_variable::~condition_variable()
-{
- CloseHandle(mEvents[_CONDITION_EVENT_ONE]);
- CloseHandle(mEvents[_CONDITION_EVENT_ALL]);
- DeleteCriticalSection(&mWaitersCountLock);
+condition_variable::~condition_variable() {
+ CloseHandle(mEvents[_CONDITION_EVENT_ONE]);
+ CloseHandle(mEvents[_CONDITION_EVENT_ALL]);
+ DeleteCriticalSection(&mWaitersCountLock);
}
#endif
#if defined(_TTHREAD_WIN32_)
-void condition_variable::_wait()
-{
- // Wait for either event to become signaled due to notify_one() or
- // notify_all() being called
- int result = WaitForMultipleObjects(2, mEvents, FALSE, INFINITE);
-
- // Check if we are the last waiter
- EnterCriticalSection(&mWaitersCountLock);
- -- mWaitersCount;
- bool lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) &&
- (mWaitersCount == 0);
- LeaveCriticalSection(&mWaitersCountLock);
-
- // If we are the last waiter to be notified to stop waiting, reset the event
- if(lastWaiter)
- ResetEvent(mEvents[_CONDITION_EVENT_ALL]);
+void condition_variable::_wait() {
+ // Wait for either event to become signaled due to notify_one() or
+ // notify_all() being called
+ int result = WaitForMultipleObjects(2, mEvents, FALSE, INFINITE);
+
+ // Check if we are the last waiter
+ EnterCriticalSection(&mWaitersCountLock);
+ -- mWaitersCount;
+ bool lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) &&
+ (mWaitersCount == 0);
+ LeaveCriticalSection(&mWaitersCountLock);
+
+ // If we are the last waiter to be notified to stop waiting, reset the event
+ if(lastWaiter)
+ ResetEvent(mEvents[_CONDITION_EVENT_ALL]);
}
#endif
#if defined(_TTHREAD_WIN32_)
-void condition_variable::notify_one()
-{
- // Are there any waiters?
- EnterCriticalSection(&mWaitersCountLock);
- bool haveWaiters = (mWaitersCount > 0);
- LeaveCriticalSection(&mWaitersCountLock);
-
- // If we have any waiting threads, send them a signal
- if(haveWaiters)
- SetEvent(mEvents[_CONDITION_EVENT_ONE]);
+void condition_variable::notify_one() {
+ // Are there any waiters?
+ EnterCriticalSection(&mWaitersCountLock);
+ bool haveWaiters = (mWaitersCount > 0);
+ LeaveCriticalSection(&mWaitersCountLock);
+
+ // If we have any waiting threads, send them a signal
+ if(haveWaiters)
+ SetEvent(mEvents[_CONDITION_EVENT_ONE]);
}
#endif
#if defined(_TTHREAD_WIN32_)
-void condition_variable::notify_all()
-{
- // Are there any waiters?
- EnterCriticalSection(&mWaitersCountLock);
- bool haveWaiters = (mWaitersCount > 0);
- LeaveCriticalSection(&mWaitersCountLock);
-
- // If we have any waiting threads, send them a signal
- if(haveWaiters)
- SetEvent(mEvents[_CONDITION_EVENT_ALL]);
+void condition_variable::notify_all() {
+ // Are there any waiters?
+ EnterCriticalSection(&mWaitersCountLock);
+ bool haveWaiters = (mWaitersCount > 0);
+ LeaveCriticalSection(&mWaitersCountLock);
+
+ // If we have any waiting threads, send them a signal
+ if(haveWaiters)
+ SetEvent(mEvents[_CONDITION_EVENT_ALL]);
}
#endif
@@ -128,16 +123,15 @@ void condition_variable::notify_all()
//------------------------------------------------------------------------------
#if defined(_TTHREAD_POSIX_)
-static thread::id _pthread_t_to_ID(const pthread_t &aHandle)
-{
- static mutex idMapLock;
- static std::map<pthread_t, unsigned long int> idMap;
- static unsigned long int idCount(1);
-
- lock_guard<mutex> guard(idMapLock);
- if(idMap.find(aHandle) == idMap.end())
- idMap[aHandle] = idCount ++;
- return thread::id(idMap[aHandle]);
+static thread::id _pthread_t_to_ID(const pthread_t &aHandle) {
+ static mutex idMapLock;
+ static std::map<pthread_t, unsigned long int> idMap;
+ static unsigned long int idCount(1);
+
+ lock_guard<mutex> guard(idMapLock);
+ if(idMap.find(aHandle) == idMap.end())
+ idMap[aHandle] = idCount ++;
+ return thread::id(idMap[aHandle]);
}
#endif // _TTHREAD_POSIX_
@@ -148,9 +142,9 @@ static thread::id _pthread_t_to_ID(const pthread_t &aHandle)
/// Information to pass to the new thread (what to run).
struct _thread_start_info {
- void (*mFunction)(void *); ///< Pointer to the function to be executed.
- void * mArg; ///< Function argument for the thread function.
- thread * mThread; ///< Pointer to the thread object.
+ void (*mFunction)(void *); ///< Pointer to the function to be executed.
+ void * mArg; ///< Function argument for the thread function.
+ thread * mThread; ///< Pointer to the thread object.
};
// Thread wrapper function.
@@ -160,129 +154,116 @@ unsigned WINAPI thread::wrapper_function(void * aArg)
void * thread::wrapper_function(void * aArg)
#endif
{
- // Get thread startup information
- _thread_start_info * ti = (_thread_start_info *) aArg;
-
- try
- {
- // Call the actual client thread function
- ti->mFunction(ti->mArg);
- }
- catch(...)
- {
- // Uncaught exceptions will terminate the application (default behavior
- // according to C++11)
- std::terminate();
- }
-
- // The thread is no longer executing
- lock_guard<mutex> guard(ti->mThread->mDataMutex);
- ti->mThread->mNotAThread = true;
-
- // The thread is responsible for freeing the startup information
- delete ti;
-
- return 0;
+ // Get thread startup information
+ _thread_start_info * ti = (_thread_start_info *) aArg;
+
+ try {
+ // Call the actual client thread function
+ ti->mFunction(ti->mArg);
+ } catch(...) {
+ // Uncaught exceptions will terminate the application (default behavior
+ // according to C++11)
+ std::terminate();
+ }
+
+ // The thread is no longer executing
+ lock_guard<mutex> guard(ti->mThread->mDataMutex);
+ ti->mThread->mNotAThread = true;
+
+ // The thread is responsible for freeing the startup information
+ delete ti;
+
+ return 0;
}
-thread::thread(void (*aFunction)(void *), void * aArg)
-{
- // Serialize access to this thread structure
- lock_guard<mutex> guard(mDataMutex);
+thread::thread(void (*aFunction)(void *), void * aArg) {
+ // Serialize access to this thread structure
+ lock_guard<mutex> guard(mDataMutex);
- // Fill out the thread startup information (passed to the thread wrapper,
- // which will eventually free it)
- _thread_start_info * ti = new _thread_start_info;
- ti->mFunction = aFunction;
- ti->mArg = aArg;
- ti->mThread = this;
+ // Fill out the thread startup information (passed to the thread wrapper,
+ // which will eventually free it)
+ _thread_start_info * ti = new _thread_start_info;
+ ti->mFunction = aFunction;
+ ti->mArg = aArg;
+ ti->mThread = this;
- // The thread is now alive
- mNotAThread = false;
+ // The thread is now alive
+ mNotAThread = false;
- // Create the thread
+ // Create the thread
#if defined(_TTHREAD_WIN32_)
- mHandle = (HANDLE) _beginthreadex(0, 0, wrapper_function, (void *) ti, 0, &mWin32ThreadID);
+ mHandle = (HANDLE) _beginthreadex(0, 0, wrapper_function, (void *) ti, 0, &mWin32ThreadID);
#elif defined(_TTHREAD_POSIX_)
- if(pthread_create(&mHandle, NULL, wrapper_function, (void *) ti) != 0)
- mHandle = 0;
+ if(pthread_create(&mHandle, NULL, wrapper_function, (void *) ti) != 0)
+ mHandle = 0;
#endif
- // Did we fail to create the thread?
- if(!mHandle)
- {
- mNotAThread = true;
- delete ti;
- }
+ // Did we fail to create the thread?
+ if(!mHandle) {
+ mNotAThread = true;
+ delete ti;
+ }
}
-thread::~thread()
-{
- if(joinable())
- std::terminate();
+thread::~thread() {
+ if(joinable())
+ std::terminate();
}
-void thread::join()
-{
- if(joinable())
- {
+void thread::join() {
+ if(joinable()) {
#if defined(_TTHREAD_WIN32_)
- WaitForSingleObject(mHandle, INFINITE);
- CloseHandle(mHandle);
+ WaitForSingleObject(mHandle, INFINITE);
+ CloseHandle(mHandle);
#elif defined(_TTHREAD_POSIX_)
- pthread_join(mHandle, NULL);
+ pthread_join(mHandle, NULL);
#endif
- }
+ }
}
-bool thread::joinable() const
-{
- mDataMutex.lock();
- bool result = !mNotAThread;
- mDataMutex.unlock();
- return result;
+bool thread::joinable() const {
+ mDataMutex.lock();
+ bool result = !mNotAThread;
+ mDataMutex.unlock();
+ return result;
}
-void thread::detach()
-{
- mDataMutex.lock();
- if(!mNotAThread)
- {
+void thread::detach() {
+ mDataMutex.lock();
+ if(!mNotAThread) {
#if defined(_TTHREAD_WIN32_)
- CloseHandle(mHandle);
+ CloseHandle(mHandle);
#elif defined(_TTHREAD_POSIX_)
- pthread_detach(mHandle);
+ pthread_detach(mHandle);
#endif
- mNotAThread = true;
- }
- mDataMutex.unlock();
+ mNotAThread = true;
+ }
+ mDataMutex.unlock();
}
-thread::id thread::get_id() const
-{
- if(!joinable())
- return id();
+thread::id thread::get_id() const {
+ if(!joinable())
+ return id();
#if defined(_TTHREAD_WIN32_)
- return id((unsigned long int) mWin32ThreadID);
+ return id((unsigned long int) mWin32ThreadID);
#elif defined(_TTHREAD_POSIX_)
- return _pthread_t_to_ID(mHandle);
+ return _pthread_t_to_ID(mHandle);
#endif
}
-unsigned thread::hardware_concurrency()
-{
+unsigned thread::hardware_concurrency() {
#if defined(_TTHREAD_WIN32_)
- SYSTEM_INFO si;
- GetSystemInfo(&si);
- return (int) si.dwNumberOfProcessors;
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ return (int) si.dwNumberOfProcessors;
#elif defined(_SC_NPROCESSORS_ONLN)
- return (int) sysconf(_SC_NPROCESSORS_ONLN);
+ return (int) sysconf(_SC_NPROCESSORS_ONLN);
#elif defined(_SC_NPROC_ONLN)
- return (int) sysconf(_SC_NPROC_ONLN);
+ return (int) sysconf(_SC_NPROC_ONLN);
#else
- // The standard requires this function to return zero if the number of
- // hardware cores could not be determined.
- return 0;
+ // The standard requires this function to return zero if the number of
+ // hardware cores could not be determined.
+ return 0;
#endif
}
@@ -291,12 +272,11 @@ unsigned thread::hardware_concurrency()
// this_thread
//------------------------------------------------------------------------------
-thread::id this_thread::get_id()
-{
+thread::id this_thread::get_id() {
#if defined(_TTHREAD_WIN32_)
- return thread::id((unsigned long int) GetCurrentThreadId());
+ return thread::id((unsigned long int) GetCurrentThreadId());
#elif defined(_TTHREAD_POSIX_)
- return _pthread_t_to_ID(pthread_self());
+ return _pthread_t_to_ID(pthread_self());
#endif
}
diff --git a/src/uscxml/concurrency/tinythread.h b/src/uscxml/concurrency/tinythread.h
index aed7b58..2e5caa0 100644
--- a/src/uscxml/concurrency/tinythread.h
+++ b/src/uscxml/concurrency/tinythread.h
@@ -57,30 +57,30 @@ freely, subject to the following restrictions:
// Which platform are we on?
#if !defined(_TTHREAD_PLATFORM_DEFINED_)
- #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
- #define _TTHREAD_WIN32_
- #else
- #define _TTHREAD_POSIX_
- #endif
- #define _TTHREAD_PLATFORM_DEFINED_
+#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
+#define _TTHREAD_WIN32_
+#else
+#define _TTHREAD_POSIX_
+#endif
+#define _TTHREAD_PLATFORM_DEFINED_
#endif
// Platform specific includes
#if defined(_TTHREAD_WIN32_)
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
- #define __UNDEF_LEAN_AND_MEAN
- #endif
- #include <windows.h>
- #ifdef __UNDEF_LEAN_AND_MEAN
- #undef WIN32_LEAN_AND_MEAN
- #undef __UNDEF_LEAN_AND_MEAN
- #endif
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#define __UNDEF_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#ifdef __UNDEF_LEAN_AND_MEAN
+#undef WIN32_LEAN_AND_MEAN
+#undef __UNDEF_LEAN_AND_MEAN
+#endif
#else
- #include <pthread.h>
- #include <signal.h>
- #include <sched.h>
- #include <unistd.h>
+#include <pthread.h>
+#include <signal.h>
+#include <sched.h>
+#include <unistd.h>
#endif
// Generic includes
@@ -95,21 +95,21 @@ freely, subject to the following restrictions:
// Do we have a fully featured C++11 compiler?
#if (__cplusplus > 199711L) || (defined(__STDCXX_VERSION__) && (__STDCXX_VERSION__ >= 201001L))
- #define _TTHREAD_CPP11_
+#define _TTHREAD_CPP11_
#endif
// ...at least partial C++11?
#if defined(_TTHREAD_CPP11_) || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__)
- #define _TTHREAD_CPP11_PARTIAL_
+#define _TTHREAD_CPP11_PARTIAL_
#endif
// Macro for disabling assignments of objects.
#ifdef _TTHREAD_CPP11_PARTIAL_
- #define _TTHREAD_DISABLE_ASSIGNMENT(name) \
+#define _TTHREAD_DISABLE_ASSIGNMENT(name) \
name(const name&) = delete; \
name& operator=(const name&) = delete;
#else
- #define _TTHREAD_DISABLE_ASSIGNMENT(name) \
+#define _TTHREAD_DISABLE_ASSIGNMENT(name) \
name(const name&); \
name& operator=(const name&);
#endif
@@ -136,11 +136,11 @@ freely, subject to the following restrictions:
/// @hideinitializer
#if !defined(_TTHREAD_CPP11_) && !defined(thread_local)
- #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
- #define thread_local __thread
- #else
- #define thread_local __declspec(thread)
- #endif
+#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
+#define thread_local __thread
+#else
+#define thread_local __declspec(thread)
+#endif
#endif
@@ -157,89 +157,84 @@ namespace tthread {
/// on that object).
/// @see recursive_mutex
class mutex {
- public:
- /// Constructor.
- mutex()
+public:
+ /// Constructor.
+ mutex()
#if defined(_TTHREAD_WIN32_)
- : mAlreadyLocked(false)
+ : mAlreadyLocked(false)
#endif
- {
+ {
#if defined(_TTHREAD_WIN32_)
- InitializeCriticalSection(&mHandle);
+ InitializeCriticalSection(&mHandle);
#else
- pthread_mutex_init(&mHandle, NULL);
+ pthread_mutex_init(&mHandle, NULL);
#endif
- }
+ }
- /// Destructor.
- ~mutex()
- {
+ /// Destructor.
+ ~mutex() {
#if defined(_TTHREAD_WIN32_)
- DeleteCriticalSection(&mHandle);
+ DeleteCriticalSection(&mHandle);
#else
- pthread_mutex_destroy(&mHandle);
+ pthread_mutex_destroy(&mHandle);
#endif
- }
+ }
- /// Lock the mutex.
- /// The method will block the calling thread until a lock on the mutex can
- /// be obtained. The mutex remains locked until @c unlock() is called.
- /// @see lock_guard
- inline void lock()
- {
+ /// Lock the mutex.
+ /// The method will block the calling thread until a lock on the mutex can
+ /// be obtained. The mutex remains locked until @c unlock() is called.
+ /// @see lock_guard
+ inline void lock() {
#if defined(_TTHREAD_WIN32_)
- EnterCriticalSection(&mHandle);
- while(mAlreadyLocked) Sleep(1000); // Simulate deadlock...
- mAlreadyLocked = true;
+ EnterCriticalSection(&mHandle);
+ while(mAlreadyLocked) Sleep(1000); // Simulate deadlock...
+ mAlreadyLocked = true;
#else
- pthread_mutex_lock(&mHandle);
+ pthread_mutex_lock(&mHandle);
#endif
- }
-
- /// Try to lock the mutex.
- /// The method will try to lock the mutex. If it fails, the function will
- /// return immediately (non-blocking).
- /// @return @c true if the lock was acquired, or @c false if the lock could
- /// not be acquired.
- inline bool try_lock()
- {
+ }
+
+ /// Try to lock the mutex.
+ /// The method will try to lock the mutex. If it fails, the function will
+ /// return immediately (non-blocking).
+ /// @return @c true if the lock was acquired, or @c false if the lock could
+ /// not be acquired.
+ inline bool try_lock() {
#if defined(_TTHREAD_WIN32_)
- bool ret = (TryEnterCriticalSection(&mHandle) ? true : false);
- if(ret && mAlreadyLocked)
- {
- LeaveCriticalSection(&mHandle);
- ret = false;
- }
- return ret;
+ bool ret = (TryEnterCriticalSection(&mHandle) ? true : false);
+ if(ret && mAlreadyLocked) {
+ LeaveCriticalSection(&mHandle);
+ ret = false;
+ }
+ return ret;
#else
- return (pthread_mutex_trylock(&mHandle) == 0) ? true : false;
+ return (pthread_mutex_trylock(&mHandle) == 0) ? true : false;
#endif
- }
+ }
- /// Unlock the mutex.
- /// If any threads are waiting for the lock on this mutex, one of them will
- /// be unblocked.
- inline void unlock()
- {
+ /// Unlock the mutex.
+ /// If any threads are waiting for the lock on this mutex, one of them will
+ /// be unblocked.
+ inline void unlock() {
#if defined(_TTHREAD_WIN32_)
- mAlreadyLocked = false;
- LeaveCriticalSection(&mHandle);
+ mAlreadyLocked = false;
+ LeaveCriticalSection(&mHandle);
#else
- pthread_mutex_unlock(&mHandle);
+ pthread_mutex_unlock(&mHandle);
#endif
- }
+ }
- _TTHREAD_DISABLE_ASSIGNMENT(mutex)
+ _TTHREAD_DISABLE_ASSIGNMENT(mutex)
- private:
+private:
#if defined(_TTHREAD_WIN32_)
- CRITICAL_SECTION mHandle;
- bool mAlreadyLocked;
+ CRITICAL_SECTION mHandle;
+ bool mAlreadyLocked;
#else
- pthread_mutex_t mHandle;
+ pthread_mutex_t mHandle;
#endif
- friend class condition_variable;
+ friend class condition_variable;
};
/// Recursive mutex class.
@@ -249,79 +244,74 @@ class mutex {
/// number of times).
/// @see mutex
class recursive_mutex {
- public:
- /// Constructor.
- recursive_mutex()
- {
+public:
+ /// Constructor.
+ recursive_mutex() {
#if defined(_TTHREAD_WIN32_)
- InitializeCriticalSection(&mHandle);
+ InitializeCriticalSection(&mHandle);
#else
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&mHandle, &attr);
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&mHandle, &attr);
#endif
- }
+ }
- /// Destructor.
- ~recursive_mutex()
- {
+ /// Destructor.
+ ~recursive_mutex() {
#if defined(_TTHREAD_WIN32_)
- DeleteCriticalSection(&mHandle);
+ DeleteCriticalSection(&mHandle);
#else
- pthread_mutex_destroy(&mHandle);
+ pthread_mutex_destroy(&mHandle);
#endif
- }
+ }
- /// Lock the mutex.
- /// The method will block the calling thread until a lock on the mutex can
- /// be obtained. The mutex remains locked until @c unlock() is called.
- /// @see lock_guard
- inline void lock()
- {
+ /// Lock the mutex.
+ /// The method will block the calling thread until a lock on the mutex can
+ /// be obtained. The mutex remains locked until @c unlock() is called.
+ /// @see lock_guard
+ inline void lock() {
#if defined(_TTHREAD_WIN32_)
- EnterCriticalSection(&mHandle);
+ EnterCriticalSection(&mHandle);
#else
- pthread_mutex_lock(&mHandle);
+ pthread_mutex_lock(&mHandle);
#endif
- }
-
- /// Try to lock the mutex.
- /// The method will try to lock the mutex. If it fails, the function will
- /// return immediately (non-blocking).
- /// @return @c true if the lock was acquired, or @c false if the lock could
- /// not be acquired.
- inline bool try_lock()
- {
+ }
+
+ /// Try to lock the mutex.
+ /// The method will try to lock the mutex. If it fails, the function will
+ /// return immediately (non-blocking).
+ /// @return @c true if the lock was acquired, or @c false if the lock could
+ /// not be acquired.
+ inline bool try_lock() {
#if defined(_TTHREAD_WIN32_)
- return TryEnterCriticalSection(&mHandle) ? true : false;
+ return TryEnterCriticalSection(&mHandle) ? true : false;
#else
- return (pthread_mutex_trylock(&mHandle) == 0) ? true : false;
+ return (pthread_mutex_trylock(&mHandle) == 0) ? true : false;
#endif
- }
+ }
- /// Unlock the mutex.
- /// If any threads are waiting for the lock on this mutex, one of them will
- /// be unblocked.
- inline void unlock()
- {
+ /// Unlock the mutex.
+ /// If any threads are waiting for the lock on this mutex, one of them will
+ /// be unblocked.
+ inline void unlock() {
#if defined(_TTHREAD_WIN32_)
- LeaveCriticalSection(&mHandle);
+ LeaveCriticalSection(&mHandle);
#else
- pthread_mutex_unlock(&mHandle);
+ pthread_mutex_unlock(&mHandle);
#endif
- }
+ }
- _TTHREAD_DISABLE_ASSIGNMENT(recursive_mutex)
+ _TTHREAD_DISABLE_ASSIGNMENT(recursive_mutex)
- private:
+private:
#if defined(_TTHREAD_WIN32_)
- CRITICAL_SECTION mHandle;
+ CRITICAL_SECTION mHandle;
#else
- pthread_mutex_t mHandle;
+ pthread_mutex_t mHandle;
#endif
- friend class condition_variable;
+ friend class condition_variable;
};
/// Lock guard class.
@@ -341,27 +331,25 @@ class recursive_mutex {
template <class T>
class lock_guard {
- public:
- typedef T mutex_type;
-
- lock_guard() : mMutex(0) {}
-
- /// The constructor locks the mutex.
- explicit lock_guard(mutex_type &aMutex)
- {
- mMutex = &aMutex;
- mMutex->lock();
- }
-
- /// The destructor unlocks the mutex.
- ~lock_guard()
- {
- if(mMutex)
- mMutex->unlock();
- }
-
- private:
- mutex_type * mMutex;
+public:
+ typedef T mutex_type;
+
+ lock_guard() : mMutex(0) {}
+
+ /// The constructor locks the mutex.
+ explicit lock_guard(mutex_type &aMutex) {
+ mMutex = &aMutex;
+ mMutex->lock();
+ }
+
+ /// The destructor unlocks the mutex.
+ ~lock_guard() {
+ if(mMutex)
+ mMutex->unlock();
+ }
+
+private:
+ mutex_type * mMutex;
};
/// Condition variable class.
@@ -390,179 +378,173 @@ class lock_guard {
/// }
/// @endcode
class condition_variable {
- public:
- /// Constructor.
+public:
+ /// Constructor.
#if defined(_TTHREAD_WIN32_)
- condition_variable();
+ condition_variable();
#else
- condition_variable()
- {
- pthread_cond_init(&mHandle, NULL);
- }
+ condition_variable() {
+ pthread_cond_init(&mHandle, NULL);
+ }
#endif
- /// Destructor.
+ /// Destructor.
#if defined(_TTHREAD_WIN32_)
- ~condition_variable();
+ ~condition_variable();
#else
- ~condition_variable()
- {
- pthread_cond_destroy(&mHandle);
- }
-#endif
-
- /// Wait for the condition.
- /// The function will block the calling thread until the condition variable
- /// is woken by @c notify_one(), @c notify_all() or a spurious wake up.
- /// @param[in] aMutex A mutex that will be unlocked when the wait operation
- /// starts, an locked again as soon as the wait operation is finished.
- template <class _mutexT>
- inline void wait(_mutexT &aMutex)
- {
+ ~condition_variable() {
+ pthread_cond_destroy(&mHandle);
+ }
+#endif
+
+ /// Wait for the condition.
+ /// The function will block the calling thread until the condition variable
+ /// is woken by @c notify_one(), @c notify_all() or a spurious wake up.
+ /// @param[in] aMutex A mutex that will be unlocked when the wait operation
+ /// starts, an locked again as soon as the wait operation is finished.
+ template <class _mutexT>
+ inline void wait(_mutexT &aMutex) {
#if defined(_TTHREAD_WIN32_)
- // Increment number of waiters
- EnterCriticalSection(&mWaitersCountLock);
- ++ mWaitersCount;
- LeaveCriticalSection(&mWaitersCountLock);
-
- // Release the mutex while waiting for the condition (will decrease
- // the number of waiters when done)...
- aMutex.unlock();
- _wait();
- aMutex.lock();
+ // Increment number of waiters
+ EnterCriticalSection(&mWaitersCountLock);
+ ++ mWaitersCount;
+ LeaveCriticalSection(&mWaitersCountLock);
+
+ // Release the mutex while waiting for the condition (will decrease
+ // the number of waiters when done)...
+ aMutex.unlock();
+ _wait();
+ aMutex.lock();
#else
- pthread_cond_wait(&mHandle, &aMutex.mHandle);
+ pthread_cond_wait(&mHandle, &aMutex.mHandle);
#endif
- }
+ }
- /// Notify one thread that is waiting for the condition.
- /// If at least one thread is blocked waiting for this condition variable,
- /// one will be woken up.
- /// @note Only threads that started waiting prior to this call will be
- /// woken up.
+ /// Notify one thread that is waiting for the condition.
+ /// If at least one thread is blocked waiting for this condition variable,
+ /// one will be woken up.
+ /// @note Only threads that started waiting prior to this call will be
+ /// woken up.
#if defined(_TTHREAD_WIN32_)
- void notify_one();
+ void notify_one();
#else
- inline void notify_one()
- {
- pthread_cond_signal(&mHandle);
- }
+ inline void notify_one() {
+ pthread_cond_signal(&mHandle);
+ }
#endif
- /// Notify all threads that are waiting for the condition.
- /// All threads that are blocked waiting for this condition variable will
- /// be woken up.
- /// @note Only threads that started waiting prior to this call will be
- /// woken up.
+ /// Notify all threads that are waiting for the condition.
+ /// All threads that are blocked waiting for this condition variable will
+ /// be woken up.
+ /// @note Only threads that started waiting prior to this call will be
+ /// woken up.
#if defined(_TTHREAD_WIN32_)
- void notify_all();
+ void notify_all();
#else
- inline void notify_all()
- {
- pthread_cond_broadcast(&mHandle);
- }
+ inline void notify_all() {
+ pthread_cond_broadcast(&mHandle);
+ }
#endif
- _TTHREAD_DISABLE_ASSIGNMENT(condition_variable)
+ _TTHREAD_DISABLE_ASSIGNMENT(condition_variable)
- private:
+private:
#if defined(_TTHREAD_WIN32_)
- void _wait();
- HANDLE mEvents[2]; ///< Signal and broadcast event HANDLEs.
- unsigned int mWaitersCount; ///< Count of the number of waiters.
- CRITICAL_SECTION mWaitersCountLock; ///< Serialize access to mWaitersCount.
+ void _wait();
+ HANDLE mEvents[2]; ///< Signal and broadcast event HANDLEs.
+ unsigned int mWaitersCount; ///< Count of the number of waiters.
+ CRITICAL_SECTION mWaitersCountLock; ///< Serialize access to mWaitersCount.
#else
- pthread_cond_t mHandle;
+ pthread_cond_t mHandle;
#endif
};
/// Thread class.
class thread {
- public:
+public:
#if defined(_TTHREAD_WIN32_)
- typedef HANDLE native_handle_type;
+ typedef HANDLE native_handle_type;
#else
- typedef pthread_t native_handle_type;
+ typedef pthread_t native_handle_type;
#endif
- class id;
+ class id;
- /// Default constructor.
- /// Construct a @c thread object without an associated thread of execution
- /// (i.e. non-joinable).
- thread() : mHandle(0), mNotAThread(true)
+ /// Default constructor.
+ /// Construct a @c thread object without an associated thread of execution
+ /// (i.e. non-joinable).
+ thread() : mHandle(0), mNotAThread(true)
#if defined(_TTHREAD_WIN32_)
- , mWin32ThreadID(0)
-#endif
- {}
-
- /// Thread starting constructor.
- /// Construct a @c thread object with a new thread of execution.
- /// @param[in] aFunction A function pointer to a function of type:
- /// <tt>void fun(void * arg)</tt>
- /// @param[in] aArg Argument to the thread function.
- /// @note This constructor is not fully compatible with the standard C++
- /// thread class. It is more similar to the pthread_create() (POSIX) and
- /// CreateThread() (Windows) functions.
- thread(void (*aFunction)(void *), void * aArg);
-
- /// Destructor.
- /// @note If the thread is joinable upon destruction, @c std::terminate()
- /// will be called, which terminates the process. It is always wise to do
- /// @c join() before deleting a thread object.
- ~thread();
-
- /// Wait for the thread to finish (join execution flows).
- /// After calling @c join(), the thread object is no longer associated with
- /// a thread of execution (i.e. it is not joinable, and you may not join
- /// with it nor detach from it).
- void join();
-
- /// Check if the thread is joinable.
- /// A thread object is joinable if it has an associated thread of execution.
- bool joinable() const;
-
- /// Detach from the thread.
- /// After calling @c detach(), the thread object is no longer assicated with
- /// a thread of execution (i.e. it is not joinable). The thread continues
- /// execution without the calling thread blocking, and when the thread
- /// ends execution, any owned resources are released.
- void detach();
-
- /// Return the thread ID of a thread object.
- id get_id() const;
-
- /// Get the native handle for this thread.
- /// @note Under Windows, this is a @c HANDLE, and under POSIX systems, this
- /// is a @c pthread_t.
- inline native_handle_type native_handle()
- {
- return mHandle;
- }
-
- /// Determine the number of threads which can possibly execute concurrently.
- /// This function is useful for determining the optimal number of threads to
- /// use for a task.
- /// @return The number of hardware thread contexts in the system.
- /// @note If this value is not defined, the function returns zero (0).
- static unsigned hardware_concurrency();
-
- _TTHREAD_DISABLE_ASSIGNMENT(thread)
-
- private:
- native_handle_type mHandle; ///< Thread handle.
- mutable mutex mDataMutex; ///< Serializer for access to the thread private data.
- bool mNotAThread; ///< True if this object is not a thread of execution.
+ , mWin32ThreadID(0)
+#endif
+ {}
+
+ /// Thread starting constructor.
+ /// Construct a @c thread object with a new thread of execution.
+ /// @param[in] aFunction A function pointer to a function of type:
+ /// <tt>void fun(void * arg)</tt>
+ /// @param[in] aArg Argument to the thread function.
+ /// @note This constructor is not fully compatible with the standard C++
+ /// thread class. It is more similar to the pthread_create() (POSIX) and
+ /// CreateThread() (Windows) functions.
+ thread(void (*aFunction)(void *), void * aArg);
+
+ /// Destructor.
+ /// @note If the thread is joinable upon destruction, @c std::terminate()
+ /// will be called, which terminates the process. It is always wise to do
+ /// @c join() before deleting a thread object.
+ ~thread();
+
+ /// Wait for the thread to finish (join execution flows).
+ /// After calling @c join(), the thread object is no longer associated with
+ /// a thread of execution (i.e. it is not joinable, and you may not join
+ /// with it nor detach from it).
+ void join();
+
+ /// Check if the thread is joinable.
+ /// A thread object is joinable if it has an associated thread of execution.
+ bool joinable() const;
+
+ /// Detach from the thread.
+ /// After calling @c detach(), the thread object is no longer assicated with
+ /// a thread of execution (i.e. it is not joinable). The thread continues
+ /// execution without the calling thread blocking, and when the thread
+ /// ends execution, any owned resources are released.
+ void detach();
+
+ /// Return the thread ID of a thread object.
+ id get_id() const;
+
+ /// Get the native handle for this thread.
+ /// @note Under Windows, this is a @c HANDLE, and under POSIX systems, this
+ /// is a @c pthread_t.
+ inline native_handle_type native_handle() {
+ return mHandle;
+ }
+
+ /// Determine the number of threads which can possibly execute concurrently.
+ /// This function is useful for determining the optimal number of threads to
+ /// use for a task.
+ /// @return The number of hardware thread contexts in the system.
+ /// @note If this value is not defined, the function returns zero (0).
+ static unsigned hardware_concurrency();
+
+ _TTHREAD_DISABLE_ASSIGNMENT(thread)
+
+private:
+ native_handle_type mHandle; ///< Thread handle.
+ mutable mutex mDataMutex; ///< Serializer for access to the thread private data.
+ bool mNotAThread; ///< True if this object is not a thread of execution.
#if defined(_TTHREAD_WIN32_)
- unsigned int mWin32ThreadID; ///< Unique thread ID (filled out by _beginthreadex).
+ unsigned int mWin32ThreadID; ///< Unique thread ID (filled out by _beginthreadex).
#endif
- // This is the internal thread wrapper function.
+ // This is the internal thread wrapper function.
#if defined(_TTHREAD_WIN32_)
- static unsigned WINAPI wrapper_function(void * aArg);
+ static unsigned WINAPI wrapper_function(void * aArg);
#else
- static void * wrapper_function(void * aArg);
+ static void * wrapper_function(void * aArg);
#endif
};
@@ -570,60 +552,52 @@ class thread {
/// The thread ID is a unique identifier for each thread.
/// @see thread::get_id()
class thread::id {
- public:
- /// Default constructor.
- /// The default constructed ID is that of thread without a thread of
- /// execution.
- id() : mId(0) {};
-
- id(unsigned long int aId) : mId(aId) {};
-
- id(const id& aId) : mId(aId.mId) {};
-
- inline id & operator=(const id &aId)
- {
- mId = aId.mId;
- return *this;
- }
-
- inline friend bool operator==(const id &aId1, const id &aId2)
- {
- return (aId1.mId == aId2.mId);
- }
-
- inline friend bool operator!=(const id &aId1, const id &aId2)
- {
- return (aId1.mId != aId2.mId);
- }
-
- inline friend bool operator<=(const id &aId1, const id &aId2)
- {
- return (aId1.mId <= aId2.mId);
- }
-
- inline friend bool operator<(const id &aId1, const id &aId2)
- {
- return (aId1.mId < aId2.mId);
- }
-
- inline friend bool operator>=(const id &aId1, const id &aId2)
- {
- return (aId1.mId >= aId2.mId);
- }
-
- inline friend bool operator>(const id &aId1, const id &aId2)
- {
- return (aId1.mId > aId2.mId);
- }
-
- inline friend std::ostream& operator <<(std::ostream &os, const id &obj)
- {
- os << obj.mId;
- return os;
- }
-
- private:
- unsigned long int mId;
+public:
+ /// Default constructor.
+ /// The default constructed ID is that of thread without a thread of
+ /// execution.
+ id() : mId(0) {};
+
+ id(unsigned long int aId) : mId(aId) {};
+
+ id(const id& aId) : mId(aId.mId) {};
+
+ inline id & operator=(const id &aId) {
+ mId = aId.mId;
+ return *this;
+ }
+
+ inline friend bool operator==(const id &aId1, const id &aId2) {
+ return (aId1.mId == aId2.mId);
+ }
+
+ inline friend bool operator!=(const id &aId1, const id &aId2) {
+ return (aId1.mId != aId2.mId);
+ }
+
+ inline friend bool operator<=(const id &aId1, const id &aId2) {
+ return (aId1.mId <= aId2.mId);
+ }
+
+ inline friend bool operator<(const id &aId1, const id &aId2) {
+ return (aId1.mId < aId2.mId);
+ }
+
+ inline friend bool operator>=(const id &aId1, const id &aId2) {
+ return (aId1.mId >= aId2.mId);
+ }
+
+ inline friend bool operator>(const id &aId1, const id &aId2) {
+ return (aId1.mId > aId2.mId);
+ }
+
+ inline friend std::ostream& operator <<(std::ostream &os, const id &obj) {
+ os << obj.mId;
+ return os;
+ }
+
+private:
+ unsigned long int mId;
};
@@ -633,77 +607,76 @@ typedef long long __intmax_t;
/// Minimal implementation of the @c ratio class. This class provides enough
/// functionality to implement some basic @c chrono classes.
template <__intmax_t N, __intmax_t D = 1> class ratio {
- public:
- static double _as_double() { return double(N) / double(D); }
+public:
+ static double _as_double() {
+ return double(N) / double(D);
+ }
};
/// Minimal implementation of the @c chrono namespace.
/// The @c chrono namespace provides types for specifying time intervals.
namespace chrono {
- /// Duration template class. This class provides enough functionality to
- /// implement @c this_thread::sleep_for().
- template <class _Rep, class _Period = ratio<1> > class duration {
- private:
- _Rep rep_;
- public:
- typedef _Rep rep;
- typedef _Period period;
-
- /// Construct a duration object with the given duration.
- template <class _Rep2>
- explicit duration(const _Rep2& r) : rep_(r) {};
-
- /// Return the value of the duration object.
- rep count() const
- {
- return rep_;
- }
- };
-
- // Standard duration types.
- typedef duration<__intmax_t, ratio<1, 1000000000> > nanoseconds; ///< Duration with the unit nanoseconds.
- typedef duration<__intmax_t, ratio<1, 1000000> > microseconds; ///< Duration with the unit microseconds.
- typedef duration<__intmax_t, ratio<1, 1000> > milliseconds; ///< Duration with the unit milliseconds.
- typedef duration<__intmax_t> seconds; ///< Duration with the unit seconds.
- typedef duration<__intmax_t, ratio<60> > minutes; ///< Duration with the unit minutes.
- typedef duration<__intmax_t, ratio<3600> > hours; ///< Duration with the unit hours.
+/// Duration template class. This class provides enough functionality to
+/// implement @c this_thread::sleep_for().
+template <class _Rep, class _Period = ratio<1> > class duration {
+private:
+ _Rep rep_;
+public:
+ typedef _Rep rep;
+ typedef _Period period;
+
+ /// Construct a duration object with the given duration.
+ template <class _Rep2>
+ explicit duration(const _Rep2& r) : rep_(r) {};
+
+ /// Return the value of the duration object.
+ rep count() const {
+ return rep_;
+ }
+};
+
+// Standard duration types.
+typedef duration<__intmax_t, ratio<1, 1000000000> > nanoseconds; ///< Duration with the unit nanoseconds.
+typedef duration<__intmax_t, ratio<1, 1000000> > microseconds; ///< Duration with the unit microseconds.
+typedef duration<__intmax_t, ratio<1, 1000> > milliseconds; ///< Duration with the unit milliseconds.
+typedef duration<__intmax_t> seconds; ///< Duration with the unit seconds.
+typedef duration<__intmax_t, ratio<60> > minutes; ///< Duration with the unit minutes.
+typedef duration<__intmax_t, ratio<3600> > hours; ///< Duration with the unit hours.
}
/// The namespace @c this_thread provides methods for dealing with the
/// calling thread.
namespace this_thread {
- /// Return the thread ID of the calling thread.
- thread::id get_id();
-
- /// Yield execution to another thread.
- /// Offers the operating system the opportunity to schedule another thread
- /// that is ready to run on the current processor.
- inline void yield()
- {
+/// Return the thread ID of the calling thread.
+thread::id get_id();
+
+/// Yield execution to another thread.
+/// Offers the operating system the opportunity to schedule another thread
+/// that is ready to run on the current processor.
+inline void yield() {
#if defined(_TTHREAD_WIN32_)
- Sleep(0);
+ Sleep(0);
#else
- sched_yield();
-#endif
- }
-
- /// Blocks the calling thread for a period of time.
- /// @param[in] aTime Minimum time to put the thread to sleep.
- /// Example usage:
- /// @code
- /// // Sleep for 100 milliseconds
- /// this_thread::sleep_for(chrono::milliseconds(100));
- /// @endcode
- /// @note Supported duration types are: nanoseconds, microseconds,
- /// milliseconds, seconds, minutes and hours.
- template <class _Rep, class _Period> void sleep_for(const chrono::duration<_Rep, _Period>& aTime)
- {
+ sched_yield();
+#endif
+}
+
+/// Blocks the calling thread for a period of time.
+/// @param[in] aTime Minimum time to put the thread to sleep.
+/// Example usage:
+/// @code
+/// // Sleep for 100 milliseconds
+/// this_thread::sleep_for(chrono::milliseconds(100));
+/// @endcode
+/// @note Supported duration types are: nanoseconds, microseconds,
+/// milliseconds, seconds, minutes and hours.
+template <class _Rep, class _Period> void sleep_for(const chrono::duration<_Rep, _Period>& aTime) {
#if defined(_TTHREAD_WIN32_)
- Sleep(int(double(aTime.count()) * (1000.0 * _Period::_as_double()) + 0.5));
+ Sleep(int(double(aTime.count()) * (1000.0 * _Period::_as_double()) + 0.5));
#else
- usleep(int(double(aTime.count()) * (1000000.0 * _Period::_as_double()) + 0.5));
+ usleep(int(double(aTime.count()) * (1000000.0 * _Period::_as_double()) + 0.5));
#endif
- }
+}
}
}
diff --git a/src/uscxml/debug/SCXMLDotWriter.h b/src/uscxml/debug/SCXMLDotWriter.h
index 7ebb916..0a3c2dc 100644
--- a/src/uscxml/debug/SCXMLDotWriter.h
+++ b/src/uscxml/debug/SCXMLDotWriter.h
@@ -11,33 +11,33 @@ class Interpreter;
class SCXMLDotWriter {
public:
-
- struct ElemDetails {
- std::string name;
- std::string details;
- std::string content;
- };
-
+
+ struct ElemDetails {
+ std::string name;
+ std::string details;
+ std::string content;
+ };
+
SCXMLDotWriter(Interpreter* interpreter);
~SCXMLDotWriter();
-
- static void toDot(const std::string& filename, Interpreter* interpreter);
- void writeSCXMLElement(std::ostream& os, const Arabica::DOM::Element<std::string>& elem);
- void writeStateElement(std::ostream& os, const Arabica::DOM::Element<std::string>& elem);
- void writeTransitionElement(std::ostream& os, const Arabica::DOM::Element<std::string>& elem);
-
- std::string getDetailedLabel(const Arabica::DOM::Element<std::string>& elem, int indentation = 0);
- std::string colorForIndent(int indent);
-
- std::string idForNode(const Arabica::DOM::Node<std::string>& node);
- std::string nameForNode(const Arabica::DOM::Node<std::string>& node);
-
- static std::string getPrefix();
- static std::string dotEscape(const std::string& text);
-
- Interpreter* _interpreter;
- std::set<std::string> _knownIds;
- static int _indentation;
+
+ static void toDot(const std::string& filename, Interpreter* interpreter);
+ void writeSCXMLElement(std::ostream& os, const Arabica::DOM::Element<std::string>& elem);
+ void writeStateElement(std::ostream& os, const Arabica::DOM::Element<std::string>& elem);
+ void writeTransitionElement(std::ostream& os, const Arabica::DOM::Element<std::string>& elem);
+
+ std::string getDetailedLabel(const Arabica::DOM::Element<std::string>& elem, int indentation = 0);
+ std::string colorForIndent(int indent);
+
+ std::string idForNode(const Arabica::DOM::Node<std::string>& node);
+ std::string nameForNode(const Arabica::DOM::Node<std::string>& node);
+
+ static std::string getPrefix();
+ static std::string dotEscape(const std::string& text);
+
+ Interpreter* _interpreter;
+ std::set<std::string> _knownIds;
+ static int _indentation;
};
}
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
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 1fdaaee..7bd6c47 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -13,10 +13,19 @@ target_link_libraries(test-apache-commons uscxml)
add_test(test-apache-commons ${CURRENT_BINARY_DIR}/test-apache-commons ${CMAKE_SOURCE_DIR}/test/samples/apache)
set_target_properties(test-apache-commons PROPERTIES FOLDER "Tests")
-add_executable(test-ecmascript-v8 src/test-ecmascript-v8.cpp)
-target_link_libraries(test-ecmascript-v8 uscxml)
-add_test(test-ecmascript-v8 ${CURRENT_BINARY_DIR}/test-ecmascript-v8 ${CMAKE_SOURCE_DIR}/test/src/test-ecmascript.scxml)
-set_target_properties(test-ecmascript-v8 PROPERTIES FOLDER "Tests")
+if (V8_FOUND)
+ add_executable(test-ecmascript-v8 src/test-ecmascript-v8.cpp)
+ target_link_libraries(test-ecmascript-v8 uscxml)
+ add_test(test-ecmascript-v8 ${CURRENT_BINARY_DIR}/test-ecmascript-v8 ${CMAKE_SOURCE_DIR}/test/src/test-ecmascript.scxml)
+ set_target_properties(test-ecmascript-v8 PROPERTIES FOLDER "Tests")
+endif()
+
+if (SWI_FOUND)
+ add_executable(test-prolog-swi src/test-prolog-swi.cpp)
+ target_link_libraries(test-prolog-swi uscxml)
+ add_test(test-prolog-swi ${CURRENT_BINARY_DIR}/test-prolog-swi ${CMAKE_SOURCE_DIR}/test/src/test-prolog.scxml)
+ set_target_properties(test-prolog-swi PROPERTIES FOLDER "Tests")
+endif()
add_executable(test-communication src/test-communication.cpp)
target_link_libraries(test-communication uscxml)
diff --git a/test/samples/uscxml/test-ecmascript.scxml b/test/samples/uscxml/test-ecmascript.scxml
index aa88f17..7dfd94c 100644
--- a/test/samples/uscxml/test-ecmascript.scxml
+++ b/test/samples/uscxml/test-ecmascript.scxml
@@ -77,13 +77,7 @@
</foreach>
</foreach>
</onentry>
- <transition target="externalEvents" />
- </state>
- <state id="externalEvents">
- <onentry>
- <log expr="'-- External Events'" />
- </onentry>
- <transition target="datamodels" event="event1" cond="_event.name == 'event1'" />
+ <transition target="datamodels" />
</state>
<state id="datamodels">
<datamodel>
diff --git a/test/samples/uscxml/test-prolog.scxml b/test/samples/uscxml/test-prolog.scxml
new file mode 100644
index 0000000..75a1c64
--- /dev/null
+++ b/test/samples/uscxml/test-prolog.scxml
@@ -0,0 +1,15 @@
+<scxml datamodel="prolog" initial="start" binding="late">
+ <datamodel>
+ <data id="facts">
+ cat(tom).
+ animal(X):- cat(X).
+ </data>
+ </datamodel>
+ <script>
+ cat(tom).
+ cat(X).
+ animal(X).
+ </script>
+ <state id="start">
+ </state>
+</scxml> \ No newline at end of file
diff --git a/test/src/test-apache-commons.cpp b/test/src/test-apache-commons.cpp
index 3bfbfed..9ac4442 100644
--- a/test/src/test-apache-commons.cpp
+++ b/test/src/test-apache-commons.cpp
@@ -8,61 +8,61 @@ using namespace Arabica::XPath;
static std::string path;
bool testEvents1() {
- LOG(INFO) << "---- testEvent1 ";
- Interpreter* interpreter = Interpreter::fromURI(path + "/eventdata-01.xml");
+ LOG(INFO) << "---- testEvent1 ";
+ Interpreter* interpreter = Interpreter::fromURI(path + "/eventdata-01.xml");
interpreter->start();
- interpreter->waitForStabilization();
- assert(interpreter->getConfiguration().size() == 1);
- assert(Interpreter::isMember(interpreter->getState("state1"), interpreter->getConfiguration()));
-
- Event eventFoo;
- eventFoo.name = "event.foo";
- eventFoo.atom = "3";
- interpreter->receive(eventFoo);
- interpreter->waitForStabilization();
- assert(interpreter->getConfiguration().size() == 1);
- assert(Interpreter::isMember(interpreter->getState("state3"), interpreter->getConfiguration()));
-
- Event eventBar;
- eventBar.name = "event.bar";
- eventBar.atom = "6";
- interpreter->receive(eventBar);
- interpreter->waitForStabilization();
- assert(interpreter->getConfiguration().size() == 1);
- assert(Interpreter::isMember(interpreter->getState("state6"), interpreter->getConfiguration()));
-
- Event eventBaz;
- eventBaz.name = "event.baz";
- eventBaz.atom = "7";
- interpreter->receive(eventBaz);
-
- delete interpreter;
- return true;
+ interpreter->waitForStabilization();
+ assert(interpreter->getConfiguration().size() == 1);
+ assert(Interpreter::isMember(interpreter->getState("state1"), interpreter->getConfiguration()));
+
+ Event eventFoo;
+ eventFoo.name = "event.foo";
+ eventFoo.atom = "3";
+ interpreter->receive(eventFoo);
+ interpreter->waitForStabilization();
+ assert(interpreter->getConfiguration().size() == 1);
+ assert(Interpreter::isMember(interpreter->getState("state3"), interpreter->getConfiguration()));
+
+ Event eventBar;
+ eventBar.name = "event.bar";
+ eventBar.atom = "6";
+ interpreter->receive(eventBar);
+ interpreter->waitForStabilization();
+ assert(interpreter->getConfiguration().size() == 1);
+ assert(Interpreter::isMember(interpreter->getState("state6"), interpreter->getConfiguration()));
+
+ Event eventBaz;
+ eventBaz.name = "event.baz";
+ eventBaz.atom = "7";
+ interpreter->receive(eventBaz);
+
+ delete interpreter;
+ return true;
}
bool testEvents2() {
- LOG(INFO) << "---- testEvent2 ";
- Interpreter* interpreter = Interpreter::fromURI(path + "/eventdata-02.xml");
+ LOG(INFO) << "---- testEvent2 ";
+ Interpreter* interpreter = Interpreter::fromURI(path + "/eventdata-02.xml");
interpreter->start();
- interpreter->waitForStabilization();
- assert(interpreter->getConfiguration().size() == 1);
- assert(Interpreter::isMember(interpreter->getState("state0"), interpreter->getConfiguration()));
-
- Event eventConnAlert;
- eventConnAlert.name = "connection.alerting";
- eventConnAlert.atom = "'line2'";
- interpreter->receive(eventConnAlert);
- interpreter->waitForStabilization();
- assert(interpreter->getConfiguration().size() == 1);
- assert(Interpreter::isMember(interpreter->getState("state2"), interpreter->getConfiguration()));
-
- Event eventConnAlert2;
- eventConnAlert2.name = "connection.alerting";
- eventConnAlert2.compound["line"] = Data(std::string("4"));
- interpreter->receive(eventConnAlert2);
-
- delete interpreter;
- return true;
+ interpreter->waitForStabilization();
+ assert(interpreter->getConfiguration().size() == 1);
+ assert(Interpreter::isMember(interpreter->getState("state0"), interpreter->getConfiguration()));
+
+ Event eventConnAlert;
+ eventConnAlert.name = "connection.alerting";
+ eventConnAlert.atom = "'line2'";
+ interpreter->receive(eventConnAlert);
+ interpreter->waitForStabilization();
+ assert(interpreter->getConfiguration().size() == 1);
+ assert(Interpreter::isMember(interpreter->getState("state2"), interpreter->getConfiguration()));
+
+ Event eventConnAlert2;
+ eventConnAlert2.name = "connection.alerting";
+ eventConnAlert2.compound["line"] = Data(std::string("4"));
+ interpreter->receive(eventConnAlert2);
+
+ delete interpreter;
+ return true;
}
//bool testEvents3() {
@@ -73,7 +73,7 @@ bool testEvents2() {
// Thread::sleepMs(200);
// assert(interpreter->getConfiguration().size() == 1);
// assert(Interpreter::isMember(interpreter->getState("state0"), interpreter->getConfiguration()));
-//
+//
// Event eventConnAlert;
// eventConnAlert.name = "connection.alerting";
// eventConnAlert.atom = "'line2'";
@@ -81,7 +81,7 @@ bool testEvents2() {
// Thread::sleepMs(200);
// assert(interpreter->getConfiguration().size() == 1);
// assert(Interpreter::isMember(interpreter->getState("state2"), interpreter->getConfiguration()));
-//
+//
// Event eventConnAlert2;
// eventConnAlert2.name = "connection.alerting";
// eventConnAlert2.compound["line"] = Data(std::string("4"));
@@ -89,40 +89,40 @@ bool testEvents2() {
// Thread::sleepMs(200);
// assert(interpreter->getConfiguration().size() == 1);
// assert(Interpreter::isMember(interpreter->getState("state4"), interpreter->getConfiguration()));
-//
+//
// delete Interpreter;
// return true;
//}
int main(int argc, char** argv) {
- if (argc != 2) {
- std::cerr << "Expected path to scxml file from apache commons distribution" << std::endl;
- exit(EXIT_FAILURE);
- }
-
- path = "file://";
- path += argv[1];
-
- if (!testEvents1())
- return EXIT_FAILURE;
- if (!testEvents2())
- return EXIT_FAILURE;
+ if (argc != 2) {
+ std::cerr << "Expected path to scxml file from apache commons distribution" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ path = "file://";
+ path += argv[1];
+
+ if (!testEvents1())
+ return EXIT_FAILURE;
+ if (!testEvents2())
+ return EXIT_FAILURE;
// if (!testEvents3())
// return EXIT_FAILURE;
-
+
//
// Interpreter* scxmlInterpreter = new Interpreter(path + "/tie-breaker-01.xml");
// SCXMLRunner* scxmlRun = new SCXMLRunner(scxmlInterpreter);
// scxmlRun->start();
-//
+//
// Thread::sleepMs(100);
// assert(Interpreter::isMember(scxmlinterpreter->getState("ten"), scxmlinterpreter->getConfiguration()));
-//
+//
// boost::shared_ptr<Event> event = boost::shared_ptr<Event>(new Event());
// event->name = "ten.done";
// scxmlinterpreter->receive(event);
// scxmlRun->join();
// scxmlinterpreter->receive(event);
-
+
} \ No newline at end of file
diff --git a/test/src/test-communication.cpp b/test/src/test-communication.cpp
index ac0fa6c..a0cdbbd 100644
--- a/test/src/test-communication.cpp
+++ b/test/src/test-communication.cpp
@@ -2,30 +2,30 @@
#include <DOM/io/Stream.hpp>
int main(int argc, char** argv) {
- if (argc != 2) {
- std::cerr << "Expected path to test-communication.scxml" << std::endl;
- exit(EXIT_FAILURE);
- }
-
-
- using namespace uscxml;
- std::list<Interpreter*> _interpreters;
+ if (argc != 2) {
+ std::cerr << "Expected path to test-communication.scxml" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+
+ using namespace uscxml;
+ std::list<Interpreter*> _interpreters;
// Event e;
// e.compound["foo"] = Data("bar", Data::VERBATIM);
// e.compound["foo2"] = Data("bar2", Data::VERBATIM);
// std::cout << e.toDocument() << std::endl;
-
- int nrInterpreters = 1;
- for (int i = 0; i < nrInterpreters; i++) {
- _interpreters.push_back(Interpreter::fromURI(argv[1]));
- _interpreters.back()->start();
- }
- std::list<Interpreter*>::iterator interIter = _interpreters.begin();
- while(interIter != _interpreters.end()) {
- (*interIter)->join();
- interIter++;
- }
+ int nrInterpreters = 1;
+ for (int i = 0; i < nrInterpreters; i++) {
+ _interpreters.push_back(Interpreter::fromURI(argv[1]));
+ _interpreters.back()->start();
+ }
+
+ std::list<Interpreter*>::iterator interIter = _interpreters.begin();
+ while(interIter != _interpreters.end()) {
+ (*interIter)->join();
+ interIter++;
+ }
} \ No newline at end of file
diff --git a/test/src/test-completion.cpp b/test/src/test-completion.cpp
index b75baf6..67d8708 100644
--- a/test/src/test-completion.cpp
+++ b/test/src/test-completion.cpp
@@ -3,18 +3,18 @@
#include <DOM/io/Stream.hpp>
int main(int argc, char** argv) {
- if (argc != 2) {
- std::cerr << "Expected path to scxml document" << std::endl;
- exit(EXIT_FAILURE);
- }
-
- using namespace uscxml;
+ if (argc != 2) {
+ std::cerr << "Expected path to scxml document" << std::endl;
+ exit(EXIT_FAILURE);
+ }
- Interpreter* interpreter = Interpreter::fromURI(argv[1]);
- //SCXMLDotWriter::toDot("output.dot", interpreter);
+ using namespace uscxml;
+
+ Interpreter* interpreter = Interpreter::fromURI(argv[1]);
+ //SCXMLDotWriter::toDot("output.dot", interpreter);
interpreter->interpret();
-
-
+
+
return EXIT_SUCCESS;
} \ No newline at end of file
diff --git a/test/src/test-ecmascript-v8.cpp b/test/src/test-ecmascript-v8.cpp
index bca9343..9ce39d9 100644
--- a/test/src/test-ecmascript-v8.cpp
+++ b/test/src/test-ecmascript-v8.cpp
@@ -2,23 +2,23 @@
#include "uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h"
int main(int argc, char** argv) {
- if (argc != 2) {
- std::cerr << "Expected path to test-ecmascript.scxml" << std::endl;
- exit(EXIT_FAILURE);
- }
+ if (argc != 2) {
+ std::cerr << "Expected path to test-ecmascript.scxml" << std::endl;
+ exit(EXIT_FAILURE);
+ }
- using namespace uscxml;
- using namespace Arabica::DOM;
- using namespace Arabica::XPath;
+ using namespace uscxml;
+ using namespace Arabica::DOM;
+ using namespace Arabica::XPath;
+
+ Interpreter* scxml = Interpreter::fromURI(argv[1]);
+ scxml->start();
+ scxml->waitForStabilization();
+
+ Event event1;
+ event1.name = "event1";
+ scxml->receive(event1);
+ scxml->join();
+ tthread::this_thread::sleep_for(tthread::chrono::milliseconds(500));
- Interpreter* scxml = Interpreter::fromURI(argv[1]);
- scxml->start();
- scxml->waitForStabilization();
-
- Event event1;
- event1.name = "event1";
- scxml->receive(event1);
- scxml->join();
- tthread::this_thread::sleep_for(tthread::chrono::milliseconds(500));
-
} \ No newline at end of file
diff --git a/test/src/test-eventdelay.cpp b/test/src/test-eventdelay.cpp
index 17a88ca..a3fec34 100644
--- a/test/src/test-eventdelay.cpp
+++ b/test/src/test-eventdelay.cpp
@@ -6,18 +6,18 @@ int eventCalled = 0;
static void callback(void* userData, const std::string eventId) {
// std::cout << eventId << ": " << (const char*)userData << std::endl;
- std::cout << eventId << std::endl << std::flush;
- eventCalled++;
+ std::cout << eventId << std::endl << std::flush;
+ eventCalled++;
}
int main(int argc, char** argv) {
- using namespace uscxml;
+ using namespace uscxml;
DelayedEventQueue* eq = new DelayedEventQueue();
- std::cout << "Starting" << std::endl;
- eq->start();
- tthread::this_thread::sleep_for(tthread::chrono::milliseconds(10));
+ std::cout << "Starting" << std::endl;
+ eq->start();
+ tthread::this_thread::sleep_for(tthread::chrono::milliseconds(10));
// eq->addEvent("foo", callback, 200, (void*)"event foo");
// eq->addEvent("bar", callback, 400, (void*)"event bar");
@@ -26,14 +26,14 @@ int main(int argc, char** argv) {
// eq->addEvent("bar", callback, 300, (void*)"event bar");
// eq->addEvent("baz", callback, 400, (void*)"event baz");
- for (unsigned int i = 0; i <= 2000; i += 200) {
+ for (unsigned int i = 0; i <= 2000; i += 200) {
// eq->stop();
- std::stringstream ss;
- ss << i;
- eq->addEvent(ss.str(), callback, i, NULL);
- std::cout << "Added " << i << std::endl;
+ std::stringstream ss;
+ ss << i;
+ eq->addEvent(ss.str(), callback, i, NULL);
+ std::cout << "Added " << i << std::endl;
// eq->start();
- }
- tthread::this_thread::sleep_for(tthread::chrono::milliseconds(2000));
+ }
+ tthread::this_thread::sleep_for(tthread::chrono::milliseconds(2000));
} \ No newline at end of file
diff --git a/test/src/test-execution.cpp b/test/src/test-execution.cpp
index cea89b5..272ce41 100644
--- a/test/src/test-execution.cpp
+++ b/test/src/test-execution.cpp
@@ -1,16 +1,16 @@
#include "uscxml/Interpreter.h"
int main(int argc, char** argv) {
- if (argc != 2) {
- std::cerr << "Expected path to test-execution.scxml" << std::endl;
- exit(EXIT_FAILURE);
- }
-
- using namespace uscxml;
- using namespace Arabica::DOM;
- using namespace Arabica::XPath;
-
- Interpreter* interpreter = Interpreter::fromURI(argv[1]);
- interpreter->dump();
- interpreter->interpret();
+ if (argc != 2) {
+ std::cerr << "Expected path to test-execution.scxml" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ using namespace uscxml;
+ using namespace Arabica::DOM;
+ using namespace Arabica::XPath;
+
+ Interpreter* interpreter = Interpreter::fromURI(argv[1]);
+ interpreter->dump();
+ interpreter->interpret();
} \ No newline at end of file
diff --git a/test/src/test-predicates.cpp b/test/src/test-predicates.cpp
index 0494c24..2905f40 100644
--- a/test/src/test-predicates.cpp
+++ b/test/src/test-predicates.cpp
@@ -3,58 +3,58 @@
#undef protected
int main(int argc, char** argv) {
- if (argc != 2) {
- std::cerr << "Expected path to test-predicates.scxml" << std::endl;
- exit(EXIT_FAILURE);
- }
-
- using namespace uscxml;
- using namespace Arabica::DOM;
- using namespace Arabica::XPath;
-
- Interpreter* interpreter = Interpreter::fromURI(argv[1]);
-
- Node<std::string> atomicState = interpreter->getState("atomic");
- assert(Interpreter::isAtomic(atomicState));
- assert(!Interpreter::isParallel(atomicState));
- assert(!Interpreter::isCompound(atomicState));
-
- Node<std::string> compoundState = interpreter->getState("compound");
- assert(!Interpreter::isAtomic(compoundState));
- assert(!Interpreter::isParallel(compoundState));
- assert(Interpreter::isCompound(compoundState));
-
- Node<std::string> parallelState = interpreter->getState("parallel");
- assert(!Interpreter::isAtomic(parallelState));
- assert(Interpreter::isParallel(parallelState));
- assert(!Interpreter::isCompound(parallelState)); // parallel states are not compound!
-
- Node<std::string> initialState = interpreter->getInitialState();
- assert(initialState == atomicState);
-
- NodeSet<std::string> childs = interpreter->getChildStates(compoundState);
- Node<std::string> compundChild1 = interpreter->getState("compundChild1");
- Node<std::string> compundChild2 = interpreter->getState("compundChild2");
- assert(childs.size() > 0);
- assert(Interpreter::isMember(compundChild1, childs));
- assert(Interpreter::isMember(compundChild2, childs));
- assert(!Interpreter::isMember(compoundState, childs));
-
- assert(Interpreter::isDescendant(compundChild1, compoundState));
-
- std::string transEvents;
- transEvents = "error";
- assert(Interpreter::nameMatch(transEvents, "error"));
- assert(!Interpreter::nameMatch(transEvents, "foo"));
-
- transEvents = "error foo";
- assert(Interpreter::nameMatch(transEvents, "error"));
- assert(Interpreter::nameMatch(transEvents, "error.send"));
- assert(Interpreter::nameMatch(transEvents, "error.send.failed"));
- assert(Interpreter::nameMatch(transEvents, "foo"));
- assert(Interpreter::nameMatch(transEvents, "foo.bar"));
- assert(!Interpreter::nameMatch(transEvents, "errors.my.custom"));
- assert(!Interpreter::nameMatch(transEvents, "errorhandler.mistake"));
- assert(!Interpreter::nameMatch(transEvents, "errOr.send"));
- assert(!Interpreter::nameMatch(transEvents, "foobar"));
+ if (argc != 2) {
+ std::cerr << "Expected path to test-predicates.scxml" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ using namespace uscxml;
+ using namespace Arabica::DOM;
+ using namespace Arabica::XPath;
+
+ Interpreter* interpreter = Interpreter::fromURI(argv[1]);
+
+ Node<std::string> atomicState = interpreter->getState("atomic");
+ assert(Interpreter::isAtomic(atomicState));
+ assert(!Interpreter::isParallel(atomicState));
+ assert(!Interpreter::isCompound(atomicState));
+
+ Node<std::string> compoundState = interpreter->getState("compound");
+ assert(!Interpreter::isAtomic(compoundState));
+ assert(!Interpreter::isParallel(compoundState));
+ assert(Interpreter::isCompound(compoundState));
+
+ Node<std::string> parallelState = interpreter->getState("parallel");
+ assert(!Interpreter::isAtomic(parallelState));
+ assert(Interpreter::isParallel(parallelState));
+ assert(!Interpreter::isCompound(parallelState)); // parallel states are not compound!
+
+ Node<std::string> initialState = interpreter->getInitialState();
+ assert(initialState == atomicState);
+
+ NodeSet<std::string> childs = interpreter->getChildStates(compoundState);
+ Node<std::string> compundChild1 = interpreter->getState("compundChild1");
+ Node<std::string> compundChild2 = interpreter->getState("compundChild2");
+ assert(childs.size() > 0);
+ assert(Interpreter::isMember(compundChild1, childs));
+ assert(Interpreter::isMember(compundChild2, childs));
+ assert(!Interpreter::isMember(compoundState, childs));
+
+ assert(Interpreter::isDescendant(compundChild1, compoundState));
+
+ std::string transEvents;
+ transEvents = "error";
+ assert(Interpreter::nameMatch(transEvents, "error"));
+ assert(!Interpreter::nameMatch(transEvents, "foo"));
+
+ transEvents = "error foo";
+ assert(Interpreter::nameMatch(transEvents, "error"));
+ assert(Interpreter::nameMatch(transEvents, "error.send"));
+ assert(Interpreter::nameMatch(transEvents, "error.send.failed"));
+ assert(Interpreter::nameMatch(transEvents, "foo"));
+ assert(Interpreter::nameMatch(transEvents, "foo.bar"));
+ assert(!Interpreter::nameMatch(transEvents, "errors.my.custom"));
+ assert(!Interpreter::nameMatch(transEvents, "errorhandler.mistake"));
+ assert(!Interpreter::nameMatch(transEvents, "errOr.send"));
+ assert(!Interpreter::nameMatch(transEvents, "foobar"));
} \ No newline at end of file
diff --git a/test/src/test-prolog-swi.cpp b/test/src/test-prolog-swi.cpp
new file mode 100644
index 0000000..17947af
--- /dev/null
+++ b/test/src/test-prolog-swi.cpp
@@ -0,0 +1,25 @@
+#include "uscxml/Interpreter.h"
+#include "uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h"
+
+int main(int argc, char** argv) {
+ if (argc != 2) {
+ std::cerr << "Expected path to test-prolog.scxml" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ using namespace uscxml;
+ using namespace Arabica::DOM;
+ using namespace Arabica::XPath;
+
+ uscxml::Factory::pluginPath = "/Users/sradomski/Documents/TK/Code/uscxml/build/xcode/lib";
+ Interpreter* scxml = Interpreter::fromURI(argv[1]);
+ scxml->start();
+ scxml->waitForStabilization();
+
+ Event event1;
+ event1.name = "event1";
+ scxml->receive(event1);
+ scxml->join();
+ tthread::this_thread::sleep_for(tthread::chrono::milliseconds(500));
+
+} \ No newline at end of file