diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bindings/swig/php/uscxmlNativePHP.php | 18 | ||||
-rw-r--r-- | src/uscxml/Convenience.h | 12 | ||||
-rw-r--r-- | src/uscxml/Interpreter.cpp | 58 | ||||
-rw-r--r-- | src/uscxml/Interpreter.h | 8 | ||||
-rw-r--r-- | src/uscxml/Message.cpp | 58 | ||||
-rw-r--r-- | src/uscxml/Message.h | 4 | ||||
-rw-r--r-- | src/uscxml/interpreter/InterpreterDraft6.cpp | 5 | ||||
-rw-r--r-- | src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp | 15 | ||||
-rw-r--r-- | src/uscxml/server/HTTPServer.cpp | 31 | ||||
-rw-r--r-- | src/uscxml/util/Base64.h | 5 | ||||
-rw-r--r-- | src/uscxml/util/Base64.hpp | 14 | ||||
-rw-r--r-- | src/uscxml/util/MD5.c | 1 |
12 files changed, 161 insertions, 68 deletions
diff --git a/src/bindings/swig/php/uscxmlNativePHP.php b/src/bindings/swig/php/uscxmlNativePHP.php index d7bb3d0..3aba5be 100644 --- a/src/bindings/swig/php/uscxmlNativePHP.php +++ b/src/bindings/swig/php/uscxmlNativePHP.php @@ -2,12 +2,12 @@ /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). - * Version 2.0.9 - * - * This file is not intended to be easily readable and contains a number of + * 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. + * 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. @@ -1030,13 +1030,7 @@ class Interpreter { } static function tokenizeIdRefs($idRefs) { - $r=Interpreter_tokenizeIdRefs($idRefs); - 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; + return Interpreter_tokenizeIdRefs($idRefs); } static function spaceNormalize($text) { diff --git a/src/uscxml/Convenience.h b/src/uscxml/Convenience.h index 9f4c1a1..0177476 100644 --- a/src/uscxml/Convenience.h +++ b/src/uscxml/Convenience.h @@ -49,7 +49,7 @@ inline bool isNumeric( const char* pszInput, int nNumberBase) { } inline bool iequals(const std::string& a, const std::string& b) { - // this impementation beats boost::iequals 2700ms vs 2100ms for test-performance.scxml + // this impementation beats boost::iequals 2700ms vs 2100ms for test-performance.scxml - we don't care for non-ascii yet unsigned int size = a.size(); if (b.size() != size) return false; @@ -59,6 +59,16 @@ inline bool iequals(const std::string& a, const std::string& b) { return true; } +inline bool equals(const std::string& a, const std::string& b) { + unsigned int size = a.size(); + if (b.size() != size) + return false; + for (unsigned int i = 0; i < size; ++i) + if (a[i] != b[i]) + return false; + return true; +} + // see http://www.cplusplus.com/forum/general/27544/ // Little-endian operating systems: diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 1314986..dfd9311 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -912,11 +912,11 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { // namelist if (HAS_ATTR(element, "namelist")) { if (_dataModel) { - std::vector<std::string> names = tokenizeIdRefs(ATTR(element, "namelist")); - for (int i = 0; i < names.size(); i++) { - Data namelistValue = _dataModel.getStringAsData(names[i]); - sendReq.namelist[names[i]] = namelistValue; - sendReq.data.compound[names[i]] = namelistValue; + std::list<std::string> names = tokenizeIdRefs(ATTR(element, "namelist")); + for (std::list<std::string>::const_iterator nameIter = names.begin(); nameIter != names.end(); nameIter++) { + Data namelistValue = _dataModel.getStringAsData(*nameIter); + sendReq.namelist[*nameIter] = namelistValue; + sendReq.data.compound[*nameIter] = namelistValue; } } else { LOG(ERROR) << "Namelist attribute at send requires datamodel to be defined"; @@ -1054,9 +1054,9 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) { // namelist if (HAS_ATTR(element, "namelist")) { - std::vector<std::string> names = tokenizeIdRefs(ATTR(element, "namelist")); - for (int i = 0; i < names.size(); i++) { - invokeReq.namelist[names[i]] = _dataModel.evalAsString(names[i]); + std::list<std::string> names = tokenizeIdRefs(ATTR(element, "namelist")); + for (std::list<std::string>::const_iterator nameIter = names.begin(); nameIter != names.end(); nameIter++) { + invokeReq.namelist[*nameIter] = _dataModel.evalAsString(*nameIter); } } @@ -1235,10 +1235,11 @@ bool InterpreterImpl::hasConditionMatch(const Arabica::DOM::Node<std::string>& c void InterpreterImpl::executeContent(const NodeList<std::string>& content, bool rethrow) { for (unsigned int i = 0; i < content.getLength(); i++) { - if (content.item(i).getNodeType() != Node_base::ELEMENT_NODE) + const Arabica::DOM::Node<std::string>& node = content.item(i); + if (node.getNodeType() != Node_base::ELEMENT_NODE) continue; try { - executeContent(content.item(i), true); + executeContent(node, true); } CATCH_AND_DISTRIBUTE2("Error when executing content", content.item(i)); } @@ -1246,10 +1247,11 @@ void InterpreterImpl::executeContent(const NodeList<std::string>& content, bool void InterpreterImpl::executeContent(const NodeSet<std::string>& content, bool rethrow) { for (unsigned int i = 0; i < content.size(); i++) { - if (content[i].getNodeType() != Node_base::ELEMENT_NODE) + const Arabica::DOM::Node<std::string>& node = content[i]; + if (node.getNodeType() != Node_base::ELEMENT_NODE) continue; try { - executeContent(content[i], true); + executeContent(node, true); } CATCH_AND_DISTRIBUTE2("Error when executing content", content[i]); } @@ -1598,9 +1600,9 @@ NEXT_ANCESTOR: return ancestor; } -Arabica::XPath::NodeSet<std::string> InterpreterImpl::getStates(const std::vector<std::string>& stateIds) { +Arabica::XPath::NodeSet<std::string> InterpreterImpl::getStates(const std::list<std::string>& stateIds) { Arabica::XPath::NodeSet<std::string> states; - std::vector<std::string>::const_iterator tokenIter = stateIds.begin(); + std::list<std::string>::const_iterator tokenIter = stateIds.begin(); while(tokenIter != stateIds.end()) { states.push_back(getState(*tokenIter)); tokenIter++; @@ -1717,18 +1719,32 @@ NodeSet<std::string> InterpreterImpl::getTargetStates(const Arabica::DOM::Node<s } std::string targetId = ((Arabica::DOM::Element<std::string>)transition).getAttribute("target"); - - std::vector<std::string> targetIds = InterpreterImpl::tokenizeIdRefs(ATTR(transition, "target")); - for (int i = 0; i < targetIds.size(); i++) { - Arabica::DOM::Node<std::string> state = getState(targetIds[i]); + std::list<std::string> targetIds = InterpreterImpl::tokenizeIdRefs(ATTR(transition, "target")); + for (std::list<std::string>::const_iterator targetIter = targetIds.begin(); targetIter != targetIds.end(); targetIter++) { + Arabica::DOM::Node<std::string> state = getState(*targetIter); assert(HAS_ATTR(state, "id")); targetStates.push_back(state); } return targetStates; } -std::vector<std::string> InterpreterImpl::tokenizeIdRefs(const std::string& idRefs) { - std::vector<std::string> ids; +std::list<std::string> InterpreterImpl::tokenizeIdRefs(const std::string& idRefs) { + std::list<std::string> ids; + + // appr. 3x faster than stringstream + size_t start = 0; + for (int i = 0; i < idRefs.size(); i++) { + if (isspace(idRefs[i])) { + if (i > 0 && start < i - 1) { + ids.push_back(idRefs.substr(start, i - start)); + } + while(isspace(idRefs[++i])); // skip whitespaces + start = i; + } else if (i + 1 == idRefs.size()) { + ids.push_back(idRefs.substr(start, i + 1 - start)); + } + } + #if 0 if (idRefs.length() > 0) { @@ -1740,11 +1756,13 @@ std::vector<std::string> InterpreterImpl::tokenizeIdRefs(const std::string& idRe } #endif +#if 0 // this version is somewhat fatser than the one above std::stringstream ss (idRefs); std::string item; while(ss >> item) ids.push_back(item); +#endif return ids; } diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index 5cc9053..d2e63e9 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -236,7 +236,7 @@ public: } Arabica::DOM::Node<std::string> getState(const std::string& stateId); - Arabica::XPath::NodeSet<std::string> getStates(const std::vector<std::string>& stateIds); + Arabica::XPath::NodeSet<std::string> getStates(const std::list<std::string>& stateIds); Arabica::DOM::Document<std::string>& getDocument() { return _document; @@ -286,7 +286,7 @@ public: static bool isCompound(const Arabica::DOM::Node<std::string>& state); static bool isDescendant(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2); - static std::vector<std::string> tokenizeIdRefs(const std::string& idRefs); + static std::list<std::string> tokenizeIdRefs(const std::string& idRefs); static std::string spaceNormalize(const std::string& text); bool isInEmbeddedDocument(const Arabica::DOM::Node<std::string>& node); @@ -540,7 +540,7 @@ public: Arabica::DOM::Node<std::string> getState(const std::string& stateId) { return _impl->getState(stateId); } - Arabica::XPath::NodeSet<std::string> getStates(const std::vector<std::string>& stateIds) { + Arabica::XPath::NodeSet<std::string> getStates(const std::list<std::string>& stateIds) { return _impl->getStates(stateIds); } @@ -628,7 +628,7 @@ public: return InterpreterImpl::isDescendant(s1, s2); } - static std::vector<std::string> tokenizeIdRefs(const std::string& idRefs) { + static std::list<std::string> tokenizeIdRefs(const std::string& idRefs) { return InterpreterImpl::tokenizeIdRefs(idRefs); } static std::string spaceNormalize(const std::string& text) { diff --git a/src/uscxml/Message.cpp b/src/uscxml/Message.cpp index c79e08a..26cf640 100644 --- a/src/uscxml/Message.cpp +++ b/src/uscxml/Message.cpp @@ -61,6 +61,64 @@ Blob::Blob(void* _data, size_t _size, const std::string& _mimeType, bool adopt) size = _size; } +#if 0 +// there 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)); } diff --git a/src/uscxml/Message.h b/src/uscxml/Message.h index 5de9a56..5f6703e 100644 --- a/src/uscxml/Message.h +++ b/src/uscxml/Message.h @@ -55,9 +55,7 @@ public: return uscxml::md5(data, size); } - std::string base64() { - return base64Encode((char* const)data, size); - } + std::string base64(); Blob* fromBase64(const std::string base64) { std::string decoded = base64Decode(base64); diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp index c9c00ef..772ad96 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.cpp +++ b/src/uscxml/interpreter/InterpreterDraft6.cpp @@ -467,9 +467,8 @@ bool InterpreterDraft6::isEnabledTransition(const Node<std::string>& transition, return false; } - std::vector<std::string> eventNames = tokenizeIdRefs(eventName); - - std::vector<std::string>::iterator eventIter = eventNames.begin(); + std::list<std::string> eventNames = tokenizeIdRefs(eventName); + std::list<std::string>::iterator eventIter = eventNames.begin(); while(eventIter != eventNames.end()) { if(nameMatch(*eventIter, event) && hasConditionMatch(transition)) { return true; diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index 947c0c2..9827b91 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -400,9 +400,10 @@ Data JSCDataModel::getValueAsData(const JSValueRef value) { if (!isNumeric(property.c_str(), 10)) isArray = false; propertySet.insert(property); - JSStringRelease(stringValue); + //JSStringRelease(stringValue); // JSPropertyNameArrayRelease does the job it seems free(buf); } + JSPropertyNameArrayRelease(properties); std::set<std::string>::iterator propIter = propertySet.begin(); while(propIter != propertySet.end()) { if (isArray) { @@ -537,14 +538,14 @@ void JSCDataModel::assign(const Element<std::string>& assignElem, throw Event("error.execution", Event::PLATFORM); // flags on attribute are ignored? - if (key.compare("_sessionid") == 0) - return; //throw Event("error.execution", Event::PLATFORM); + if (key.compare("_sessionid") == 0) // test 322 + throw Event("error.execution", Event::PLATFORM); if (key.compare("_name") == 0) - return; //throw Event("error.execution", Event::PLATFORM); - if (key.compare("_ioprocessors") == 0) - return; //throw Event("error.execution", Event::PLATFORM); + throw Event("error.execution", Event::PLATFORM); + if (key.compare("_ioprocessors") == 0) // test 326 + throw Event("error.execution", Event::PLATFORM); if (key.compare("_invokers") == 0) - return; //throw Event("error.execution", Event::PLATFORM); + throw Event("error.execution", Event::PLATFORM); if (HAS_ATTR(assignElem, "expr")) { evalAsValue(key + " = " + ATTR(assignElem, "expr")); diff --git a/src/uscxml/server/HTTPServer.cpp b/src/uscxml/server/HTTPServer.cpp index 358c819..6b24cd8 100644 --- a/src/uscxml/server/HTTPServer.cpp +++ b/src/uscxml/server/HTTPServer.cpp @@ -92,17 +92,24 @@ HTTPServer::HTTPServer(unsigned short port, unsigned short wsPort, SSLConfig* ss evhttp_set_allowed_methods(_http, allowedMethods); // allow all methods - if (_port > 0) + if (_port > 0) { _httpHandle = evhttp_bind_socket_with_handle(_http, INADDR_ANY, _port); - if (_httpHandle) - LOG(INFO) << "HTTP server listening on tcp/" << _port; + if (_httpHandle) { + LOG(INFO) << "HTTP server listening on tcp/" << _port; + } else { + LOG(ERROR) << "HTTP server cannot bind to tcp/" << _wsPort; + } + } _wsPort = wsPort; - if (_wsPort > 0) + if (_wsPort > 0) { _wsHandle = evws_bind_socket(_evws, _wsPort); - if (_wsHandle) - LOG(INFO) << "WebSocket server listening on tcp/" << _wsPort; - + if (_wsHandle) { + LOG(INFO) << "WebSocket server listening on tcp/" << _wsPort; + } else { + LOG(ERROR) << "WebSocket server cannot bind to tcp/" << _wsPort; + } + } #if (defined EVENT_SSL_FOUND && defined OPENSSL_FOUND && defined OPENSSL_HAS_ELIPTIC_CURVES) _sslHandle = NULL; _https = NULL; @@ -136,11 +143,15 @@ HTTPServer::HTTPServer(unsigned short port, unsigned short wsPort, SSLConfig* ss evhttp_set_bevcb(_https, sslBufferEventCallback, ctx); evhttp_set_gencb(_https, sslGeneralBufferEventCallback, NULL); - if (_sslPort > 0) + if (_sslPort > 0) { _sslHandle = evhttp_bind_socket_with_handle(_https, INADDR_ANY, _sslPort); - if (_sslHandle) - LOG(INFO) << "HTTPS server listening on tcp/" << _wsPort; + if (_sslHandle) { + LOG(INFO) << "HTTPS server listening on tcp/" << _wsPort; + } else { + LOG(ERROR) << "HTTPS server cannot bind to tcp/" << _wsPort; + } + } } #endif diff --git a/src/uscxml/util/Base64.h b/src/uscxml/util/Base64.h index 7dfc83c..a07d24e 100644 --- a/src/uscxml/util/Base64.h +++ b/src/uscxml/util/Base64.h @@ -36,9 +36,7 @@ extern "C" { } base64_decodestate; USCXML_API void base64_init_decodestate(base64_decodestate* state_in); - USCXML_API int base64_decode_value(char value_in); - USCXML_API int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in); /// ENDCODE @@ -54,11 +52,8 @@ extern "C" { } base64_encodestate; USCXML_API void base64_init_encodestate(base64_encodestate* state_in); - USCXML_API char base64_encode_value(char value_in); - USCXML_API int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); - USCXML_API int base64_encode_blockend(char* code_out, base64_encodestate* state_in); #ifdef __cplusplus diff --git a/src/uscxml/util/Base64.hpp b/src/uscxml/util/Base64.hpp index a106a12..e3cbe03 100644 --- a/src/uscxml/util/Base64.hpp +++ b/src/uscxml/util/Base64.hpp @@ -12,7 +12,7 @@ extern "C" { namespace uscxml { -USCXML_API inline std::string base64Encode(const char* data, unsigned int len) { +USCXML_API inline std::string base64Encode(const char* data, unsigned int len, bool withBlockEnd = true) { base64_encodestate* ctx = (base64_encodestate*)malloc(sizeof(base64_encodestate)); base64_init_encodestate(ctx); @@ -22,10 +22,15 @@ USCXML_API inline std::string base64Encode(const char* data, unsigned int len) { * be approximated with this formula: */ + int written = 0; char* out = (char*)malloc(len * 1.4 + 814); - base64_encode_block(data, len, out, ctx); + written += base64_encode_block(data, len, out, ctx); + if (withBlockEnd) { + written += base64_encode_blockend(out + written, ctx); + written--; // drop the newline + } + std::string result(out, written); free(ctx); - std::string result(out); free(out); return result; } @@ -42,5 +47,8 @@ USCXML_API inline std::string base64Decode(const std::string& data) { return result; } +// USCXML_API std::string base64Decode(const std::string& data); +// USCXML_API std::string base64Encode(const char* data, unsigned int len); + } #endif /* end of include guard: BASE64_H_5FKG12HF */ diff --git a/src/uscxml/util/MD5.c b/src/uscxml/util/MD5.c index 1bf05e4..f553c9c 100644 --- a/src/uscxml/util/MD5.c +++ b/src/uscxml/util/MD5.c @@ -52,6 +52,7 @@ */ #include "MD5.h" +#include <string.h> #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ #ifdef ARCH_IS_BIG_ENDIAN |