diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-07-04 19:46:07 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-07-04 19:46:07 (GMT) |
commit | 7bd0256239f247ed01ee6c673e31283c794bb3d0 (patch) | |
tree | a8c9b03374d995c6fd4b23cac2f5be282344bba3 /src | |
parent | 096f7df1137dd62871cacd371bf023e39d6b30e5 (diff) | |
download | uscxml-7bd0256239f247ed01ee6c673e31283c794bb3d0.zip uscxml-7bd0256239f247ed01ee6c673e31283c794bb3d0.tar.gz uscxml-7bd0256239f247ed01ee6c673e31283c794bb3d0.tar.bz2 |
Reactiveated umundo invoker
Diffstat (limited to 'src')
-rw-r--r-- | src/uscxml/Interpreter.cpp | 13 | ||||
-rw-r--r-- | src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp | 14 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/umundo/JSON.pb.cc | 462 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/umundo/JSON.pb.h | 369 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp | 228 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/umundo/UmundoInvoker.h | 18 |
7 files changed, 1034 insertions, 71 deletions
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index bdda8c8..158ea96 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -634,13 +634,12 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { } if (delay.size() > 0) { boost::trim(delay); - std::stringstream delayTime; - if (delay.size() > 2 && boost::iequals("ms", delay.substr(delay.length() - 2, 2))) { - delayTime << delay.substr(0, delay.size() - 2); - delayTime >> sendReq.delayMs; - } else if (delay.size() > 1 && boost::iequals("s", delay.substr(delay.length() - 1, 1))) { - delayTime << delay.substr(0, delay.size() - 1); - delayTime >> sendReq.delayMs; + + NumAttr delayAttr(delay); + if (boost::iequals(delayAttr.unit, "ms")) { + sendReq.delayMs = strTo<uint32_t>(delayAttr.value); + } else if (boost::iequals(delayAttr.unit, "s")) { + sendReq.delayMs = strTo<uint32_t>(delayAttr.value); sendReq.delayMs *= 1000; } else { LOG(ERROR) << "Cannot make sense of delay value " << delay << ": does not end in 's' or 'ms'"; diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index c78cdad..8feb73a 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -220,9 +220,12 @@ Data JSCDataModel::getValueAsData(const JSValueRef value) { if (exception) handleException(exception); - char* buf = (char*)malloc(JSStringGetMaximumUTF8CStringSize(stringValue)); - JSStringGetUTF8CString(stringValue, buf, sizeof(buf)); + size_t maxSize = JSStringGetMaximumUTF8CStringSize(stringValue); + char* buf = new char[maxSize]; + JSStringGetUTF8CString(stringValue, buf, maxSize); + data.atom = std::string(buf); + JSStringRelease(stringValue); free(buf); break; } @@ -236,12 +239,14 @@ Data JSCDataModel::getValueAsData(const JSValueRef value) { bool isArray = true; for (size_t i = 0; i < paramCount; i++) { JSStringRef stringValue = JSPropertyNameArrayGetNameAtIndex(properties, i); - char* buf = (char*)malloc(JSStringGetMaximumUTF8CStringSize(stringValue)); - JSStringGetUTF8CString(stringValue, buf, sizeof(buf)); + size_t maxSize = JSStringGetMaximumUTF8CStringSize(stringValue); + char* buf = new char[maxSize]; + JSStringGetUTF8CString(stringValue, buf, maxSize); std::string property(buf); if (!isNumeric(property.c_str(), 10)) isArray = false; propertySet.insert(property); + JSStringRelease(stringValue); free(buf); } std::set<std::string>::iterator propIter = propertySet.begin(); @@ -261,7 +266,6 @@ Data JSCDataModel::getValueAsData(const JSValueRef value) { } propIter++; } - break; } } diff --git a/src/uscxml/plugins/invoker/CMakeLists.txt b/src/uscxml/plugins/invoker/CMakeLists.txt index f0d124f..34d8918 100644 --- a/src/uscxml/plugins/invoker/CMakeLists.txt +++ b/src/uscxml/plugins/invoker/CMakeLists.txt @@ -113,6 +113,7 @@ endif() if (UMUNDO_FOUND) file(GLOB_RECURSE UMUNDO_INVOKER umundo/*.cpp + umundo/*.cc umundo/*.h) source_group("Invoker\\umundo" FILES ${UMUNDO_INVOKER}) if (BUILD_AS_PLUGINS) diff --git a/src/uscxml/plugins/invoker/umundo/JSON.pb.cc b/src/uscxml/plugins/invoker/umundo/JSON.pb.cc new file mode 100644 index 0000000..9e245c1 --- /dev/null +++ b/src/uscxml/plugins/invoker/umundo/JSON.pb.cc @@ -0,0 +1,462 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: JSON.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "JSON.pb.h" + +#include <algorithm> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace { + +const ::google::protobuf::Descriptor* JSONProto_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + JSONProto_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_JSON_2eproto() { + protobuf_AddDesc_JSON_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "JSON.proto"); + GOOGLE_CHECK(file != NULL); + JSONProto_descriptor_ = file->message_type(0); + static const int JSONProto_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(JSONProto, compound_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(JSONProto, key_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(JSONProto, atom_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(JSONProto, verbatim_), + }; + JSONProto_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + JSONProto_descriptor_, + JSONProto::default_instance_, + JSONProto_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(JSONProto, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(JSONProto, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(JSONProto)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_JSON_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + JSONProto_descriptor_, &JSONProto::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_JSON_2eproto() { + delete JSONProto::default_instance_; + delete JSONProto_reflection_; +} + +void protobuf_AddDesc_JSON_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\nJSON.proto\"V\n\tJSONProto\022\034\n\010compound\030\001 " + "\003(\0132\n.JSONProto\022\013\n\003key\030\002 \001(\t\022\014\n\004atom\030\003 \001" + "(\t\022\020\n\010verbatim\030\004 \001(\010", 100); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "JSON.proto", &protobuf_RegisterTypes); + JSONProto::default_instance_ = new JSONProto(); + JSONProto::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_JSON_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_JSON_2eproto { + StaticDescriptorInitializer_JSON_2eproto() { + protobuf_AddDesc_JSON_2eproto(); + } +} static_descriptor_initializer_JSON_2eproto_; + +// =================================================================== + +#ifndef _MSC_VER +const int JSONProto::kCompoundFieldNumber; +const int JSONProto::kKeyFieldNumber; +const int JSONProto::kAtomFieldNumber; +const int JSONProto::kVerbatimFieldNumber; +#endif // !_MSC_VER + +JSONProto::JSONProto() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void JSONProto::InitAsDefaultInstance() { +} + +JSONProto::JSONProto(const JSONProto& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void JSONProto::SharedCtor() { + _cached_size_ = 0; + key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + atom_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + verbatim_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +JSONProto::~JSONProto() { + SharedDtor(); +} + +void JSONProto::SharedDtor() { + if (key_ != &::google::protobuf::internal::kEmptyString) { + delete key_; + } + if (atom_ != &::google::protobuf::internal::kEmptyString) { + delete atom_; + } + if (this != default_instance_) { + } +} + +void JSONProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* JSONProto::descriptor() { + protobuf_AssignDescriptorsOnce(); + return JSONProto_descriptor_; +} + +const JSONProto& JSONProto::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_JSON_2eproto(); + return *default_instance_; +} + +JSONProto* JSONProto::default_instance_ = NULL; + +JSONProto* JSONProto::New() const { + return new JSONProto; +} + +void JSONProto::Clear() { + if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { + if (has_key()) { + if (key_ != &::google::protobuf::internal::kEmptyString) { + key_->clear(); + } + } + if (has_atom()) { + if (atom_ != &::google::protobuf::internal::kEmptyString) { + atom_->clear(); + } + } + verbatim_ = false; + } + compound_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool JSONProto::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .JSONProto compound = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_compound: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_compound())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_compound; + if (input->ExpectTag(18)) goto parse_key; + break; + } + + // optional string key = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_key: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_key())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->key().data(), this->key().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_atom; + break; + } + + // optional string atom = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_atom: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_atom())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->atom().data(), this->atom().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(32)) goto parse_verbatim; + break; + } + + // optional bool verbatim = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_verbatim: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &verbatim_))); + set_has_verbatim(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void JSONProto::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .JSONProto compound = 1; + for (int i = 0; i < this->compound_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->compound(i), output); + } + + // optional string key = 2; + if (has_key()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->key().data(), this->key().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->key(), output); + } + + // optional string atom = 3; + if (has_atom()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->atom().data(), this->atom().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->atom(), output); + } + + // optional bool verbatim = 4; + if (has_verbatim()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(4, this->verbatim(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* JSONProto::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .JSONProto compound = 1; + for (int i = 0; i < this->compound_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->compound(i), target); + } + + // optional string key = 2; + if (has_key()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->key().data(), this->key().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->key(), target); + } + + // optional string atom = 3; + if (has_atom()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->atom().data(), this->atom().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->atom(), target); + } + + // optional bool verbatim = 4; + if (has_verbatim()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(4, this->verbatim(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int JSONProto::ByteSize() const { + int total_size = 0; + + if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { + // optional string key = 2; + if (has_key()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->key()); + } + + // optional string atom = 3; + if (has_atom()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->atom()); + } + + // optional bool verbatim = 4; + if (has_verbatim()) { + total_size += 1 + 1; + } + + } + // repeated .JSONProto compound = 1; + total_size += 1 * this->compound_size(); + for (int i = 0; i < this->compound_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->compound(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void JSONProto::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const JSONProto* source = + ::google::protobuf::internal::dynamic_cast_if_available<const JSONProto*>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void JSONProto::MergeFrom(const JSONProto& from) { + GOOGLE_CHECK_NE(&from, this); + compound_.MergeFrom(from.compound_); + if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) { + if (from.has_key()) { + set_key(from.key()); + } + if (from.has_atom()) { + set_atom(from.atom()); + } + if (from.has_verbatim()) { + set_verbatim(from.verbatim()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void JSONProto::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void JSONProto::CopyFrom(const JSONProto& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool JSONProto::IsInitialized() const { + + return true; +} + +void JSONProto::Swap(JSONProto* other) { + if (other != this) { + compound_.Swap(&other->compound_); + std::swap(key_, other->key_); + std::swap(atom_, other->atom_); + std::swap(verbatim_, other->verbatim_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata JSONProto::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = JSONProto_descriptor_; + metadata.reflection = JSONProto_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +// @@protoc_insertion_point(global_scope) diff --git a/src/uscxml/plugins/invoker/umundo/JSON.pb.h b/src/uscxml/plugins/invoker/umundo/JSON.pb.h new file mode 100644 index 0000000..fe4ee57 --- /dev/null +++ b/src/uscxml/plugins/invoker/umundo/JSON.pb.h @@ -0,0 +1,369 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: JSON.proto + +#ifndef PROTOBUF_JSON_2eproto__INCLUDED +#define PROTOBUF_JSON_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 2005000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_JSON_2eproto(); +void protobuf_AssignDesc_JSON_2eproto(); +void protobuf_ShutdownFile_JSON_2eproto(); + +class JSONProto; + +// =================================================================== + +class JSONProto : public ::google::protobuf::Message { + public: + JSONProto(); + virtual ~JSONProto(); + + JSONProto(const JSONProto& from); + + inline JSONProto& operator=(const JSONProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const JSONProto& default_instance(); + + void Swap(JSONProto* other); + + // implements Message ---------------------------------------------- + + JSONProto* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const JSONProto& from); + void MergeFrom(const JSONProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .JSONProto compound = 1; + inline int compound_size() const; + inline void clear_compound(); + static const int kCompoundFieldNumber = 1; + inline const ::JSONProto& compound(int index) const; + inline ::JSONProto* mutable_compound(int index); + inline ::JSONProto* add_compound(); + inline const ::google::protobuf::RepeatedPtrField< ::JSONProto >& + compound() const; + inline ::google::protobuf::RepeatedPtrField< ::JSONProto >* + mutable_compound(); + + // optional string key = 2; + inline bool has_key() const; + inline void clear_key(); + static const int kKeyFieldNumber = 2; + inline const ::std::string& key() const; + inline void set_key(const ::std::string& value); + inline void set_key(const char* value); + inline void set_key(const char* value, size_t size); + inline ::std::string* mutable_key(); + inline ::std::string* release_key(); + inline void set_allocated_key(::std::string* key); + + // optional string atom = 3; + inline bool has_atom() const; + inline void clear_atom(); + static const int kAtomFieldNumber = 3; + inline const ::std::string& atom() const; + inline void set_atom(const ::std::string& value); + inline void set_atom(const char* value); + inline void set_atom(const char* value, size_t size); + inline ::std::string* mutable_atom(); + inline ::std::string* release_atom(); + inline void set_allocated_atom(::std::string* atom); + + // optional bool verbatim = 4; + inline bool has_verbatim() const; + inline void clear_verbatim(); + static const int kVerbatimFieldNumber = 4; + inline bool verbatim() const; + inline void set_verbatim(bool value); + + // @@protoc_insertion_point(class_scope:JSONProto) + private: + inline void set_has_key(); + inline void clear_has_key(); + inline void set_has_atom(); + inline void clear_has_atom(); + inline void set_has_verbatim(); + inline void clear_has_verbatim(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::JSONProto > compound_; + ::std::string* key_; + ::std::string* atom_; + bool verbatim_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_JSON_2eproto(); + friend void protobuf_AssignDesc_JSON_2eproto(); + friend void protobuf_ShutdownFile_JSON_2eproto(); + + void InitAsDefaultInstance(); + static JSONProto* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// JSONProto + +// repeated .JSONProto compound = 1; +inline int JSONProto::compound_size() const { + return compound_.size(); +} +inline void JSONProto::clear_compound() { + compound_.Clear(); +} +inline const ::JSONProto& JSONProto::compound(int index) const { + return compound_.Get(index); +} +inline ::JSONProto* JSONProto::mutable_compound(int index) { + return compound_.Mutable(index); +} +inline ::JSONProto* JSONProto::add_compound() { + return compound_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::JSONProto >& +JSONProto::compound() const { + return compound_; +} +inline ::google::protobuf::RepeatedPtrField< ::JSONProto >* +JSONProto::mutable_compound() { + return &compound_; +} + +// optional string key = 2; +inline bool JSONProto::has_key() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void JSONProto::set_has_key() { + _has_bits_[0] |= 0x00000002u; +} +inline void JSONProto::clear_has_key() { + _has_bits_[0] &= ~0x00000002u; +} +inline void JSONProto::clear_key() { + if (key_ != &::google::protobuf::internal::kEmptyString) { + key_->clear(); + } + clear_has_key(); +} +inline const ::std::string& JSONProto::key() const { + return *key_; +} +inline void JSONProto::set_key(const ::std::string& value) { + set_has_key(); + if (key_ == &::google::protobuf::internal::kEmptyString) { + key_ = new ::std::string; + } + key_->assign(value); +} +inline void JSONProto::set_key(const char* value) { + set_has_key(); + if (key_ == &::google::protobuf::internal::kEmptyString) { + key_ = new ::std::string; + } + key_->assign(value); +} +inline void JSONProto::set_key(const char* value, size_t size) { + set_has_key(); + if (key_ == &::google::protobuf::internal::kEmptyString) { + key_ = new ::std::string; + } + key_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* JSONProto::mutable_key() { + set_has_key(); + if (key_ == &::google::protobuf::internal::kEmptyString) { + key_ = new ::std::string; + } + return key_; +} +inline ::std::string* JSONProto::release_key() { + clear_has_key(); + if (key_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = key_; + key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void JSONProto::set_allocated_key(::std::string* key) { + if (key_ != &::google::protobuf::internal::kEmptyString) { + delete key_; + } + if (key) { + set_has_key(); + key_ = key; + } else { + clear_has_key(); + key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional string atom = 3; +inline bool JSONProto::has_atom() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void JSONProto::set_has_atom() { + _has_bits_[0] |= 0x00000004u; +} +inline void JSONProto::clear_has_atom() { + _has_bits_[0] &= ~0x00000004u; +} +inline void JSONProto::clear_atom() { + if (atom_ != &::google::protobuf::internal::kEmptyString) { + atom_->clear(); + } + clear_has_atom(); +} +inline const ::std::string& JSONProto::atom() const { + return *atom_; +} +inline void JSONProto::set_atom(const ::std::string& value) { + set_has_atom(); + if (atom_ == &::google::protobuf::internal::kEmptyString) { + atom_ = new ::std::string; + } + atom_->assign(value); +} +inline void JSONProto::set_atom(const char* value) { + set_has_atom(); + if (atom_ == &::google::protobuf::internal::kEmptyString) { + atom_ = new ::std::string; + } + atom_->assign(value); +} +inline void JSONProto::set_atom(const char* value, size_t size) { + set_has_atom(); + if (atom_ == &::google::protobuf::internal::kEmptyString) { + atom_ = new ::std::string; + } + atom_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* JSONProto::mutable_atom() { + set_has_atom(); + if (atom_ == &::google::protobuf::internal::kEmptyString) { + atom_ = new ::std::string; + } + return atom_; +} +inline ::std::string* JSONProto::release_atom() { + clear_has_atom(); + if (atom_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = atom_; + atom_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} +inline void JSONProto::set_allocated_atom(::std::string* atom) { + if (atom_ != &::google::protobuf::internal::kEmptyString) { + delete atom_; + } + if (atom) { + set_has_atom(); + atom_ = atom; + } else { + clear_has_atom(); + atom_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + } +} + +// optional bool verbatim = 4; +inline bool JSONProto::has_verbatim() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void JSONProto::set_has_verbatim() { + _has_bits_[0] |= 0x00000008u; +} +inline void JSONProto::clear_has_verbatim() { + _has_bits_[0] &= ~0x00000008u; +} +inline void JSONProto::clear_verbatim() { + verbatim_ = false; + clear_has_verbatim(); +} +inline bool JSONProto::verbatim() const { + return verbatim_; +} +inline void JSONProto::set_verbatim(bool value) { + set_has_verbatim(); + verbatim_ = value; +} + + +// @@protoc_insertion_point(namespace_scope) + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_JSON_2eproto__INCLUDED diff --git a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp index 641d713..2b3377e 100644 --- a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp +++ b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp @@ -16,15 +16,19 @@ bool connect(pluma::Host& host) { } #endif -UmundoInvoker::UmundoInvoker() : _node(NULL), _pub(NULL), _sub(NULL) { +UmundoInvoker::UmundoInvoker() : _pub(NULL), _sub(NULL) { } UmundoInvoker::~UmundoInvoker() { if (_node) { - if (_sub) + if (_sub) { _node->removeSubscriber(*_sub); - if (_pub) + delete _sub; + } + if (_pub) { _node->removePublisher(*_pub); + delete _pub; + } } }; @@ -40,64 +44,88 @@ Data UmundoInvoker::getDataModelVariables() { } void UmundoInvoker::send(const SendRequest& req) { - umundo::Message* msg = new umundo::Message(); + umundo::Message msg; if (req.name.length() > 0) { - msg->putMeta("event", req.name); + msg.putMeta("event", req.name); } else { - msg->putMeta("event", "umundo"); + msg.putMeta("event", "umundo"); } - if (req.params.find("type") != req.params.end()) { - // assume JSON in content to transform to protobuf object - if (req.content.length() > 0 && _interpreter->getDataModel()) { - std::string type; - std::multimap<std::string, std::string>::const_iterator typeIter = req.params.find("type"); - if (typeIter != req.params.end()) - type = typeIter->second; - const google::protobuf::Message* protoMsg = umundo::PBSerializer::getProto(type); - if (protoMsg == NULL) { - LOG(ERROR) << "No type " << type << " is known, pass a directory with proto .desc files via types param when invoking"; + if (req.content.length()) { + try { + Data data = _interpreter->getDataModel().getStringAsData(req.content); + if (!data) { + LOG(ERROR) << "Cannot transform content to data object per datamodel"; return; } - try { - Data data = _interpreter->getDataModel().getStringAsData(req.content); + + std::string type; + if (req.params.find("type") != req.params.end()) { + // we are supposed to build a typed object + type = req.params.find("type")->second; + + const google::protobuf::Message* protoMsg = umundo::PBSerializer::getProto(type); + if (protoMsg == NULL) { + LOG(ERROR) << "No type '" << type << "' is known, pass a directory with proto .desc files via types param when invoking"; + return; + } + google::protobuf::Message* pbMsg = protoMsg->New(); if (!dataToProtobuf(pbMsg, data)) { LOG(ERROR) << "Cannot create message from JSON - not sending"; - } else { + return; + } + + if (!_isService) { // add all s11n properties - if (!_isService) { - _pub->prepareMsg(msg, type, pbMsg); - _pub->send(msg); - } else { - std::map<umundo::ServiceDescription, umundo::ServiceStub*>::iterator svcIter = _svcs.begin(); - while(svcIter != _svcs.end()) { - umundo::ServiceStub* stub = svcIter->second; - Event event; - void* rv = NULL; - stub->callStubMethod(req.name, pbMsg, type, rv, ""); - protobufToData(event.data, *(const google::protobuf::Message*)rv); - - event.name = _invokeId + ".reply." + req.name; - event.origin = msg->getMeta("um.channel"); - event.origintype = "umundo"; - event.type = Event::EXTERNAL; - - returnEvent(event); - svcIter++; - } + _pub->prepareMsg(&msg, type, pbMsg); + _pub->send(&msg); + } else { + // invoke as service + std::map<umundo::ServiceDescription, umundo::ServiceStub*>::iterator svcIter = _svcs.begin(); + while(svcIter != _svcs.end()) { + umundo::ServiceStub* stub = svcIter->second; + Event event; + void* rv = NULL; + stub->callStubMethod(req.name, pbMsg, type, rv, ""); + protobufToData(event.data, *(const google::protobuf::Message*)rv); + + event.name = _invokeId + ".reply." + req.name; + event.origin = msg.getMeta("um.channel"); + event.origintype = "umundo"; + event.type = Event::EXTERNAL; + + returnEvent(event); + svcIter++; } } - } catch (Event e) { - LOG(ERROR) << "Syntax error when invoking umundo:" << std::endl << e << std::endl; - return; + } else { + // just encode JSON + JSONProto* jsonProtoMsg = new JSONProto(); + if (!dataToJSONbuf(jsonProtoMsg, data)) { + LOG(ERROR) << "Cannot create message from JSON - not sending"; + return; + } + + if (!_isService) { + // add all s11n properties + _pub->prepareMsg(&msg, "JSON", jsonProtoMsg); + _pub->send(&msg); + } else { + LOG(ERROR) << "Cannot invoke services with untyped JSON"; + return; + } + } - } else { - LOG(ERROR) << "Required JSON object in content" << std::endl; + } catch (Event e) { + LOG(ERROR) << "Syntax error when invoking umundo:" << std::endl << e << std::endl; return; } - } + } else { + LOG(ERROR) << "Required JSON object in content" << std::endl; + return; + } } void UmundoInvoker::cancel(const std::string sendId) { @@ -157,6 +185,9 @@ void UmundoInvoker::invoke(const InvokeRequest& req) { _pub = new umundo::TypedPublisher(channelName); _sub = new umundo::TypedSubscriber(channelName, this); + _pub->setGreeter(this); + _sub->registerType("JSON", new JSONProto()); + _node->addPublisher(*_pub); _node->addSubscriber(*_sub); @@ -168,6 +199,26 @@ void UmundoInvoker::invoke(const InvokeRequest& req) { } } +void UmundoInvoker::welcome(umundo::TypedPublisher pub, const std::string& nodeId, const std::string& subId) { + Event event; + event.name = "umundo.sub.added"; + event.data.compound["nodeId"] = Data(nodeId, Data::VERBATIM); + event.data.compound["subId"] = Data(subId, Data::VERBATIM); + event.data.compound["channel"] = Data(pub.getChannelName(), Data::VERBATIM); + event.data.compound["totalSubs"] = Data(toStr(pub.waitForSubscribers(0)), Data::VERBATIM); + returnEvent(event); +} + +void UmundoInvoker::farewell(umundo::TypedPublisher pub, const std::string& nodeId, const std::string& subId) { + Event event; + event.name = "umundo.sub.removed"; + event.data.compound["nodeId"] = Data(nodeId, Data::VERBATIM); + event.data.compound["subId"] = Data(subId, Data::VERBATIM); + event.data.compound["channel"] = Data(pub.getChannelName(), Data::VERBATIM); + event.data.compound["totalSubs"] = Data(toStr(pub.waitForSubscribers(0)), Data::VERBATIM); + returnEvent(event); +} + void UmundoInvoker::receive(void* object, umundo::Message* msg) { uscxml::Event event; if (msg->getMeta().find("event") != msg->getMeta().end()) { @@ -184,14 +235,19 @@ void UmundoInvoker::receive(void* object, umundo::Message* msg) { // if (msg->getMeta().find("um.s11n.type") != msg->getMeta().end()) // event.compound["class"] = msg->getMeta("um.s11n.type"); - if (object != NULL) - protobufToData(event.data, *(const google::protobuf::Message*)object); + if (object != NULL) { + if (msg->getMeta().find("um.s11n.type") != msg->getMeta().end() && + boost::equals(msg->getMeta().find("um.s11n.type")->second, "JSON")) { + jsonbufToData(event.data, *(JSONProto*)object); + } else { + protobufToData(event.data, *(const google::protobuf::Message*)object); + } + } // get meta fields into event std::map<std::string, std::string>::const_iterator metaIter = msg->getMeta().begin(); while(metaIter != msg->getMeta().end()) { - if (metaIter->first.substr(0,3).compare("um.") != 0) - event.data.compound[metaIter->first] = Data(metaIter->second, Data::VERBATIM); + event.data.compound[metaIter->first] = Data(metaIter->second, Data::VERBATIM); metaIter++; } @@ -249,19 +305,46 @@ void UmundoInvoker::removed(umundo::ServiceDescription desc) { void UmundoInvoker::changed(umundo::ServiceDescription desc) { } -std::multimap<std::string, std::pair<std::string, umundo::Node*> > UmundoInvoker::_nodes; -umundo::Node* UmundoInvoker::getNode(InterpreterImpl* interpreter, const std::string& domain) { +std::multimap<std::string, std::pair<std::string, boost::weak_ptr<umundo::Node> > > UmundoInvoker::_nodes; +boost::shared_ptr<umundo::Node> UmundoInvoker::getNode(InterpreterImpl* interpreter, const std::string& domain) { std::pair<_nodes_t::iterator, _nodes_t::iterator> range = _nodes.equal_range(interpreter->getName()); for (_nodes_t::iterator it = range.first; it != range.second; it++) { if (it->second.first.compare(domain) == 0) - return it->second.second; + return it->second.second.lock(); } - umundo::Node* node = new umundo::Node(domain); - std::pair<std::string, std::pair<std::string, umundo::Node*> > pair = std::make_pair(interpreter->getName(), std::make_pair(domain, node)); + boost::shared_ptr<umundo::Node> node = boost::shared_ptr<umundo::Node>(new umundo::Node(domain)); + std::pair<std::string, std::pair<std::string, boost::weak_ptr<umundo::Node> > > pair = std::make_pair(interpreter->getName(), std::make_pair(domain, node)); _nodes.insert(pair); return node; } +bool UmundoInvoker::jsonbufToData(Data& data, const JSONProto& json) { + if (json.compound_size() > 0) { + if (json.compound(0).key().size() > 0) { + // compound + for (int i = 0; i < json.compound_size(); i++) { + jsonbufToData(data.compound[json.compound(i).key()], json.compound(i)); + } + } else { + // array + for (int i = 0; i < json.compound_size(); i++) { + Data arrayData; + data.array.push_back(arrayData); + jsonbufToData(data.array.back(), json.compound(i)); + } + } + } else if (json.atom().size() > 0) { + data.atom = json.atom(); + if (json.verbatim()) { + data.type = Data::VERBATIM; + } else { + data.type = Data::INTERPRETED; + } + } + + return true; +} + bool UmundoInvoker::protobufToData(Data& data, const google::protobuf::Message& msg) { const google::protobuf::Descriptor* desc = msg.GetDescriptor(); const google::protobuf::Reflection* reflect = msg.GetReflection(); @@ -377,6 +460,43 @@ bool UmundoInvoker::protobufToData(Data& data, const google::protobuf::Message& return true; } +bool UmundoInvoker::dataToJSONbuf(JSONProto* msg, Data& data) { + const google::protobuf::Descriptor* desc = msg->GetDescriptor(); + const google::protobuf::Reflection* reflect = msg->GetReflection(); + + if (!data.compound.empty()) { + const google::protobuf::FieldDescriptor* fieldDesc = desc->FindFieldByName("compound"); + + std::map<std::string, Data>::iterator compoundIter = data.compound.begin(); + while(compoundIter != data.compound.end()) { + JSONProto* compoundMsg = (JSONProto*)reflect->AddMessage(msg, fieldDesc); + dataToJSONbuf(compoundMsg, compoundIter->second); + compoundMsg->set_key(compoundIter->first); + compoundIter++; + } + } else if (!data.array.empty()) { + const google::protobuf::FieldDescriptor* fieldDesc = desc->FindFieldByName("compound"); + + std::list<Data>::iterator arrayIter = data.array.begin(); + while(arrayIter != data.array.end()) { + JSONProto* arrayMsg = (JSONProto*)reflect->AddMessage(msg, fieldDesc); + dataToJSONbuf(arrayMsg, *arrayIter); + arrayIter++; + } + } else if (!data.atom.empty()) { + const google::protobuf::FieldDescriptor* atomDesc = desc->FindFieldByName("atom"); + const google::protobuf::FieldDescriptor* verbDesc = desc->FindFieldByName("verbatim"); + + if (data.type == Data::VERBATIM) { + reflect->SetBool(msg, verbDesc, true); + } else { + reflect->SetBool(msg, verbDesc, false); + } + reflect->SetString(msg, atomDesc, data.atom); + } + return true; +} + bool UmundoInvoker::dataToProtobuf(google::protobuf::Message* msg, Data& data) { const google::protobuf::Descriptor* desc = msg->GetDescriptor(); const google::protobuf::Reflection* reflect = msg->GetReflection(); diff --git a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h index f917819..4d81e79 100644 --- a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h +++ b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h @@ -8,6 +8,8 @@ #include <umundo/rpc.h> #include <umundo/s11n/protobuf/PBSerializer.h> +#include "JSON.pb.h" + #ifdef BUILD_AS_PLUGINS #include "uscxml/plugins/Plugins.h" #endif @@ -16,7 +18,7 @@ namespace uscxml { class Interpreter; -class UmundoInvoker : public InvokerImpl, public umundo::TypedReceiver, public umundo::ResultSet<umundo::ServiceDescription> { + class UmundoInvoker : public InvokerImpl, public umundo::TypedReceiver, public umundo::ResultSet<umundo::ServiceDescription>, public umundo::TypedGreeter { public: UmundoInvoker(); virtual ~UmundoInvoker(); @@ -41,13 +43,19 @@ public: virtual void removed(umundo::ServiceDescription); virtual void changed(umundo::ServiceDescription); + virtual void welcome(umundo::TypedPublisher, const std::string& nodeId, const std::string& subId); + virtual void farewell(umundo::TypedPublisher, const std::string& nodeId, const std::string& subId); + protected: bool _isService; + bool dataToJSONbuf(JSONProto* msg, Data& data); bool dataToProtobuf(google::protobuf::Message* msg, Data& data); + + bool jsonbufToData(Data& data, const JSONProto& json); bool protobufToData(Data& data, const google::protobuf::Message& msg); - umundo::Node* _node; + boost::shared_ptr<umundo::Node> _node; umundo::TypedPublisher* _pub; umundo::TypedSubscriber* _sub; @@ -55,9 +63,9 @@ protected: umundo::ServiceManager* _svcMgr; std::map<umundo::ServiceDescription, umundo::ServiceStub*> _svcs; - static std::multimap<std::string, std::pair<std::string, umundo::Node*> > _nodes; - typedef std::multimap<std::string, std::pair<std::string, umundo::Node*> > _nodes_t; - static umundo::Node* getNode(InterpreterImpl* interpreter, const std::string& domain); + static std::multimap<std::string, std::pair<std::string, boost::weak_ptr<umundo::Node> > > _nodes; + typedef std::multimap<std::string, std::pair<std::string, boost::weak_ptr<umundo::Node> > > _nodes_t; + static boost::shared_ptr<umundo::Node> getNode(InterpreterImpl* interpreter, const std::string& domain); }; #ifdef BUILD_AS_PLUGINS |