diff options
Diffstat (limited to 'src/uscxml/util')
-rw-r--r-- | src/uscxml/util/DOM.cpp | 45 | ||||
-rw-r--r-- | src/uscxml/util/DOM.h | 96 | ||||
-rw-r--r-- | src/uscxml/util/Predicates.cpp | 51 | ||||
-rw-r--r-- | src/uscxml/util/URL.cpp | 20 | ||||
-rw-r--r-- | src/uscxml/util/URL.h | 7 |
5 files changed, 149 insertions, 70 deletions
diff --git a/src/uscxml/util/DOM.cpp b/src/uscxml/util/DOM.cpp index ecf0960..7793fb5 100644 --- a/src/uscxml/util/DOM.cpp +++ b/src/uscxml/util/DOM.cpp @@ -52,7 +52,7 @@ std::ostream& operator<< (std::ostream& os, const DOMNode& node) { } std::ostream& operator<< (std::ostream& os, const X& xmlString) { - os << xmlString._localForm; + os << xmlString.str(); return os; } @@ -236,20 +236,13 @@ void DOMUtils::inPostFixOrder(const std::set<std::string>& elements, if (root == NULL) return; - DOMNodeList* children = root->getChildNodes(); - for (size_t i = 0; i < children->getLength(); i++) { - if (children->item(i)->getNodeType() != DOMNode::ELEMENT_NODE) - continue; - const DOMElement* childElem = dynamic_cast<const DOMElement*>(children->item(i)); + for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { if (!includeEmbeddedDoc && LOCALNAME(childElem) == "scxml") continue; inPostFixOrder(elements, childElem, includeEmbeddedDoc, nodes); } - for (size_t i = 0; i < children->getLength(); i++) { - if (children->item(i)->getNodeType() != DOMNode::ELEMENT_NODE) - continue; - const DOMElement* childElem = dynamic_cast<const DOMElement*>(children->item(i)); + for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { if (!includeEmbeddedDoc && TAGNAME(childElem) == XML_PREFIX(root).str() + "scxml") continue; @@ -278,14 +271,14 @@ void DOMUtils::inDocumentOrder(const std::set<std::string>& elements, nodes.push_back((DOMElement*)root); } - DOMNodeList* children = root->getChildNodes(); - for (size_t i = 0; i < children->getLength(); i++) { - if (children->item(i)->getNodeType() != DOMNode::ELEMENT_NODE) - continue; - const DOMElement* childElem = dynamic_cast<const DOMElement*>(children->item(i)); - if (!includeEmbeddedDoc && TAGNAME(childElem) == XML_PREFIX(root).str() + "scxml") - continue; - inDocumentOrder(elements, childElem, includeEmbeddedDoc, nodes); + /// @todo: item from getChildNodes is O(N)! + DOMElement* child = root->getFirstElementChild(); + while(child) { + if (includeEmbeddedDoc || TAGNAME(child) != XML_PREFIX(root).str() + "scxml") { + inDocumentOrder(elements, child, includeEmbeddedDoc, nodes); + } + + child = child->getNextElementSibling(); } } @@ -350,12 +343,7 @@ std::list<DOMElement*> DOMUtils::filterChildElements(const std::string& tagName, if (!node) return filteredChildElems; - DOMNodeList* children = node->getChildNodes(); - for (unsigned int i = 0; i < children->getLength(); i++) { - if (children->item(i)->getNodeType() != DOMNode::ELEMENT_NODE) - continue; - const DOMElement* childElem = dynamic_cast<const DOMElement*>(children->item(i)); - + for (auto childElem = node->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { // std::cerr << TAGNAME(childs.item(i)) << std::endl; if(iequals(TAGNAME(childElem), tagName)) { filteredChildElems.push_back((DOMElement*)childElem); @@ -391,12 +379,11 @@ std::list<DOMNode*> DOMUtils::filterChildType(const DOMNode::NodeType type, if (!node) return filteredChildTypes; - DOMNodeList* children = node->getChildNodes(); - for (unsigned int i = 0; i < children->getLength(); i++) { - if (children->item(i)->getNodeType() == type) - filteredChildTypes.push_back(children->item(i)); + for (auto child = node->getFirstChild(); child; child = child->getNextSibling()) { + if (child->getNodeType() == type) + filteredChildTypes.push_back(child); if (recurse) { - std::list<DOMNode*> nested = filterChildType(type, children->item(i), recurse); + std::list<DOMNode*> nested = filterChildType(type, child, recurse); filteredChildTypes.merge(nested); } diff --git a/src/uscxml/util/DOM.h b/src/uscxml/util/DOM.h index f259ea0..3ab27a3 100644 --- a/src/uscxml/util/DOM.h +++ b/src/uscxml/util/DOM.h @@ -117,17 +117,18 @@ protected: // create a prefix from a given element - useful for copying namespace information #define XML_PREFIX(element) X(element->getPrefix() ? X(element->getPrefix()).str() + ":" : "") +#if 1 class USCXML_API X { public : X(X const &other) { _localForm = other._localForm; - _otherForm = XERCESC_NS::XMLString::replicate(other._otherForm); + _unicodeForm = XERCESC_NS::XMLString::replicate(other._unicodeForm); _deallocOther = true; } void operator=(X const &other) { // did we maybe leak before? _localForm = other._localForm; - _otherForm = XERCESC_NS::XMLString::replicate(other._otherForm); + _unicodeForm = XERCESC_NS::XMLString::replicate(other._unicodeForm); _deallocOther = true; } @@ -138,39 +139,39 @@ public : _localForm = std::string(tmp); XERCESC_NS::XMLString::release(&tmp); } - _otherForm = NULL; + _unicodeForm = NULL; _deallocOther = false; } X(const std::string& fromTranscode) { // Call the private transcoding method _localForm = fromTranscode; - _otherForm = XERCESC_NS::XMLString::transcode(fromTranscode.c_str()); + _unicodeForm = XERCESC_NS::XMLString::transcode(fromTranscode.c_str()); _deallocOther = true; } X(const char* const fromTranscode) { // Call the private transcoding method _localForm = fromTranscode; - _otherForm = XERCESC_NS::XMLString::transcode(fromTranscode); + _unicodeForm = XERCESC_NS::XMLString::transcode(fromTranscode); _deallocOther = true; } X(char* fromTranscode) { // Call the private transcoding method _localForm = fromTranscode; - _otherForm = XERCESC_NS::XMLString::transcode(fromTranscode); + _unicodeForm = XERCESC_NS::XMLString::transcode(fromTranscode); _deallocOther = true; } X() { - _otherForm = NULL; + _unicodeForm = NULL; _deallocOther = false; } ~X() { if (_deallocOther) - XERCESC_NS::XMLString::release(&_otherForm); + XERCESC_NS::XMLString::release(&_unicodeForm); } const std::string& str() const { @@ -178,8 +179,8 @@ public : } operator const XMLCh* () { - assert(_otherForm != NULL); // constructor with XMLCh - return _otherForm; + assert(_unicodeForm != NULL); // constructor with XMLCh + return _unicodeForm; } operator bool () { @@ -196,9 +197,82 @@ protected: private: bool _deallocOther; std::string _localForm; - XMLCh* _otherForm; + XMLCh* _unicodeForm; }; + +#else +class USCXML_API X { +public : + X() { + } + + void operator=(X const &other) { + localForm = other.localForm; + if (unicodeForm != NULL) { + XERCESC_NS::XMLString::release(&unicodeForm); + } + unicodeForm = XERCESC_NS::XMLString::replicate(other.unicodeForm); + } + + X(X const &other) { + localForm = other.localForm; + unicodeForm = XERCESC_NS::XMLString::replicate(other.unicodeForm); + } + + X(const char* const toTranscode) { + if (toTranscode != NULL) { + localForm = toTranscode; + unicodeForm = XERCESC_NS::XMLString::transcode(toTranscode); + } + } + + X(const XMLCh* toTranscode) { + if (toTranscode != NULL) { + unicodeForm = XERCESC_NS::XMLString::replicate(toTranscode); + localForm = XERCESC_NS::XMLString::transcode(toTranscode); + } + } + + X(const std::string& toTranscode) { + localForm = toTranscode; + unicodeForm = XERCESC_NS::XMLString::transcode(toTranscode.c_str()); + } + + ~X() { + if (unicodeForm != NULL) { + XERCESC_NS::XMLString::release(&unicodeForm); + } + } + + operator XMLCh* () const { + return unicodeForm; + } + + operator const std::string& () { + return localForm; + } + + const std::string& str() const { + return localForm; + } + + const XMLCh* unicode() const { + return unicodeForm; + } + + +protected: + friend USCXML_API std::ostream& operator<< (std::ostream& os, const X& data); + +private: + XMLCh* unicodeForm = NULL; + std::string localForm; + +}; + +#endif + USCXML_API std::ostream& operator<< (std::ostream& os, const X& xmlString); USCXML_API std::ostream& operator<< (std::ostream& os, const XERCESC_NS::DOMNode& node); diff --git a/src/uscxml/util/Predicates.cpp b/src/uscxml/util/Predicates.cpp index 2f46d75..cd41089 100644 --- a/src/uscxml/util/Predicates.cpp +++ b/src/uscxml/util/Predicates.cpp @@ -27,11 +27,7 @@ using namespace XERCESC_NS; std::list<DOMElement*> getChildStates(const DOMElement* state, bool properOnly) { std::list<DOMElement*> children; - DOMNodeList* childElems = state->getChildNodes(); - for (size_t i = 0; i < childElems->getLength(); i++) { - if (childElems->item(i)->getNodeType() != DOMNode::ELEMENT_NODE) - continue; - DOMElement* childElem = dynamic_cast<DOMElement*>(childElems->item(i)); + for (auto childElem = state->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { if (isState(childElem, properOnly)) { children.push_back(childElem); } @@ -74,17 +70,23 @@ DOMElement* getSourceState(const DOMElement* transition) { #define VERBOSE_FIND_LCCA 0 DOMElement* findLCCA(const std::list<DOMElement*>& states) { - + std::list<DOMElement*> ancestors = getProperAncestors(states.front(), NULL); DOMElement* ancestor = NULL; +#if VERBOSE_FIND_LCCA + std::cout << "states: " << states.size() << std::endl; + std::cout << "front: " << DOMUtils::xPathForNode(states.front()) << std::endl; + std::cout << "ancestors: " << ancestors.size() << std::endl; +#endif + for (auto ancIter = ancestors.begin(); ancIter != ancestors.end(); ancIter++) { if (!isCompound(dynamic_cast<DOMElement*>(*ancIter))) continue; for (auto stateIter = states.begin(); stateIter != states.end(); stateIter++) { #if VERBOSE_FIND_LCCA - std::cerr << "Checking " << ATTR_CAST(states[j], "id") << " and " << ATTR_CAST(ancestors[i], "id") << std::endl; + std::cerr << "Checking " << ATTR_CAST(*stateIter, "id") << " and " << ATTR_CAST(*ancIter, "id") << std::endl; #endif if (!DOMUtils::isDescendant(*stateIter, *ancIter)) @@ -97,11 +99,11 @@ NEXT_ANCESTOR: } // take uppermost root as ancestor - if (!ancestor) + if (!ancestor && ancestors.size() > 0) ancestor = ancestors.back(); #if VERBOSE_FIND_LCCA - std::cerr << " -> " << ATTR_CAST(ancestor, "id") << " " << ancestor.getLocalName() << std::endl; + std::cerr << " -> " << ATTR_CAST(ancestor, "id") << " " << ancestor->getLocalName() << std::endl; #endif return ancestor; } @@ -118,7 +120,9 @@ NEXT_ANCESTOR: std::list<DOMElement*> getProperAncestors(const DOMElement* s1, const DOMElement* s2) { std::list<DOMElement*> ancestors; - if (isState(s1)) { + if (isState(s1, false)) { + // is it correct to also consider pseudo-states? + // gcc bug in findLCCA with test387, test388, test579, test580 otherwise DOMNode* node = (DOMNode*)s1; while((node = node->getParentNode())) { if (node->getNodeType() != DOMNode::ELEMENT_NODE) @@ -127,9 +131,10 @@ std::list<DOMElement*> getProperAncestors(const DOMElement* s1, const DOMElement const DOMElement* nodeElem = dynamic_cast<const DOMElement*>(node); if (!isState(nodeElem)) break; + if (!iequals(LOCALNAME(nodeElem), "parallel") && - !iequals(LOCALNAME(nodeElem), "state") && - !iequals(LOCALNAME(nodeElem), "scxml")) + !iequals(LOCALNAME(nodeElem), "state") && + !iequals(LOCALNAME(nodeElem), "scxml")) break; if (node == s2) break; @@ -143,10 +148,11 @@ std::list<DOMElement*> getExitSet(const DOMElement* transition, const DOMElement std::list<DOMElement*> statesToExit; if (HAS_ATTR(transition, "target")) { DOMElement* domain = getTransitionDomain(transition, root); - if (!domain) + if (domain == NULL) return statesToExit; - // std::cout << DOMUtils::xPathForNode(domain) << std::endl; +// std::cout << "transition: " << DOMUtils::xPathForNode(transition) << std::endl; +// std::cout << "domain: " << DOMUtils::xPathForNode(domain) << std::endl; std::set<std::string> elements; elements.insert(XML_PREFIX(transition).str() + "parallel"); @@ -157,16 +163,20 @@ std::list<DOMElement*> getExitSet(const DOMElement* transition, const DOMElement if (statesToExit.front() == domain) { statesToExit.pop_front(); // do not include domain itself } +// std::cout << "OK" << std::endl; + } return statesToExit; } bool conflicts(const DOMElement* t1, const DOMElement* t2, const DOMElement* root) { - return (DOMUtils::hasIntersection(getExitSet(t1, root), getExitSet(t2, root)) || - (getSourceState(t1) == getSourceState(t2)) || + return ( + (getSourceState(t1) == getSourceState(t2)) || (DOMUtils::isDescendant(getSourceState(t1), getSourceState(t2))) || - (DOMUtils::isDescendant(getSourceState(t2), getSourceState(t1)))); + (DOMUtils::isDescendant(getSourceState(t2), getSourceState(t1))) || + (DOMUtils::hasIntersection(getExitSet(t1, root), getExitSet(t2, root))) + ); } bool isState(const DOMElement* state, bool properOnly) { @@ -280,6 +290,7 @@ DOMElement* getTransitionDomain(const DOMElement* transition, const DOMElement* BREAK_LOOP: tStates.push_front(source); + return findLCCA(tStates); } @@ -359,11 +370,7 @@ std::list<DOMElement*> getInitialStates(const DOMElement* state, const DOMElemen // first child state std::list<DOMElement*> initStates; - DOMNodeList* children = state->getChildNodes(); - for (size_t i = 0; i < children->getLength(); i++) { - if (children->item(i)->getNodeType() != DOMNode::ELEMENT_NODE) - continue; - DOMElement* childElem = dynamic_cast<DOMElement*>(children->item(i)); + for (auto childElem = state->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { if (isState(childElem)) { initStates.push_back(childElem); return initStates; diff --git a/src/uscxml/util/URL.cpp b/src/uscxml/util/URL.cpp index a76c772..2e98fce 100644 --- a/src/uscxml/util/URL.cpp +++ b/src/uscxml/util/URL.cpp @@ -118,6 +118,8 @@ URLImpl::URLImpl(const std::string& url) : _orig(url), _handle(NULL), _isDownloa URLImpl::~URLImpl() { uriFreeUriMembersA(&_uri); + if (_handle != NULL) + curl_easy_cleanup(_handle); } URL URLImpl::resolve(URLImpl* relative, URLImpl* absolute) { @@ -590,7 +592,7 @@ void URLFetcher::fetchURL(URL& url) { char* header = (char*)malloc(paramIter->first.size() + strlen(value) + 3); sprintf(header,"%s: %s", paramIter->first.c_str(), value); headers = curl_slist_append(headers, header); - + free(header); // curl_free(key); // curl_free(value); paramIter++; @@ -598,11 +600,12 @@ void URLFetcher::fetchURL(URL& url) { // Disable "Expect: 100-continue" headers = curl_slist_append(headers, "Expect:"); + instance->_handlesToHeaders[handle] = headers; - (curlError = curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers)) == CURLE_OK || + (curlError = curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers)) == CURLE_OK || LOG(ERROR) << "Cannot headers for " << std::string(url) << ": " << curl_easy_strerror(curlError); - //curl_slist_free_all(headers); +// curl_slist_free_all(headers); } else if (url._impl->_requestType == URLRequestType::GET) { @@ -629,6 +632,10 @@ void URLFetcher::breakURL(URL& url) { curl_multi_remove_handle(instance->_multiHandle, handle); instance->_handlesToURLs.erase(handle); } + if (instance->_handlesToHeaders.find(handle) != instance->_handlesToHeaders.end()) { + curl_slist_free_all(instance->_handlesToHeaders[handle]); + instance->_handlesToHeaders.erase(handle); + } } void URLFetcher::start() { @@ -745,7 +752,6 @@ void URLFetcher::perform() { LOG(WARNING) << "curl_multi_remove_handle: " << curl_multi_strerror(err); } - _handlesToURLs.erase(msg->easy_handle); break; default: _handlesToURLs[msg->easy_handle]._impl->downloadFailed(msg->data.result); @@ -753,9 +759,13 @@ void URLFetcher::perform() { if (err != CURLM_OK) { LOG(WARNING) << "curl_multi_remove_handle: " << curl_multi_strerror(err); } + break; - _handlesToURLs.erase(msg->easy_handle); } + _handlesToURLs.erase(msg->easy_handle); + curl_slist_free_all(_handlesToHeaders[msg->easy_handle]); + _handlesToHeaders.erase(msg->easy_handle); + } else { LOG(ERROR) << "Curl reports info on unfinished download?!"; } diff --git a/src/uscxml/util/URL.h b/src/uscxml/util/URL.h index 8127892..2b5c9e0 100644 --- a/src/uscxml/util/URL.h +++ b/src/uscxml/util/URL.h @@ -165,7 +165,7 @@ protected: static void prepareException(ErrorEvent& exception, int errorCode, const std::string& origUri, UriParserStateA* parser); - CURL* _handle; + CURL* _handle = NULL; std::stringstream _rawInContent; std::stringstream _rawInHeader; std::map<std::string, std::string> _inHeaders; @@ -176,8 +176,8 @@ protected: std::string _statusCode; std::string _statusMsg; - bool _isDownloaded; - bool _hasFailed; + bool _isDownloaded = false; + bool _hasFailed = false; std::string _error; std::condition_variable_any _condVar; @@ -325,6 +325,7 @@ protected: bool _isStarted; std::map<CURL*, URL> _handlesToURLs; + std::map<CURL*, curl_slist*> _handlesToHeaders; CURLM* _multiHandle; char* _envProxy; }; |