diff options
author | Stefan Radomski <github@mintwerk.de> | 2014-06-27 22:41:36 (GMT) |
---|---|---|
committer | Stefan Radomski <github@mintwerk.de> | 2014-06-27 22:41:36 (GMT) |
commit | d48cefb17820d5dc4b6f05ee4a78a12c897997cd (patch) | |
tree | a0ef030204ec2eb656845d03876006d9cdc0760c | |
parent | 625cce77ff40f6c207526199433de553fea791f9 (diff) | |
parent | c70d02010ea99e6c8e35da3b767f41f1ee5dce56 (diff) | |
download | uscxml-d48cefb17820d5dc4b6f05ee4a78a12c897997cd.zip uscxml-d48cefb17820d5dc4b6f05ee4a78a12c897997cd.tar.gz uscxml-d48cefb17820d5dc4b6f05ee4a78a12c897997cd.tar.bz2 |
Merge pull request #44 from sradomski/master
Major header movement
111 files changed, 2632 insertions, 3883 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 90e5316..6a26928 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -358,6 +358,8 @@ if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") if(GCC_VERSION VERSION_EQUAL 4.7 OR GCC_VERSION VERSION_GREATER 4.7) # when compiling as C++11, narrowing is a warning but older compilers complain about the option add_definitions(-Wno-narrowing) + # recent gcc started to complain about unused globals + add_definitions(-Wno-unused-variable) endif() if(GCC_VERSION VERSION_EQUAL 4.8 OR GCC_VERSION VERSION_GREATER 4.8) @@ -946,6 +948,8 @@ foreach( FILE ${USCXML_FILES} ) elseif (${FILE} MATCHES ".*\\/debug\\/.*") source_group("Interpreter\\debug" FILES ${FILE}) + elseif (${FILE} MATCHES ".*\\/plugins\\/.*") + source_group("Interpreter\\plugins" FILES ${FILE}) elseif (${FILE} MATCHES ".*\\/transform\\/.*") source_group("Interpreter\\transform" FILES ${FILE}) elseif (${FILE} MATCHES ".*\\/util\\/.*") @@ -954,6 +958,8 @@ foreach( FILE ${USCXML_FILES} ) source_group("Interpreter\\concurrency" FILES ${FILE}) elseif (${FILE} MATCHES ".*\\/server\\/.*") source_group("Interpreter\\server" FILES ${FILE}) + elseif (${FILE} MATCHES ".*\\/messages\\/.*") + source_group("Interpreter\\messages" FILES ${FILE}) else () source_group(Interpreter FILES ${FILE}) @@ -47,29 +47,10 @@ uSCXML still fails the following ecmascript tests: <table> <tr><th>Test#</th><th>Status</th><th>Description</th><th>Comment</th></tr> <tr> - <td><tt><a href="https://github.com/tklab-tud/uscxml/blob/master/test/samples/w3c/ecma/test329.scxml">329</a></tt></td> + <td><tt><a href="https://github.com/tklab-tud/uscxml/blob/master/test/w3c/ecma/test579.scxml">579</a></tt></td> <td><tt>Failed</tt></td> - <td>"test that none of the system variables can be modified"</td> - <td>uSCXML allows writing to <tt>_event</tt>. This is very useful to have a scope - that vanishes when processing an event is finished. I raised the issue on the ML and it might make it into a later draft</td> - </tr> - <tr> - <td><tt><a href="https://github.com/tklab-tud/uscxml/blob/master/test/samples/w3c/ecma/test346.scxml">346</a></tt></td> - <td><tt>Failed</tt></td> - <td>"test that any attempt to change the value of a system variable causes error.execution to be raised"</td> - <td>Same issue as above: we allow writing to <tt>_event</tt>.</td> - </tr> - <tr> - <td> - <tt> - <a href="https://github.com/tklab-tud/uscxml/blob/master/test/samples/w3c/ecma/test519.scxml">519</a> - <a href="https://github.com/tklab-tud/uscxml/blob/master/test/samples/w3c/ecma/test520.scxml">520</a> - <a href="https://github.com/tklab-tud/uscxml/blob/master/test/samples/w3c/ecma/test531.scxml">531</a> - <a href="https://github.com/tklab-tud/uscxml/blob/master/test/samples/w3c/ecma/test534.scxml">534</a> - </tt></td> - <td><tt>Failed</tt></td> - <td></td> - <td>Tests contain non-standard ECMAScript.</td> + <td>"Before the parent state has been visited for the first time, if a transition is executed that takes the history state as its target, the SCXML processor MUST execute any executable content in the transition after the parent state's onentry content and any content in a possible initial transition."</td> + <td>Functionality was recently added and is not yet supported.</td> </tr> </table> @@ -91,7 +72,7 @@ objects of <tt>uscxml::Interpreter</tt>. ### Non-Blocking Interpretation with SCXML from URL Interpreter scxml = Interpreter::fromURL("http://www.example.com/fancy.scxml"); - scxml.start(); // non-blocking + scxml.start(); // non-blocking in own thread There are some cases, i.e. with graphical invokers, where the main thread is <emph>required</emph> in order to react to UI events. You will have to deligate control flow from the main thread into the interpreter @@ -126,15 +107,15 @@ You can register an <tt>InterpreterMonitor</tt> prior to start in order to recei control-flow upon various events in the Interpreter. class StatusMonitor : public uscxml::InterpreterMonitor { - void onStableConfiguration(Interpreter) {} - void beforeCompletion(Interpreter) {} - void afterCompletion(Interpreter) {} - void beforeMicroStep(Interpreter) {} - void beforeTakingTransitions(Interpreter, const Arabica::XPath::NodeSet<std::string>&) {} - void beforeEnteringStates(Interpreter, const Arabica::XPath::NodeSet<std::string>&) {} - void afterEnteringStates(Interpreter) {} - void beforeExitingStates(Interpreter, const Arabica::XPath::NodeSet<std::string>&) {} - void afterExitingStates(Interpreter) {} + void onStableConfiguration(...) + void beforeCompletion(...) + void afterCompletion(...) + void beforeMicroStep(...) + void beforeTakingTransitions(...) + void beforeEnteringStates(...) + void afterEnteringStates(...) + void beforeExitingStates(...) + void afterExitingStates(...) }; StatusMonitor statMon; diff --git a/apps/uscxml-browser.cpp b/apps/uscxml-browser.cpp index a3ba8c8..7efacf5 100644 --- a/apps/uscxml-browser.cpp +++ b/apps/uscxml-browser.cpp @@ -4,6 +4,9 @@ #include "uscxml/debug/DebuggerServlet.h" #include <glog/logging.h> +#include "uscxml/Factory.h" +#include "uscxml/server/HTTPServer.h" + #ifdef HAS_SIGNAL_H #include <signal.h> #endif diff --git a/apps/uscxml-transform.cpp b/apps/uscxml-transform.cpp index 1d03b98..3ee1f50 100644 --- a/apps/uscxml-transform.cpp +++ b/apps/uscxml-transform.cpp @@ -5,6 +5,11 @@ #include "uscxml/DOMUtils.h" #include <glog/logging.h> #include <fstream> +#include <iostream> + +#include "uscxml/Factory.h" +#include "uscxml/server/HTTPServer.h" +#include "getopt.h" #ifdef HAS_SIGNAL_H #include <signal.h> diff --git a/contrib/iwyu-g++ b/contrib/iwyu-g++ index b3b66da..27b98be 100755 --- a/contrib/iwyu-g++ +++ b/contrib/iwyu-g++ @@ -1,4 +1,7 @@ #!/bin/sh + +# call as cmake CC=[..]/iwyu-gcc CXX=[..]/iwyu-g++ + IWYU_COMMAND=/usr/bin/iwyu COMPILER_COMMAND=/usr/bin/g++ $IWYU_COMMAND $@ diff --git a/contrib/local/test-include-linux.sh b/contrib/local/test-include-linux.sh new file mode 100755 index 0000000..19d0bd2 --- /dev/null +++ b/contrib/local/test-include-linux.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +ME=`basename $0` +DIR="$( cd "$( dirname "$0" )" && pwd )" +IWYU="/usr/bin/iwyu" +CLANG="/usr/bin/clang++" + +cd $DIR + +mkdir uscxml +touch uscxml/config.h + +#set -e + +SOURCES=`find ../../src -name "*.cpp"` + +for SOURCE in ${SOURCES}; do + if [[ "$SOURCE" == *plugins* ]]; then + continue + fi + echo ${SOURCE} + + ${IWYU} -c \ + -I /usr/include \ + -I ${DIR}/../prebuilt/include \ + -I ${DIR}/../prebuilt/linux-i686/gnu/include/arabica \ + -I ${DIR}/../prebuilt/linux-i686/gnu/include \ + -I ${DIR}/../src/evws \ + -I /usr/include/libxml2 \ + -I ${DIR} \ + -I ${DIR}/../../src ${SOURCE} +done
\ No newline at end of file diff --git a/contrib/local/test-include-macosx.sh b/contrib/local/test-include-macosx.sh new file mode 100755 index 0000000..b71103a --- /dev/null +++ b/contrib/local/test-include-macosx.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +set -e + +ME=`basename $0` +DIR="$( cd "$( dirname "$0" )" && pwd )" + +cd $DIR + +HEADERS=`find ../../src -name *.h` + +for HEADER in ${HEADERS}; do + if [[ "$HEADER" == *inttypes.h* ]]; then + continue + fi + if [[ "$HEADER" == *bindings* ]]; then + continue + fi + if [[ "$HEADER" == *plugins* ]]; then + continue + fi + echo ${HEADER} + + echo "\ +#include \"${HEADER}\" +int main() {} " > test.cpp + + g++ \ + -I ${DIR}/../prebuilt/include \ + -I ${DIR}/../prebuilt/darwin-i386/10.9/clang/include/arabica \ + -I ${DIR}/../prebuilt/darwin-i386/10.9/clang/include \ + -I ${DIR}/../src/evws \ + -I /opt/local/include/libxml2 \ + -I /opt/local/lib/swipl-7.1.4/include \ + -I ${DIR}/../../src test.cpp +done
\ No newline at end of file diff --git a/embedding/csharp/embedding/embedding.suo b/embedding/csharp/embedding/embedding.suo Binary files differdeleted file mode 100644 index 3c8cd31..0000000 --- a/embedding/csharp/embedding/embedding.suo +++ /dev/null diff --git a/embedding/csharp/embedding/embedding.userprefs b/embedding/csharp/embedding/embedding.userprefs deleted file mode 100644 index 681be08..0000000 --- a/embedding/csharp/embedding/embedding.userprefs +++ /dev/null @@ -1,12 +0,0 @@ -<Properties> - <MonoDevelop.Ide.Workspace ActiveConfiguration="Debug|x86" /> - <MonoDevelop.Ide.Workbench ActiveDocument="embedding/Program.cs"> - <Files> - <File FileName="embedding/Program.cs" Line="16" Column="40" /> - </Files> - </MonoDevelop.Ide.Workbench> - <MonoDevelop.Ide.DebuggingService.Breakpoints> - <BreakpointStore /> - </MonoDevelop.Ide.DebuggingService.Breakpoints> - <MonoDevelop.Ide.DebuggingService.PinnedWatches /> -</Properties>
\ No newline at end of file diff --git a/embedding/csharp/embedding/embedding.sln b/embedding/csharp/uSCXMLEmbedding.sln index 0f9a49e..6c3a244 100644 --- a/embedding/csharp/embedding/embedding.sln +++ b/embedding/csharp/uSCXMLEmbedding.sln @@ -1,7 +1,7 @@ 
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "embedding", "embedding\embedding.csproj", "{75E5EE93-513B-45DA-AD50-64C570AAD0C0}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples", "uSCXMLEmbedding\Examples.csproj", "{A186DC8C-0655-49D4-A1DB-3C23A24DAA5E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -9,10 +9,10 @@ Global Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {75E5EE93-513B-45DA-AD50-64C570AAD0C0}.Debug|x86.ActiveCfg = Debug|x86
- {75E5EE93-513B-45DA-AD50-64C570AAD0C0}.Debug|x86.Build.0 = Debug|x86
- {75E5EE93-513B-45DA-AD50-64C570AAD0C0}.Release|x86.ActiveCfg = Release|x86
- {75E5EE93-513B-45DA-AD50-64C570AAD0C0}.Release|x86.Build.0 = Release|x86
+ {A186DC8C-0655-49D4-A1DB-3C23A24DAA5E}.Debug|x86.ActiveCfg = Debug|x86
+ {A186DC8C-0655-49D4-A1DB-3C23A24DAA5E}.Debug|x86.Build.0 = Debug|x86
+ {A186DC8C-0655-49D4-A1DB-3C23A24DAA5E}.Release|x86.ActiveCfg = Release|x86
+ {A186DC8C-0655-49D4-A1DB-3C23A24DAA5E}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/embedding/csharp/embedding/embedding/embedding.csproj b/embedding/csharp/uSCXMLEmbedding/Examples.csproj index ca54bd4..b1579bf 100644 --- a/embedding/csharp/embedding/embedding/embedding.csproj +++ b/embedding/csharp/uSCXMLEmbedding/Examples.csproj @@ -5,11 +5,11 @@ <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{75E5EE93-513B-45DA-AD50-64C570AAD0C0}</ProjectGuid>
+ <ProjectGuid>{A186DC8C-0655-49D4-A1DB-3C23A24DAA5E}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>embedding</RootNamespace>
- <AssemblyName>embedding</AssemblyName>
+ <RootNamespace>uSCXMLEmbedding</RootNamespace>
+ <AssemblyName>uSCXMLEmbedding</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
@@ -23,12 +23,6 @@ <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <EnvironmentVariables>
- <EnvironmentVariables>
- <Variable name="DYLD_FALLBACK_LIBRARY_PATH" value="/Users/sradomski/Documents/TK/Code/uscxml/build/cli/lib/csharp" />
- <Variable name="MONO_LOG_LEVEL" value="debug" />
- </EnvironmentVariables>
- </EnvironmentVariables>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
@@ -47,19 +41,18 @@ <Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
- <Reference Include="uscxmlCSharp, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
+ <Reference Include="uscxmlCSharp">
<HintPath>C:\Users\sradomski\Desktop\build\uscxml\lib\uscxmlCSharp.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
- <Compile Include="TestExecutableContent.cs" />
- <Compile Include="TestInterpreterMonitor.cs" />
- <Compile Include="TestIOProc.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="TestDataModel.cs" />
- <Compile Include="TestInvoker.cs" />
+ <Compile Include="Extensions\SampleDataModel.cs" />
+ <Compile Include="Extensions\SampleExecutableContent.cs" />
+ <Compile Include="Extensions\SampleInterpreterMonitor.cs" />
+ <Compile Include="Extensions\SampleInvoker.cs" />
+ <Compile Include="Extensions\SampleIOProc.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
diff --git a/embedding/csharp/embedding/embedding/TestDataModel.cs b/embedding/csharp/uSCXMLEmbedding/Extensions/SampleDataModel.cs index bfcfd30..4d70594 100644 --- a/embedding/csharp/embedding/embedding/TestDataModel.cs +++ b/embedding/csharp/uSCXMLEmbedding/Extensions/SampleDataModel.cs @@ -6,11 +6,11 @@ using org.uscxml; namespace EmbeddedDataModel
{
- class TestDataModel : DataModel
+ class SampleDataModel : DataModel
{
public override DataModel create(Interpreter interpreter)
{
- return new TestDataModel();
+ return new SampleDataModel();
}
public override void eval(string scriptElem, string expr)
diff --git a/embedding/csharp/embedding/embedding/TestExecutableContent.cs b/embedding/csharp/uSCXMLEmbedding/Extensions/SampleExecutableContent.cs index 199445b..a86776f 100644 --- a/embedding/csharp/embedding/embedding/TestExecutableContent.cs +++ b/embedding/csharp/uSCXMLEmbedding/Extensions/SampleExecutableContent.cs @@ -6,7 +6,7 @@ using org.uscxml; namespace embedding
{
- class TestExecutableContent : ExecutableContent
+ class SampleExecutableContent : ExecutableContent
{
public override string getLocalName()
{
@@ -25,7 +25,7 @@ namespace embedding public override ExecutableContent create(Interpreter interpreter)
{
- return new TestExecutableContent();
+ return new SampleExecutableContent();
}
diff --git a/embedding/csharp/embedding/embedding/TestIOProc.cs b/embedding/csharp/uSCXMLEmbedding/Extensions/SampleIOProc.cs index 1c00034..5abbf37 100644 --- a/embedding/csharp/embedding/embedding/TestIOProc.cs +++ b/embedding/csharp/uSCXMLEmbedding/Extensions/SampleIOProc.cs @@ -6,8 +6,13 @@ using org.uscxml; namespace embedding
{
- class TestIOProc : IOProcessor
+ class SampleIOProc : IOProcessor
{
+ public override IOProcessor create(Interpreter interpreter)
+ {
+ return new SampleIOProc();
+ }
+
public override DataNative getDataModelVariables()
{
DataNative data = new DataNative();
diff --git a/embedding/csharp/embedding/embedding/TestInterpreterMonitor.cs b/embedding/csharp/uSCXMLEmbedding/Extensions/SampleInterpreterMonitor.cs index 03eb9d6..2a2f561 100644 --- a/embedding/csharp/embedding/embedding/TestInterpreterMonitor.cs +++ b/embedding/csharp/uSCXMLEmbedding/Extensions/SampleInterpreterMonitor.cs @@ -6,7 +6,7 @@ using org.uscxml; namespace embedding
{
- class TestInterpreterMonitor : InterpreterMonitor
+ class SampleInterpreterMonitor : InterpreterMonitor
{
public override void afterCompletion(Interpreter interpreter) { }
public override void afterMicroStep(Interpreter interpreter) { }
diff --git a/embedding/csharp/embedding/embedding/TestInvoker.cs b/embedding/csharp/uSCXMLEmbedding/Extensions/SampleInvoker.cs index 11493d3..f5fb363 100644 --- a/embedding/csharp/embedding/embedding/TestInvoker.cs +++ b/embedding/csharp/uSCXMLEmbedding/Extensions/SampleInvoker.cs @@ -6,8 +6,13 @@ using org.uscxml; namespace EmbeddedInvoker
{
- class TestInvoker : Invoker
+ class SampleInvoker : Invoker
{
+ public override Invoker create(Interpreter interpreter)
+ {
+ return new SampleInvoker();
+ }
+
public override DataNative getDataModelVariables()
{
DataNative data = new DataNative();
diff --git a/embedding/csharp/embedding/embedding/Program.cs b/embedding/csharp/uSCXMLEmbedding/Program.cs index 3b5a28c..559d28f 100644 --- a/embedding/csharp/embedding/embedding/Program.cs +++ b/embedding/csharp/uSCXMLEmbedding/Program.cs @@ -28,8 +28,8 @@ namespace embedding SetDllDirectory("C:\\Users\\sradomski\\Desktop\\build\\uscxml\\lib\\csharp");
}
- Interpreter interpreter = Interpreter.fromXML("<scxml><state id=\"foo\" final=\"true\" /></scxml>");
- interpreter.addMonitor(new TestInterpreterMonitor());
+ Interpreter interpreter = Interpreter.fromXML("<scxml><state id=\"f oo\" final=\"true\" /></scxml>");
+ interpreter.addMonitor(new SampleInterpreterMonitor());
interpreter.interpret();
}
}
diff --git a/embedding/csharp/embedding/embedding/Properties/AssemblyInfo.cs b/embedding/csharp/uSCXMLEmbedding/Properties/AssemblyInfo.cs index bd9015e..141c1cf 100644 --- a/embedding/csharp/embedding/embedding/Properties/AssemblyInfo.cs +++ b/embedding/csharp/uSCXMLEmbedding/Properties/AssemblyInfo.cs @@ -5,11 +5,11 @@ using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("embedding")]
+[assembly: AssemblyTitle("uSCXMLEmbedding")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("embedding")]
+[assembly: AssemblyProduct("uSCXMLEmbedding")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -20,7 +20,7 @@ using System.Runtime.InteropServices; [assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("0d270ead-e8cf-4cc1-a2c8-fa123e71812c")]
+[assembly: Guid("5bcfdd5c-6567-40dd-b4ea-3a9d3c64076a")]
// Version information for an assembly consists of the following four values:
//
diff --git a/src/bindings/CMakeLists.txt b/src/bindings/CMakeLists.txt index 667bfb9..ca5b774 100644 --- a/src/bindings/CMakeLists.txt +++ b/src/bindings/CMakeLists.txt @@ -23,7 +23,6 @@ if (SWIG_FOUND) INCLUDE(${SWIG_USE_FILE}) add_subdirectory(swig/java) add_subdirectory(swig/csharp) - add_subdirectory(swig/php) else() message(STATUS "SWIG version 2.0.5 is required, found ${SWIG_VERSION} - skipping java wrapper generation") endif() diff --git a/src/bindings/swig/csharp/uscxml.i b/src/bindings/swig/csharp/uscxml.i index 6f4f214..988c541 100644 --- a/src/bindings/swig/csharp/uscxml.i +++ b/src/bindings/swig/csharp/uscxml.i @@ -140,6 +140,18 @@ WRAP_THROW_EXCEPTION(uscxml::Interpreter::interpret); %include "../../../uscxml/Interpreter.h" %include "../../../uscxml/concurrency/BlockingQueue.h" +%include "../../../uscxml/messages/Blob.h" +%include "../../../uscxml/messages/Data.h" +%include "../../../uscxml/messages/Event.h" +%include "../../../uscxml/messages/InvokeRequest.h" +%include "../../../uscxml/messages/SendRequest.h" + +%include "../../../uscxml/plugins/DataModel.h" +%include "../../../uscxml/plugins/EventHandler.h" +%include "../../../uscxml/plugins/ExecutableContent.h" +%include "../../../uscxml/plugins/Invoker.h" +%include "../../../uscxml/plugins/IOProcessor.h" + %include "../wrapped/WrappedInvoker.h" %include "../wrapped/WrappedDataModel.h" %include "../wrapped/WrappedExecutableContent.h" diff --git a/src/bindings/swig/java/CMakeLists.txt b/src/bindings/swig/java/CMakeLists.txt index 3a7e9e0..f00d903 100644 --- a/src/bindings/swig/java/CMakeLists.txt +++ b/src/bindings/swig/java/CMakeLists.txt @@ -69,6 +69,7 @@ if (ANT_EXECUTABLE) WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/contrib/java COMMENT "Creating the jar ...") + set_target_properties(java PROPERTIES FOLDER "Bindings") else() message(STATUS "Could not find ant binary - will not build jars") endif()
\ No newline at end of file diff --git a/src/bindings/swig/java/uscxml.i b/src/bindings/swig/java/uscxml.i index 64dfdd5..880b02d 100644 --- a/src/bindings/swig/java/uscxml.i +++ b/src/bindings/swig/java/uscxml.i @@ -101,6 +101,18 @@ WRAP_THROW_EXCEPTION(uscxml::Interpreter::interpret); %include "../../../uscxml/Interpreter.h" %include "../../../uscxml/concurrency/BlockingQueue.h" +%include "../../../uscxml/messages/Blob.h" +%include "../../../uscxml/messages/Data.h" +%include "../../../uscxml/messages/Event.h" +%include "../../../uscxml/messages/InvokeRequest.h" +%include "../../../uscxml/messages/SendRequest.h" + +%include "../../../uscxml/plugins/DataModel.h" +%include "../../../uscxml/plugins/EventHandler.h" +%include "../../../uscxml/plugins/ExecutableContent.h" +%include "../../../uscxml/plugins/Invoker.h" +%include "../../../uscxml/plugins/IOProcessor.h" + %include "../wrapped/WrappedInvoker.h" %include "../wrapped/WrappedDataModel.h" %include "../wrapped/WrappedExecutableContent.h" diff --git a/src/bindings/swig/php/CMakeLists.txt b/src/bindings/swig/php/CMakeLists.txt deleted file mode 100644 index 3884a7f..0000000 --- a/src/bindings/swig/php/CMakeLists.txt +++ /dev/null @@ -1,100 +0,0 @@ -# generate PHP module - -find_package(PHP5) -if(PHP5_FOUND) - include_directories(${PHP5_INCLUDE_PATH}) -else() - message(STATUS "No PHP5 libraries found - not building php module") - return() -endif() - -# copied from cmake's FindPHP4.cmake and adapted -if(APPLE) - # this is a hack for now - set(PHP_MODULE_CXX_FLAGS "${CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS} -Wno-unused-label -Wl,-flat_namespace") - foreach(symbol - __efree - __emalloc - __estrdup - __estrndup - __object_init - __object_init_ex - __zend_get_parameters_array_ex - __zend_list_find - __zval_copy_ctor - __zval_copy_ctor_func - _add_property_zval_ex - _alloc_globals - _compiler_globals - _convert_to_double - _convert_to_long - _convert_to_boolean - __convert_to_string - _gc_remove_zval_from_buffer - _call_user_function - _executor_globals - _zend_get_constant - _zend_lookup_class - _zend_register_long_constant - _zval_is_true - _zend_error - _zend_hash_find - __zend_hash_add_or_update - _zend_register_internal_class_ex - _zend_register_list_destructors_ex - _zend_register_resource - _zend_rsrc_list_get_rsrc_type - _zend_wrong_param_count - _zend_throw_exception - _zval_used_for_init - ) - set(PHP_MODULE_CXX_FLAGS - "${PHP_MODULE_CXX_FLAGS},-U,${symbol}") - endforeach() -endif() - -#message(FATAL_ERROR "PHP_LDFLAGS: ${PHP_LDFLAGS}") - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${PHP_INCLUDE_DIRS}) - -SET(CMAKE_SWIG_FLAGS "") - -# we need ; to produce a space with the package .. weird -SET_SOURCE_FILES_PROPERTIES(uscxml.i PROPERTIES CPLUSPLUS ON) - -SWIG_ADD_MODULE(uscxmlNativePHP php5 uscxml.i) -foreach(PHP_LIBRARY ${PHP_LIBRARIES}) -# SWIG_LINK_LIBRARIES(uscxmlNativePHP ${PHP_LIBRARY}) -endforeach() -SWIG_LINK_LIBRARIES(uscxmlNativePHP uscxml) - -if (APPLE) - set_target_properties(uscxmlNativePHP PROPERTIES LINK_FLAGS ${PHP_MODULE_CXX_FLAGS}) -endif() - -set(PHP_COMPILE_FLAGS "-DSWIG") - -if (PHP_ZTS_ENABLED) - # we are only building php bindings for unices anyhow - set(PHP_COMPILE_FLAGS "${PHP_COMPILE_FLAGS} -DZTS") - set(PHP_COMPILE_FLAGS "${PHP_COMPILE_FLAGS} -DPTHREADS") -endif() -if (PHP_DEBUG_ENABLED) - set(PHP_COMPILE_FLAGS "${PHP_COMPILE_FLAGS} -DZEND_DEBUG") -endif() - -set(USCXML_LANGUAGE_BINDINGS "php ${USCXML_LANGUAGE_BINDINGS}") - -ADD_CUSTOM_COMMAND( - TARGET uscxmlNativePHP - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_BINARY_DIR}/uscxmlNativePHP.php - ${PROJECT_SOURCE_DIR}/src/bindings/swig/php/uscxmlNativePHP.php -) - -set_target_properties(uscxmlNativePHP PROPERTIES COMPILE_FLAGS ${PHP_COMPILE_FLAGS}) -set_target_properties(uscxmlNativePHP PROPERTIES FOLDER "Bindings") -set(USCXML_LANGUAGE_BINDINGS ${USCXML_LANGUAGE_BINDINGS} PARENT_SCOPE) - diff --git a/src/bindings/swig/php/test.php b/src/bindings/swig/php/test.php deleted file mode 100644 index f0c9e06..0000000 --- a/src/bindings/swig/php/test.php +++ /dev/null @@ -1,83 +0,0 @@ -<?php - -require_once('uscxmlNativePHP.php'); - -// $exts = get_loaded_extensions(); -// foreach ($exts as $e) -// { -// echo "Name: ".$e." --"; -// print_r(get_extension_funcs($e)); -// } - -class MyMonitor extends InterpreterMonitor { - function beforeExitingStates($interpreter,$statesToExit) { - print "MyMonitor.beforeExitingStates()\n"; - } - function afterExitingStates($interpreter) { - print "MyMonitor.afterExitingStates()\n"; - } - function beforeEnteringStates($interpreter,$statesToEnter) { - print "MyMonitor.beforeEnteringStates()\n"; - } - function afterEnteringStates($interpreter) { - print "MyMonitor.afterEnteringStates()\n"; - } - function onStableConfiguration($interpreter) { - print "MyMonitor.onStableConfiguration()\n"; - } - function beforeCompletion($interpreter) { - print "MyMonitor.beforeCompletion()\n"; - } - function afterCompletion($interpreter) { - print "MyMonitor.afterCompletion()\n"; - } - function beforeMicroStep($interpreter) { - print "MyMonitor.beforeMicroStep()\n"; - } - function beforeTakingTransitions($interpreter,$transitions) { - print "MyMonitor.beforeTakingTransitions()\n"; - } -} - -$monitor = new MyMonitor(); - -// run interpreter in blocking mode -$interpreter = Interpreter::fromURI('https://raw.github.com/tklab-tud/uscxml/master/test/samples/uscxml/test-ecmascript.scxml'); -$interpreter->addMonitor($monitor); -$interpreter->interpret(); - -// start interpreter as a thread -$interpreter = Interpreter::fromURI('https://raw.github.com/tklab-tud/uscxml/master/test/samples/uscxml/test-invoked.scxml'); -$parentQueue = new ParentQueue(); -$interpreter->setParentQueue($parentQueue); -$interpreter->start(); - -while($interpreter->isRunning()) { - $event = $parentQueue->pop(); - print("Name: " . $event->getName() . "\n"); - print("Type: " . $event->getType() . "\n"); - print("Origin: " . $event->getOrigin() . "\n"); - print("OriginType: " . $event->getOriginType() . "\n"); - print("Content " . strlen($event->getContent()) . "bytes: \n'" . $event->getContent() . "'\n"); - - $namelist = $event->getNameList(); - print("Namelist ".$namelist->size()." elements: \n"); - $keys = $event->getNameListKeys(); - for ($i = 0; $i < $keys->size(); $i++) { - print($keys->get($i) . "\t" . $namelist->get($keys->get($i)) . "\n"); - } - - $params = $event->getParams(); - print("Params ". $params->size() ." elements: \n"); - $keys = $event->getParamKeys(); - for ($i = 0; $i < $keys->size(); $i++) { - print($keys->get($i)."\n"); - $paramList = $params->get($keys->get($i)); - for ($j = 0; $j < $paramList->size(); $j++) { - print("\t" . $paramList->get($i) . "\n"); - } - } - -} - -?>
\ No newline at end of file diff --git a/src/bindings/swig/php/uscxml.i b/src/bindings/swig/php/uscxml.i deleted file mode 100644 index 38421c6..0000000 --- a/src/bindings/swig/php/uscxml.i +++ /dev/null @@ -1,182 +0,0 @@ -%module(directors="1", allprotected="1") uscxmlNativePHP - -// import swig typemaps -%include "stl.i" - -// macros from cmake -%import "uscxml/config.h" - -// disable warning related to unknown base class -#pragma SWIG nowarn=401 - -%rename(c_array) array; -%rename(equals) operator==; -%rename(isValid) operator bool; -%ignore operator!=; -%ignore operator<; -%ignore operator=; -%ignore operator[]; -%ignore operator std::list<Data>; -%ignore operator std::string; -%ignore operator std::map<std::string,Data>; -%ignore operator<<; - -%template(StringMap) std::map<std::string, std::string>; -%template(StringVector) std::vector<std::string>; -%template(Params) std::map<std::string, std::vector<std::string> >; - -//************************************************** -// This ends up in the generated wrapper code -//************************************************** - -%{ -#include "../../../uscxml/Message.h" -#include "../../../uscxml/Interpreter.h" -#include "../../../uscxml/concurrency/BlockingQueue.h" -#include "../../../uscxml/DOMUtils.h" - -using namespace uscxml; - -%} - -// Add this to the very top of the generated wrapper code - -%insert("begin") %{ -void*** tsrm_ls; -%} - -%feature("director") uscxml::InterpreterMonitor; - -%ignore uscxml::NumAttr; -%ignore uscxml::SCXMLParser; -%ignore uscxml::InterpreterImpl; - -//*********************************************** -// Beautify interpreter class -//*********************************************** - -%ignore uscxml::Interpreter::getDelayQueue(); - -%extend uscxml::Interpreter { - std::vector<std::string> getConfiguration() { - std::vector<std::string> config; - Arabica::XPath::NodeSet<std::string> configNodes = self->getConfiguration(); - for (int i = 0; i < configNodes.size(); i++) { - config.push_back(ATTR(configNodes[i], "id")); - } - return config; - } -} -%ignore uscxml::Interpreter::getConfiguration(); - -%extend uscxml::Interpreter { - std::vector<std::string> getBasicConfiguration() { - std::vector<std::string> config; - Arabica::XPath::NodeSet<std::string> configNodes = self->getBasicConfiguration(); - for (int i = 0; i < configNodes.size(); i++) { - config.push_back(ATTR(configNodes[i], "id")); - } - return config; - } -} -%ignore uscxml::Interpreter::getBasicConfiguration(); - -%extend uscxml::Interpreter { - bool isState(const std::string stateId) { - Arabica::DOM::Node<std::string> state = self->getState(stateId); - return self->isState(state); - } -} -%ignore uscxml::Interpreter::isState(Arabica::DOM::Node<std::string>); - -%extend uscxml::Interpreter { - bool isPseudoState(const std::string stateId) { - Arabica::DOM::Node<std::string> state = self->getState(stateId); - return self->isPseudoState(state); - } -} -%ignore uscxml::Interpreter::isPseudoState(Arabica::DOM::Node<std::string>); - -%extend uscxml::Interpreter { - bool isTransitionTarget(const std::string stateId) { - Arabica::DOM::Node<std::string> state = self->getState(stateId); - return self->isTransitionTarget(state); - } -} -%ignore uscxml::Interpreter::isTransitionTarget(Arabica::DOM::Node<std::string>); - -%extend uscxml::Interpreter { - bool isTargetless(const std::string stateId) { - Arabica::DOM::Node<std::string> state = self->getState(stateId); - return self->isTargetless(state); - } -} -%ignore uscxml::Interpreter::isTargetless(Arabica::DOM::Node<std::string>); - -%extend uscxml::Interpreter { - bool isAtomic(const std::string stateId) { - Arabica::DOM::Node<std::string> state = self->getState(stateId); - return self->isAtomic(state); - } -} -%ignore uscxml::Interpreter::isAtomic(Arabica::DOM::Node<std::string>); - -%extend uscxml::Interpreter { - bool isInitial(const std::string stateId) { - Arabica::DOM::Node<std::string> state = self->getState(stateId); - return self->isInitial(state); - } -} -%ignore uscxml::Interpreter::isInitial(Arabica::DOM::Node<std::string>); - -%extend uscxml::Interpreter { - bool isFinal(const std::string stateId) { - Arabica::DOM::Node<std::string> state = self->getState(stateId); - return self->isFinal(state); - } -} -%ignore uscxml::Interpreter::isFinal(Arabica::DOM::Node<std::string>); - -%extend uscxml::Interpreter { - bool isHistory(const std::string stateId) { - Arabica::DOM::Node<std::string> state = self->getState(stateId); - return self->isHistory(state); - } -} -%ignore uscxml::Interpreter::isHistory(Arabica::DOM::Node<std::string>); - -%extend uscxml::Interpreter { - bool isParallel(const std::string stateId) { - Arabica::DOM::Node<std::string> state = self->getState(stateId); - return self->isParallel(state); - } -} -%ignore uscxml::Interpreter::isParallel(Arabica::DOM::Node<std::string>); - -%extend uscxml::Interpreter { - bool isCompound(const std::string stateId) { - Arabica::DOM::Node<std::string> state = self->getState(stateId); - return self->isCompound(state); - } -} -%ignore uscxml::Interpreter::isCompound(Arabica::DOM::Node<std::string>); - -%extend uscxml::Interpreter { - bool isDescendant(const std::string stateId1, const std::string stateId2) { - Arabica::DOM::Node<std::string> state1 = self->getState(stateId1); - Arabica::DOM::Node<std::string> state2 = self->getState(stateId2); - return self->isDescendant(state1, state2); - } -} -%ignore uscxml::Interpreter::isDescendant(Arabica::DOM::Node<std::string>); - -//*********************************************** -// Parse the header file to generate wrappers -//*********************************************** - -%include "../../../uscxml/Common.h" -%include "../../../uscxml/Message.h" -%include "../../../uscxml/Interpreter.h" -%include "../../../uscxml/concurrency/BlockingQueue.h" - -%template(ParentQueue) uscxml::concurrency::BlockingQueue<uscxml::SendRequest>; diff --git a/src/bindings/swig/php/uscxmlNativePHP.php b/src/bindings/swig/php/uscxmlNativePHP.php deleted file mode 100644 index 3aba5be..0000000 --- a/src/bindings/swig/php/uscxmlNativePHP.php +++ /dev/null @@ -1,1313 +0,0 @@ -<?php - -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 2.0.11 - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ - -// Try to load our extension if it's not already loaded. -if (!extension_loaded('uscxmlNativePHP')) { - if (strtolower(substr(PHP_OS, 0, 3)) === 'win') { - if (!dl('php_uscxmlNativePHP.dll')) return; - } else { - // PHP_SHLIB_SUFFIX gives 'dylib' on MacOS X but modules are 'so'. - if (PHP_SHLIB_SUFFIX === 'dylib') { - if (!dl('uscxmlNativePHP.so')) return; - } else { - if (!dl('uscxmlNativePHP.'.PHP_SHLIB_SUFFIX)) return; - } - } -} - - - -abstract class uscxmlNativePHP { - const CAN_NOTHING = 0; - - const CAN_BASIC_HTTP = 1; - - const CAN_GENERIC_HTTP = 2; -} - -/* PHP Proxy Classes */ -class StringMap { - public $_cPtr=null; - protected $_pData=array(); - - function __set($var,$value) { - if ($var === 'thisown') return swig_uscxmlNativePHP_alter_newobject($this->_cPtr,$value); - $this->_pData[$var] = $value; - } - - function __isset($var) { - if ($var === 'thisown') return true; - return array_key_exists($var, $this->_pData); - } - - function __get($var) { - if ($var === 'thisown') return swig_uscxmlNativePHP_get_newobject($this->_cPtr); - return $this->_pData[$var]; - } - - function __construct($arg1=null) { - if (is_resource($arg1) && get_resource_type($arg1) === '_p_std__mapT_std__string_std__string_t') { - $this->_cPtr=$arg1; - return; - } - switch (func_num_args()) { - case 0: $this->_cPtr=new_StringMap(); break; - default: $this->_cPtr=new_StringMap($arg1); - } - } - - function size() { - return StringMap_size($this->_cPtr); - } - - function clear() { - StringMap_clear($this->_cPtr); - } - - function get($key) { - return StringMap_get($this->_cPtr,$key); - } - - function set($key,$x) { - StringMap_set($this->_cPtr,$key,$x); - } - - function del($key) { - StringMap_del($this->_cPtr,$key); - } - - function has_key($key) { - return StringMap_has_key($this->_cPtr,$key); - } - - function is_empty() { - return StringMap_is_empty($this->_cPtr); - } -} - -class StringVector { - public $_cPtr=null; - protected $_pData=array(); - - function __set($var,$value) { - if ($var === 'thisown') return swig_uscxmlNativePHP_alter_newobject($this->_cPtr,$value); - $this->_pData[$var] = $value; - } - - function __isset($var) { - if ($var === 'thisown') return true; - return array_key_exists($var, $this->_pData); - } - - function __get($var) { - if ($var === 'thisown') return swig_uscxmlNativePHP_get_newobject($this->_cPtr); - return $this->_pData[$var]; - } - - function __construct($n=null) { - if (is_resource($n) && get_resource_type($n) === '_p_std__vectorT_std__string_t') { - $this->_cPtr=$n; - return; - } - switch (func_num_args()) { - case 0: $this->_cPtr=new_StringVector(); break; - default: $this->_cPtr=new_StringVector($n); - } - } - - function size() { - return StringVector_size($this->_cPtr); - } - - function capacity() { - return StringVector_capacity($this->_cPtr); - } - - function reserve($n) { - StringVector_reserve($this->_cPtr,$n); - } - - function clear() { - StringVector_clear($this->_cPtr); - } - - function push($x) { - StringVector_push($this->_cPtr,$x); - } - - function is_empty() { - return StringVector_is_empty($this->_cPtr); - } - - function pop() { - return StringVector_pop($this->_cPtr); - } - - function get($i) { - return StringVector_get($this->_cPtr,$i); - } - - function set($i,$val) { - StringVector_set($this->_cPtr,$i,$val); - } -} - -class Params { - public $_cPtr=null; - protected $_pData=array(); - - function __set($var,$value) { - if ($var === 'thisown') return swig_uscxmlNativePHP_alter_newobject($this->_cPtr,$value); - $this->_pData[$var] = $value; - } - - function __isset($var) { - if ($var === 'thisown') return true; - return array_key_exists($var, $this->_pData); - } - - function __get($var) { - if ($var === 'thisown') return swig_uscxmlNativePHP_get_newobject($this->_cPtr); - return $this->_pData[$var]; - } - - function __construct($arg1=null) { - if (is_resource($arg1) && get_resource_type($arg1) === '_p_std__mapT_std__string_std__vectorT_std__string_t_t') { - $this->_cPtr=$arg1; - return; - } - switch (func_num_args()) { - case 0: $this->_cPtr=new_Params(); break; - default: $this->_cPtr=new_Params($arg1); - } - } - - function size() { - return Params_size($this->_cPtr); - } - - function clear() { - Params_clear($this->_cPtr); - } - - function get($key) { - $r=Params_get($this->_cPtr,$key); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new StringVector($r); - } - return $r; - } - - function set($key,$x) { - Params_set($this->_cPtr,$key,$x); - } - - function del($key) { - Params_del($this->_cPtr,$key); - } - - function has_key($key) { - return Params_has_key($this->_cPtr,$key); - } - - function is_empty() { - return Params_is_empty($this->_cPtr); - } -} - -class Blob { - public $_cPtr=null; - protected $_pData=array(); - - function __set($var,$value) { - $func = 'Blob_'.$var.'_set'; - if (function_exists($func)) return call_user_func($func,$this->_cPtr,$value); - if ($var === 'thisown') return swig_uscxmlNativePHP_alter_newobject($this->_cPtr,$value); - $this->_pData[$var] = $value; - } - - function __isset($var) { - if (function_exists('Blob_'.$var.'_set')) return true; - if ($var === 'thisown') return true; - return array_key_exists($var, $this->_pData); - } - - function __get($var) { - $func = 'Blob_'.$var.'_get'; - if (function_exists($func)) return call_user_func($func,$this->_cPtr); - if ($var === 'thisown') return swig_uscxmlNativePHP_get_newobject($this->_cPtr); - return $this->_pData[$var]; - } - - function __construct($size_or_data,$size=null,$mimeType=null,$adopt=false) { - if (is_resource($size_or_data) && get_resource_type($size_or_data) === '_p_uscxml__Blob') { - $this->_cPtr=$size_or_data; - return; - } - switch (func_num_args()) { - case 1: $this->_cPtr=new_Blob($size_or_data); break; - case 2: $this->_cPtr=new_Blob($size_or_data,$size); break; - default: $this->_cPtr=new_Blob($size_or_data,$size,$mimeType,$adopt); - } - } - - function md5() { - return Blob_md5($this->_cPtr); - } - - function base64() { - return Blob_base64($this->_cPtr); - } - - function fromBase64($base64) { - $r=Blob_fromBase64($this->_cPtr,$base64); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new Blob($r); - } - return $r; - } -} - -class Data { - public $_cPtr=null; - protected $_pData=array(); - - function __set($var,$value) { - $func = 'Data_'.$var.'_set'; - if (function_exists($func)) return call_user_func($func,$this->_cPtr,$value); - if ($var === 'thisown') return swig_uscxmlNativePHP_alter_newobject($this->_cPtr,$value); - $this->_pData[$var] = $value; - } - - function __isset($var) { - if (function_exists('Data_'.$var.'_set')) return true; - if ($var === 'thisown') return true; - return array_key_exists($var, $this->_pData); - } - - function __get($var) { - $func = 'Data_'.$var.'_get'; - if (function_exists($func)) return call_user_func($func,$this->_cPtr); - if ($var === 'thisown') return swig_uscxmlNativePHP_get_newobject($this->_cPtr); - return $this->_pData[$var]; - } - - const VERBATIM = 0; - - const INTERPRETED = Data_INTERPRETED; - - function __construct($atom__or_data_or_dom=null,$type__or_size=null,$mimeType=null,$adopt=null) { - if (is_resource($atom__or_data_or_dom) && get_resource_type($atom__or_data_or_dom) === '_p_uscxml__Data') { - $this->_cPtr=$atom__or_data_or_dom; - return; - } - switch (func_num_args()) { - case 0: $this->_cPtr=new_Data(); break; - case 1: $this->_cPtr=new_Data($atom__or_data_or_dom); break; - case 2: $this->_cPtr=new_Data($atom__or_data_or_dom,$type__or_size); break; - case 3: $this->_cPtr=new_Data($atom__or_data_or_dom,$type__or_size,$mimeType); break; - default: $this->_cPtr=new_Data($atom__or_data_or_dom,$type__or_size,$mimeType,$adopt); - } - } - - function isValid() { - return Data_isValid($this->_cPtr); - } - - function hasKey($key) { - return Data_hasKey($this->_cPtr,$key); - } - - static function fromJSON($jsonString) { - $r=Data_fromJSON($jsonString); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new Data($r); - } - return $r; - } - - static function toJSON($data) { - return Data_toJSON($data); - } - - static function fromXML($xmlString) { - $r=Data_fromXML($xmlString); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new Data($r); - } - return $r; - } - - function toDocument() { - return Data_toDocument($this->_cPtr); - } - - function toXMLString() { - return Data_toXMLString($this->_cPtr); - } - - function getCompound() { - return Data_getCompound($this->_cPtr); - } - - function setCompound($compound) { - Data_setCompound($this->_cPtr,$compound); - } - - function getArray() { - return Data_getArray($this->_cPtr); - } - - function setArray($array) { - Data_setArray($this->_cPtr,$array); - } - - function getAtom() { - return Data_getAtom($this->_cPtr); - } - - function setAtom($atom) { - Data_setAtom($this->_cPtr,$atom); - } - - function getType() { - return Data_getType($this->_cPtr); - } - - function setType($type) { - Data_setType($this->_cPtr,$type); - } -} - -class Event { - public $_cPtr=null; - protected $_pData=array(); - - function __set($var,$value) { - $func = 'Event_'.$var.'_set'; - if (function_exists($func)) return call_user_func($func,$this->_cPtr,$value); - if ($var === 'thisown') return swig_uscxmlNativePHP_alter_newobject($this->_cPtr,$value); - $this->_pData[$var] = $value; - } - - function __isset($var) { - if (function_exists('Event_'.$var.'_set')) return true; - if ($var === 'thisown') return true; - return array_key_exists($var, $this->_pData); - } - - function __get($var) { - if ($var === 'data') return new Data(Event_data_get($this->_cPtr)); - $func = 'Event_'.$var.'_get'; - if (function_exists($func)) return call_user_func($func,$this->_cPtr); - if ($var === 'thisown') return swig_uscxmlNativePHP_get_newobject($this->_cPtr); - return $this->_pData[$var]; - } - - const INTERNAL = 1; - - const EXTERNAL = 2; - - const PLATFORM = 3; - - function __construct($name_or_xmlString=null,$type=null) { - if (is_resource($name_or_xmlString) && get_resource_type($name_or_xmlString) === '_p_uscxml__Event') { - $this->_cPtr=$name_or_xmlString; - return; - } - switch (func_num_args()) { - case 0: $this->_cPtr=new_Event(); break; - case 1: $this->_cPtr=new_Event($name_or_xmlString); break; - default: $this->_cPtr=new_Event($name_or_xmlString,$type); - } - } - - function getName() { - return Event_getName($this->_cPtr); - } - - function setName($name) { - Event_setName($this->_cPtr,$name); - } - - function getEventType() { - return Event_getEventType($this->_cPtr); - } - - function setEventType($type) { - Event_setEventType($this->_cPtr,$type); - } - - function getOrigin() { - return Event_getOrigin($this->_cPtr); - } - - function setOrigin($origin) { - Event_setOrigin($this->_cPtr,$origin); - } - - function getOriginType() { - return Event_getOriginType($this->_cPtr); - } - - function setOriginType($originType) { - Event_setOriginType($this->_cPtr,$originType); - } - - function getDOM() { - return Event_getDOM($this->_cPtr); - } - - function setDOM($dom) { - Event_setDOM($this->_cPtr,$dom); - } - - function getRaw() { - return Event_getRaw($this->_cPtr); - } - - function setRaw($raw) { - Event_setRaw($this->_cPtr,$raw); - } - - function getContent() { - return Event_getContent($this->_cPtr); - } - - function setContent($content) { - Event_setContent($this->_cPtr,$content); - } - - function getXML() { - return Event_getXML($this->_cPtr); - } - - function setXML($xml) { - Event_setXML($this->_cPtr,$xml); - } - - function getSendId() { - return Event_getSendId($this->_cPtr); - } - - function setSendId($sendId) { - Event_setSendId($this->_cPtr,$sendId); - } - - function getInvokeId() { - return Event_getInvokeId($this->_cPtr); - } - - function setInvokeId($invokeId) { - Event_setInvokeId($this->_cPtr,$invokeId); - } - - function getData() { - $r=Event_getData($this->_cPtr); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new Data($r); - } - return $r; - } - - function setData($data) { - Event_setData($this->_cPtr,$data); - } - - function initContent($content) { - Event_initContent($this->_cPtr,$content); - } - - static function fromXML($xmlString) { - $r=Event_fromXML($xmlString); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new Event($r); - } - return $r; - } - - function toDocument() { - return Event_toDocument($this->_cPtr); - } - - function toXMLString() { - return Event_toXMLString($this->_cPtr); - } - - function getNameList() { - return Event_getNameList($this->_cPtr); - } - - function getParams() { - return Event_getParams($this->_cPtr); - } - - static function getParam($params,$name,$target) { - return Event_getParam($params,$name,$target); - } -} - -class InvokeRequest extends Event { - public $_cPtr=null; - - function __set($var,$value) { - $func = 'InvokeRequest_'.$var.'_set'; - if (function_exists($func)) return call_user_func($func,$this->_cPtr,$value); - if ($var === 'thisown') return swig_uscxmlNativePHP_alter_newobject($this->_cPtr,$value); - Event::__set($var,$value); - } - - function __isset($var) { - if (function_exists('InvokeRequest_'.$var.'_set')) return true; - if ($var === 'thisown') return true; - return Event::__isset($var); - } - - function __get($var) { - $func = 'InvokeRequest_'.$var.'_get'; - if (function_exists($func)) return call_user_func($func,$this->_cPtr); - if ($var === 'thisown') return swig_uscxmlNativePHP_get_newobject($this->_cPtr); - return Event::__get($var); - } - - function __construct($event=null) { - if (is_resource($event) && get_resource_type($event) === '_p_uscxml__InvokeRequest') { - $this->_cPtr=$event; - return; - } - switch (func_num_args()) { - case 0: $this->_cPtr=new_InvokeRequest(); break; - default: $this->_cPtr=new_InvokeRequest($event); - } - } - - function getType() { - return InvokeRequest_getType($this->_cPtr); - } - - function setType($type) { - InvokeRequest_setType($this->_cPtr,$type); - } - - function getSource() { - return InvokeRequest_getSource($this->_cPtr); - } - - function setSource($src) { - InvokeRequest_setSource($this->_cPtr,$src); - } - - function isAutoForwarded() { - return InvokeRequest_isAutoForwarded($this->_cPtr); - } - - function setAutoForwarded($autoForward) { - InvokeRequest_setAutoForwarded($this->_cPtr,$autoForward); - } - - static function fromXML($xmlString) { - $r=InvokeRequest_fromXML($xmlString); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new InvokeRequest($r); - } - return $r; - } - - function toDocument() { - return InvokeRequest_toDocument($this->_cPtr); - } - - function toXMLString() { - return InvokeRequest_toXMLString($this->_cPtr); - } -} - -class SendRequest extends Event { - public $_cPtr=null; - - function __set($var,$value) { - $func = 'SendRequest_'.$var.'_set'; - if (function_exists($func)) return call_user_func($func,$this->_cPtr,$value); - if ($var === 'thisown') return swig_uscxmlNativePHP_alter_newobject($this->_cPtr,$value); - Event::__set($var,$value); - } - - function __isset($var) { - if (function_exists('SendRequest_'.$var.'_set')) return true; - if ($var === 'thisown') return true; - return Event::__isset($var); - } - - function __get($var) { - $func = 'SendRequest_'.$var.'_get'; - if (function_exists($func)) return call_user_func($func,$this->_cPtr); - if ($var === 'thisown') return swig_uscxmlNativePHP_get_newobject($this->_cPtr); - return Event::__get($var); - } - - function __construct($event=null) { - if (is_resource($event) && get_resource_type($event) === '_p_uscxml__SendRequest') { - $this->_cPtr=$event; - return; - } - switch (func_num_args()) { - case 0: $this->_cPtr=new_SendRequest(); break; - default: $this->_cPtr=new_SendRequest($event); - } - } - - function getTarget() { - return SendRequest_getTarget($this->_cPtr); - } - - function setTarget($target) { - SendRequest_setTarget($this->_cPtr,$target); - } - - function getType() { - return SendRequest_getType($this->_cPtr); - } - - function setType($type) { - SendRequest_setType($this->_cPtr,$type); - } - - function getDelayMs() { - return SendRequest_getDelayMs($this->_cPtr); - } - - function setDelayMs($delayMs) { - SendRequest_setDelayMs($this->_cPtr,$delayMs); - } - - static function fromXML($xmlString) { - $r=SendRequest_fromXML($xmlString); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new SendRequest($r); - } - return $r; - } - - function toDocument() { - return SendRequest_toDocument($this->_cPtr); - } - - function toXMLString() { - return SendRequest_toXMLString($this->_cPtr); - } -} - -class InterpreterOptions { - public $_cPtr=null; - protected $_pData=array(); - - function __set($var,$value) { - $func = 'InterpreterOptions_'.$var.'_set'; - if (function_exists($func)) return call_user_func($func,$this->_cPtr,$value); - if ($var === 'thisown') return swig_uscxmlNativePHP_alter_newobject($this->_cPtr,$value); - $this->_pData[$var] = $value; - } - - function __isset($var) { - if (function_exists('InterpreterOptions_'.$var.'_set')) return true; - if ($var === 'thisown') return true; - return array_key_exists($var, $this->_pData); - } - - function __get($var) { - if ($var === 'additionalParameters') return new StringMap(InterpreterOptions_additionalParameters_get($this->_cPtr)); - $func = 'InterpreterOptions_'.$var.'_get'; - if (function_exists($func)) return call_user_func($func,$this->_cPtr); - if ($var === 'thisown') return swig_uscxmlNativePHP_get_newobject($this->_cPtr); - return $this->_pData[$var]; - } - function __construct($h) { - $this->_cPtr=$h; - } - - function isValid() { - return InterpreterOptions_isValid($this->_cPtr); - } - - static function printUsageAndExit($progName) { - InterpreterOptions_printUsageAndExit($progName); - } - - static function fromCmdLine($argc,$argv) { - $r=InterpreterOptions_fromCmdLine($argc,$argv); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new InterpreterOptions($r); - } - return $r; - } - - function getCapabilities() { - return InterpreterOptions_getCapabilities($this->_cPtr); - } -} - -class Interpreter { - public $_cPtr=null; - protected $_pData=array(); - - function __set($var,$value) { - if ($var === 'thisown') return swig_uscxmlNativePHP_alter_newobject($this->_cPtr,$value); - $this->_pData[$var] = $value; - } - - function __isset($var) { - if ($var === 'thisown') return true; - return array_key_exists($var, $this->_pData); - } - - function __get($var) { - if ($var === 'thisown') return swig_uscxmlNativePHP_get_newobject($this->_cPtr); - return $this->_pData[$var]; - } - - static function fromDOM($dom) { - $r=Interpreter_fromDOM($dom); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new Interpreter($r); - } - return $r; - } - - static function fromXML($xml) { - $r=Interpreter_fromXML($xml); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new Interpreter($r); - } - return $r; - } - - static function fromURI($uri) { - $r=Interpreter_fromURI($uri); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new Interpreter($r); - } - return $r; - } - - static function fromInputSource($source) { - $r=Interpreter_fromInputSource($source); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new Interpreter($r); - } - return $r; - } - - function __construct($impl_or_other=null) { - if (is_resource($impl_or_other) && get_resource_type($impl_or_other) === '_p_uscxml__Interpreter') { - $this->_cPtr=$impl_or_other; - return; - } - switch (func_num_args()) { - case 0: $this->_cPtr=new_Interpreter(); break; - default: $this->_cPtr=new_Interpreter($impl_or_other); - } - } - - function isValid() { - return Interpreter_isValid($this->_cPtr); - } - - function equals($other) { - return Interpreter_equals($this->_cPtr,$other); - } - - function start() { - Interpreter_start($this->_cPtr); - } - - function join() { - Interpreter_join($this->_cPtr); - } - - function isRunning() { - return Interpreter_isRunning($this->_cPtr); - } - - function interpret() { - Interpreter_interpret($this->_cPtr); - } - - function addMonitor($monitor) { - Interpreter_addMonitor($this->_cPtr,$monitor); - } - - function removeMonitor($monitor) { - Interpreter_removeMonitor($this->_cPtr,$monitor); - } - - function setBaseURI($baseURI) { - Interpreter_setBaseURI($this->_cPtr,$baseURI); - } - - function getBaseURI() { - return Interpreter_getBaseURI($this->_cPtr); - } - - function setNameSpaceInfo($namespaceInfo) { - Interpreter_setNameSpaceInfo($this->_cPtr,$namespaceInfo); - } - - function getNameSpaceInfo() { - $r=Interpreter_getNameSpaceInfo($this->_cPtr); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new StringMap($r); - } - return $r; - } - - function setCmdLineOptions($params) { - Interpreter_setCmdLineOptions($this->_cPtr,$params); - } - - function getCmdLineOptions() { - $r=Interpreter_getCmdLineOptions($this->_cPtr); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new Data($r); - } - return $r; - } - - function getHTTPServlet() { - return Interpreter_getHTTPServlet($this->_cPtr); - } - - function getDataModel() { - return Interpreter_getDataModel($this->_cPtr); - } - - function setParentQueue($parentQueue) { - Interpreter_setParentQueue($this->_cPtr,$parentQueue); - } - - function setFactory($factory) { - Interpreter_setFactory($this->_cPtr,$factory); - } - - function getFactory() { - return Interpreter_getFactory($this->_cPtr); - } - - function getXPathPrefix() { - return Interpreter_getXPathPrefix($this->_cPtr); - } - - function getXMLPrefix() { - return Interpreter_getXMLPrefix($this->_cPtr); - } - - function getNSContext() { - return Interpreter_getNSContext($this->_cPtr); - } - - function getXMLPrefixForNS($ns) { - return Interpreter_getXMLPrefixForNS($this->_cPtr,$ns); - } - - function receiveInternal($event) { - Interpreter_receiveInternal($this->_cPtr,$event); - } - - function receive($event,$toFront=false) { - Interpreter_receive($this->_cPtr,$event,$toFront); - } - - function getCurrentEvent() { - $r=Interpreter_getCurrentEvent($this->_cPtr); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new Event($r); - } - return $r; - } - - function setConfiguration($states) { - Interpreter_setConfiguration($this->_cPtr,$states); - } - - function setInvokeRequest($req) { - Interpreter_setInvokeRequest($this->_cPtr,$req); - } - - function getState($stateId) { - return Interpreter_getState($this->_cPtr,$stateId); - } - - function getStates($stateIds) { - return Interpreter_getStates($this->_cPtr,$stateIds); - } - - function getDocument() { - return Interpreter_getDocument($this->_cPtr); - } - - function setCapabilities($capabilities) { - Interpreter_setCapabilities($this->_cPtr,$capabilities); - } - - function setName($name) { - Interpreter_setName($this->_cPtr,$name); - } - - function getName() { - return Interpreter_getName($this->_cPtr); - } - - function getSessionId() { - return Interpreter_getSessionId($this->_cPtr); - } - - function getIOProcessors() { - return Interpreter_getIOProcessors($this->_cPtr); - } - - function getInvokers() { - return Interpreter_getInvokers($this->_cPtr); - } - - function runOnMainThread($fps,$blocking=true) { - return Interpreter_runOnMainThread($this->_cPtr,$fps,$blocking); - } - - static function isMember($node,$set) { - return Interpreter_isMember($node,$set); - } - - function dump() { - Interpreter_dump($this->_cPtr); - } - - function hasLegalConfiguration() { - return Interpreter_hasLegalConfiguration($this->_cPtr); - } - - function isLegalConfiguration($config) { - return Interpreter_isLegalConfiguration($this->_cPtr,$config); - } - - static function tokenizeIdRefs($idRefs) { - return Interpreter_tokenizeIdRefs($idRefs); - } - - static function spaceNormalize($text) { - return Interpreter_spaceNormalize($text); - } - - function getInitialStates($state=null) { - switch (func_num_args()) { - case 0: $r=Interpreter_getInitialStates($this->_cPtr); break; - default: $r=Interpreter_getInitialStates($this->_cPtr,$state); - } - return $r; - } - - static function getChildStates($state) { - return Interpreter_getChildStates($state); - } - - static function getParentState($element) { - return Interpreter_getParentState($element); - } - - static function getAncestorElement($node,$tagName) { - return Interpreter_getAncestorElement($node,$tagName); - } - - function getTargetStates($transition) { - return Interpreter_getTargetStates($this->_cPtr,$transition); - } - - function getSourceState($transition) { - return Interpreter_getSourceState($this->_cPtr,$transition); - } - - static function filterChildElements($tagname_or_tagName,$node_or_nodeSet) { - return Interpreter_filterChildElements($tagname_or_tagName,$node_or_nodeSet); - } - - function findLCCA($states) { - return Interpreter_findLCCA($this->_cPtr,$states); - } - - function getProperAncestors($s1,$s2) { - return Interpreter_getProperAncestors($this->_cPtr,$s1,$s2); - } - - function getImpl() { - return Interpreter_getImpl($this->_cPtr); - } - - static function getInstances() { - return Interpreter_getInstances(); - } - - function getConfiguration() { - $r=Interpreter_getConfiguration($this->_cPtr); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new StringVector($r); - } - return $r; - } - - function getBasicConfiguration() { - $r=Interpreter_getBasicConfiguration($this->_cPtr); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new StringVector($r); - } - return $r; - } - - function isState($stateId=null) { - switch (func_num_args()) { - case 0: $r=Interpreter_isState($this->_cPtr); break; - default: $r=Interpreter_isState($this->_cPtr,$stateId); - } - return $r; - } - - function isPseudoState($stateId=null) { - switch (func_num_args()) { - case 0: $r=Interpreter_isPseudoState($this->_cPtr); break; - default: $r=Interpreter_isPseudoState($this->_cPtr,$stateId); - } - return $r; - } - - function isTransitionTarget($stateId=null) { - switch (func_num_args()) { - case 0: $r=Interpreter_isTransitionTarget($this->_cPtr); break; - default: $r=Interpreter_isTransitionTarget($this->_cPtr,$stateId); - } - return $r; - } - - function isTargetless($stateId=null) { - switch (func_num_args()) { - case 0: $r=Interpreter_isTargetless($this->_cPtr); break; - default: $r=Interpreter_isTargetless($this->_cPtr,$stateId); - } - return $r; - } - - function isAtomic($stateId=null) { - switch (func_num_args()) { - case 0: $r=Interpreter_isAtomic($this->_cPtr); break; - default: $r=Interpreter_isAtomic($this->_cPtr,$stateId); - } - return $r; - } - - function isInitial($state_or_stateId) { - return Interpreter_isInitial($this->_cPtr,$state_or_stateId); - } - - function isFinal($stateId=null) { - switch (func_num_args()) { - case 0: $r=Interpreter_isFinal($this->_cPtr); break; - default: $r=Interpreter_isFinal($this->_cPtr,$stateId); - } - return $r; - } - - function isHistory($stateId=null) { - switch (func_num_args()) { - case 0: $r=Interpreter_isHistory($this->_cPtr); break; - default: $r=Interpreter_isHistory($this->_cPtr,$stateId); - } - return $r; - } - - function isParallel($stateId=null) { - switch (func_num_args()) { - case 0: $r=Interpreter_isParallel($this->_cPtr); break; - default: $r=Interpreter_isParallel($this->_cPtr,$stateId); - } - return $r; - } - - function isCompound($stateId=null) { - switch (func_num_args()) { - case 0: $r=Interpreter_isCompound($this->_cPtr); break; - default: $r=Interpreter_isCompound($this->_cPtr,$stateId); - } - return $r; - } - - function isDescendant($s2_or_stateId1,$stateId2=null) { - switch (func_num_args()) { - case 1: $r=Interpreter_isDescendant($this->_cPtr,$s2_or_stateId1); break; - default: $r=Interpreter_isDescendant($this->_cPtr,$s2_or_stateId1,$stateId2); - } - return $r; - } -} - -class InterpreterMonitor { - public $_cPtr=null; - protected $_pData=array(); - - function __set($var,$value) { - if ($var === 'thisown') return swig_uscxmlNativePHP_alter_newobject($this->_cPtr,$value); - $this->_pData[$var] = $value; - } - - function __isset($var) { - if ($var === 'thisown') return true; - return array_key_exists($var, $this->_pData); - } - - function __get($var) { - if ($var === 'thisown') return swig_uscxmlNativePHP_get_newobject($this->_cPtr); - return $this->_pData[$var]; - } - - function onStableConfiguration($interpreter) { - InterpreterMonitor_onStableConfiguration($this->_cPtr,$interpreter); - } - - function beforeCompletion($interpreter) { - InterpreterMonitor_beforeCompletion($this->_cPtr,$interpreter); - } - - function afterCompletion($interpreter) { - InterpreterMonitor_afterCompletion($this->_cPtr,$interpreter); - } - - function beforeMicroStep($interpreter) { - InterpreterMonitor_beforeMicroStep($this->_cPtr,$interpreter); - } - - function beforeTakingTransitions($interpreter,$transitions) { - InterpreterMonitor_beforeTakingTransitions($this->_cPtr,$interpreter,$transitions); - } - - function beforeEnteringStates($interpreter,$statesToEnter) { - InterpreterMonitor_beforeEnteringStates($this->_cPtr,$interpreter,$statesToEnter); - } - - function afterEnteringStates($interpreter) { - InterpreterMonitor_afterEnteringStates($this->_cPtr,$interpreter); - } - - function beforeExitingStates($interpreter,$statesToExit) { - InterpreterMonitor_beforeExitingStates($this->_cPtr,$interpreter,$statesToExit); - } - - function afterExitingStates($interpreter) { - InterpreterMonitor_afterExitingStates($this->_cPtr,$interpreter); - } - - function __construct($res=null) { - if (is_resource($res) && get_resource_type($res) === '_p_uscxml__InterpreterMonitor') { - $this->_cPtr=$res; - return; - } - if (get_class($this) === 'InterpreterMonitor') { - $_this = null; - } else { - $_this = $this; - } - $this->_cPtr=new_InterpreterMonitor($_this); - } -} - -class ParentQueue { - public $_cPtr=null; - protected $_pData=array(); - - function __set($var,$value) { - if ($var === 'thisown') return swig_uscxmlNativePHP_alter_newobject($this->_cPtr,$value); - $this->_pData[$var] = $value; - } - - function __isset($var) { - if ($var === 'thisown') return true; - return array_key_exists($var, $this->_pData); - } - - function __get($var) { - if ($var === 'thisown') return swig_uscxmlNativePHP_get_newobject($this->_cPtr); - return $this->_pData[$var]; - } - - function __construct($res=null) { - if (is_resource($res) && get_resource_type($res) === '_p_uscxml__concurrency__BlockingQueueT_uscxml__SendRequest_t') { - $this->_cPtr=$res; - return; - } - $this->_cPtr=new_ParentQueue(); - } - - function push($elem) { - ParentQueue_push($this->_cPtr,$elem); - } - - function push_front($elem) { - ParentQueue_push_front($this->_cPtr,$elem); - } - - function pop() { - $r=ParentQueue_pop($this->_cPtr); - if (is_resource($r)) { - $c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3)); - if (class_exists($c)) return new $c($r); - return new SendRequest($r); - } - return $r; - } - - function isEmpty() { - return ParentQueue_isEmpty($this->_cPtr); - } -} - - -?> diff --git a/src/bindings/swig/uscxml_ignores.i b/src/bindings/swig/uscxml_ignores.i index 38b3e9e..c5bf88b 100644 --- a/src/bindings/swig/uscxml_ignores.i +++ b/src/bindings/swig/uscxml_ignores.i @@ -93,6 +93,7 @@ %ignore uscxml::DataModel::DataModel(const DataModel&); %ignore uscxml::DataModel::eval(const Arabica::DOM::Element<std::string>&, const std::string&); %ignore uscxml::DataModel::evalAsBool(const Arabica::DOM::Node<std::string>&, const std::string&); +%ignore uscxml::DataModel::evalAsBool(const std::string&); %ignore uscxml::DataModel::throwErrorExecution(const std::string&); %ignore uscxml::DataModel::throwErrorPlatform(const std::string&); %ignore uscxml::DataModel::init(const Arabica::DOM::Element<std::string>&, const Arabica::DOM::Document<std::string>&, const std::string&); @@ -174,9 +175,11 @@ %ignore uscxml::Event::getFirstDOMElement; %ignore uscxml::Event::dom; %ignore uscxml::Event::getDOM(); +%ignore uscxml::Event::setDOM(const Arabica::DOM::Node<std::string>&); %ignore uscxml::Event::setDOM(const Arabica::DOM::Document<std::string>&); %ignore uscxml::Event::toDocument(); %ignore uscxml::Event::getParams(); +%ignore uscxml::Event::getParam; // Data diff --git a/src/bindings/swig/wrapped/WrappedDataModel.h b/src/bindings/swig/wrapped/WrappedDataModel.h index 0d0630c..013f22c 100644 --- a/src/bindings/swig/wrapped/WrappedDataModel.h +++ b/src/bindings/swig/wrapped/WrappedDataModel.h @@ -20,8 +20,15 @@ #ifndef WRAPPEDDATAMODEL_H_DBAAD6AF #define WRAPPEDDATAMODEL_H_DBAAD6AF -#include "../../../uscxml/Message.h" -#include "../../../uscxml/Factory.h" +#include <vector> +#include <list> +#include <ostream> +#include <string> + +#include <DOM/Document.hpp> +#include <DOM/io/Stream.hpp> + +#include "../../../uscxml/plugins/DataModel.h" #include "../../../uscxml/Interpreter.h" namespace uscxml { diff --git a/src/bindings/swig/wrapped/WrappedExecutableContent.h b/src/bindings/swig/wrapped/WrappedExecutableContent.h index fb09e54..e00704a 100644 --- a/src/bindings/swig/wrapped/WrappedExecutableContent.h +++ b/src/bindings/swig/wrapped/WrappedExecutableContent.h @@ -20,6 +20,13 @@ #ifndef WRAPPEDEXECUTABLECONTENT_H_F690F480 #define WRAPPEDEXECUTABLECONTENT_H_F690F480 +#include <vector> +#include <ostream> +#include <string> + +#include <DOM/Document.hpp> +#include <DOM/io/Stream.hpp> + #include "../../../uscxml/Message.h" #include "../../../uscxml/Factory.h" #include "../../../uscxml/Interpreter.h" diff --git a/src/bindings/swig/wrapped/WrappedIOProcessor.h b/src/bindings/swig/wrapped/WrappedIOProcessor.h index 716d9f4..1d134dc 100644 --- a/src/bindings/swig/wrapped/WrappedIOProcessor.h +++ b/src/bindings/swig/wrapped/WrappedIOProcessor.h @@ -20,6 +20,14 @@ #ifndef WRAPPEDIOPROCESSOR_H_AE98064A #define WRAPPEDIOPROCESSOR_H_AE98064A +#include <vector> +#include <list> +#include <ostream> +#include <string> + +#include <DOM/Document.hpp> +#include <DOM/io/Stream.hpp> + #include "../../../uscxml/Message.h" #include "../../../uscxml/Factory.h" #include "../../../uscxml/Interpreter.h" diff --git a/src/bindings/swig/wrapped/WrappedInterpreterMonitor.h b/src/bindings/swig/wrapped/WrappedInterpreterMonitor.h index 57372ea..0aac660 100644 --- a/src/bindings/swig/wrapped/WrappedInterpreterMonitor.h +++ b/src/bindings/swig/wrapped/WrappedInterpreterMonitor.h @@ -20,6 +20,13 @@ #ifndef WRAPPEDINTERPRETERMONITOR_H_F5C83A0D #define WRAPPEDINTERPRETERMONITOR_H_F5C83A0D +#include <vector> +#include <list> +#include <ostream> +#include <string> + +#include <DOM/Document.hpp> +#include <DOM/io/Stream.hpp> #include "../../../uscxml/Message.h" #include "../../../uscxml/Factory.h" diff --git a/src/bindings/swig/wrapped/WrappedInvoker.h b/src/bindings/swig/wrapped/WrappedInvoker.h index ff56b15..b3ff200 100644 --- a/src/bindings/swig/wrapped/WrappedInvoker.h +++ b/src/bindings/swig/wrapped/WrappedInvoker.h @@ -20,6 +20,14 @@ #ifndef WRAPPEDINVOKER_H_F9725D47 #define WRAPPEDINVOKER_H_F9725D47 +#include <vector> +#include <list> +#include <ostream> +#include <string> + +#include <DOM/Document.hpp> +#include <DOM/io/Stream.hpp> + #include "../../../uscxml/Message.h" #include "../../../uscxml/Factory.h" #include "../../../uscxml/Interpreter.h" diff --git a/src/uscxml/CMakeLists.txt b/src/uscxml/CMakeLists.txt index da620fb..c38bcbf 100644 --- a/src/uscxml/CMakeLists.txt +++ b/src/uscxml/CMakeLists.txt @@ -25,6 +25,13 @@ file(GLOB_RECURSE USCXML_CONCURRENCY source_group("Interpreter" FILES ${USCXML_CONCURRENCY}) list (APPEND USCXML_FILES ${USCXML_CONCURRENCY}) +file(GLOB_RECURSE USCXML_MESSAGES + messages/*.cpp + messages/*.h +) +source_group("Interpreter" FILES ${USCXML_MESSAGES}) +list (APPEND USCXML_FILES ${USCXML_MESSAGES}) + file(GLOB_RECURSE USCXML_DEBUG debug/*.cpp debug/*.h @@ -63,6 +70,16 @@ file(GLOB USCXML_CORE source_group("Interpreter" FILES ${USCXML_CORE}) list (APPEND USCXML_FILES ${USCXML_CORE}) +file(GLOB USCXML_PLUGINS + plugins/DataModel.h + plugins/EventHandler.h + plugins/ExecutableContent.h + plugins/Invoker.h + plugins/IOProcessor.h +) +source_group("Interpreter" FILES ${USCXML_PLUGINS}) +list (APPEND USCXML_FILES ${USCXML_PLUGINS}) + if (BUILD_AS_PLUGINS) list (APPEND USCXML_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/plugins) file(GLOB PLUMA diff --git a/src/uscxml/Convenience.h b/src/uscxml/Convenience.h index fcc696c..54e62c3 100644 --- a/src/uscxml/Convenience.h +++ b/src/uscxml/Convenience.h @@ -22,6 +22,7 @@ #include <inttypes.h> #include <boost/detail/endian.hpp> +#include <boost/lexical_cast.hpp> namespace uscxml { inline bool isnan(double x) { diff --git a/src/uscxml/DOMUtils.h b/src/uscxml/DOMUtils.h index 178f32a..7748f48 100644 --- a/src/uscxml/DOMUtils.h +++ b/src/uscxml/DOMUtils.h @@ -24,6 +24,7 @@ #include <DOM/SAX2DOM/SAX2DOM.hpp> #include <SAX/helpers/DefaultHandler.hpp> #include <SAX/helpers/CatchErrorHandler.hpp> +#include <DOM/io/Stream.hpp> // operator<< for nodes #define TAGNAME(elem) ((Arabica::DOM::Element<std::string>)elem).getTagName() #define LOCALNAME(elem) ((Arabica::DOM::Element<std::string>)elem).getLocalName() @@ -40,6 +41,31 @@ public: static bool attributeIsTrue(const::std::string& value); }; +class USCXML_API NumAttr { +public: + NumAttr(const std::string& str) { + size_t valueStart = str.find_first_of("0123456789."); + if (valueStart != std::string::npos) { + size_t valueEnd = str.find_last_of("0123456789."); + if (valueEnd != std::string::npos) { + value = str.substr(valueStart, (valueEnd - valueStart) + 1); + size_t unitStart = str.find_first_not_of(" \t", valueEnd + 1); + if (unitStart != std::string::npos) { + size_t unitEnd = str.find_last_of(" \t"); + if (unitEnd != std::string::npos && unitEnd > unitStart) { + unit = str.substr(unitStart, unitEnd - unitStart); + } else { + unit = str.substr(unitStart, str.length() - unitStart); + } + } + } + } + } + + std::string value; + std::string unit; +}; + class ScriptEntityResolver : public Arabica::SAX::EntityResolver<std::string> { virtual InputSourceT resolveEntity(const std::string& publicId, const std::string& systemId) { Arabica::SAX::InputSource<std::string> is; diff --git a/src/uscxml/Factory.cpp b/src/uscxml/Factory.cpp index 8edaf07..3556aba 100644 --- a/src/uscxml/Factory.cpp +++ b/src/uscxml/Factory.cpp @@ -24,6 +24,8 @@ #include "uscxml/Interpreter.h" #include <glog/logging.h> +#include "uscxml/server/InterpreterServlet.h" + #include "uscxml/plugins/datamodel/null/NULLDataModel.h" // see http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system diff --git a/src/uscxml/Factory.h b/src/uscxml/Factory.h index ff08754..a0f5178 100644 --- a/src/uscxml/Factory.h +++ b/src/uscxml/Factory.h @@ -21,8 +21,13 @@ #define FACTORY_H_5WKLGPRB #include "uscxml/Common.h" -#include "uscxml/Message.h" -#include "uscxml/Convenience.h" + +#include "uscxml/plugins/ExecutableContent.h" +#include "uscxml/plugins/EventHandler.h" +#include "uscxml/plugins/IOProcessor.h" +#include "uscxml/plugins/Invoker.h" +#include "uscxml/plugins/DataModel.h" + #include <string.h> #ifdef BUILD_AS_PLUGINS @@ -38,404 +43,6 @@ namespace uscxml { class InterpreterImpl; -class USCXML_API ExecutableContentImpl { -public: - ExecutableContentImpl() {}; - virtual ~ExecutableContentImpl() {}; - virtual boost::shared_ptr<ExecutableContentImpl> create(InterpreterImpl* interpreter) = 0; - - virtual void setInterpreter(InterpreterImpl* interpreter) { - _interpreter = interpreter; - } - - virtual std::string getLocalName() = 0; ///< The name of the element. - virtual std::string getNamespace() { - return "http://www.w3.org/2005/07/scxml"; ///< The namespace of the element. - } - virtual void enterElement(const Arabica::DOM::Node<std::string>& node) = 0; ///< Invoked when entering the element as part of evaluating executable content. - virtual void exitElement(const Arabica::DOM::Node<std::string>& node) = 0; ///< Invoked when exiting the element as part of evaluating executable content. - virtual bool processChildren() = 0; ///< Whether or not the interpreter should process this elements children. - -protected: - InterpreterImpl* _interpreter; -}; - -class USCXML_API ExecutableContent { -public: - ExecutableContent() : _impl() {} - ExecutableContent(boost::shared_ptr<ExecutableContentImpl> const impl) : _impl(impl) { } - ExecutableContent(const ExecutableContent& other) : _impl(other._impl) { } - virtual ~ExecutableContent() {}; - - operator bool() const { - return _impl; - } - bool operator< (const ExecutableContent& other) const { - return _impl < other._impl; - } - bool operator==(const ExecutableContent& other) const { - return _impl == other._impl; - } - bool operator!=(const ExecutableContent& other) const { - return _impl != other._impl; - } - ExecutableContent& operator= (const ExecutableContent& other) { - _impl = other._impl; - return *this; - } - - void setInterpreter(InterpreterImpl* interpreter) { - _impl->setInterpreter(interpreter); - } - - std::string getLocalName() { - return _impl->getLocalName(); - } - std::string getNamespace() { - return _impl->getNamespace(); - } - void enterElement(const Arabica::DOM::Node<std::string>& node) { - return _impl->enterElement(node); - } - void exitElement(const Arabica::DOM::Node<std::string>& node) { - return _impl->exitElement(node); - } - bool processChildren() { - return _impl->processChildren(); - } -protected: - boost::shared_ptr<ExecutableContentImpl> _impl; - -}; - -class USCXML_API EventHandlerImpl { -public: - virtual ~EventHandlerImpl() {} - - virtual std::list<std::string> getNames() = 0; - - virtual void setInterpreter(InterpreterImpl* interpreter) { - _interpreter = interpreter; - } - void setInvokeId(const std::string& invokeId) { - _invokeId = invokeId; - } - void setType(const std::string& type) { - _type = type; - } - - void setElement(const Arabica::DOM::Element<std::string>& element) { - _element = element; - } - - Arabica::DOM::Element<std::string> getElement() { - return _element; - } - - virtual Data getDataModelVariables() = 0; - virtual void send(const SendRequest& req) = 0; - - virtual void runOnMainThread() {}; - void returnEvent(Event& event); - void returnErrorExecution(const std::string&); - void returnErrorPlatform(const std::string&); - -protected: - InterpreterImpl* _interpreter; - Arabica::DOM::Element<std::string> _element; - std::string _invokeId; - std::string _type; - -}; - -class USCXML_API EventHandler { -public: - EventHandler() : _impl() {} - EventHandler(boost::shared_ptr<EventHandlerImpl> const impl) : _impl(impl) { } - EventHandler(const EventHandler& other) : _impl(other._impl) { } - virtual ~EventHandler() {}; - - virtual std::list<std::string> getNames() { - return _impl->getNames(); - } - - virtual Data getDataModelVariables() const { - return _impl->getDataModelVariables(); - }; - virtual void send(const SendRequest& req) { - return _impl->send(req); - }; - virtual void runOnMainThread() { - return _impl->runOnMainThread(); - } - - void setInterpreter(InterpreterImpl* interpreter) { - _impl->setInterpreter(interpreter); - } - void setInvokeId(const std::string& invokeId) { - _impl->setInvokeId(invokeId); - } - void setType(const std::string& type) { - _impl->setType(type); - } - - void setElement(const Arabica::DOM::Element<std::string>& element) { - _impl->setElement(element); - } - - Arabica::DOM::Element<std::string> getElement() { - return _impl->getElement(); - } - -protected: - boost::shared_ptr<EventHandlerImpl> _impl; - friend class InterpreterImpl; -}; - -class USCXML_API IOProcessorImpl : public EventHandlerImpl { -public: - IOProcessorImpl() {}; - virtual ~IOProcessorImpl() {}; - virtual boost::shared_ptr<IOProcessorImpl> create(InterpreterImpl* interpreter) = 0; -}; - -class USCXML_API IOProcessor : public EventHandler { -public: - IOProcessor() : _impl() {} - IOProcessor(boost::shared_ptr<IOProcessorImpl> const impl) : EventHandler(impl), _impl(impl) { } - IOProcessor(const IOProcessor& other) : EventHandler(other._impl), _impl(other._impl) { } - virtual ~IOProcessor() {}; - - operator bool() const { - return _impl; - } - bool operator< (const IOProcessor& other) const { - return _impl < other._impl; - } - bool operator==(const IOProcessor& other) const { - return _impl == other._impl; - } - bool operator!=(const IOProcessor& other) const { - return _impl != other._impl; - } - IOProcessor& operator= (const IOProcessor& other) { - _impl = other._impl; - EventHandler::_impl = _impl; - return *this; - } - -protected: - boost::shared_ptr<IOProcessorImpl> _impl; - friend class InterpreterImpl; -}; - -class USCXML_API InvokerImpl : public EventHandlerImpl { -public: - virtual ~InvokerImpl() {} - virtual void invoke(const InvokeRequest& req) = 0; - virtual boost::shared_ptr<InvokerImpl> create(InterpreterImpl* interpreter) = 0; -}; - -class USCXML_API Invoker : public EventHandler { -public: - Invoker() : _impl() {} - Invoker(boost::shared_ptr<InvokerImpl> const impl) : EventHandler(impl), _impl(impl) { } - Invoker(const Invoker& other) : EventHandler(other._impl), _impl(other._impl) { } - virtual ~Invoker() {}; - - operator bool() const { - return _impl; - } - bool operator< (const Invoker& other) const { - return _impl < other._impl; - } - bool operator==(const Invoker& other) const { - return _impl == other._impl; - } - bool operator!=(const Invoker& other) const { - return _impl != other._impl; - } - Invoker& operator= (const Invoker& other) { - _impl = other._impl; - EventHandler::_impl = _impl; - return *this; - } - - virtual void invoke(InvokeRequest& req) { - _impl->invoke(req); - } - -protected: - boost::shared_ptr<InvokerImpl> _impl; -}; - -class USCXML_API DataModelImpl { -public: - virtual ~DataModelImpl() {} - virtual boost::shared_ptr<DataModelImpl> create(InterpreterImpl* interpreter) = 0; - virtual std::list<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; - - size_t replaceExpressions(std::string& content); - - // foreach - virtual uint32_t getLength(const std::string& expr) = 0; - virtual void setForeach(const std::string& item, - const std::string& array, - const std::string& index, - uint32_t iteration) = 0; - virtual void pushContext() = 0; - virtual void popContext() = 0; - - virtual void eval(const Arabica::DOM::Element<std::string>& scriptElem, - const std::string& expr) = 0; - - virtual std::string evalAsString(const std::string& expr) = 0; - - virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& scriptNode, - const std::string& expr) = 0; - virtual bool evalAsBool(const std::string& expr) { - return evalAsBool(Arabica::DOM::Node<std::string>(), expr); - } - - virtual bool isDeclared(const std::string& expr) = 0; - - virtual void assign(const Arabica::DOM::Element<std::string>& assignElem, - const Arabica::DOM::Node<std::string>& node, - const std::string& content) = 0; - virtual void assign(const std::string& location, const Data& data) = 0; - - virtual void init(const Arabica::DOM::Element<std::string>& dataElem, - const Arabica::DOM::Node<std::string>& node, - const std::string& content) = 0; - virtual void init(const std::string& location, const Data& data) = 0; - - virtual void setInterpreter(InterpreterImpl* interpreter) { - _interpreter = interpreter; - } - - virtual std::string andExpressions(std::list<std::string>) { - return ""; - } - - static void throwErrorExecution(const std::string& cause); - static void throwErrorPlatform(const std::string& cause); - - // we need it public for various static functions -protected: - InterpreterImpl* _interpreter; -}; - -class USCXML_API DataModel { -public: - DataModel() : _impl() {} - DataModel(const boost::shared_ptr<DataModelImpl> impl) : _impl(impl) { } - DataModel(const DataModel& other) : _impl(other._impl) { } - virtual ~DataModel() {}; - - operator bool() const { - return _impl; - } - bool operator< (const DataModel& other) const { - return _impl < other._impl; - } - bool operator==(const DataModel& other) const { - return _impl == other._impl; - } - bool operator!=(const DataModel& other) const { - return _impl != other._impl; - } - DataModel& operator= (const DataModel& other) { - _impl = other._impl; - return *this; - } - - virtual std::list<std::string> getNames() { - return _impl->getNames(); - } - - virtual bool validate(const std::string& location, const std::string& schema) { - return _impl->validate(location, schema); - } - virtual void setEvent(const Event& event) { - return _impl->setEvent(event); - } - virtual Data getStringAsData(const std::string& content) { - return _impl->getStringAsData(content); - } - - virtual void pushContext() { - return _impl->pushContext(); - } - virtual void popContext() { - return _impl->popContext(); - } - - virtual void eval(const Arabica::DOM::Element<std::string>& scriptElem, - const std::string& expr) { - return _impl->eval(scriptElem, expr); - } - virtual std::string evalAsString(const std::string& expr) { - return _impl->evalAsString(expr); - } - virtual bool evalAsBool(const std::string& expr) { - return _impl->evalAsBool(expr); - } - virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& scriptNode, - const std::string& expr) { - return _impl->evalAsBool(scriptNode, expr); - } - - virtual uint32_t getLength(const std::string& expr) { - return _impl->getLength(expr); - } - virtual void setForeach(const std::string& item, - const std::string& array, - const std::string& index, - uint32_t iteration) { - return _impl->setForeach(item, array, index, iteration); - } - - virtual void assign(const Arabica::DOM::Element<std::string>& assignElem, - const Arabica::DOM::Node<std::string>& node, - const std::string& content) { - return _impl->assign(assignElem, node, content); - } - virtual void assign(const std::string& location, const Data& data) { - return _impl->assign(location, data); - } - - virtual void init(const Arabica::DOM::Element<std::string>& dataElem, - const Arabica::DOM::Node<std::string>& node, - const std::string& content) { - return _impl->init(dataElem, node, content); - } - virtual void init(const std::string& location, const Data& data) { - return _impl->init(location, data); - } - - virtual bool isDeclared(const std::string& expr) { - return _impl->isDeclared(expr); - } - - size_t replaceExpressions(std::string& content) { - return _impl->replaceExpressions(content); - } - - std::string andExpressions(std::list<std::string> expressions) { - return _impl->andExpressions(expressions); - } - - virtual void setInterpreter(InterpreterImpl* interpreter) { - _impl->setInterpreter(interpreter); - } - -protected: - boost::shared_ptr<DataModelImpl> _impl; -}; class USCXML_API Factory { public: diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index f5aaf77..22fb79e 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -25,22 +25,30 @@ #include "uscxml/DOMUtils.h" #include "uscxml/transform/ChartToFSM.h" // only for testing +#include "getopt.h" + #include "uscxml/plugins/invoker/http/HTTPServletInvoker.h" +#include "uscxml/server/InterpreterServlet.h" +#include "uscxml/concurrency/eventqueue/DelayedEventQueue.h" #include <DOM/Simple/DOMImplementation.hpp> #include <SAX/helpers/InputSourceResolver.hpp> +#include <DOM/io/Stream.hpp> #include <boost/lexical_cast.hpp> #include <boost/tokenizer.hpp> #include <boost/algorithm/string.hpp> #include <glog/logging.h> +#include <iostream> +#include <io/uri.hpp> #include <assert.h> #include <algorithm> #include "uscxml/interpreter/InterpreterDraft6.h" #include "uscxml/interpreter/InterpreterRC.h" +#include "uscxml/Factory.h" #if 1 #define INTERPRETER_IMPL InterpreterDraft6 @@ -52,43 +60,42 @@ /// valid interpreter state transitions #define VALID_FROM_INSTANTIATED(newState) ( \ - newState == InterpreterState::USCXML_FAULTED || \ - newState == InterpreterState::USCXML_MICROSTEPPED || \ - newState == InterpreterState::USCXML_DESTROYED\ + newState == USCXML_MICROSTEPPED || \ + newState == USCXML_DESTROYED\ ) #define VALID_FROM_FAULTED(newState) ( \ - newState == InterpreterState::USCXML_DESTROYED\ + newState == USCXML_DESTROYED\ ) #define VALID_FROM_INITIALIZED(newState) ( \ - newState == InterpreterState::USCXML_MICROSTEPPED || \ - newState == InterpreterState::USCXML_FINISHED \ + newState == USCXML_MICROSTEPPED || \ + newState == USCXML_FINISHED \ ) #define VALID_FROM_MICROSTEPPED(newState) ( \ - newState == InterpreterState::USCXML_DESTROYED || \ - newState == InterpreterState::USCXML_MACROSTEPPED || \ - newState == InterpreterState::USCXML_MICROSTEPPED || \ - newState == InterpreterState::USCXML_FINISHED \ + newState == USCXML_DESTROYED || \ + newState == USCXML_MACROSTEPPED || \ + newState == USCXML_MICROSTEPPED || \ + newState == USCXML_FINISHED \ ) #define VALID_FROM_MACROSTEPPED(newState) ( \ - newState == InterpreterState::USCXML_DESTROYED || \ - newState == InterpreterState::USCXML_MICROSTEPPED || \ - newState == InterpreterState::USCXML_IDLE || \ - newState == InterpreterState::USCXML_FINISHED \ + newState == USCXML_DESTROYED || \ + newState == USCXML_MICROSTEPPED || \ + newState == USCXML_IDLE || \ + newState == USCXML_FINISHED \ ) #define VALID_FROM_IDLE(newState) ( \ - newState == InterpreterState::USCXML_DESTROYED || \ - newState == InterpreterState::USCXML_MICROSTEPPED || \ - newState == InterpreterState::USCXML_MACROSTEPPED \ + newState == USCXML_DESTROYED || \ + newState == USCXML_MICROSTEPPED || \ + newState == USCXML_MACROSTEPPED \ ) #define VALID_FROM_FINISHED(newState) ( \ - newState == InterpreterState::USCXML_DESTROYED || \ - newState == InterpreterState::USCXML_INSTANTIATED \ + newState == USCXML_DESTROYED || \ + newState == USCXML_INSTANTIATED \ ) #define THROW_ERROR_PLATFORM(msg) \ @@ -336,10 +343,12 @@ std::map<std::string, boost::weak_ptr<InterpreterImpl> > Interpreter::getInstanc InterpreterImpl::InterpreterImpl() { - _state.state = InterpreterState::USCXML_INSTANTIATED; - _state.thread = 0; + _state = USCXML_INSTANTIATED; + _lastRunOnMainThread = 0; _thread = NULL; + _isStarted = false; + _isRunning = false; _sendQueue = NULL; _parentQueue = NULL; _topLevelFinalReached = false; @@ -448,7 +457,7 @@ Interpreter Interpreter::fromInputSource(Arabica::SAX::InputSource<std::string>& THROW_ERROR_PLATFORM(parser.errors()) } else { THROW_ERROR_PLATFORM("Failed to create interpreter"); -// interpreterImpl->setInterpreterState(InterpreterState::USCXML_FAULTED, parser.errors()); +// interpreterImpl->setInterpreterState(USCXML_FAULTED, parser.errors()); } } return interpreter; @@ -531,7 +540,7 @@ InterpreterImpl::~InterpreterImpl() { delete(_thread); } else { // this can happen with a shared_from_this at an interpretermonitor - setInterpreterState(InterpreterState::USCXML_DESTROYED); + setInterpreterState(USCXML_DESTROYED); } } join(); @@ -541,12 +550,12 @@ InterpreterImpl::~InterpreterImpl() { } void InterpreterImpl::start() { - _state.thread |= InterpreterState::USCXML_THREAD_STARTED; + _isStarted = true; _thread = new tthread::thread(InterpreterImpl::run, this); } void InterpreterImpl::stop() { - _state.thread &= ~InterpreterState::USCXML_THREAD_STARTED; + _isStarted = false; } void InterpreterImpl::join() { @@ -555,23 +564,21 @@ void InterpreterImpl::join() { }; bool InterpreterImpl::isRunning() { - // return _running || !_topLevelFinalReached; - return (_state.thread & InterpreterState::USCXML_THREAD_RUNNING) > 0; + return _isRunning && !_topLevelFinalReached; } void InterpreterImpl::run(void* instance) { InterpreterImpl* interpreter = ((InterpreterImpl*)instance); - interpreter->_state.thread |= InterpreterState::USCXML_THREAD_RUNNING; + interpreter->_isRunning = true; try { InterpreterState state; - while(interpreter->_state.thread & InterpreterState::USCXML_THREAD_STARTED) { + while(interpreter->_isStarted) { state = interpreter->step(-1); - switch (state & InterpreterState::USCXML_INTERPRETER_MASK) { - case uscxml::InterpreterState::USCXML_FAULTED: - case uscxml::InterpreterState::USCXML_FINISHED: - case uscxml::InterpreterState::USCXML_DESTROYED: + switch (state) { + case uscxml::USCXML_FINISHED: + case uscxml::USCXML_DESTROYED: // return as we finished goto DONE_THREAD; default: @@ -586,58 +593,42 @@ void InterpreterImpl::run(void* instance) { LOG(ERROR) << "InterpreterImpl::run catched unknown exception"; } DONE_THREAD: - ((InterpreterImpl*)instance)->_state.thread &= ~InterpreterState::USCXML_THREAD_RUNNING; - ((InterpreterImpl*)instance)->_state.thread &= ~InterpreterState::USCXML_THREAD_STARTED; + ((InterpreterImpl*)instance)->_isRunning = false; + ((InterpreterImpl*)instance)->_isStarted = false; } InterpreterState InterpreterImpl::getInterpreterState() { return _state; } -void InterpreterImpl::setInterpreterState(InterpreterState::State newState) { - setInterpreterState(newState, Event()); -} - -void InterpreterImpl::setInterpreterState(InterpreterState::State newState, const std::string& error) { - Event e; - e.name = "error.platform"; - e.data.compound["cause"] = Data(error, Data::VERBATIM); - setInterpreterState(newState, e); -} - -void InterpreterImpl::setInterpreterState(InterpreterState::State newState, const Event& error) { +void InterpreterImpl::setInterpreterState(InterpreterState newState) { switch (_state) { - case InterpreterState::USCXML_INSTANTIATED: + case USCXML_INSTANTIATED: if (VALID_FROM_INSTANTIATED(newState)) break; assert(false); break; - case InterpreterState::USCXML_FAULTED: - if (VALID_FROM_FAULTED(newState)) - break; - assert(false); - break; - case InterpreterState::USCXML_MICROSTEPPED: + case USCXML_MICROSTEPPED: if (VALID_FROM_MICROSTEPPED(newState)) break; assert(false); break; - case InterpreterState::USCXML_MACROSTEPPED: + case USCXML_MACROSTEPPED: if (VALID_FROM_MACROSTEPPED(newState)) break; assert(false); break; - case InterpreterState::USCXML_IDLE: + case USCXML_IDLE: if (VALID_FROM_IDLE(newState)) break; assert(false); break; - case InterpreterState::USCXML_FINISHED: + case USCXML_FINISHED: if (VALID_FROM_FINISHED(newState)) break; assert(false); break; - case InterpreterState::USCXML_DESTROYED: + case USCXML_DESTROYED: assert(false); break; @@ -645,13 +636,11 @@ void InterpreterImpl::setInterpreterState(InterpreterState::State newState, cons break; } - _state.state = newState; - _state.msg = error; + _state = newState; } bool InterpreterImpl::runOnMainThread(int fps, bool blocking) { - tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); - if (_state == InterpreterState::USCXML_FINISHED || _state == InterpreterState::USCXML_FAULTED || _state == InterpreterState::USCXML_DESTROYED) + if (_state == USCXML_FINISHED || _state == USCXML_DESTROYED || !_isStarted) return false; if (fps > 0) { @@ -665,6 +654,7 @@ bool InterpreterImpl::runOnMainThread(int fps, bool blocking) { } } + tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); _lastRunOnMainThread = tthread::timeStamp(); { @@ -695,7 +685,7 @@ void InterpreterImpl::reset() { _topLevelFinalReached = false; _isInitialized = false; - setInterpreterState(InterpreterState::USCXML_INSTANTIATED); + setInterpreterState(USCXML_INSTANTIATED); } void InterpreterImpl::setupAndNormalizeDOM() { @@ -2475,12 +2465,12 @@ bool InterpreterImpl::hasLegalConfiguration() { return isLegalConfiguration(_configuration); } -bool InterpreterImpl::isLegalConfiguration(const std::vector<std::string>& config) { +bool InterpreterImpl::isLegalConfiguration(const std::list<std::string>& config) { NodeSet<std::string> states; - for (int i = 0; i < config.size(); i++) { - Node<std::string> state = getState(config[i]); + for (std::list<std::string>::const_iterator confIter = config.begin(); confIter != config.end(); confIter++) { + Node<std::string> state = getState(*confIter); if (!state) { - LOG(INFO) << "No state with id '" << config[i] << "'"; + LOG(INFO) << "No state with id '" << *confIter << "'"; return false; } states.push_back(state); @@ -2626,21 +2616,17 @@ void InterpreterImpl::DOMEventListener::handleEvent(Arabica::DOM::Events::Event< } std::ostream& operator<< (std::ostream& os, const InterpreterState& interpreterState) { - os << "[" << InterpreterState::stateToString(interpreterState.state) << "]:" << std::endl; - os << interpreterState.msg; + os << "[" << InterpreterImpl::stateToString(interpreterState) << "]" << std::endl; return os; } -std::string InterpreterState::stateToString(int32_t state) { +std::string InterpreterImpl::stateToString(InterpreterState state) { std::stringstream ss; - switch(state & USCXML_INTERPRETER_MASK) { + switch(state) { case USCXML_INSTANTIATED: ss << "INSTANTIATED"; break; - case USCXML_FAULTED: - ss << "FAULTED"; - break; case USCXML_MICROSTEPPED: ss << "MICROSTEPPED"; break; @@ -2661,17 +2647,6 @@ std::string InterpreterState::stateToString(int32_t state) { break; } - if (state & USCXML_THREAD_STARTED) { - ss << ", " << "STARTED"; - } else { - ss << ", " << "STOPPED"; - } - if (state & USCXML_THREAD_RUNNING) { - ss << ", " << "RUNNING"; - } else { - ss << ", " << "JOINED"; - } - return ss.str(); } diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index 9a3e553..a07d9af 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -22,31 +22,31 @@ // this has to be the first include or MSVC will run amok #include "uscxml/Common.h" -#include "getopt.h" - -#include "uscxml/URL.h" +#include <iostream> // arabica xpath uses cerr without iostream #include <boost/shared_ptr.hpp> -#include <iostream> #include <set> #include <map> #include <XPath/XPath.hpp> #include <DOM/Document.hpp> -#include <io/uri.hpp> #include <DOM/SAX2DOM/SAX2DOM.hpp> #include <SAX/helpers/CatchErrorHandler.hpp> #include <DOM/Events/EventTarget.hpp> #include <DOM/Events/EventListener.hpp> -#include "uscxml/concurrency/tinythread.h" -#include "uscxml/concurrency/eventqueue/DelayedEventQueue.h" #include "uscxml/concurrency/BlockingQueue.h" -#include "uscxml/Message.h" -#include "uscxml/Factory.h" +#include "uscxml/messages/Data.h" +#include "uscxml/messages/SendRequest.h" +#include "uscxml/URL.h" + +#include "uscxml/plugins/DataModel.h" +#include "uscxml/plugins/IOProcessor.h" +#include "uscxml/plugins/Invoker.h" +#include "uscxml/plugins/ExecutableContent.h" + -#include "uscxml/server/InterpreterServlet.h" #define USCXML_MONITOR_CATCH(callback) \ catch (Event e) { \ @@ -56,7 +56,7 @@ catch (Event e) { \ } catch (...) { \ LOG(ERROR) << "An exception occured when calling " #callback " on monitors"; \ } \ -if (_state == InterpreterState::USCXML_DESTROYED) { \ +if (_state == USCXML_DESTROYED) { \ throw boost::bad_weak_ptr(); \ } \ @@ -89,31 +89,10 @@ namespace uscxml { class HTTPServletInvoker; class InterpreterMonitor; - -class USCXML_API NumAttr { -public: - NumAttr(const std::string& str) { - size_t valueStart = str.find_first_of("0123456789."); - if (valueStart != std::string::npos) { - size_t valueEnd = str.find_last_of("0123456789."); - if (valueEnd != std::string::npos) { - value = str.substr(valueStart, (valueEnd - valueStart) + 1); - size_t unitStart = str.find_first_not_of(" \t", valueEnd + 1); - if (unitStart != std::string::npos) { - size_t unitEnd = str.find_last_of(" \t"); - if (unitEnd != std::string::npos && unitEnd > unitStart) { - unit = str.substr(unitStart, unitEnd - unitStart); - } else { - unit = str.substr(unitStart, str.length() - unitStart); - } - } - } - } - } - - std::string value; - std::string unit; -}; +class InterpreterHTTPServlet; +class InterpreterWebSocketServlet; +class Factory; +class DelayedEventQueue; enum Capabilities { CAN_NOTHING = 0, @@ -219,54 +198,16 @@ private: void init(const std::map<std::string, std::string>& nsInfo); }; -struct USCXML_API InterpreterState { - // see: http://stackoverflow.com/questions/18591924/how-to-use-bitmask - enum State { - USCXML_DESTROYED = 0x0001, // - USCXML_INSTANTIATED = 0x0002, // nothing really, just instantiated - USCXML_MICROSTEPPED = 0x0004, // - USCXML_MACROSTEPPED = 0x0008, // - USCXML_IDLE = 0x0010, // - USCXML_FAULTED = 0x0020, // something went very wrong - USCXML_FINISHED = 0x0040, // machine reached a final configuration - }; - - enum ThreadState { - USCXML_THREAD_RUNNING = 0x0100, // - USCXML_THREAD_STARTED = 0x0200, // - }; - - enum BitMask { - USCXML_THREAD_MASK = 0xff00, - USCXML_INTERPRETER_MASK = 0x00ff, - }; - - bool operator==(const InterpreterState& other) const { - return state == other.state && msg == other.msg; - } - bool operator!=(const InterpreterState& other) const { - return !(*this == other); - } - - operator int() { - return (int)(state | thread); - } - - Event getMessage() { - return msg; - } - - static std::string stateToString(int32_t state); - - friend USCXML_API std::ostream& operator<< (std::ostream& os, const InterpreterState& interpreterState); - friend USCXML_API class InterpreterImpl; - -protected: - int32_t thread; - State state; - Event msg; +enum InterpreterState { + USCXML_DESTROYED = -2, ///< destructor ran - users should never see this one + USCXML_FINISHED = -1, ///< machine reached a final configuration and is done + USCXML_IDLE = 0, ///< stable configuration and queues empty + USCXML_INSTANTIATED = 1, ///< nothing really, just instantiated + USCXML_MICROSTEPPED = 2, ///< processed one transition set + USCXML_MACROSTEPPED = 4, ///< processed all transition sets and reached a stable configuration }; + USCXML_API std::ostream& operator<< (std::ostream& os, const InterpreterState& interpreterState); class USCXML_API InterpreterImpl : public boost::enable_shared_from_this<InterpreterImpl> { @@ -383,8 +324,8 @@ public: return basicConfig; } - void setInitalConfiguration(const std::vector<std::string>& states) { - _userDefinedStartConfiguration = states; + void setInitalConfiguration(const std::list<std::string>& states) { + _startConfiguration = states; } void setInvokeRequest(const InvokeRequest& req) { _invokeReq = req; @@ -424,7 +365,7 @@ public: bool hasLegalConfiguration(); bool isLegalConfiguration(const Arabica::XPath::NodeSet<std::string>&); - bool isLegalConfiguration(const std::vector<std::string>&); + bool isLegalConfiguration(const std::list<std::string>&); static bool isState(const Arabica::DOM::Node<std::string>& state); static bool isPseudoState(const Arabica::DOM::Node<std::string>& state); @@ -439,6 +380,8 @@ public: bool isInEmbeddedDocument(const Arabica::DOM::Node<std::string>& node); bool isInitial(const Arabica::DOM::Node<std::string>& state); + static std::string stateToString(InterpreterState state); + Arabica::DOM::Node<std::string> getState(const std::string& stateId); Arabica::XPath::NodeSet<std::string> getStates(const std::list<std::string>& stateIds); Arabica::XPath::NodeSet<std::string> getAllStates(); @@ -481,9 +424,7 @@ protected: void initializeData(const Arabica::DOM::Element<std::string>& data); void finalizeAndAutoForwardCurrentEvent(); - void setInterpreterState(InterpreterState::State newState, const std::string& error); - void setInterpreterState(InterpreterState::State newState, const Event& error); - void setInterpreterState(InterpreterState::State newState); + void setInterpreterState(InterpreterState newState); bool _stable; tthread::thread* _thread; @@ -503,11 +444,14 @@ protected: bool _isInitialized; bool _domIsSetup; + bool _isStarted; + bool _isRunning; + InterpreterImpl::Binding _binding; Arabica::XPath::NodeSet<std::string> _configuration; Arabica::XPath::NodeSet<std::string> _alreadyEntered; Arabica::XPath::NodeSet<std::string> _statesToInvoke; - std::vector<std::string> _userDefinedStartConfiguration; + std::list<std::string> _startConfiguration; InvokeRequest _invokeReq; DataModel _dataModel; @@ -588,9 +532,7 @@ public: virtual ~Interpreter() {}; operator bool() const { - return (_impl && - _impl->_state != InterpreterState::USCXML_FAULTED && - _impl->_state != InterpreterState::USCXML_DESTROYED); + return (_impl && _impl->_state != USCXML_DESTROYED); } bool operator< (const Interpreter& other) const { return _impl < other._impl; @@ -716,7 +658,7 @@ public: return _impl->getBasicConfiguration(); } - void setInitalConfiguration(const std::vector<std::string>& states) { + void setInitalConfiguration(const std::list<std::string>& states) { return _impl->setInitalConfiguration(states); } @@ -772,7 +714,7 @@ public: return _impl->isLegalConfiguration(config); } - bool isLegalConfiguration(const std::vector<std::string>& config) { + bool isLegalConfiguration(const std::list<std::string>& config) { return _impl->isLegalConfiguration(config); } diff --git a/src/uscxml/Message.cpp b/src/uscxml/Message.cpp index 1ac3573..465b4ba 100644 --- a/src/uscxml/Message.cpp +++ b/src/uscxml/Message.cpp @@ -28,769 +28,30 @@ #include <boost/algorithm/string.hpp> -#ifdef HAS_STRING_H -#include <string.h> -#endif - -extern "C" { -#include "jsmn.h" // minimal json parser -} namespace uscxml { -static int _dataIndentation = 1; - -Blob::~Blob() { - free(data); -} - -Blob::Blob(size_t _size) { - data = (char*)malloc(_size); - memset(data, 0, _size); - size = _size; -} - -Blob::Blob(void* _data, size_t _size, const std::string& _mimeType, bool adopt) { - if (adopt) { - data = (char*)_data; - } else { - data = (char*)malloc(_size); - memcpy(data, _data, _size); - } - mimeType = _mimeType; - size = _size; -} - -#if 0 -// this used to work base64 encoded images in a browser - can't check extensively just now -static const std::string base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - -std::string Blob::base64() { - - int in_len = size; - char const* bytes_to_encode = data; - - std::string ret; - int i = 0; - int j = 0; - unsigned char char_array_3[3]; - unsigned char char_array_4[4]; - - while (in_len--) { - char_array_3[i++] = *(bytes_to_encode++); - if (i == 3) { - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for(i = 0; (i <4) ; i++) - ret += base64_chars[char_array_4[i]]; - i = 0; - } - } - - if (i) { - for(j = i; j < 3; j++) - char_array_3[j] = '\0'; - - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for (j = 0; (j < i + 1); j++) - ret += base64_chars[char_array_4[j]]; - - while((i++ < 3)) - ret += '='; - - } - - return ret; - -} -#else -std::string Blob::base64() { - return base64Encode((char* const)data, size); -} -#endif - -Data::Data(const char* _data, size_t _size, const std::string& mimeType, bool adopt) { - binary = boost::shared_ptr<Blob>(new Blob((void*)_data, _size, mimeType, adopt)); -} - -void Data::merge(const Data& other) { - if (other.compound.size() > 0) { - if (compound.size() == 0) { - compound = other.compound; - } else { - std::map<std::string, Data>::const_iterator compIter = other.compound.begin(); - while (compIter != other.compound.end()) { - if (compound.find(compIter->first) != compound.end()) { - // we do have the same key, merge - compound[compIter->first].merge(compIter->second); - } else { - compound[compIter->first] = compIter->second; - } - compIter++; - } - } - } - if (other.array.size() > 0) { - if (array.size() == 0) { - array = other.array; - } else { - std::list<Data>::const_iterator arrIter = other.array.begin(); - while(arrIter != other.array.end()) { - array.push_back(*arrIter); - arrIter++; - } - } - } - if (other.atom.size() > 0) { - atom = other.atom; - type = other.type; - } -} - -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; -// 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); -// 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); -// 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; - } -} - -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", "payload"); - payloadElem.setPrefix("scxml"); - - 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", "property"); - propertyElem.setPrefix("scxml"); - - 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::Node<std::string> Event::getFirstDOMElement() const { -// return getFirstDOMElement(dom); -//} -// -//Arabica::DOM::Document<std::string> Event::getStrippedDOM() const { -// return getStrippedDOM(dom); -//} - -//Arabica::DOM::Node<std::string> Event::getFirstDOMElement(const Arabica::DOM::Document<std::string> dom) { -// Arabica::DOM::Node<std::string> data = dom.getDocumentElement().getFirstChild(); -// while (data) { -// if (data.getNodeType() == Arabica::DOM::Node_base::TEXT_NODE) { -// std::string trimmed = boost::trim_copy(data.getNodeValue()); -// if (trimmed.length() == 0) { -// data = data.getNextSibling(); -// continue; -// } -// } -// break; -// } -// return data; -//} -// -//Arabica::DOM::Document<std::string> Event::getStrippedDOM(const Arabica::DOM::Document<std::string> dom) { -// Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); -// Arabica::DOM::Document<std::string> document = domFactory.createDocument("", "", 0); -// if (dom) { -// document.getDocumentElement().appendChild(document.importNode(getFirstDOMElement(dom), true)); -// } -// 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::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", "payload"); - payloadElem.setPrefix("scxml"); - - scxmlMsg.appendChild(payloadElem); - } - Arabica::DOM::Node<std::string> payloadElem = scxmlMsg.getElementsByTagName("scxml:payload").item(0); - - // add parameters - std::multimap<std::string, Data>::iterator paramIter = params.begin(); - while(paramIter != params.end()) { - Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "property"); - propertyElem.setPrefix("scxml"); - - propertyElem.setAttribute("name", paramIter->first); - // this is simplified - Data might be more elaborate than a simple string atom - Arabica::DOM::Text<std::string> textElem = document.createTextNode(paramIter->second.atom); - propertyElem.appendChild(textElem); - payloadElem.appendChild(propertyElem); - paramIter++; - } - - // add namelist elements - std::map<std::string, Data>::iterator namelistIter = namelist.begin(); - while(namelistIter != namelist.end()) { - Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "property"); - propertyElem.setPrefix("scxml"); - - propertyElem.setAttribute("name", namelistIter->first); - // this is simplified - Data might be more elaborate than a simple string atom - Arabica::DOM::Text<std::string> textElem = document.createTextNode(namelistIter->second.atom); - 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; -} -Data Data::fromXML(const std::string& xmlString) { - return Data(); -} -Data Data::fromJSON(const std::string& jsonString) { - Data data; - std::string trimmed = boost::trim_copy(jsonString); - if (trimmed.length() == 0) - return data; - if (trimmed.find_first_of("{[") != 0) - return data; - jsmn_parser p; - - jsmntok_t* t = NULL; - - // we do not know the number of tokens beforehand, start with something sensible and increase - int rv; - int frac = 16; // length/token ratio - do { - jsmn_init(&p); - - frac /= 2; - int nrTokens = trimmed.size() / frac; - if (t != NULL) { - free(t); -// LOG(INFO) << "Increasing JSON length to token ratio to 1/" << frac; - } - t = (jsmntok_t*)malloc((nrTokens + 1) * sizeof(jsmntok_t)); - if (t == NULL) { - LOG(ERROR) << "Cannot parse JSON, ran out of memory!"; - return data; - } - memset(t, 0, (nrTokens + 1) * sizeof(jsmntok_t)); - - rv = jsmn_parse(&p, trimmed.c_str(), t, nrTokens); - } while (rv == JSMN_ERROR_NOMEM && frac > 1); - - if (rv != 0) { - switch (rv) { - case JSMN_ERROR_NOMEM: - LOG(ERROR) << "Cannot parse JSON, not enough tokens were provided!"; - break; - case JSMN_ERROR_INVAL: - LOG(ERROR) << "Cannot parse JSON, invalid character inside JSON string!"; - break; - case JSMN_ERROR_PART: - LOG(ERROR) << "Cannot parse JSON, the string is not a full JSON packet, more bytes expected!"; - break; - default: - break; - } - free(t); - return data; - } - - if (t[0].end != trimmed.length()) - return data; - -// jsmntok_t* token = t; -// while(token->end) { -// std::cout << trimmed.substr(token->start, token->end - token->start) << std::endl; -// std::cout << "------" << std::endl; -// token++; -// } - - std::list<Data*> dataStack; - std::list<jsmntok_t> tokenStack; - dataStack.push_back(&data); - - size_t currTok = 0; - do { - // used for debugging -// jsmntok_t t2 = t[currTok]; -// std::string value = trimmed.substr(t[currTok].start, t[currTok].end - t[currTok].start); - switch (t[currTok].type) { - case JSMN_STRING: - dataStack.back()->type = Data::VERBATIM; - case JSMN_PRIMITIVE: { - std::string value = trimmed.substr(t[currTok].start, t[currTok].end - t[currTok].start); - if (dataStack.back()->type == Data::VERBATIM) { - boost::replace_all(value, "\\\"", "\""); - boost::replace_all(value, "\\n", "\n"); - } - dataStack.back()->atom = value; - dataStack.pop_back(); - currTok++; - break; - } - case JSMN_OBJECT: - case JSMN_ARRAY: - tokenStack.push_back(t[currTok]); - currTok++; - break; - } - // used for debugging -// t2 = t[currTok]; -// value = trimmed.substr(t[currTok].start, t[currTok].end - t[currTok].start); - - // there are no more tokens - if (t[currTok].end == 0 || tokenStack.empty()) - break; - - // next token starts after current one => pop - while (t[currTok].end > tokenStack.back().end) { - tokenStack.pop_back(); - dataStack.pop_back(); - } - - if (tokenStack.back().type == JSMN_OBJECT && (t[currTok].type == JSMN_PRIMITIVE || t[currTok].type == JSMN_STRING)) { - // grab key and push new data - std::string value = trimmed.substr(t[currTok].start, t[currTok].end - t[currTok].start); - dataStack.push_back(&(dataStack.back()->compound[value])); - currTok++; - } - if (tokenStack.back().type == JSMN_ARRAY) { - // push new index - dataStack.back()->array.push_back(Data()); - dataStack.push_back(&(dataStack.back()->array.back())); - } - - } while (true); - - free(t); - return data; -} - -void Event::initContent(const std::string& content) { - // try to parse as JSON - Data json = Data::fromJSON(content); - if (!json.empty()) { - data = json; - return; - } - - // try to parse as XML - Arabica::SAX2DOM::Parser<std::string> parser; - Arabica::SAX::CatchErrorHandler<std::string> errorHandler; - parser.setErrorHandler(errorHandler); - - std::istringstream is(content); - Arabica::SAX::InputSource<std::string> inputSource; - inputSource.setByteStream(is); - if (parser.parse(inputSource)) { - dom = parser.getDocument(); - return; - } - - this->content = content; -} - -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.data.compound[key] = Data(value, Data::VERBATIM); - } - } - } - } - } - } - return event; -} - -SendRequest SendRequest::fromXML(const std::string& xmlString) { - Event::fromXML(xmlString); - return SendRequest(); -} - -InvokeRequest InvokeRequest::fromXML(const std::string& xmlString) { - Event::fromXML(xmlString); - return InvokeRequest(); -} #ifndef SWIGJAVA -std::ostream& operator<< (std::ostream& os, const InvokeRequest& invokeReq) { - - std::string indent; - for (int i = 0; i < _dataIndentation; i++) { - indent += " "; - } - - os << indent << "InvokeReq" << (invokeReq.autoForward ? " with autoforward" : "") << std::endl; - - if (invokeReq.type.size() > 0) - os << indent << " type: " << invokeReq.type << std::endl; - - if (invokeReq.src.size() > 0) - os<< indent << " src: " << invokeReq.src << std::endl; - - if (invokeReq.namelist.size() > 0) { - os << indent << " namelist: " << std::endl; - InvokeRequest::namelist_t::const_iterator namelistIter = invokeReq.namelist.begin(); - while(namelistIter != invokeReq.namelist.end()) { - os << indent << " " << namelistIter->first << ": " << namelistIter->second << std::endl; - namelistIter++; - } - } - - if (invokeReq.params.size() > 0) { - os << indent << " params: " << std::endl; - SendRequest::params_t::const_iterator paramIter = invokeReq.params.begin(); - while(paramIter != invokeReq.params.end()) { - os << indent << " " << paramIter->first << ": " << paramIter->second << std::endl; - paramIter++; - } - } - - if (invokeReq.content.size() > 0) - os << indent << " content: " << invokeReq.content << std::endl; - - _dataIndentation++; - os << (Event)invokeReq; - _dataIndentation--; - return os; - -} #endif #ifndef SWIGJAVA -std::ostream& operator<< (std::ostream& os, const SendRequest& sendReq) { - - std::string indent; - for (int i = 0; i < _dataIndentation; i++) { - indent += " "; - } - - os << indent << "SendReq" << std::endl; - - if (sendReq.target.size() > 0) - os << indent << " target: " << sendReq.target << std::endl; - - if (sendReq.type.size() > 0) - os << indent << " type: " << sendReq.type << std::endl; - - if (sendReq.delayMs > 0) - os<< indent << " delay: " << sendReq.delayMs << std::endl; - - if (sendReq.namelist.size() > 0) { - os << indent << " namelist: " << std::endl; - SendRequest::namelist_t::const_iterator namelistIter = sendReq.namelist.begin(); - while(namelistIter != sendReq.namelist.end()) { - os << indent << " " << namelistIter->first << ": " << namelistIter->second << std::endl; - namelistIter++; - } - } - - if (sendReq.params.size() > 0) { - os << indent << " params: " << std::endl; - SendRequest::params_t::const_iterator paramIter = sendReq.params.begin(); - while(paramIter != sendReq.params.end()) { - os << indent << " " << paramIter->first << ": " << paramIter->second << std::endl; - paramIter++; - } - } - - if (sendReq.content.size() > 0) - os << indent << " content: " << sendReq.content << std::endl; - - _dataIndentation++; - os << (Event)sendReq; - _dataIndentation--; - return os; - -} #endif #ifndef SWIGJAVA -std::ostream& operator<< (std::ostream& os, const Event& event) { - std::string indent; - for (int i = 0; i < _dataIndentation; i++) { - indent += " "; - } - - os << indent << (event.eventType == Event::EXTERNAL ? "External" : "Internal") << " Event " << (event.dom ? "with DOM attached" : "") << std::endl; - - if (event.name.size() > 0) - os << indent << " name: " << event.name << std::endl; - if (event.origin.size() > 0) - os << indent << " origin: " << event.origin << std::endl; - if (event.origintype.size() > 0) - os << indent << " origintype: " << event.origintype << std::endl; - if (event.params.size() > 0) { - std::multimap<std::string, Data>::const_iterator paramIter = event.params.begin(); - os << indent << " params:" << std::endl; - _dataIndentation++; - while(paramIter != event.params.end()) { - os << indent << " " << paramIter->first << ": "; - os << indent << paramIter->second << std::endl; - paramIter++; - } - _dataIndentation--; - } - if (event.namelist.size() > 0) { - std::map<std::string, Data>::const_iterator namelistIter = event.namelist.begin(); - os << indent << " namelist:" << std::endl; - _dataIndentation++; - while(namelistIter != event.namelist.end()) { - os << indent << " " << namelistIter->first << ": "; - os << indent << namelistIter->second << std::endl; - namelistIter++; - } - _dataIndentation--; - - } - _dataIndentation++; - os << indent << " data: " << event.data << std::endl; - _dataIndentation--; - return os; -} #endif #ifndef SWIGJAVA -std::ostream& operator<< (std::ostream& os, const Data& data) { - os << Data::toJSON(data); - return os; -} #endif -std::string Data::toJSON(const Data& data) { - std::stringstream 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 += " "; - - std::string seperator; - os << std::endl << indent << "{"; - compoundIter = data.compound.begin(); - while(compoundIter != data.compound.end()) { - os << seperator << std::endl << indent << " \"" << compoundIter->first << "\": " << keyPadding.substr(0, longestKey - compoundIter->first.size()); - _dataIndentation += 1; - os << compoundIter->second; - _dataIndentation -= 1; - seperator = ", "; - compoundIter++; - } - os << std::endl << indent << "}"; - } else if (data.array.size() > 0) { - - std::string seperator; - os << std::endl << indent << "["; - std::list<Data>::const_iterator arrayIter = data.array.begin(); - while(arrayIter != data.array.end()) { - _dataIndentation += 1; - os << seperator << *arrayIter; - _dataIndentation -= 1; - seperator = ", "; - arrayIter++; - } - os << "]"; - } else if (data.atom.size() > 0) { - // empty string is handled below - if (data.type == Data::VERBATIM) { - os << "\""; - for (int i = 0; i < data.atom.size(); i++) { - // escape string - if (false) { - } else if (data.atom[i] == '"') { - os << "\\\""; - } else if (data.atom[i] == '\n') { - os << "\\n"; - } else if (data.atom[i] == '\t') { - os << "\\t"; - } else { - os << data.atom[i]; - } - } - os << "\""; - } else { - os << data.atom; - } - } else if (data.node) { - std::ostringstream xmlSerSS; - xmlSerSS << data.node; - std::string xmlSer = xmlSerSS.str(); - boost::replace_all(xmlSer, "\"", "\\\""); - boost::replace_all(xmlSer, "\n", "\\n"); - boost::replace_all(xmlSer, "\t", "\\t"); - os << "\"" << xmlSer << "\""; - } else { - if (data.type == Data::VERBATIM) { - os << "\"\""; // empty string - } else { - os << "null"; - } - } - return os.str(); -} }
\ No newline at end of file diff --git a/src/uscxml/Message.h b/src/uscxml/Message.h index 05dc758..5732857 100644 --- a/src/uscxml/Message.h +++ b/src/uscxml/Message.h @@ -20,555 +20,11 @@ #ifndef EVENT_H_XZAQ4HR #define EVENT_H_XZAQ4HR -#include <map> -#include <list> -#include <set> -#include <vector> -#include <string> - -#include <DOM/Document.hpp> -#include <DOM/io/Stream.hpp> - -#include <boost/shared_ptr.hpp> -#include <boost/lexical_cast.hpp> -#include <inttypes.h> - -#include "uscxml/Common.h" - -#include "uscxml/Convenience.h" - -#include "uscxml/util/MD5.hpp" -#include "uscxml/util/Base64.hpp" - -namespace uscxml { - -class USCXML_API Blob { -public: - ~Blob(); - Blob(size_t size); - Blob(void* data, size_t size, const std::string& mimeType, bool adopt = false); - char* data; - size_t size; - std::string mimeType; - - std::string md5() { - return uscxml::md5(data, size); - } - - std::string base64(); - - Blob* fromBase64(const std::string base64) { - std::string decoded = base64Decode(base64); - return new Blob((void*)decoded.c_str(), decoded.length(), mimeType); - } -}; - -class USCXML_API Data { -public: - enum Type { - VERBATIM, - INTERPRETED, - }; - - Data() : type(INTERPRETED) {} - - // TODO: default INTERPRETED is unfortunate - Data(const std::string& atom_, Type type_ = INTERPRETED) : atom(atom_), type(type_) {} - Data(const char* data, size_t size, const std::string& mimeType, bool adopt = false); - - // convenience constructors - Data(short atom_) : atom(toStr(atom_)), type(INTERPRETED) {} - Data(int atom_) : atom(toStr(atom_)), type(INTERPRETED) {} - Data(unsigned int atom_) : atom(toStr(atom_)), type(INTERPRETED) {} - Data(long atom_) : atom(toStr(atom_)), type(INTERPRETED) {} - Data(unsigned long atom_) : atom(toStr(atom_)), type(INTERPRETED) {} - Data(float atom_) : atom(toStr(atom_)), type(INTERPRETED) {} - Data(double atom_) : atom(toStr(atom_)), type(INTERPRETED) {} - Data(bool atom_) : type(INTERPRETED) { - if (atom_) { - atom = "true"; - } else { - atom = "false"; - } - } - - template <typename T> Data(T value, Type type_) : atom(toStr(value)), type(type_) {} - -#if 0 - // constructor for arbitrary types, skip if type is subclass though (C++11) - // we will have to drop this constructor as it interferes with operator Data() and entails C++11 - template <typename T> - Data(T value, typename std::enable_if<! std::is_base_of<Data, T>::value>::type* = nullptr) - : atom(toStr(value)), type(INTERPRETED) {} -#endif - - - explicit Data(const Arabica::DOM::Node<std::string>& dom); - virtual ~Data() {} - - bool empty() const { - bool hasContent = (atom.length() > 0 || !compound.empty() || !array.empty() || binary || node); - return !hasContent; - } - - bool operator<(const Data& other) const { - std::string thisJSON = Data::toJSON(*this); - std::string otherJSON = Data::toJSON(other); - return (thisJSON < otherJSON); - } - - void merge(const Data& other); - - bool hasKey(const std::string& key) const { - return (!compound.empty() && compound.find(key) != compound.end()); - } - - Data& operator[](const std::string& key) { - return operator[](key.c_str()); - } - - const Data& operator[](const std::string& key) const { - return operator[](key.c_str()); - } - - Data& operator[](const char* key) { - return compound[key]; - } - - const Data& operator[](const char* key) const { - return compound.at(key); - } - - Data& operator[](const size_t index) { - while(array.size() < index) { - array.push_back(Data("", Data::VERBATIM)); - } - std::list<Data>::iterator arrayIter = array.begin(); - for (int i = 0; i < index; i++, arrayIter++) {} - return *arrayIter; - } - - const Data at(const std::string& key) const { - return at(key.c_str()); - } - - const Data at(const char* key) const { - if (hasKey(key)) - return compound.at(key); - Data data; - return data; - } - - const Data item(const size_t index) const { - if (array.size() < index) { - std::list<Data>::const_iterator arrayIter; - for (int i = 0; i < index; i++, arrayIter++) {} - return *arrayIter; - } - Data data; - return data; - } - - bool operator==(const Data &other) const { - if (other.atom.size() != atom.size()) - return false; - if (other.type != type) - return false; - if (other.binary != binary) - return false; - if (other.array.size() != array.size()) - return false; - if (other.compound.size() != compound.size()) - return false; - - if (other.atom != atom) - return false; - if (other.array != array) - return false; - if (other.compound != compound) - return false; - if (other.node != node) - return false; - - return true; - } - - bool operator!=(const Data &other) const { - return !(*this == other); - } - - operator std::string() const { - return atom; - } - - operator std::map<std::string, Data>() { - return compound; - } - - operator std::list<Data>() { - return array; - } - - static Data fromJSON(const std::string& jsonString); - static std::string toJSON(const Data& 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> getCompound() { - return compound; - } - void setCompound(const std::map<std::string, Data>& compound) { - this->compound = compound; - } - - std::list<Data> getArray() { - return array; - } - void setArray(const std::list<Data>& array) { - this->array = array; - } - - std::string getAtom() { - return atom; - } - void setAtom(const std::string& atom) { - this->atom = atom; - } - - Type getType() { - return type; - } - void setType(const Type type) { - this->type = type; - } - - -#ifdef SWIGIMPORTED -protected: -#endif - - Arabica::DOM::Node<std::string> node; - std::map<std::string, Data> compound; - std::list<Data> array; - std::string atom; - boost::shared_ptr<Blob> binary; - Type type; - -protected: - Arabica::DOM::Document<std::string> toNode(const Arabica::DOM::Document<std::string>& factory, const Data& data); - friend USCXML_API std::ostream& operator<< (std::ostream& os, const Data& data); -}; - -class USCXML_API Event { -public: - enum Type { - INTERNAL = 1, - EXTERNAL = 2, - PLATFORM = 3 - }; - - Event() : eventType(INTERNAL), hideSendId(false) {} - Event(const std::string& name, Type type = INTERNAL) : name(name), eventType(type), hideSendId(false) {} - Event(const Arabica::DOM::Node<std::string>& xmlString) : eventType(INTERNAL), hideSendId(false) {}; - bool operator< (const Event& other) const { - return this < &other; - } - - bool operator==(const Event& other) const { - return (this->name == other.name && - this->sendid == other.sendid && - this->invokeid == other.invokeid && - this->data == other.data); - } - bool operator!=(const Event& other) const { - return !(*this == other); - } - - std::string getName() { - return name; - } - void setName(const std::string& name) { - this->name = name; - } - - Type getEventType() { - return eventType; - } - void setEventType(const Type type) { - this->eventType = type; - } - - std::string getOrigin() { - return origin; - } - void setOrigin(const std::string& origin) { - this->origin = origin; - } - - std::string getOriginType() { - return origintype; - } - void setOriginType(const std::string& originType) { - this->origintype = originType; - } - - Arabica::DOM::Node<std::string> getDOM() { - return dom; - } - void setDOM(const Arabica::DOM::Node<std::string>& dom) { - this->dom = dom; - } - -// Arabica::DOM::Node<std::string> getFirstDOMElement() const; -// Arabica::DOM::Document<std::string> getStrippedDOM() const; -// -// static Arabica::DOM::Node<std::string> getFirstDOMElement(const Arabica::DOM::Document<std::string> dom); -// static Arabica::DOM::Document<std::string> getStrippedDOM(const Arabica::DOM::Document<std::string> dom); - - std::string getRaw() { - return raw; - } - void setRaw(const std::string& raw) { - this->raw = raw; - } - - std::string getContent() { - return content; - } - void setContent(const std::string& content) { - this->content = content; - } - - std::string getXML() { - return xml; - } - void setXML(const std::string& xml) { - this->xml = xml; - } - - std::string getSendId() { - return sendid; - } - void setSendId(const std::string& sendId) { - this->sendid = sendId; - } - - std::string getInvokeId() { - return invokeid; - } - void setInvokeId(const std::string& invokeId) { - this->invokeid = invokeId; - } - - Data getData() { - return data; - } - void setData(const Data& data) { - this->data = data; - } - - void initContent(const std::string& content); - - static Event 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>& getNameList() { - return namelist; - } - std::multimap<std::string, Data>& getParams() { - return params; - } - - typedef std::multimap<std::string, Data> params_t; - typedef std::map<std::string, Data> namelist_t; - - static bool getParam(params_t params, const std::string& name, Data& target) { - if (params.find(name) != params.end()) { - target = params.find(name)->second; - return true; - } - return false; - } - - static bool getParam(params_t params, const std::string& name, std::list<Data>& target) { - if (params.find(name) != params.end()) { - std::pair<params_t::iterator, params_t::iterator> rangeIter = params.equal_range(name); - while(rangeIter.first != rangeIter.second) { - target.push_back(rangeIter.first->second); - rangeIter.first++; - } - return true; - } - return false; - } - - template <typename T> static bool getParam(params_t params, const std::string& name, T& target) { - if (params.find(name) != params.end()) { - target = boost::lexical_cast<T>(params.find(name)->second.atom); - return true; - } - return false; - } - - static bool getParam(params_t params, const std::string& name, bool& target) { - if (params.find(name) != params.end()) { - target = true; - if (iequals(params.find(name)->second.atom, "false")) { - target = false; - } else if(iequals(params.find(name)->second.atom, "off")) { - target = false; - } else if(iequals(params.find(name)->second.atom, "no")) { - target = false; - } else if(iequals(params.find(name)->second.atom, "0")) { - target = false; - } - return true; - } - return false; - } - - template <typename T> static bool getParam(params_t params, const std::string& name, std::list<T>& target) { - if (params.find(name) != params.end()) { - std::pair<params_t::iterator, params_t::iterator> rangeIter = params.equal_range(name); - while(rangeIter.first != rangeIter.second) { - target.push_back(boost::lexical_cast<T>(rangeIter.first->second.atom)); - rangeIter.first++; - } - return true; - } - return false; - } - - -#ifdef SWIGIMPORTED -protected: -#endif - - std::string raw; - std::string xml; - std::string name; - Type eventType; - std::string origin; - std::string origintype; - Arabica::DOM::Node<std::string> dom; - std::string sendid; - bool hideSendId; - std::string invokeid; - Data data; - std::string content; - std::map<std::string, Data> namelist; - std::multimap<std::string, Data> params; - - friend USCXML_API std::ostream& operator<< (std::ostream& os, const Event& event); -}; - -class USCXML_API InvokeRequest : public Event { -public: - InvokeRequest(Event event) : Event(event) {} - InvokeRequest() {} - - std::string getType() { - return type; - } - void setType(const std::string& type) { - this->type = type; - } - - std::string getSource() { - return src; - } - void setSource(const std::string& src) { - this->src = src; - } - - bool isAutoForwarded() { - return autoForward; - } - void setAutoForwarded(bool autoForward) { - this->autoForward = autoForward; - } - - static InvokeRequest fromXML(const std::string& xmlString); - Arabica::DOM::Document<std::string> toDocument(); - std::string toXMLString() { - std::stringstream ss; - ss << toDocument(); - return ss.str(); - } - -#ifdef SWIGIMPORTED -protected: -#endif - std::string type; - std::string src; - bool autoForward; - - friend USCXML_API std::ostream& operator<< (std::ostream& os, const InvokeRequest& sendReq); - -}; - -class USCXML_API SendRequest : public Event { -public: - SendRequest() {} - SendRequest(Event event) : Event(event) {} - - std::string getTarget() { - return target; - } - void setTarget(const std::string& target) { - this->target = target; - } - - std::string getType() { - return type; - } - void setType(const std::string& type) { - this->type = type; - } - - uint32_t getDelayMs() { - return delayMs; - } - void setDelayMs(uint32_t delayMs) { - this->delayMs = delayMs; - } - - 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(); - } - -#ifdef SWIGIMPORTED -protected: -#endif - std::string target; - std::string type; - uint32_t delayMs; - - friend USCXML_API std::ostream& operator<< (std::ostream& os, const SendRequest& sendReq); - -}; - -USCXML_API std::ostream& operator<< (std::ostream& os, const InvokeRequest& invokeReq); -USCXML_API std::ostream& operator<< (std::ostream& os, const SendRequest& sendReq); -USCXML_API std::ostream& operator<< (std::ostream& os, const Event& event); -USCXML_API std::ostream& operator<< (std::ostream& os, const Data& data); - -} +#include "uscxml/messages/Blob.h" +#include "uscxml/messages/Data.h" +#include "uscxml/messages/Event.h" +#include "uscxml/messages/SendRequest.h" +#include "uscxml/messages/InvokeRequest.h" #endif /* end of include guard: EVENT_H_XZAQ4HR */ diff --git a/src/uscxml/URL.cpp b/src/uscxml/URL.cpp index 1ba8404..aaf4cde 100644 --- a/src/uscxml/URL.cpp +++ b/src/uscxml/URL.cpp @@ -21,6 +21,8 @@ #include "URL.h" #include "UUID.h" +#include <sys/stat.h> + #include "uscxml/config.h" #include <fstream> #include <boost/lexical_cast.hpp> @@ -39,6 +41,8 @@ #include <pwd.h> #endif +#include "uscxml/messages/Event.h" + #include <cstdlib> // mkstemp #ifdef HAS_UNISTD_H #include <unistd.h> // mkstemp legacy diff --git a/src/uscxml/URL.h b/src/uscxml/URL.h index fd89503..01f3e1b 100644 --- a/src/uscxml/URL.h +++ b/src/uscxml/URL.h @@ -23,14 +23,13 @@ #include <curl/curl.h> #include <string> #include <iostream> -#include <sstream> #include <map> #include <vector> #include <set> -#include "Message.h" + +#include "uscxml/messages/Data.h" #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> -#include <sys/stat.h> #include "uscxml/concurrency/tinythread.h" diff --git a/src/uscxml/UUID.cpp b/src/uscxml/UUID.cpp index 68f0d76..8647739 100644 --- a/src/uscxml/UUID.cpp +++ b/src/uscxml/UUID.cpp @@ -19,6 +19,7 @@ #include "UUID.h" #include <sstream> +#include <boost/uuid/uuid_io.hpp> namespace uscxml { boost::uuids::random_generator UUID::uuidGen; diff --git a/src/uscxml/UUID.h b/src/uscxml/UUID.h index c4ccaee..af129e7 100644 --- a/src/uscxml/UUID.h +++ b/src/uscxml/UUID.h @@ -21,10 +21,8 @@ #define UUID_H_8X65R2EI #include "uscxml/Common.h" -#include <boost/uuid/uuid.hpp> #include <boost/uuid/uuid_generators.hpp> -#include <boost/uuid/uuid_io.hpp> -#include <ostream> +#include <string> namespace uscxml { diff --git a/src/uscxml/concurrency/eventqueue/DelayedEventQueue.cpp b/src/uscxml/concurrency/eventqueue/DelayedEventQueue.cpp index 46c12e4..642c4a0 100644 --- a/src/uscxml/concurrency/eventqueue/DelayedEventQueue.cpp +++ b/src/uscxml/concurrency/eventqueue/DelayedEventQueue.cpp @@ -17,12 +17,13 @@ * @endcond */ -#include "uscxml/Message.h" #include "DelayedEventQueue.h" +#include "uscxml/messages/Event.h" + #include <glog/logging.h> -#include <assert.h> + #include <event2/event.h> -#include <sstream> +#include "event2/thread.h" namespace uscxml { diff --git a/src/uscxml/concurrency/eventqueue/DelayedEventQueue.h b/src/uscxml/concurrency/eventqueue/DelayedEventQueue.h index 0059bb5..2248c47 100644 --- a/src/uscxml/concurrency/eventqueue/DelayedEventQueue.h +++ b/src/uscxml/concurrency/eventqueue/DelayedEventQueue.h @@ -22,15 +22,15 @@ #include "uscxml/concurrency/tinythread.h" -#include <event2/thread.h> -#include <event2/http.h> + +#include "uscxml/Common.h" +#include "event2/util.h" // for evutil_socket_t #include <event2/event.h> #include <inttypes.h> #include <map> #include <string> -#include <iostream> namespace uscxml { diff --git a/src/uscxml/concurrency/tinythread.h b/src/uscxml/concurrency/tinythread.h index 867f036..cf313d5 100644 --- a/src/uscxml/concurrency/tinythread.h +++ b/src/uscxml/concurrency/tinythread.h @@ -25,6 +25,7 @@ freely, subject to the following restrictions: #define _TINYTHREAD_H_ #include "uscxml/Common.h" +#include <ostream> /// @file /// @mainpage TinyThread++ API Reference diff --git a/src/uscxml/debug/Breakpoint.h b/src/uscxml/debug/Breakpoint.h index 5cf92a1..71308aa 100644 --- a/src/uscxml/debug/Breakpoint.h +++ b/src/uscxml/debug/Breakpoint.h @@ -20,8 +20,11 @@ #ifndef BREAKPOINT_H_VR7K7T1X #define BREAKPOINT_H_VR7K7T1X -#include "uscxml/Message.h" +#include <string> // for string #include "uscxml/Interpreter.h" +#include "DOM/Element.hpp" // for Element +#include "uscxml/Common.h" // for USCXML_API +#include "uscxml/messages/Data.h" // for Data namespace uscxml { diff --git a/src/uscxml/debug/Debugger.cpp b/src/uscxml/debug/Debugger.cpp index b74b2a9..cb4d522 100644 --- a/src/uscxml/debug/Debugger.cpp +++ b/src/uscxml/debug/Debugger.cpp @@ -19,6 +19,7 @@ #include "uscxml/debug/Debugger.h" #include "uscxml/DOMUtils.h" +#include "uscxml/debug/DebugSession.h" namespace uscxml { diff --git a/src/uscxml/debug/Debugger.h b/src/uscxml/debug/Debugger.h index 9adbae6..03846e5 100644 --- a/src/uscxml/debug/Debugger.h +++ b/src/uscxml/debug/Debugger.h @@ -20,13 +20,15 @@ #ifndef DEBUGGERMONITOR_H_Z050WPFH #define DEBUGGERMONITOR_H_Z050WPFH -#include "uscxml/Message.h" +#include "uscxml/messages/Data.h" // for Data +#include "uscxml/messages/Event.h" // for Event #include "uscxml/Interpreter.h" #include "uscxml/debug/Breakpoint.h" -#include "uscxml/debug/DebugSession.h" namespace uscxml { +class DebugSession; + class USCXML_API Debugger : public InterpreterMonitor { public: Debugger() { diff --git a/src/uscxml/debug/DebuggerServlet.cpp b/src/uscxml/debug/DebuggerServlet.cpp index d7528f0..49306a2 100644 --- a/src/uscxml/debug/DebuggerServlet.cpp +++ b/src/uscxml/debug/DebuggerServlet.cpp @@ -18,6 +18,7 @@ */ #include "uscxml/debug/DebuggerServlet.h" +#include "uscxml/debug/DebugSession.h" #include "uscxml/UUID.h" #include <boost/algorithm/string.hpp> diff --git a/src/uscxml/debug/DebuggerServlet.h b/src/uscxml/debug/DebuggerServlet.h index ce6f082..8abe741 100644 --- a/src/uscxml/debug/DebuggerServlet.h +++ b/src/uscxml/debug/DebuggerServlet.h @@ -21,11 +21,9 @@ #define DEBUGGERSERVLET_H_ATUMDA3G #include "uscxml/Common.h" -#include "getopt.h" #include <glog/logging.h> #include "uscxml/server/HTTPServer.h" -#include "uscxml/Interpreter.h" #include "uscxml/debug/Debugger.h" #include "uscxml/concurrency/tinythread.h" diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp index e2ab620..dd23a87 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.cpp +++ b/src/uscxml/interpreter/InterpreterDraft6.cpp @@ -18,6 +18,7 @@ */ #include "InterpreterDraft6.h" +#include "uscxml/concurrency/eventqueue/DelayedEventQueue.h" #include <glog/logging.h> #include "uscxml/UUID.h" @@ -37,10 +38,9 @@ InterpreterState InterpreterDraft6::interpret() { while(true) { state = step(-1); - switch (state & InterpreterState::USCXML_INTERPRETER_MASK) { - case uscxml::InterpreterState::USCXML_FAULTED: - case uscxml::InterpreterState::USCXML_FINISHED: - case uscxml::InterpreterState::USCXML_DESTROYED: + switch (state) { + case uscxml::USCXML_FINISHED: + case uscxml::USCXML_DESTROYED: // return as we finished return state; default: @@ -61,7 +61,7 @@ InterpreterState InterpreterDraft6::interpret() { NodeSet<std::string> InterpreterDraft6::getDocumentInitialTransitions() { NodeSet<std::string> initialTransitions; - if (_userDefinedStartConfiguration.size() > 0) { + if (_startConfiguration.size() > 0) { // we emulate entering a given configuration by creating a pseudo deep history Element<std::string> initHistory = _document.createElementNS(_nsInfo.nsURL, "history"); _nsInfo.setPrefix(initHistory); @@ -72,8 +72,8 @@ NodeSet<std::string> InterpreterDraft6::getDocumentInitialTransitions() { std::string histId = ATTR(initHistory, "id"); NodeSet<std::string> histStates; - for (int i = 0; i < _userDefinedStartConfiguration.size(); i++) { - histStates.push_back(getState(_userDefinedStartConfiguration[i])); + for (std::list<std::string>::const_iterator stateIter = _startConfiguration.begin(); stateIter != _startConfiguration.end(); stateIter++) { + histStates.push_back(getState(*stateIter)); } _historyValue[histId] = histStates; @@ -119,9 +119,7 @@ InterpreterState InterpreterDraft6::step(int waitForMS = 0) { try { tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); - if (_state & InterpreterState::USCXML_FINISHED || - _state & InterpreterState::USCXML_FAULTED || - _state & InterpreterState::USCXML_DESTROYED) { + if (_state == USCXML_FINISHED || _state == USCXML_DESTROYED) { return _state; } @@ -148,7 +146,7 @@ InterpreterState InterpreterDraft6::step(int waitForMS = 0) { enabledTransitions.to_document_order(); microstep(enabledTransitions); - setInterpreterState(InterpreterState::USCXML_MICROSTEPPED); + setInterpreterState(USCXML_MICROSTEPPED); return _state; } @@ -174,19 +172,19 @@ InterpreterState InterpreterDraft6::step(int waitForMS = 0) { } // test 319 - even if we do not enable transitions, consider it a microstep - setInterpreterState(InterpreterState::USCXML_MICROSTEPPED); + setInterpreterState(USCXML_MICROSTEPPED); return _state; } else { _stable = true; } // even if we did nothing - count as microstep - setInterpreterState(InterpreterState::USCXML_MICROSTEPPED); + setInterpreterState(USCXML_MICROSTEPPED); if (_topLevelFinalReached) goto EXIT_INTERPRETER; - setInterpreterState(InterpreterState::USCXML_MACROSTEPPED); + setInterpreterState(USCXML_MACROSTEPPED); USCXML_MONITOR_CALLBACK(onStableConfiguration) // when we reach a stable configuration, invoke @@ -201,7 +199,7 @@ InterpreterState InterpreterDraft6::step(int waitForMS = 0) { _statesToInvoke = NodeSet<std::string>(); if (_externalQueue.isEmpty()) { - setInterpreterState(InterpreterState::USCXML_IDLE); + setInterpreterState(USCXML_IDLE); if (waitForMS < 0) { // wait blockingly for an event forever @@ -224,7 +222,7 @@ InterpreterState InterpreterDraft6::step(int waitForMS = 0) { return _state; } - setInterpreterState(InterpreterState::USCXML_MACROSTEPPED); + setInterpreterState(USCXML_MACROSTEPPED); } _currEvent = _externalQueue.pop(); @@ -281,15 +279,11 @@ EXIT_INTERPRETER: if(_dataModel) _dataModel = DataModel(); - setInterpreterState(InterpreterState::USCXML_FINISHED); + setInterpreterState(USCXML_FINISHED); return _state; - } catch (Event e) { - setInterpreterState(InterpreterState::USCXML_FAULTED, e); - return _state; - } catch (boost::bad_weak_ptr e) { LOG(ERROR) << "Unclean shutdown " << std::endl << std::endl; - setInterpreterState(InterpreterState::USCXML_DESTROYED); + setInterpreterState(USCXML_DESTROYED); return _state; } diff --git a/src/uscxml/interpreter/InterpreterRC.cpp b/src/uscxml/interpreter/InterpreterRC.cpp index 7f8c91c..53feae8 100644 --- a/src/uscxml/interpreter/InterpreterRC.cpp +++ b/src/uscxml/interpreter/InterpreterRC.cpp @@ -19,6 +19,9 @@ #include "InterpreterRC.h" +#include "uscxml/Factory.h" +#include "uscxml/concurrency/eventqueue/DelayedEventQueue.h" + #include <glog/logging.h> #include "uscxml/UUID.h" #include "uscxml/DOMUtils.h" @@ -114,7 +117,7 @@ InterpreterState InterpreterRC::interpret() { NodeSet<std::string> initialTransitions; - if (_userDefinedStartConfiguration.size() > 0) { + if (_startConfiguration.size() > 0) { // we emulate entering a given configuration by creating a pseudo deep history Element<std::string> initHistory = _document.createElementNS(_nsInfo.nsURL, "history"); _nsInfo.setPrefix(initHistory); @@ -125,8 +128,8 @@ InterpreterState InterpreterRC::interpret() { std::string histId = ATTR(initHistory, "id"); NodeSet<std::string> histStates; - for (int i = 0; i < _userDefinedStartConfiguration.size(); i++) { - histStates.push_back(getState(_userDefinedStartConfiguration[i])); + for (std::list<std::string>::const_iterator stateIter = _startConfiguration.begin(); stateIter != _startConfiguration.end(); stateIter++) { + histStates.push_back(getState(*stateIter)); } _historyValue[histId] = histStates; diff --git a/src/uscxml/messages/Blob.cpp b/src/uscxml/messages/Blob.cpp new file mode 100644 index 0000000..1d07e6a --- /dev/null +++ b/src/uscxml/messages/Blob.cpp @@ -0,0 +1,61 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#include "uscxml/messages/Blob.h" + +#include "uscxml/util/MD5.hpp" +#include "uscxml/util/Base64.hpp" + +namespace uscxml { + +Blob::~Blob() { + free(data); +} + +std::string Blob::md5() { + return uscxml::md5(data, size); +} + +Blob* Blob::fromBase64(const std::string base64) { + std::string decoded = base64Decode(base64); + return new Blob((void*)decoded.c_str(), decoded.length(), mimeType); +} + +Blob::Blob(size_t _size) { + data = (char*)malloc(_size); + memset(data, 0, _size); + size = _size; +} + +Blob::Blob(void* _data, size_t _size, const std::string& _mimeType, bool adopt) { + if (adopt) { + data = (char*)_data; + } else { + data = (char*)malloc(_size); + memcpy(data, _data, _size); + } + mimeType = _mimeType; + size = _size; +} + +std::string Blob::base64() { + return base64Encode((char* const)data, size); +} + +}
\ No newline at end of file diff --git a/src/uscxml/messages/Blob.h b/src/uscxml/messages/Blob.h new file mode 100644 index 0000000..b4fcd46 --- /dev/null +++ b/src/uscxml/messages/Blob.h @@ -0,0 +1,47 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef BLOB_H_E1B6D2C3 +#define BLOB_H_E1B6D2C3 + +#include <string> + +#include "uscxml/Common.h" + +namespace uscxml { + +class USCXML_API Blob { +public: + ~Blob(); + Blob(size_t size); + Blob(void* data, size_t size, const std::string& mimeType, bool adopt = false); + char* data; + size_t size; + std::string mimeType; + + std::string base64(); + + std::string md5(); + Blob* fromBase64(const std::string base64); + +}; + +} + +#endif /* end of include guard: BLOB_H_E1B6D2C3 */ diff --git a/src/uscxml/messages/Data.cpp b/src/uscxml/messages/Data.cpp new file mode 100644 index 0000000..6706253 --- /dev/null +++ b/src/uscxml/messages/Data.cpp @@ -0,0 +1,387 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#include "uscxml/messages/Data.h" +#include "uscxml/messages/Blob.h" + +#include <boost/algorithm/string.hpp> + +#include "uscxml/DOMUtils.h" +#include "glog/logging.h" + +#ifdef HAS_STRING_H +#include <string.h> +#endif + +extern "C" { +#include "jsmn.h" // minimal json parser +} + +namespace uscxml { + +Data::Data(const char* _data, size_t _size, const std::string& mimeType, bool adopt) { + binary = boost::shared_ptr<Blob>(new Blob((void*)_data, _size, mimeType, adopt)); +} + +void Data::merge(const Data& other) { + if (other.compound.size() > 0) { + if (compound.size() == 0) { + compound = other.compound; + } else { + std::map<std::string, Data>::const_iterator compIter = other.compound.begin(); + while (compIter != other.compound.end()) { + if (compound.find(compIter->first) != compound.end()) { + // we do have the same key, merge + compound[compIter->first].merge(compIter->second); + } else { + compound[compIter->first] = compIter->second; + } + compIter++; + } + } + } + if (other.array.size() > 0) { + if (array.size() == 0) { + array = other.array; + } else { + std::list<Data>::const_iterator arrIter = other.array.begin(); + while(arrIter != other.array.end()) { + array.push_back(*arrIter); + arrIter++; + } + } + } + if (other.atom.size() > 0) { + atom = other.atom; + type = other.type; + } +} + +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; +// 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); +// 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); +// 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; + } +} + +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", "payload"); + payloadElem.setPrefix("scxml"); + + 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", "property"); + propertyElem.setPrefix("scxml"); + + 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; +} + +Data Data::fromXML(const std::string& xmlString) { + return Data(); +} + +Data Data::fromJSON(const std::string& jsonString) { + Data data; + + std::string trimmed = boost::trim_copy(jsonString); + + if (trimmed.length() == 0) + return data; + + if (trimmed.find_first_of("{[") != 0) + return data; + + jsmn_parser p; + + jsmntok_t* t = NULL; + + // we do not know the number of tokens beforehand, start with something sensible and increase + int rv; + int frac = 16; // length/token ratio + do { + jsmn_init(&p); + + frac /= 2; + int nrTokens = trimmed.size() / frac; + if (t != NULL) { + free(t); +// LOG(INFO) << "Increasing JSON length to token ratio to 1/" << frac; + } + t = (jsmntok_t*)malloc((nrTokens + 1) * sizeof(jsmntok_t)); + if (t == NULL) { + LOG(ERROR) << "Cannot parse JSON, ran out of memory!"; + return data; + } + memset(t, 0, (nrTokens + 1) * sizeof(jsmntok_t)); + + rv = jsmn_parse(&p, trimmed.c_str(), t, nrTokens); + } while (rv == JSMN_ERROR_NOMEM && frac > 1); + + if (rv != 0) { + switch (rv) { + case JSMN_ERROR_NOMEM: + LOG(ERROR) << "Cannot parse JSON, not enough tokens were provided!"; + break; + case JSMN_ERROR_INVAL: + LOG(ERROR) << "Cannot parse JSON, invalid character inside JSON string!"; + break; + case JSMN_ERROR_PART: + LOG(ERROR) << "Cannot parse JSON, the string is not a full JSON packet, more bytes expected!"; + break; + default: + break; + } + free(t); + return data; + } + + if (t[0].end != trimmed.length()) + return data; + +// jsmntok_t* token = t; +// while(token->end) { +// std::cout << trimmed.substr(token->start, token->end - token->start) << std::endl; +// std::cout << "------" << std::endl; +// token++; +// } + + std::list<Data*> dataStack; + std::list<jsmntok_t> tokenStack; + dataStack.push_back(&data); + + size_t currTok = 0; + do { + // used for debugging +// jsmntok_t t2 = t[currTok]; +// std::string value = trimmed.substr(t[currTok].start, t[currTok].end - t[currTok].start); + switch (t[currTok].type) { + case JSMN_STRING: + dataStack.back()->type = Data::VERBATIM; + case JSMN_PRIMITIVE: { + std::string value = trimmed.substr(t[currTok].start, t[currTok].end - t[currTok].start); + if (dataStack.back()->type == Data::VERBATIM) { + boost::replace_all(value, "\\\"", "\""); + boost::replace_all(value, "\\n", "\n"); + } + dataStack.back()->atom = value; + dataStack.pop_back(); + currTok++; + break; + } + case JSMN_OBJECT: + case JSMN_ARRAY: + tokenStack.push_back(t[currTok]); + currTok++; + break; + } + // used for debugging +// t2 = t[currTok]; +// value = trimmed.substr(t[currTok].start, t[currTok].end - t[currTok].start); + + // there are no more tokens + if (t[currTok].end == 0 || tokenStack.empty()) + break; + + // next token starts after current one => pop + while (t[currTok].end > tokenStack.back().end) { + tokenStack.pop_back(); + dataStack.pop_back(); + } + + if (tokenStack.back().type == JSMN_OBJECT && (t[currTok].type == JSMN_PRIMITIVE || t[currTok].type == JSMN_STRING)) { + // grab key and push new data + std::string value = trimmed.substr(t[currTok].start, t[currTok].end - t[currTok].start); + dataStack.push_back(&(dataStack.back()->compound[value])); + currTok++; + } + if (tokenStack.back().type == JSMN_ARRAY) { + // push new index + dataStack.back()->array.push_back(Data()); + dataStack.push_back(&(dataStack.back()->array.back())); + } + + } while (true); + + free(t); + return data; +} + +std::ostream& operator<< (std::ostream& os, const Data& data) { + os << Data::toJSON(data); + return os; +} + +std::string Data::toJSON(const Data& data) { + std::stringstream 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 += " "; + + std::string seperator; + os << std::endl << indent << "{"; + compoundIter = data.compound.begin(); + while(compoundIter != data.compound.end()) { + os << seperator << std::endl << indent << " \"" << compoundIter->first << "\": " << keyPadding.substr(0, longestKey - compoundIter->first.size()); + _dataIndentation += 1; + os << compoundIter->second; + _dataIndentation -= 1; + seperator = ", "; + compoundIter++; + } + os << std::endl << indent << "}"; + } else if (data.array.size() > 0) { + + std::string seperator; + os << std::endl << indent << "["; + std::list<Data>::const_iterator arrayIter = data.array.begin(); + while(arrayIter != data.array.end()) { + _dataIndentation += 1; + os << seperator << *arrayIter; + _dataIndentation -= 1; + seperator = ", "; + arrayIter++; + } + os << "]"; + } else if (data.atom.size() > 0) { + // empty string is handled below + if (data.type == Data::VERBATIM) { + os << "\""; + for (int i = 0; i < data.atom.size(); i++) { + // escape string + if (false) { + } else if (data.atom[i] == '"') { + os << "\\\""; + } else if (data.atom[i] == '\n') { + os << "\\n"; + } else if (data.atom[i] == '\t') { + os << "\\t"; + } else { + os << data.atom[i]; + } + } + os << "\""; + } else { + os << data.atom; + } + } else if (data.node) { + std::ostringstream xmlSerSS; + xmlSerSS << data.node; + std::string xmlSer = xmlSerSS.str(); + boost::replace_all(xmlSer, "\"", "\\\""); + boost::replace_all(xmlSer, "\n", "\\n"); + boost::replace_all(xmlSer, "\t", "\\t"); + os << "\"" << xmlSer << "\""; + } else { + if (data.type == Data::VERBATIM) { + os << "\"\""; // empty string + } else { + os << "null"; + } + } + return os.str(); +} + +}
\ No newline at end of file diff --git a/src/uscxml/messages/Data.h b/src/uscxml/messages/Data.h new file mode 100644 index 0000000..bf13409 --- /dev/null +++ b/src/uscxml/messages/Data.h @@ -0,0 +1,243 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef DATA_H_09E4D8E5 +#define DATA_H_09E4D8E5 + +#include <list> +#include <map> + +#include <boost/shared_ptr.hpp> + +#include "uscxml/Common.h" +#include "uscxml/Convenience.h" +#include <DOM/Document.hpp> + +namespace uscxml { + +class Blob; + +static int _dataIndentation = 1; + +class USCXML_API Data { +public: + enum Type { + VERBATIM, + INTERPRETED, + }; + + Data() : type(INTERPRETED) {} + + // TODO: default INTERPRETED is unfortunate + Data(const std::string& atom_, Type type_ = INTERPRETED) : atom(atom_), type(type_) {} + Data(const char* data, size_t size, const std::string& mimeType, bool adopt = false); + + // convenience constructors + Data(short atom_) : atom(toStr(atom_)), type(INTERPRETED) {} + Data(int atom_) : atom(toStr(atom_)), type(INTERPRETED) {} + Data(unsigned int atom_) : atom(toStr(atom_)), type(INTERPRETED) {} + Data(long atom_) : atom(toStr(atom_)), type(INTERPRETED) {} + Data(unsigned long atom_) : atom(toStr(atom_)), type(INTERPRETED) {} + Data(float atom_) : atom(toStr(atom_)), type(INTERPRETED) {} + Data(double atom_) : atom(toStr(atom_)), type(INTERPRETED) {} + Data(bool atom_) : type(INTERPRETED) { + if (atom_) { + atom = "true"; + } else { + atom = "false"; + } + } + + template <typename T> Data(T value, Type type_) : atom(toStr(value)), type(type_) {} + +#if 0 + // constructor for arbitrary types, skip if type is subclass though (C++11) + // we will have to drop this constructor as it interferes with operator Data() and entails C++11 + template <typename T> + Data(T value, typename std::enable_if<! std::is_base_of<Data, T>::value>::type* = nullptr) + : atom(toStr(value)), type(INTERPRETED) {} +#endif + + + explicit Data(const Arabica::DOM::Node<std::string>& dom); + virtual ~Data() {} + + bool empty() const { + bool hasContent = (atom.length() > 0 || !compound.empty() || !array.empty() || binary || node); + return !hasContent; + } + + bool operator<(const Data& other) const { + std::string thisJSON = Data::toJSON(*this); + std::string otherJSON = Data::toJSON(other); + return (thisJSON < otherJSON); + } + + void merge(const Data& other); + + bool hasKey(const std::string& key) const { + return (!compound.empty() && compound.find(key) != compound.end()); + } + + Data& operator[](const std::string& key) { + return operator[](key.c_str()); + } + + const Data& operator[](const std::string& key) const { + return operator[](key.c_str()); + } + + Data& operator[](const char* key) { + return compound[key]; + } + + const Data& operator[](const char* key) const { + return compound.at(key); + } + + Data& operator[](const size_t index) { + while(array.size() < index) { + array.push_back(Data("", Data::VERBATIM)); + } + std::list<Data>::iterator arrayIter = array.begin(); + for (int i = 0; i < index; i++, arrayIter++) {} + return *arrayIter; + } + + const Data at(const std::string& key) const { + return at(key.c_str()); + } + + const Data at(const char* key) const { + if (hasKey(key)) + return compound.at(key); + Data data; + return data; + } + + const Data item(const size_t index) const { + if (array.size() < index) { + std::list<Data>::const_iterator arrayIter; + for (int i = 0; i < index; i++, arrayIter++) {} + return *arrayIter; + } + Data data; + return data; + } + + bool operator==(const Data &other) const { + if (other.atom.size() != atom.size()) + return false; + if (other.type != type) + return false; + if (other.binary != binary) + return false; + if (other.array.size() != array.size()) + return false; + if (other.compound.size() != compound.size()) + return false; + + if (other.atom != atom) + return false; + if (other.array != array) + return false; + if (other.compound != compound) + return false; + if (other.node != node) + return false; + + return true; + } + + bool operator!=(const Data &other) const { + return !(*this == other); + } + + operator std::string() const { + return atom; + } + + operator std::map<std::string, Data>() { + return compound; + } + + operator std::list<Data>() { + return array; + } + + static Data fromJSON(const std::string& jsonString); + static std::string toJSON(const Data& 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> getCompound() { + return compound; + } + void setCompound(const std::map<std::string, Data>& compound) { + this->compound = compound; + } + + std::list<Data> getArray() { + return array; + } + void setArray(const std::list<Data>& array) { + this->array = array; + } + + std::string getAtom() { + return atom; + } + void setAtom(const std::string& atom) { + this->atom = atom; + } + + Type getType() { + return type; + } + void setType(const Type type) { + this->type = type; + } + + +#ifdef SWIGIMPORTED +protected: +#endif + + Arabica::DOM::Node<std::string> node; + std::map<std::string, Data> compound; + std::list<Data> array; + std::string atom; + boost::shared_ptr<Blob> binary; + Type type; + +protected: + Arabica::DOM::Document<std::string> toNode(const Arabica::DOM::Document<std::string>& factory, const Data& data); + friend USCXML_API std::ostream& operator<< (std::ostream& os, const Data& data); +}; + +USCXML_API std::ostream& operator<< (std::ostream& os, const Data& data); + +} + +#endif /* end of include guard: DATA_H_09E4D8E5 */ diff --git a/src/uscxml/messages/Event.cpp b/src/uscxml/messages/Event.cpp new file mode 100644 index 0000000..a3e6a20 --- /dev/null +++ b/src/uscxml/messages/Event.cpp @@ -0,0 +1,187 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#include "uscxml/messages/Event.h" +#include "uscxml/DOMUtils.h" + +namespace uscxml { + +//Arabica::DOM::Node<std::string> Event::getFirstDOMElement() const { +// return getFirstDOMElement(dom); +//} +// +//Arabica::DOM::Document<std::string> Event::getStrippedDOM() const { +// return getStrippedDOM(dom); +//} + +//Arabica::DOM::Node<std::string> Event::getFirstDOMElement(const Arabica::DOM::Document<std::string> dom) { +// Arabica::DOM::Node<std::string> data = dom.getDocumentElement().getFirstChild(); +// while (data) { +// if (data.getNodeType() == Arabica::DOM::Node_base::TEXT_NODE) { +// std::string trimmed = boost::trim_copy(data.getNodeValue()); +// if (trimmed.length() == 0) { +// data = data.getNextSibling(); +// continue; +// } +// } +// break; +// } +// return data; +//} +// +//Arabica::DOM::Document<std::string> Event::getStrippedDOM(const Arabica::DOM::Document<std::string> dom) { +// Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); +// Arabica::DOM::Document<std::string> document = domFactory.createDocument("", "", 0); +// if (dom) { +// document.getDocumentElement().appendChild(document.importNode(getFirstDOMElement(dom), true)); +// } +// return document; +//} + +std::string Event::toXMLString() { + std::stringstream ss; + ss << toDocument(); + return ss.str(); +} + +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; +} + +void Event::initContent(const std::string& content) { + // try to parse as JSON + Data json = Data::fromJSON(content); + if (!json.empty()) { + data = json; + return; + } + + // try to parse as XML + Arabica::SAX2DOM::Parser<std::string> parser; + Arabica::SAX::CatchErrorHandler<std::string> errorHandler; + parser.setErrorHandler(errorHandler); + + std::istringstream is(content); + Arabica::SAX::InputSource<std::string> inputSource; + inputSource.setByteStream(is); + if (parser.parse(inputSource)) { + dom = parser.getDocument(); + return; + } + + this->content = content; +} + +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.data.compound[key] = Data(value, Data::VERBATIM); + } + } + } + } + } + } + return event; +} + +std::ostream& operator<< (std::ostream& os, const Event& event) { + std::string indent; + for (int i = 0; i < _dataIndentation; i++) { + indent += " "; + } + + os << indent << (event.eventType == Event::EXTERNAL ? "External" : "Internal") << " Event " << (event.dom ? "with DOM attached" : "") << std::endl; + + if (event.name.size() > 0) + os << indent << " name: " << event.name << std::endl; + if (event.origin.size() > 0) + os << indent << " origin: " << event.origin << std::endl; + if (event.origintype.size() > 0) + os << indent << " origintype: " << event.origintype << std::endl; + if (event.params.size() > 0) { + std::multimap<std::string, Data>::const_iterator paramIter = event.params.begin(); + os << indent << " params:" << std::endl; + _dataIndentation++; + while(paramIter != event.params.end()) { + os << indent << " " << paramIter->first << ": "; + os << indent << paramIter->second << std::endl; + paramIter++; + } + _dataIndentation--; + } + if (event.namelist.size() > 0) { + std::map<std::string, Data>::const_iterator namelistIter = event.namelist.begin(); + os << indent << " namelist:" << std::endl; + _dataIndentation++; + while(namelistIter != event.namelist.end()) { + os << indent << " " << namelistIter->first << ": "; + os << indent << namelistIter->second << std::endl; + namelistIter++; + } + _dataIndentation--; + + } + _dataIndentation++; + os << indent << " data: " << event.data << std::endl; + _dataIndentation--; + return os; +} + +}
\ No newline at end of file diff --git a/src/uscxml/messages/Event.h b/src/uscxml/messages/Event.h new file mode 100644 index 0000000..1acfce7 --- /dev/null +++ b/src/uscxml/messages/Event.h @@ -0,0 +1,235 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef EVENT_H_6174D929 +#define EVENT_H_6174D929 + +#include "uscxml/messages/Data.h" + +namespace uscxml { + +class USCXML_API Event { +public: + enum Type { + INTERNAL = 1, + EXTERNAL = 2, + PLATFORM = 3 + }; + + Event() : eventType(INTERNAL), hideSendId(false) {} + Event(const std::string& name, Type type = INTERNAL) : name(name), eventType(type), hideSendId(false) {} + Event(const Arabica::DOM::Node<std::string>& xmlString) : eventType(INTERNAL), hideSendId(false) {}; + bool operator< (const Event& other) const { + return this < &other; + } + + bool operator==(const Event& other) const { + return (this->name == other.name && + this->sendid == other.sendid && + this->invokeid == other.invokeid && + this->data == other.data); + } + bool operator!=(const Event& other) const { + return !(*this == other); + } + + std::string getName() { + return name; + } + void setName(const std::string& name) { + this->name = name; + } + + Type getEventType() { + return eventType; + } + void setEventType(const Type type) { + this->eventType = type; + } + + std::string getOrigin() { + return origin; + } + void setOrigin(const std::string& origin) { + this->origin = origin; + } + + std::string getOriginType() { + return origintype; + } + void setOriginType(const std::string& originType) { + this->origintype = originType; + } + + Arabica::DOM::Node<std::string> getDOM() { + return dom; + } + void setDOM(const Arabica::DOM::Node<std::string>& dom) { + this->dom = dom; + } + +// Arabica::DOM::Node<std::string> getFirstDOMElement() const; +// Arabica::DOM::Document<std::string> getStrippedDOM() const; +// +// static Arabica::DOM::Node<std::string> getFirstDOMElement(const Arabica::DOM::Document<std::string> dom); +// static Arabica::DOM::Document<std::string> getStrippedDOM(const Arabica::DOM::Document<std::string> dom); + + std::string getRaw() { + return raw; + } + void setRaw(const std::string& raw) { + this->raw = raw; + } + + std::string getContent() { + return content; + } + void setContent(const std::string& content) { + this->content = content; + } + + std::string getXML() { + return xml; + } + void setXML(const std::string& xml) { + this->xml = xml; + } + + std::string getSendId() { + return sendid; + } + void setSendId(const std::string& sendId) { + this->sendid = sendId; + } + + std::string getInvokeId() { + return invokeid; + } + void setInvokeId(const std::string& invokeId) { + this->invokeid = invokeId; + } + + Data getData() { + return data; + } + void setData(const Data& data) { + this->data = data; + } + + void initContent(const std::string& content); + + static Event fromXML(const std::string& xmlString); + Arabica::DOM::Document<std::string> toDocument(); + std::string toXMLString(); + + std::map<std::string, Data>& getNameList() { + return namelist; + } + std::multimap<std::string, Data>& getParams() { + return params; + } + + typedef std::multimap<std::string, Data> params_t; + typedef std::map<std::string, Data> namelist_t; + + static bool getParam(params_t params, const std::string& name, Data& target) { + if (params.find(name) != params.end()) { + target = params.find(name)->second; + return true; + } + return false; + } + + static bool getParam(params_t params, const std::string& name, std::list<Data>& target) { + if (params.find(name) != params.end()) { + std::pair<params_t::iterator, params_t::iterator> rangeIter = params.equal_range(name); + while(rangeIter.first != rangeIter.second) { + target.push_back(rangeIter.first->second); + rangeIter.first++; + } + return true; + } + return false; + } + + template <typename T> static bool getParam(params_t params, const std::string& name, T& target) { + if (params.find(name) != params.end()) { + target = boost::lexical_cast<T>(params.find(name)->second.atom); + return true; + } + return false; + } + + static bool getParam(params_t params, const std::string& name, bool& target) { + if (params.find(name) != params.end()) { + target = true; + if (iequals(params.find(name)->second.atom, "false")) { + target = false; + } else if(iequals(params.find(name)->second.atom, "off")) { + target = false; + } else if(iequals(params.find(name)->second.atom, "no")) { + target = false; + } else if(iequals(params.find(name)->second.atom, "0")) { + target = false; + } + return true; + } + return false; + } + + template <typename T> static bool getParam(params_t params, const std::string& name, std::list<T>& target) { + if (params.find(name) != params.end()) { + std::pair<params_t::iterator, params_t::iterator> rangeIter = params.equal_range(name); + while(rangeIter.first != rangeIter.second) { + target.push_back(boost::lexical_cast<T>(rangeIter.first->second.atom)); + rangeIter.first++; + } + return true; + } + return false; + } + + +#ifdef SWIGIMPORTED +protected: +#endif + + std::string raw; + std::string xml; + std::string name; + Type eventType; + std::string origin; + std::string origintype; + Arabica::DOM::Node<std::string> dom; + std::string sendid; + bool hideSendId; + std::string invokeid; + Data data; + std::string content; + std::map<std::string, Data> namelist; + std::multimap<std::string, Data> params; + + friend USCXML_API std::ostream& operator<< (std::ostream& os, const Event& event); +}; + +USCXML_API std::ostream& operator<< (std::ostream& os, const Event& event); + +} + +#endif /* end of include guard: EVENT_H_6174D929 */ diff --git a/src/uscxml/messages/InvokeRequest.cpp b/src/uscxml/messages/InvokeRequest.cpp new file mode 100644 index 0000000..a39c8c6 --- /dev/null +++ b/src/uscxml/messages/InvokeRequest.cpp @@ -0,0 +1,91 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#include "uscxml/messages/InvokeRequest.h" +#include <DOM/Simple/DOMImplementation.hpp> +#include <DOM/Document.hpp> +#include <DOM/io/Stream.hpp> + +namespace uscxml { + +std::string InvokeRequest::toXMLString() { + std::stringstream ss; + ss << toDocument(); + return ss.str(); +} + +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; +} + +InvokeRequest InvokeRequest::fromXML(const std::string& xmlString) { + Event::fromXML(xmlString); + return InvokeRequest(); +} + +std::ostream& operator<< (std::ostream& os, const InvokeRequest& invokeReq) { + + std::string indent; + for (int i = 0; i < _dataIndentation; i++) { + indent += " "; + } + + os << indent << "InvokeReq" << (invokeReq.autoForward ? " with autoforward" : "") << std::endl; + + if (invokeReq.type.size() > 0) + os << indent << " type: " << invokeReq.type << std::endl; + + if (invokeReq.src.size() > 0) + os<< indent << " src: " << invokeReq.src << std::endl; + + if (invokeReq.namelist.size() > 0) { + os << indent << " namelist: " << std::endl; + InvokeRequest::namelist_t::const_iterator namelistIter = invokeReq.namelist.begin(); + while(namelistIter != invokeReq.namelist.end()) { + os << indent << " " << namelistIter->first << ": " << namelistIter->second << std::endl; + namelistIter++; + } + } + + if (invokeReq.params.size() > 0) { + os << indent << " params: " << std::endl; + InvokeRequest::params_t::const_iterator paramIter = invokeReq.params.begin(); + while(paramIter != invokeReq.params.end()) { + os << indent << " " << paramIter->first << ": " << paramIter->second << std::endl; + paramIter++; + } + } + + if (invokeReq.content.size() > 0) + os << indent << " content: " << invokeReq.content << std::endl; + + _dataIndentation++; + os << (Event)invokeReq; + _dataIndentation--; + return os; + +} + +}
\ No newline at end of file diff --git a/src/uscxml/messages/InvokeRequest.h b/src/uscxml/messages/InvokeRequest.h new file mode 100644 index 0000000..ac5f6f7 --- /dev/null +++ b/src/uscxml/messages/InvokeRequest.h @@ -0,0 +1,72 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef INVOKEREQUEST_H_BAF058E2 +#define INVOKEREQUEST_H_BAF058E2 + +#include "uscxml/messages/Event.h" + +namespace uscxml { + +class USCXML_API InvokeRequest : public Event { +public: + InvokeRequest(Event event) : Event(event) {} + InvokeRequest() {} + + std::string getType() { + return type; + } + void setType(const std::string& type) { + this->type = type; + } + + std::string getSource() { + return src; + } + void setSource(const std::string& src) { + this->src = src; + } + + bool isAutoForwarded() { + return autoForward; + } + void setAutoForwarded(bool autoForward) { + this->autoForward = autoForward; + } + + static InvokeRequest fromXML(const std::string& xmlString); + Arabica::DOM::Document<std::string> toDocument(); + std::string toXMLString(); + +#ifdef SWIGIMPORTED +protected: +#endif + std::string type; + std::string src; + bool autoForward; + + friend USCXML_API std::ostream& operator<< (std::ostream& os, const InvokeRequest& sendReq); + +}; + +USCXML_API std::ostream& operator<< (std::ostream& os, const InvokeRequest& invokeReq); + +} + +#endif /* end of include guard: INVOKEREQUEST_H_BAF058E2 */ diff --git a/src/uscxml/messages/SendRequest.cpp b/src/uscxml/messages/SendRequest.cpp new file mode 100644 index 0000000..a8fbe13 --- /dev/null +++ b/src/uscxml/messages/SendRequest.cpp @@ -0,0 +1,135 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#include "uscxml/messages/SendRequest.h" +#include <DOM/Simple/DOMImplementation.hpp> +#include <DOM/Document.hpp> +#include <DOM/io/Stream.hpp> + +namespace uscxml { + +std::string SendRequest::toXMLString() { + std::stringstream ss; + ss << toDocument(); + return ss.str(); +} + +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", "payload"); + payloadElem.setPrefix("scxml"); + + scxmlMsg.appendChild(payloadElem); + } + Arabica::DOM::Node<std::string> payloadElem = scxmlMsg.getElementsByTagName("scxml:payload").item(0); + + // add parameters + std::multimap<std::string, Data>::iterator paramIter = params.begin(); + while(paramIter != params.end()) { + Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "property"); + propertyElem.setPrefix("scxml"); + + propertyElem.setAttribute("name", paramIter->first); + // this is simplified - Data might be more elaborate than a simple string atom + Arabica::DOM::Text<std::string> textElem = document.createTextNode(paramIter->second.atom); + propertyElem.appendChild(textElem); + payloadElem.appendChild(propertyElem); + paramIter++; + } + + // add namelist elements + std::map<std::string, Data>::iterator namelistIter = namelist.begin(); + while(namelistIter != namelist.end()) { + Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "property"); + propertyElem.setPrefix("scxml"); + + propertyElem.setAttribute("name", namelistIter->first); + // this is simplified - Data might be more elaborate than a simple string atom + Arabica::DOM::Text<std::string> textElem = document.createTextNode(namelistIter->second.atom); + propertyElem.appendChild(textElem); + payloadElem.appendChild(propertyElem); + namelistIter++; + } + + } + + scxmlMsg.setAttribute("sendid", sendid); + + return document; +} + +SendRequest SendRequest::fromXML(const std::string& xmlString) { + Event::fromXML(xmlString); + return SendRequest(); +} + +std::ostream& operator<< (std::ostream& os, const SendRequest& sendReq) { + + std::string indent; + for (int i = 0; i < _dataIndentation; i++) { + indent += " "; + } + + os << indent << "SendReq" << std::endl; + + if (sendReq.target.size() > 0) + os << indent << " target: " << sendReq.target << std::endl; + + if (sendReq.type.size() > 0) + os << indent << " type: " << sendReq.type << std::endl; + + if (sendReq.delayMs > 0) + os<< indent << " delay: " << sendReq.delayMs << std::endl; + + if (sendReq.namelist.size() > 0) { + os << indent << " namelist: " << std::endl; + SendRequest::namelist_t::const_iterator namelistIter = sendReq.namelist.begin(); + while(namelistIter != sendReq.namelist.end()) { + os << indent << " " << namelistIter->first << ": " << namelistIter->second << std::endl; + namelistIter++; + } + } + + if (sendReq.params.size() > 0) { + os << indent << " params: " << std::endl; + SendRequest::params_t::const_iterator paramIter = sendReq.params.begin(); + while(paramIter != sendReq.params.end()) { + os << indent << " " << paramIter->first << ": " << paramIter->second << std::endl; + paramIter++; + } + } + + if (sendReq.content.size() > 0) + os << indent << " content: " << sendReq.content << std::endl; + + _dataIndentation++; + os << (Event)sendReq; + _dataIndentation--; + return os; + +} + +}
\ No newline at end of file diff --git a/src/uscxml/messages/SendRequest.h b/src/uscxml/messages/SendRequest.h new file mode 100644 index 0000000..6bc3d91 --- /dev/null +++ b/src/uscxml/messages/SendRequest.h @@ -0,0 +1,72 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef SENDREQUEST_H_86B0F6A0 +#define SENDREQUEST_H_86B0F6A0 + +#include "uscxml/messages/Event.h" + +namespace uscxml { + +class USCXML_API SendRequest : public Event { +public: + SendRequest() {} + SendRequest(Event event) : Event(event) {} + + std::string getTarget() { + return target; + } + void setTarget(const std::string& target) { + this->target = target; + } + + std::string getType() { + return type; + } + void setType(const std::string& type) { + this->type = type; + } + + uint32_t getDelayMs() { + return delayMs; + } + void setDelayMs(uint32_t delayMs) { + this->delayMs = delayMs; + } + + static SendRequest fromXML(const std::string& xmlString); + Arabica::DOM::Document<std::string> toDocument(); + std::string toXMLString(); + +#ifdef SWIGIMPORTED +protected: +#endif + std::string target; + std::string type; + uint32_t delayMs; + + friend USCXML_API std::ostream& operator<< (std::ostream& os, const SendRequest& sendReq); + +}; + +USCXML_API std::ostream& operator<< (std::ostream& os, const SendRequest& sendReq); + +} + +#endif /* end of include guard: SENDREQUEST_H_86B0F6A0 */ diff --git a/src/uscxml/plugins/DataModel.h b/src/uscxml/plugins/DataModel.h new file mode 100644 index 0000000..57d4b14 --- /dev/null +++ b/src/uscxml/plugins/DataModel.h @@ -0,0 +1,209 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef DATAMODEL_H_F1F776F9 +#define DATAMODEL_H_F1F776F9 + +#include "uscxml/Common.h" +#include "uscxml/plugins/EventHandler.h" + +#include <list> +#include <boost/shared_ptr.hpp> +#include <string> +#include <sstream> + +#include "DOM/Document.hpp" + +namespace uscxml { + +class InterpreterImpl; + +class USCXML_API DataModelImpl { +public: + virtual ~DataModelImpl() {} + virtual boost::shared_ptr<DataModelImpl> create(InterpreterImpl* interpreter) = 0; + virtual std::list<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; + + size_t replaceExpressions(std::string& content); + + // foreach + virtual uint32_t getLength(const std::string& expr) = 0; + virtual void setForeach(const std::string& item, + const std::string& array, + const std::string& index, + uint32_t iteration) = 0; + virtual void pushContext() = 0; + virtual void popContext() = 0; + + virtual void eval(const Arabica::DOM::Element<std::string>& scriptElem, + const std::string& expr) = 0; + + virtual std::string evalAsString(const std::string& expr) = 0; + + virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& scriptNode, + const std::string& expr) = 0; + virtual bool evalAsBool(const std::string& expr) { + return evalAsBool(Arabica::DOM::Node<std::string>(), expr); + } + + virtual bool isDeclared(const std::string& expr) = 0; + + virtual void assign(const Arabica::DOM::Element<std::string>& assignElem, + const Arabica::DOM::Node<std::string>& node, + const std::string& content) = 0; + virtual void assign(const std::string& location, const Data& data) = 0; + + virtual void init(const Arabica::DOM::Element<std::string>& dataElem, + const Arabica::DOM::Node<std::string>& node, + const std::string& content) = 0; + virtual void init(const std::string& location, const Data& data) = 0; + + virtual void setInterpreter(InterpreterImpl* interpreter) { + _interpreter = interpreter; + } + + virtual std::string andExpressions(std::list<std::string>) { + return ""; + } + + static void throwErrorExecution(const std::string& cause); + static void throwErrorPlatform(const std::string& cause); + + // we need it public for various static functions +protected: + InterpreterImpl* _interpreter; +}; + +class USCXML_API DataModel { +public: + DataModel() : _impl() {} + DataModel(const boost::shared_ptr<DataModelImpl> impl) : _impl(impl) { } + DataModel(const DataModel& other) : _impl(other._impl) { } + virtual ~DataModel() {}; + + operator bool() const { + return _impl; + } + bool operator< (const DataModel& other) const { + return _impl < other._impl; + } + bool operator==(const DataModel& other) const { + return _impl == other._impl; + } + bool operator!=(const DataModel& other) const { + return _impl != other._impl; + } + DataModel& operator= (const DataModel& other) { + _impl = other._impl; + return *this; + } + + virtual std::list<std::string> getNames() { + return _impl->getNames(); + } + + virtual bool validate(const std::string& location, const std::string& schema) { + return _impl->validate(location, schema); + } + virtual void setEvent(const Event& event) { + return _impl->setEvent(event); + } + virtual Data getStringAsData(const std::string& content) { + return _impl->getStringAsData(content); + } + + virtual void pushContext() { + return _impl->pushContext(); + } + virtual void popContext() { + return _impl->popContext(); + } + + virtual void eval(const Arabica::DOM::Element<std::string>& scriptElem, + const std::string& expr) { + return _impl->eval(scriptElem, expr); + } + virtual std::string evalAsString(const std::string& expr) { + return _impl->evalAsString(expr); + } + virtual bool evalAsBool(const std::string& expr) { + return _impl->evalAsBool(expr); + } + virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& scriptNode, + const std::string& expr) { + return _impl->evalAsBool(scriptNode, expr); + } + + virtual uint32_t getLength(const std::string& expr) { + return _impl->getLength(expr); + } + virtual void setForeach(const std::string& item, + const std::string& array, + const std::string& index, + uint32_t iteration) { + return _impl->setForeach(item, array, index, iteration); + } + + virtual void assign(const Arabica::DOM::Element<std::string>& assignElem, + const Arabica::DOM::Node<std::string>& node, + const std::string& content) { + return _impl->assign(assignElem, node, content); + } + virtual void assign(const std::string& location, const Data& data) { + return _impl->assign(location, data); + } + + virtual void init(const Arabica::DOM::Element<std::string>& dataElem, + const Arabica::DOM::Node<std::string>& node, + const std::string& content) { + return _impl->init(dataElem, node, content); + } + virtual void init(const std::string& location, const Data& data) { + return _impl->init(location, data); + } + + virtual bool isDeclared(const std::string& expr) { + return _impl->isDeclared(expr); + } + + size_t replaceExpressions(std::string& content) { + return _impl->replaceExpressions(content); + } + + std::string andExpressions(std::list<std::string> expressions) { + return _impl->andExpressions(expressions); + } + + virtual void setInterpreter(InterpreterImpl* interpreter) { + _impl->setInterpreter(interpreter); + } + +protected: + boost::shared_ptr<DataModelImpl> _impl; +}; + + +} + + +#endif /* end of include guard: DATAMODEL_H_F1F776F9 */ diff --git a/src/uscxml/plugins/EventHandler.h b/src/uscxml/plugins/EventHandler.h new file mode 100644 index 0000000..d30feb9 --- /dev/null +++ b/src/uscxml/plugins/EventHandler.h @@ -0,0 +1,125 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef EVENTHANDLER_H_2801243E +#define EVENTHANDLER_H_2801243E + +#include "uscxml/Common.h" + +#include <list> +#include <boost/shared_ptr.hpp> +#include <string> +#include <sstream> + +#include "DOM/Document.hpp" +#include "uscxml/messages/SendRequest.h" + +namespace uscxml { + +class InterpreterImpl; + +class USCXML_API EventHandlerImpl { +public: + virtual ~EventHandlerImpl() {} + + virtual std::list<std::string> getNames() = 0; + + virtual void setInterpreter(InterpreterImpl* interpreter) { + _interpreter = interpreter; + } + void setInvokeId(const std::string& invokeId) { + _invokeId = invokeId; + } + void setType(const std::string& type) { + _type = type; + } + + void setElement(const Arabica::DOM::Element<std::string>& element) { + _element = element; + } + + Arabica::DOM::Element<std::string> getElement() { + return _element; + } + + virtual Data getDataModelVariables() = 0; + virtual void send(const SendRequest& req) = 0; + + virtual void runOnMainThread() {}; + void returnEvent(Event& event); + void returnErrorExecution(const std::string&); + void returnErrorPlatform(const std::string&); + +protected: + InterpreterImpl* _interpreter; + Arabica::DOM::Element<std::string> _element; + std::string _invokeId; + std::string _type; + +}; + +class USCXML_API EventHandler { +public: + EventHandler() : _impl() {} + EventHandler(boost::shared_ptr<EventHandlerImpl> const impl) : _impl(impl) { } + EventHandler(const EventHandler& other) : _impl(other._impl) { } + virtual ~EventHandler() {}; + + virtual std::list<std::string> getNames() { + return _impl->getNames(); + } + + virtual Data getDataModelVariables() const { + return _impl->getDataModelVariables(); + }; + virtual void send(const SendRequest& req) { + return _impl->send(req); + }; + virtual void runOnMainThread() { + return _impl->runOnMainThread(); + } + + void setInterpreter(InterpreterImpl* interpreter) { + _impl->setInterpreter(interpreter); + } + void setInvokeId(const std::string& invokeId) { + _impl->setInvokeId(invokeId); + } + void setType(const std::string& type) { + _impl->setType(type); + } + + void setElement(const Arabica::DOM::Element<std::string>& element) { + _impl->setElement(element); + } + + Arabica::DOM::Element<std::string> getElement() { + return _impl->getElement(); + } + +protected: + boost::shared_ptr<EventHandlerImpl> _impl; + friend class InterpreterImpl; +}; + + +} + + +#endif /* end of include guard: EVENTHANDLER_H_2801243E */ diff --git a/src/uscxml/plugins/ExecutableContent.h b/src/uscxml/plugins/ExecutableContent.h new file mode 100644 index 0000000..6f4335b --- /dev/null +++ b/src/uscxml/plugins/ExecutableContent.h @@ -0,0 +1,105 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef EXECUTABLECONTENT_H_1E028A2D +#define EXECUTABLECONTENT_H_1E028A2D + +#include "uscxml/Common.h" +#include <boost/shared_ptr.hpp> +#include <string> +#include <sstream> +#include "DOM/Document.hpp" + +namespace uscxml { + +class InterpreterImpl; + +class USCXML_API ExecutableContentImpl { +public: + ExecutableContentImpl() {}; + virtual ~ExecutableContentImpl() {}; + virtual boost::shared_ptr<ExecutableContentImpl> create(InterpreterImpl* interpreter) = 0; + + virtual void setInterpreter(InterpreterImpl* interpreter) { + _interpreter = interpreter; + } + + virtual std::string getLocalName() = 0; ///< The name of the element. + virtual std::string getNamespace() { + return "http://www.w3.org/2005/07/scxml"; ///< The namespace of the element. + } + virtual void enterElement(const Arabica::DOM::Node<std::string>& node) = 0; ///< Invoked when entering the element as part of evaluating executable content. + virtual void exitElement(const Arabica::DOM::Node<std::string>& node) = 0; ///< Invoked when exiting the element as part of evaluating executable content. + virtual bool processChildren() = 0; ///< Whether or not the interpreter should process this elements children. + +protected: + InterpreterImpl* _interpreter; +}; + +class USCXML_API ExecutableContent { +public: + ExecutableContent() : _impl() {} + ExecutableContent(boost::shared_ptr<ExecutableContentImpl> const impl) : _impl(impl) { } + ExecutableContent(const ExecutableContent& other) : _impl(other._impl) { } + virtual ~ExecutableContent() {}; + + operator bool() const { + return _impl; + } + bool operator< (const ExecutableContent& other) const { + return _impl < other._impl; + } + bool operator==(const ExecutableContent& other) const { + return _impl == other._impl; + } + bool operator!=(const ExecutableContent& other) const { + return _impl != other._impl; + } + ExecutableContent& operator= (const ExecutableContent& other) { + _impl = other._impl; + return *this; + } + + void setInterpreter(InterpreterImpl* interpreter) { + _impl->setInterpreter(interpreter); + } + + std::string getLocalName() { + return _impl->getLocalName(); + } + std::string getNamespace() { + return _impl->getNamespace(); + } + void enterElement(const Arabica::DOM::Node<std::string>& node) { + return _impl->enterElement(node); + } + void exitElement(const Arabica::DOM::Node<std::string>& node) { + return _impl->exitElement(node); + } + bool processChildren() { + return _impl->processChildren(); + } +protected: + boost::shared_ptr<ExecutableContentImpl> _impl; + +}; + +} + +#endif /* end of include guard: EXECUTABLECONTENT_H_1E028A2D */ diff --git a/src/uscxml/plugins/IOProcessor.h b/src/uscxml/plugins/IOProcessor.h new file mode 100644 index 0000000..79f759b --- /dev/null +++ b/src/uscxml/plugins/IOProcessor.h @@ -0,0 +1,71 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef IOPROCESSOR_H_CF4F4135 +#define IOPROCESSOR_H_CF4F4135 + +#include "uscxml/Common.h" +#include "uscxml/plugins/EventHandler.h" + +namespace uscxml { + +class InterpreterImpl; + +class USCXML_API IOProcessorImpl : public EventHandlerImpl { +public: + IOProcessorImpl() {}; + virtual ~IOProcessorImpl() {}; + virtual boost::shared_ptr<IOProcessorImpl> create(InterpreterImpl* interpreter) = 0; +}; + +class USCXML_API IOProcessor : public EventHandler { +public: + IOProcessor() : _impl() {} + IOProcessor(boost::shared_ptr<IOProcessorImpl> const impl) : EventHandler(impl), _impl(impl) { } + IOProcessor(const IOProcessor& other) : EventHandler(other._impl), _impl(other._impl) { } + virtual ~IOProcessor() {}; + + operator bool() const { + return _impl; + } + bool operator< (const IOProcessor& other) const { + return _impl < other._impl; + } + bool operator==(const IOProcessor& other) const { + return _impl == other._impl; + } + bool operator!=(const IOProcessor& other) const { + return _impl != other._impl; + } + IOProcessor& operator= (const IOProcessor& other) { + _impl = other._impl; + EventHandler::_impl = _impl; + return *this; + } + +protected: + boost::shared_ptr<IOProcessorImpl> _impl; + friend class InterpreterImpl; +}; + + +} + + +#endif /* end of include guard: IOPROCESSOR_H_CF4F4135 */ diff --git a/src/uscxml/plugins/Invoker.h b/src/uscxml/plugins/Invoker.h new file mode 100644 index 0000000..c967331 --- /dev/null +++ b/src/uscxml/plugins/Invoker.h @@ -0,0 +1,76 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef INVOKER_H_CAC11892 +#define INVOKER_H_CAC11892 + + +#include "uscxml/Common.h" +#include "uscxml/plugins/EventHandler.h" +#include "uscxml/messages/InvokeRequest.h" + +namespace uscxml { + +class InterpreterImpl; + +class USCXML_API InvokerImpl : public EventHandlerImpl { +public: + virtual ~InvokerImpl() {} + virtual void invoke(const InvokeRequest& req) = 0; + virtual boost::shared_ptr<InvokerImpl> create(InterpreterImpl* interpreter) = 0; +}; + +class USCXML_API Invoker : public EventHandler { +public: + Invoker() : _impl() {} + Invoker(boost::shared_ptr<InvokerImpl> const impl) : EventHandler(impl), _impl(impl) { } + Invoker(const Invoker& other) : EventHandler(other._impl), _impl(other._impl) { } + virtual ~Invoker() {}; + + operator bool() const { + return _impl; + } + bool operator< (const Invoker& other) const { + return _impl < other._impl; + } + bool operator==(const Invoker& other) const { + return _impl == other._impl; + } + bool operator!=(const Invoker& other) const { + return _impl != other._impl; + } + Invoker& operator= (const Invoker& other) { + _impl = other._impl; + EventHandler::_impl = _impl; + return *this; + } + + virtual void invoke(InvokeRequest& req) { + _impl->invoke(req); + } + +protected: + boost::shared_ptr<InvokerImpl> _impl; +}; + + +} + + +#endif /* end of include guard: INVOKER_H_CAC11892 */ diff --git a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp index 9594d5e..98d2dda 100644 --- a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp +++ b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp @@ -112,23 +112,23 @@ bool NULLDataModel::evalAsBool(const Arabica::DOM::Node<std::string>& node, cons // split at comma std::stringstream ss(trimmedExpr.substr(start, end - start)); - std::vector<std::string> stateExprs; + std::list<std::string> stateExprs; std::string item; while(std::getline(ss, item, ',')) { stateExprs.push_back(item); } - for (unsigned int i = 0; i < stateExprs.size(); i++) { + for (std::list<std::string>::const_iterator stateIter = stateExprs.begin(); stateIter != stateExprs.end(); stateIter++) { // remove ticks - size_t start = stateExprs[i].find_first_of("'"); - size_t end = stateExprs[i].find_last_of("'"); + size_t start = stateIter->find_first_of("'"); + size_t end = stateIter->find_last_of("'"); std::string stateName; if (start != std::string::npos && end != std::string::npos && start < end) { start++; - stateName = stateExprs[i].substr(start, end - start); + stateName = stateIter->substr(start, end - start); } else { - stateName = stateExprs[i]; + stateName = *stateIter; } if (_interpreter->isInState(stateName)) { diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp index a1edcae..cd3bbaf 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp +++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp @@ -20,6 +20,8 @@ #include "PromelaParser.h" #include "parser/promela.tab.hpp" +#include <iostream> + struct yy_buffer_state; typedef yy_buffer_state *YY_BUFFER_STATE; extern YY_BUFFER_STATE promela__scan_buffer(char *, size_t, void*); diff --git a/src/uscxml/plugins/element/file/FileElement.cpp b/src/uscxml/plugins/element/file/FileElement.cpp index 899c2d6..606cddc 100644 --- a/src/uscxml/plugins/element/file/FileElement.cpp +++ b/src/uscxml/plugins/element/file/FileElement.cpp @@ -22,6 +22,7 @@ #include <stdio.h> #include <vector> #include <boost/algorithm/string.hpp> +#include "uscxml/messages/Blob.h" #include "uscxml/DOMUtils.h" diff --git a/src/uscxml/plugins/element/respond/RespondElement.cpp b/src/uscxml/plugins/element/respond/RespondElement.cpp index 3eb55ed..06d89a7 100644 --- a/src/uscxml/plugins/element/respond/RespondElement.cpp +++ b/src/uscxml/plugins/element/respond/RespondElement.cpp @@ -19,6 +19,7 @@ #include "RespondElement.h" #include "uscxml/plugins/invoker/http/HTTPServletInvoker.h" +#include "uscxml/server/InterpreterServlet.h" #include "uscxml/DOMUtils.h" #include <glog/logging.h> diff --git a/src/uscxml/plugins/invoker/calendar/CalendarInvoker.cpp b/src/uscxml/plugins/invoker/calendar/CalendarInvoker.cpp index c6194c5..849845e 100644 --- a/src/uscxml/plugins/invoker/calendar/CalendarInvoker.cpp +++ b/src/uscxml/plugins/invoker/calendar/CalendarInvoker.cpp @@ -20,6 +20,8 @@ #include <boost/algorithm/string.hpp> #include "CalendarInvoker.h" +#include "uscxml/concurrency/eventqueue/DelayedEventQueue.h" + #include <glog/logging.h> #ifdef BUILD_AS_PLUGINS diff --git a/src/uscxml/plugins/invoker/expect/ExpectInvoker.cpp b/src/uscxml/plugins/invoker/expect/ExpectInvoker.cpp index 7d66b10..22c7942 100644 --- a/src/uscxml/plugins/invoker/expect/ExpectInvoker.cpp +++ b/src/uscxml/plugins/invoker/expect/ExpectInvoker.cpp @@ -20,6 +20,8 @@ #include "ExpectInvoker.h" #include <glog/logging.h> +#include "uscxml/concurrency/eventqueue/DelayedEventQueue.h" + #ifdef BUILD_AS_PLUGINS #include <Pluma/Connector.hpp> #endif diff --git a/src/uscxml/plugins/invoker/ffmpeg/FFMPEGInvoker.cpp b/src/uscxml/plugins/invoker/ffmpeg/FFMPEGInvoker.cpp index b6203d4..4a0ec00 100644 --- a/src/uscxml/plugins/invoker/ffmpeg/FFMPEGInvoker.cpp +++ b/src/uscxml/plugins/invoker/ffmpeg/FFMPEGInvoker.cpp @@ -20,6 +20,8 @@ #include <boost/algorithm/string.hpp> #include "FFMPEGInvoker.h" +#include "uscxml/messages/Blob.h" + #include <glog/logging.h> #include <libavutil/imgutils.h> diff --git a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp index cee98bd..f8b4904 100644 --- a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp +++ b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp @@ -20,6 +20,7 @@ #include <boost/algorithm/string.hpp> #include "HeartbeatInvoker.h" +#include "uscxml/DOMUtils.h" #include <glog/logging.h> #ifdef BUILD_AS_PLUGINS diff --git a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.h b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.h index a024181..ba4e9ef 100644 --- a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.h +++ b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.h @@ -21,6 +21,7 @@ #define HEARTBEATINVOKER_H_W09J90F0 #include <uscxml/Interpreter.h> +#include "uscxml/concurrency/eventqueue/DelayedEventQueue.h" #ifdef BUILD_AS_PLUGINS #include "uscxml/plugins/Plugins.h" diff --git a/src/uscxml/plugins/invoker/im/IMInvoker.cpp b/src/uscxml/plugins/invoker/im/IMInvoker.cpp index d086a20..08d6a03 100644 --- a/src/uscxml/plugins/invoker/im/IMInvoker.cpp +++ b/src/uscxml/plugins/invoker/im/IMInvoker.cpp @@ -23,6 +23,8 @@ #include "uscxml/DOMUtils.h" #include <boost/algorithm/string.hpp> +#include "uscxml/concurrency/eventqueue/DelayedEventQueue.h" + #ifdef BUILD_AS_PLUGINS #include <Pluma/Connector.hpp> #endif diff --git a/src/uscxml/plugins/invoker/smtp/SMTPInvoker.cpp b/src/uscxml/plugins/invoker/smtp/SMTPInvoker.cpp index 1248733..2a974ab 100644 --- a/src/uscxml/plugins/invoker/smtp/SMTPInvoker.cpp +++ b/src/uscxml/plugins/invoker/smtp/SMTPInvoker.cpp @@ -26,6 +26,7 @@ #include <boost/algorithm/string.hpp> #include "uscxml/UUID.h" +#include "uscxml/messages/Blob.h" namespace uscxml { diff --git a/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.h b/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.h index b1a9c5a..773df31 100644 --- a/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.h +++ b/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.h @@ -21,6 +21,7 @@ #define XHTMLINVOKER_H_W09J90F0 #include <uscxml/Interpreter.h> +#include "uscxml/server/HTTPServer.h" #ifdef BUILD_AS_PLUGINS #include "uscxml/plugins/Plugins.h" diff --git a/src/uscxml/plugins/ioprocessor/comet/CometIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/comet/CometIOProcessor.cpp index 007bd6f..9ec5c00 100644 --- a/src/uscxml/plugins/ioprocessor/comet/CometIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/comet/CometIOProcessor.cpp @@ -22,6 +22,7 @@ #include "uscxml/Message.h" #include <iostream> +#include <DOM/io/Stream.hpp> #include <string.h> #ifdef BUILD_AS_PLUGINS diff --git a/src/uscxml/server/InterpreterServlet.cpp b/src/uscxml/server/InterpreterServlet.cpp index 3c5c3a0..f90d111 100644 --- a/src/uscxml/server/InterpreterServlet.cpp +++ b/src/uscxml/server/InterpreterServlet.cpp @@ -20,6 +20,7 @@ #include "InterpreterServlet.h" #include "uscxml/Interpreter.h" #include <glog/logging.h> +#include <DOM/io/Stream.hpp> namespace uscxml { diff --git a/src/uscxml/server/InterpreterServlet.h b/src/uscxml/server/InterpreterServlet.h index 960ff8f..436574b 100644 --- a/src/uscxml/server/InterpreterServlet.h +++ b/src/uscxml/server/InterpreterServlet.h @@ -21,11 +21,12 @@ #define INTERPRETERSERVLET_H_XQLWNMH4 #include "HTTPServer.h" -#include "uscxml/Factory.h" +#include "uscxml/messages/SendRequest.h" // for SendRequest +#include "uscxml/plugins/IOProcessor.h" // for IOProcessorImpl namespace uscxml { -class Interpreter; +class InterpreterImpl; class InterpreterHTTPServlet : public HTTPServlet, public IOProcessorImpl { public: diff --git a/src/uscxml/transform/ChartToFSM.cpp b/src/uscxml/transform/ChartToFSM.cpp index 581ba85..3bce169 100644 --- a/src/uscxml/transform/ChartToFSM.cpp +++ b/src/uscxml/transform/ChartToFSM.cpp @@ -18,6 +18,8 @@ */ #include "uscxml/transform/ChartToFSM.h" +#include "uscxml/Factory.h" + #include <DOM/io/Stream.hpp> #include <glog/logging.h> diff --git a/test/src/test-datamodel.cpp b/test/src/test-datamodel.cpp index 452d2b9..0dc8d8a 100644 --- a/test/src/test-datamodel.cpp +++ b/test/src/test-datamodel.cpp @@ -1,6 +1,7 @@ #include "uscxml/URL.h" #include "uscxml/Message.h" #include "uscxml/Interpreter.h" +#include "uscxml/Factory.h" #include "uscxml/server/HTTPServer.h" #include <SAX/helpers/InputSourceResolver.hpp> diff --git a/test/src/test-eventdelay.cpp b/test/src/test-eventdelay.cpp index a3fec34..12cc751 100644 --- a/test/src/test-eventdelay.cpp +++ b/test/src/test-eventdelay.cpp @@ -1,4 +1,5 @@ #include "uscxml/concurrency/eventqueue/DelayedEventQueue.h" +#include <iostream> int eventCalled = 0; diff --git a/test/src/test-stress.cpp b/test/src/test-stress.cpp index 6782328..06c1aa6 100644 --- a/test/src/test-stress.cpp +++ b/test/src/test-stress.cpp @@ -1,5 +1,8 @@ #include "uscxml/config.h" #include "uscxml/Interpreter.h" +#include "uscxml/Factory.h" +#include "uscxml/server/HTTPServer.h" + #include <glog/logging.h> #include "uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.h" diff --git a/test/src/test-url.cpp b/test/src/test-url.cpp index 9c4d941..046cc8b 100644 --- a/test/src/test-url.cpp +++ b/test/src/test-url.cpp @@ -74,7 +74,7 @@ int main(int argc, char** argv) { {
Interpreter interpreter = Interpreter::fromURI("/Users/sradomski/Desktop/application_small.scxml");
assert(interpreter);
- std::vector<std::string> states;
+ std::list<std::string> states;
states.push_back("b");
interpreter.setConfiguration(states);
interpreter.interpret();
diff --git a/test/src/test-w3c.cpp b/test/src/test-w3c.cpp index 1052fda..4d866c0 100644 --- a/test/src/test-w3c.cpp +++ b/test/src/test-w3c.cpp @@ -1,6 +1,10 @@ #include "uscxml/config.h" #include "uscxml/Interpreter.h" #include "uscxml/DOMUtils.h" + +#include "uscxml/Factory.h" +#include "uscxml/server/HTTPServer.h" + #include "uscxml/transform/ChartToFSM.h" #include <glog/logging.h> #include <boost/algorithm/string.hpp> diff --git a/test/w3c/confEcma.xsl b/test/w3c/confEcma.xsl index b77e22c..af3c8d2 100644 --- a/test/w3c/confEcma.xsl +++ b/test/w3c/confEcma.xsl @@ -674,7 +674,7 @@ the basic http tests. In the case of python, we have to import the regexp modul <!-- returns true if _event/raw contains the param with the specified value --> <xsl:template match="//@conf:eventNamedParamHasValue"> <xsl:attribute name="cond"><xsl:analyze-string select="." regex="(\S+)(\s+)(\S+)"> - <xsl:matching-substring>_event.raw.search(<xsl:value-of select="regex-group(1)"/>=<xsl:value-of select="regex-group(3)"/>) !== -1</xsl:matching-substring></xsl:analyze-string></xsl:attribute> + <xsl:matching-substring>_event.raw.search('<xsl:value-of select="regex-group(1)"/>=<xsl:value-of select="regex-group(3)"/>') !== -1</xsl:matching-substring></xsl:analyze-string></xsl:attribute> </xsl:template> <xsl:template match="//@conf:messageBodyEquals"> diff --git a/test/w3c/ecma/robots.txt b/test/w3c/ecma/robots.txt index 54f3e01..9be2782 100644 --- a/test/w3c/ecma/robots.txt +++ b/test/w3c/ecma/robots.txt @@ -1,7 +1,7 @@ # # robots.txt for http://www.w3.org/ # -# $Id: robots.txt,v 1.66 2012/07/17 21:30:56 gerald Exp $ +# $Id: robots.txt,v 1.67 2014-06-25 13:06:01 ddavis Exp $ # # For use by search.w3.org @@ -93,4 +93,4 @@ Disallow: /2004/01/pp-impl Disallow: /Consortium/supporters Disallow: /2007/08/pyRdfa/ Disallow: /WAI/PF/comments/ - +Disallow: /participate/conferences.xml diff --git a/test/w3c/ecma/test446.txt b/test/w3c/ecma/test446.txt index 4db4843..3a26a2e 100644 --- a/test/w3c/ecma/test446.txt +++ b/test/w3c/ecma/test446.txt @@ -1,12 +1 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> -<html><head> -<title>300 Multiple Choices</title> -</head><body> -<h1>Multiple Choices</h1> -The document name you requested (<code>/Voice/2013/scxml-irp/446/test446.txt</code>) could not be found on this server. -However, we found documents with names similar to the one you requested.<p>Available documents: -<ul> -<li><a href="/Voice/2013/scxml-irp/446/test446.txml">/Voice/2013/scxml-irp/446/test446.txml</a> (common basename) -</ul> -Please consider informing the owner of the <a href="http://www.w3.org/Voice/2013/scxml-irp/">referring page</a> about the broken link. -</body></html> +[1,2,3]
\ No newline at end of file diff --git a/test/w3c/ecma/test513.scxml b/test/w3c/ecma/test513.scxml deleted file mode 100644 index c26d498..0000000 --- a/test/w3c/ecma/test513.scxml +++ /dev/null @@ -1,50 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!-- test that we get an HTTP success code back on successful delivery. To run this test, implementations -must support an extension to send: if the parameter httpResponse is present with value 'true', then when -the processor gets an http response code back, it must raise an event 'http.n1.nrest' where 'ni' is -the first digit of the response code and 'nrest' are the remaining digits--><scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> - -<state id="s0" initial="s01"> - <datamodel> - <data id="Var1"/> - </datamodel> - - <onentry> - <send event="timeout" delay="30s"/> - </onentry> - <invoke type="http://www.w3.org/TR/scxml/"> - <content> - <!-- child script. Once we're running send childRunning to parent and include basicHTTPAccess URI --> - <scxml initial="child0" datamodel="ecmascript" version="1.0"> - <state id="child0"> - <onentry> - <send target="#_parent" event="childRunning"> - <param name="uri" expr="_ioprocessors['basichttp']['location']"/> - </send> - </onentry> - </state> - </scxml> - </content> - </invoke> - - <transition event="*" target="fail"/> - - <state id="s01"> - <!-- when we get the event from the child, extract the access uri and use - the basicHTTP event i/o processor to send it an event --> - <transition event="childRunning" target="s02"> - <assign location="Var1" expr="_event.data.uri"/> - <send event="test" targetexpr="Var1" httpResponse="true" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"/> - </transition> - </state> - - <state id="s02"> - <!-- the child should send this back automatically. It does not need to take - any transition on the event --> - <transition event="HTTP.2" target="pass"/> - </state> - </state> - - <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> - <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> - -</scxml>
\ No newline at end of file diff --git a/test/w3c/ecma/test513.txt b/test/w3c/ecma/test513.txt new file mode 100644 index 0000000..08e9b01 --- /dev/null +++ b/test/w3c/ecma/test513.txt @@ -0,0 +1,16 @@ +This is a fully manual test. You send a well formed event to the 'location' URL + specified for your SCXML interpreter and check that you get a 200 response code back. + One way of doing this, using wget, is shown below (you can use any event name you + want, but you must use '_scxmleventname' to indicate the name of the event): + +$ wget \ +--post-data='key1=value1&key2=value2' \ +--header '_scxmleventname: test' \ +<!-- URL of your processor goes here --> + +--2014-06-25 17:54:49-- http://epikur.local:8090/925c760f-2093-4054-a24c-d972d75f0dcd/basichttp +Resolving epikur.local (epikur.local)... 10.211.55.2, 10.37.129.2, 10.0.1.54, ... +Connecting to epikur.local (epikur.local)|10.211.55.2|:8090... connected. +HTTP request sent, awaiting response... 200 OK +Length: 0 [text/html] +Saving to: ‘basichttp’
\ No newline at end of file diff --git a/test/w3c/ecma/test519.scxml b/test/w3c/ecma/test519.scxml index 8945354..0f937b1 100644 --- a/test/w3c/ecma/test519.scxml +++ b/test/w3c/ecma/test519.scxml @@ -10,7 +10,7 @@ </onentry> <!-- if other end sends us back this event, we succeed --> - <transition event="test" cond="_event.raw.search(param1=1) !== -1" target="pass"/> + <transition event="test" cond="_event.raw.search('param1=1') !== -1" target="pass"/> <transition event="*" target="fail"/> </state> diff --git a/test/w3c/ecma/test520.scxml b/test/w3c/ecma/test520.scxml index daaf3a8..cfef477 100644 --- a/test/w3c/ecma/test520.scxml +++ b/test/w3c/ecma/test520.scxml @@ -9,8 +9,10 @@ </send> </onentry> - <!-- if other end sends us back this event, we succeed --> - <transition event="HTTP.POST" cond="_event.raw.search(/this is some content/) !== -1" target="pass"/> + <!-- if other end sends us back this event, we succeed. Test for two common + ways of encoding --> + <transition event="HTTP.POST" cond="_event.raw.search(/this+is+some+content/) !== -1" target="pass"/> + <transition event="HTTP.POST" cond="_event.raw.search(/this%20is%20some%20content/) !== -1" target="pass"/> <transition event="*" target="fail"/> </state> diff --git a/test/w3c/ecma/test531.scxml b/test/w3c/ecma/test531.scxml index 9eaa3f3..2110135 100644 --- a/test/w3c/ecma/test531.scxml +++ b/test/w3c/ecma/test531.scxml @@ -6,7 +6,7 @@ of the raised event. --><scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:con <onentry> <send event="timeout" delay="3s"/> <send targetexpr="_ioprocessors['basichttp']['location']" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"> - <content>_scxmleventname=test</content> + <param name="_scxmleventname" expr="'test'"/> </send> </onentry> diff --git a/test/w3c/txml/robots.txt b/test/w3c/txml/robots.txt index 54f3e01..9be2782 100644 --- a/test/w3c/txml/robots.txt +++ b/test/w3c/txml/robots.txt @@ -1,7 +1,7 @@ # # robots.txt for http://www.w3.org/ # -# $Id: robots.txt,v 1.66 2012/07/17 21:30:56 gerald Exp $ +# $Id: robots.txt,v 1.67 2014-06-25 13:06:01 ddavis Exp $ # # For use by search.w3.org @@ -93,4 +93,4 @@ Disallow: /2004/01/pp-impl Disallow: /Consortium/supporters Disallow: /2007/08/pyRdfa/ Disallow: /WAI/PF/comments/ - +Disallow: /participate/conferences.xml diff --git a/test/w3c/txml/test446.txt b/test/w3c/txml/test446.txt index 4db4843..3a26a2e 100644 --- a/test/w3c/txml/test446.txt +++ b/test/w3c/txml/test446.txt @@ -1,12 +1 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> -<html><head> -<title>300 Multiple Choices</title> -</head><body> -<h1>Multiple Choices</h1> -The document name you requested (<code>/Voice/2013/scxml-irp/446/test446.txt</code>) could not be found on this server. -However, we found documents with names similar to the one you requested.<p>Available documents: -<ul> -<li><a href="/Voice/2013/scxml-irp/446/test446.txml">/Voice/2013/scxml-irp/446/test446.txml</a> (common basename) -</ul> -Please consider informing the owner of the <a href="http://www.w3.org/Voice/2013/scxml-irp/">referring page</a> about the broken link. -</body></html> +[1,2,3]
\ No newline at end of file diff --git a/test/w3c/txml/test513.txml b/test/w3c/txml/test513.txml deleted file mode 100644 index 65dda29..0000000 --- a/test/w3c/txml/test513.txml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0"?> - -<!-- test that we get an HTTP success code back on successful delivery. To run this test, implementations -must support an extension to send: if the parameter httpResponse is present with value 'true', then when -the processor gets an http response code back, it must raise an event 'http.n1.nrest' where 'ni' is -the first digit of the response code and 'nrest' are the remaining digits--> - -<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> - -<state id="s0" initial="s01"> - <datamodel> - <data conf:id="1"/> - </datamodel> - - <onentry> - <send event="timeout" delay="30s"/> - </onentry> - <invoke type="http://www.w3.org/TR/scxml/"> - <content> - <!-- child script. Once we're running send childRunning to parent and include basicHTTPAccess URI --> - <scxml initial="child0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> - <state id="child0"> - <onentry> - <send target="#_parent" event="childRunning"> - <param name="uri" conf:basicHTTPAccessURI=""/> - </send> - </onentry> - </state> - </scxml> - </content> - </invoke> - - <transition event="*" conf:targetfail=""/> - - <state id="s01"> - <!-- when we get the event from the child, extract the access uri and use - the basicHTTP event i/o processor to send it an event --> - <transition event="childRunning" target="s02"> - <assign conf:location="1" conf:eventDataFieldValue="uri"/> - <send event="test" conf:targetExpr="1" httpResponse="true" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"/> - </transition> - </state> - - <state id="s02"> - <!-- the child should send this back automatically. It does not need to take - any transition on the event --> - <transition event="HTTP.2" conf:targetpass=""/> - </state> - </state> - - <conf:pass/> - <conf:fail/> - -</scxml>
\ No newline at end of file diff --git a/test/w3c/txml/test513.txt b/test/w3c/txml/test513.txt new file mode 100644 index 0000000..08e9b01 --- /dev/null +++ b/test/w3c/txml/test513.txt @@ -0,0 +1,16 @@ +This is a fully manual test. You send a well formed event to the 'location' URL + specified for your SCXML interpreter and check that you get a 200 response code back. + One way of doing this, using wget, is shown below (you can use any event name you + want, but you must use '_scxmleventname' to indicate the name of the event): + +$ wget \ +--post-data='key1=value1&key2=value2' \ +--header '_scxmleventname: test' \ +<!-- URL of your processor goes here --> + +--2014-06-25 17:54:49-- http://epikur.local:8090/925c760f-2093-4054-a24c-d972d75f0dcd/basichttp +Resolving epikur.local (epikur.local)... 10.211.55.2, 10.37.129.2, 10.0.1.54, ... +Connecting to epikur.local (epikur.local)|10.211.55.2|:8090... connected. +HTTP request sent, awaiting response... 200 OK +Length: 0 [text/html] +Saving to: ‘basichttp’
\ No newline at end of file diff --git a/test/w3c/txml/test520.txml b/test/w3c/txml/test520.txml index 32ada62..7e602d0 100644 --- a/test/w3c/txml/test520.txml +++ b/test/w3c/txml/test520.txml @@ -11,8 +11,10 @@ </send> </onentry> - <!-- if other end sends us back this event, we succeed --> - <transition event="HTTP.POST" conf:messageBodyEquals="this is some content" conf:targetpass=""/> + <!-- if other end sends us back this event, we succeed. Test for two common + ways of encoding --> + <transition event="HTTP.POST" conf:messageBodyEquals="this+is+some+content" conf:targetpass=""/> + <transition event="HTTP.POST" conf:messageBodyEquals="this%20is%20some%20content" conf:targetpass=""/> <transition event="*" conf:targetfail=""/> </state> diff --git a/test/w3c/txml/test531.txml b/test/w3c/txml/test531.txml index cffe7b5..5146963 100644 --- a/test/w3c/txml/test531.txml +++ b/test/w3c/txml/test531.txml @@ -8,7 +8,7 @@ of the raised event. --> <onentry> <send event="timeout" delay="3s"/> <send conf:basicHTTPAccessURITarget="" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"> - <content>_scxmleventname=test</content> + <param name="_scxmleventname" conf:quoteExpr="test"/> </send> </onentry> diff --git a/test/w3c/xpath/robots.txt b/test/w3c/xpath/robots.txt index 54f3e01..9be2782 100644 --- a/test/w3c/xpath/robots.txt +++ b/test/w3c/xpath/robots.txt @@ -1,7 +1,7 @@ # # robots.txt for http://www.w3.org/ # -# $Id: robots.txt,v 1.66 2012/07/17 21:30:56 gerald Exp $ +# $Id: robots.txt,v 1.67 2014-06-25 13:06:01 ddavis Exp $ # # For use by search.w3.org @@ -93,4 +93,4 @@ Disallow: /2004/01/pp-impl Disallow: /Consortium/supporters Disallow: /2007/08/pyRdfa/ Disallow: /WAI/PF/comments/ - +Disallow: /participate/conferences.xml diff --git a/test/w3c/xpath/test446.txt b/test/w3c/xpath/test446.txt index 4db4843..3a26a2e 100644 --- a/test/w3c/xpath/test446.txt +++ b/test/w3c/xpath/test446.txt @@ -1,12 +1 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> -<html><head> -<title>300 Multiple Choices</title> -</head><body> -<h1>Multiple Choices</h1> -The document name you requested (<code>/Voice/2013/scxml-irp/446/test446.txt</code>) could not be found on this server. -However, we found documents with names similar to the one you requested.<p>Available documents: -<ul> -<li><a href="/Voice/2013/scxml-irp/446/test446.txml">/Voice/2013/scxml-irp/446/test446.txml</a> (common basename) -</ul> -Please consider informing the owner of the <a href="http://www.w3.org/Voice/2013/scxml-irp/">referring page</a> about the broken link. -</body></html> +[1,2,3]
\ No newline at end of file diff --git a/test/w3c/xpath/test513.scxml b/test/w3c/xpath/test513.scxml deleted file mode 100644 index bc29bb4..0000000 --- a/test/w3c/xpath/test513.scxml +++ /dev/null @@ -1,50 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!-- test that we get an HTTP success code back on successful delivery. To run this test, implementations -must support an extension to send: if the parameter httpResponse is present with value 'true', then when -the processor gets an http response code back, it must raise an event 'http.n1.nrest' where 'ni' is -the first digit of the response code and 'nrest' are the remaining digits--><scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="xpath" version="1.0"> - -<state id="s0" initial="s01"> - <datamodel> - <data id="Var1"/> - </datamodel> - - <onentry> - <send event="timeout" delay="30s"/> - </onentry> - <invoke type="http://www.w3.org/TR/scxml/"> - <content> - <!-- child script. Once we're running send childRunning to parent and include basicHTTPAccess URI --> - <scxml initial="child0" datamodel="xpath" version="1.0"> - <state id="child0"> - <onentry> - <send target="#_parent" event="childRunning"> - <param name="uri" expr="_ioprocessors/processor[@name="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"]/location/text()"/> - </send> - </onentry> - </state> - </scxml> - </content> - </invoke> - - <transition event="*" target="fail"/> - - <state id="s01"> - <!-- when we get the event from the child, extract the access uri and use - the basicHTTP event i/o processor to send it an event --> - <transition event="childRunning" target="s02"> - <assign location="$Var1" expr="$_event/data/data[@id='uri']/text()"/> - <send event="test" targetexpr="$Var1" httpResponse="true" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"/> - </transition> - </state> - - <state id="s02"> - <!-- the child should send this back automatically. It does not need to take - any transition on the event --> - <transition event="HTTP.2" target="pass"/> - </state> - </state> - - <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> - <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> - -</scxml>
\ No newline at end of file diff --git a/test/w3c/xpath/test513.txt b/test/w3c/xpath/test513.txt new file mode 100644 index 0000000..08e9b01 --- /dev/null +++ b/test/w3c/xpath/test513.txt @@ -0,0 +1,16 @@ +This is a fully manual test. You send a well formed event to the 'location' URL + specified for your SCXML interpreter and check that you get a 200 response code back. + One way of doing this, using wget, is shown below (you can use any event name you + want, but you must use '_scxmleventname' to indicate the name of the event): + +$ wget \ +--post-data='key1=value1&key2=value2' \ +--header '_scxmleventname: test' \ +<!-- URL of your processor goes here --> + +--2014-06-25 17:54:49-- http://epikur.local:8090/925c760f-2093-4054-a24c-d972d75f0dcd/basichttp +Resolving epikur.local (epikur.local)... 10.211.55.2, 10.37.129.2, 10.0.1.54, ... +Connecting to epikur.local (epikur.local)|10.211.55.2|:8090... connected. +HTTP request sent, awaiting response... 200 OK +Length: 0 [text/html] +Saving to: ‘basichttp’
\ No newline at end of file diff --git a/test/w3c/xpath/test520.scxml b/test/w3c/xpath/test520.scxml index cb54284..3c0f941 100644 --- a/test/w3c/xpath/test520.scxml +++ b/test/w3c/xpath/test520.scxml @@ -9,8 +9,10 @@ </send> </onentry> - <!-- if other end sends us back this event, we succeed --> - <transition event="HTTP.POST" cond="contains($_event/raw, this is some content)" target="pass"/> + <!-- if other end sends us back this event, we succeed. Test for two common + ways of encoding --> + <transition event="HTTP.POST" cond="contains($_event/raw, this+is+some+content)" target="pass"/> + <transition event="HTTP.POST" cond="contains($_event/raw, this%20is%20some%20content)" target="pass"/> <transition event="*" target="fail"/> </state> diff --git a/test/w3c/xpath/test531.scxml b/test/w3c/xpath/test531.scxml index 282e479..aded4d9 100644 --- a/test/w3c/xpath/test531.scxml +++ b/test/w3c/xpath/test531.scxml @@ -6,7 +6,7 @@ of the raised event. --><scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:con <onentry> <send event="timeout" delay="3s"/> <send targetexpr="$_ioprocessors/processor[@name="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"]/location/text()" type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"> - <content>_scxmleventname=test</content> + <param name="_scxmleventname" expr="'test'"/> </send> </onentry> |