diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/poco/XML/src | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/poco/XML/src')
71 files changed, 11004 insertions, 0 deletions
diff --git a/contrib/libs/poco/XML/src/AbstractContainerNode.cpp b/contrib/libs/poco/XML/src/AbstractContainerNode.cpp new file mode 100644 index 0000000000..52134ce09c --- /dev/null +++ b/contrib/libs/poco/XML/src/AbstractContainerNode.cpp @@ -0,0 +1,573 @@ +// +// AbstractContainerNode.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/AbstractContainerNode.h" +#include "Poco/DOM/Document.h" +#include "Poco/DOM/Element.h" +#include "Poco/DOM/Attr.h" +#include "Poco/DOM/DOMException.h" +#include "Poco/DOM/ElementsByTagNameList.h" +#include "Poco/DOM/AutoPtr.h" +#include "Poco/NumberParser.h" +#include "Poco/UnicodeConverter.h" + + +namespace Poco { +namespace XML { + + +const XMLString AbstractContainerNode::WILDCARD(toXMLString("*")); + + +AbstractContainerNode::AbstractContainerNode(Document* pOwnerDocument): + AbstractNode(pOwnerDocument), + _pFirstChild(0) +{ +} + + +AbstractContainerNode::AbstractContainerNode(Document* pOwnerDocument, const AbstractContainerNode& node): + AbstractNode(pOwnerDocument, node), + _pFirstChild(0) +{ +} + + +AbstractContainerNode::~AbstractContainerNode() +{ + AbstractNode* pChild = static_cast<AbstractNode*>(_pFirstChild); + while (pChild) + { + AbstractNode* pDelNode = pChild; + pChild = pChild->_pNext; + pDelNode->_pNext = 0; + pDelNode->_pParent = 0; + pDelNode->release(); + } +} + + +Node* AbstractContainerNode::firstChild() const +{ + return _pFirstChild; +} + + +Node* AbstractContainerNode::lastChild() const +{ + AbstractNode* pChild = _pFirstChild; + if (pChild) + { + while (pChild->_pNext) pChild = pChild->_pNext; + return pChild; + } + return 0; +} + + +Node* AbstractContainerNode::insertBefore(Node* newChild, Node* refChild) +{ + poco_check_ptr (newChild); + + if (static_cast<AbstractNode*>(newChild)->_pOwner != _pOwner && static_cast<AbstractNode*>(newChild)->_pOwner != this) + throw DOMException(DOMException::WRONG_DOCUMENT_ERR); + if (refChild && static_cast<AbstractNode*>(refChild)->_pParent != this) + throw DOMException(DOMException::NOT_FOUND_ERR); + if (newChild == refChild) + return newChild; + if (this == newChild) + throw DOMException(DOMException::HIERARCHY_REQUEST_ERR); + + AbstractNode* pFirst = 0; + AbstractNode* pLast = 0; + if (newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE) + { + AbstractContainerNode* pFrag = static_cast<AbstractContainerNode*>(newChild); + pFirst = pFrag->_pFirstChild; + pLast = pFirst; + if (pFirst) + { + while (pLast->_pNext) + { + pLast->_pParent = this; + pLast = pLast->_pNext; + } + pLast->_pParent = this; + } + pFrag->_pFirstChild = 0; + } + else + { + newChild->duplicate(); + AbstractContainerNode* pParent = static_cast<AbstractNode*>(newChild)->_pParent; + if (pParent) pParent->removeChild(newChild); + pFirst = static_cast<AbstractNode*>(newChild); + pLast = pFirst; + pFirst->_pParent = this; + } + if (_pFirstChild && pFirst) + { + AbstractNode* pCur = _pFirstChild; + if (pCur == refChild) + { + pLast->_pNext = _pFirstChild; + _pFirstChild = pFirst; + } + else + { + while (pCur && pCur->_pNext != refChild) pCur = pCur->_pNext; + if (pCur) + { + pLast->_pNext = pCur->_pNext; + pCur->_pNext = pFirst; + } + else throw DOMException(DOMException::NOT_FOUND_ERR); + } + } + else _pFirstChild = pFirst; + + if (events()) + { + while (pFirst && pFirst != pLast->_pNext) + { + pFirst->dispatchNodeInserted(); + pFirst->dispatchNodeInsertedIntoDocument(); + pFirst = pFirst->_pNext; + } + dispatchSubtreeModified(); + } + return newChild; +} + + +Node* AbstractContainerNode::replaceChild(Node* newChild, Node* oldChild) +{ + poco_check_ptr (newChild); + poco_check_ptr (oldChild); + + if (static_cast<AbstractNode*>(newChild)->_pOwner != _pOwner && static_cast<AbstractNode*>(newChild)->_pOwner != this) + throw DOMException(DOMException::WRONG_DOCUMENT_ERR); + if (static_cast<AbstractNode*>(oldChild)->_pParent != this) + throw DOMException(DOMException::NOT_FOUND_ERR); + if (newChild == oldChild) + return newChild; + if (this == newChild) + throw DOMException(DOMException::HIERARCHY_REQUEST_ERR); + + bool doEvents = events(); + if (newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE) + { + insertBefore(newChild, oldChild); + removeChild(oldChild); + } + else + { + AbstractContainerNode* pParent = static_cast<AbstractNode*>(newChild)->_pParent; + if (pParent) pParent->removeChild(newChild); + + if (oldChild == _pFirstChild) + { + if (doEvents) + { + _pFirstChild->dispatchNodeRemoved(); + _pFirstChild->dispatchNodeRemovedFromDocument(); + } + static_cast<AbstractNode*>(newChild)->_pNext = static_cast<AbstractNode*>(oldChild)->_pNext; + static_cast<AbstractNode*>(newChild)->_pParent = this; + _pFirstChild->_pNext = 0; + _pFirstChild->_pParent = 0; + _pFirstChild = static_cast<AbstractNode*>(newChild); + if (doEvents) + { + static_cast<AbstractNode*>(newChild)->dispatchNodeInserted(); + static_cast<AbstractNode*>(newChild)->dispatchNodeInsertedIntoDocument(); + } + } + else + { + AbstractNode* pCur = _pFirstChild; + while (pCur && pCur->_pNext != oldChild) pCur = pCur->_pNext; + if (pCur) + { + poco_assert_dbg (pCur->_pNext == oldChild); + + if (doEvents) + { + static_cast<AbstractNode*>(oldChild)->dispatchNodeRemoved(); + static_cast<AbstractNode*>(oldChild)->dispatchNodeRemovedFromDocument(); + } + static_cast<AbstractNode*>(newChild)->_pNext = static_cast<AbstractNode*>(oldChild)->_pNext; + static_cast<AbstractNode*>(newChild)->_pParent = this; + static_cast<AbstractNode*>(oldChild)->_pNext = 0; + static_cast<AbstractNode*>(oldChild)->_pParent = 0; + pCur->_pNext = static_cast<AbstractNode*>(newChild); + if (doEvents) + { + static_cast<AbstractNode*>(newChild)->dispatchNodeInserted(); + static_cast<AbstractNode*>(newChild)->dispatchNodeInsertedIntoDocument(); + } + } + else throw DOMException(DOMException::NOT_FOUND_ERR); + } + newChild->duplicate(); + oldChild->autoRelease(); + } + if (doEvents) dispatchSubtreeModified(); + return oldChild; +} + + +Node* AbstractContainerNode::removeChild(Node* oldChild) +{ + poco_check_ptr (oldChild); + + bool doEvents = events(); + if (oldChild == _pFirstChild) + { + if (doEvents) + { + static_cast<AbstractNode*>(oldChild)->dispatchNodeRemoved(); + static_cast<AbstractNode*>(oldChild)->dispatchNodeRemovedFromDocument(); + } + _pFirstChild = _pFirstChild->_pNext; + static_cast<AbstractNode*>(oldChild)->_pNext = 0; + static_cast<AbstractNode*>(oldChild)->_pParent = 0; + } + else + { + AbstractNode* pCur = _pFirstChild; + while (pCur && pCur->_pNext != oldChild) pCur = pCur->_pNext; + if (pCur) + { + if (doEvents) + { + static_cast<AbstractNode*>(oldChild)->dispatchNodeRemoved(); + static_cast<AbstractNode*>(oldChild)->dispatchNodeRemovedFromDocument(); + } + pCur->_pNext = pCur->_pNext->_pNext; + static_cast<AbstractNode*>(oldChild)->_pNext = 0; + static_cast<AbstractNode*>(oldChild)->_pParent = 0; + } + else throw DOMException(DOMException::NOT_FOUND_ERR); + } + oldChild->autoRelease(); + if (doEvents) dispatchSubtreeModified(); + return oldChild; +} + + +Node* AbstractContainerNode::appendChild(Node* newChild) +{ + return insertBefore(newChild, 0); +} + + +void AbstractContainerNode::dispatchNodeRemovedFromDocument() +{ + AbstractNode::dispatchNodeRemovedFromDocument(); + Node* pChild = firstChild(); + while (pChild) + { + static_cast<AbstractNode*>(pChild)->dispatchNodeRemovedFromDocument(); + pChild = pChild->nextSibling(); + } +} + + +void AbstractContainerNode::dispatchNodeInsertedIntoDocument() +{ + AbstractNode::dispatchNodeInsertedIntoDocument(); + Node* pChild = firstChild(); + while (pChild) + { + static_cast<AbstractNode*>(pChild)->dispatchNodeInsertedIntoDocument(); + pChild = pChild->nextSibling(); + } +} + + +bool AbstractContainerNode::hasChildNodes() const +{ + return _pFirstChild != 0; +} + + +bool AbstractContainerNode::hasAttributes() const +{ + return false; +} + + +Node* AbstractContainerNode::getNodeByPath(const XMLString& path) const +{ + XMLString::const_iterator it = path.begin(); + if (it != path.end() && *it == '/') + { + ++it; + if (it != path.end() && *it == '/') + { + ++it; + XMLString name; + while (it != path.end() && *it != '/' && *it != '@' && *it != '[') name += *it++; + if (it != path.end() && *it == '/') ++it; + if (name.empty()) name = WILDCARD; + AutoPtr<ElementsByTagNameList> pList = new ElementsByTagNameList(this, name); + unsigned long length = pList->length(); + for (unsigned long i = 0; i < length; i++) + { + XMLString::const_iterator beg = it; + const Node* pNode = findNode(beg, path.end(), pList->item(i), 0); + if (pNode) return const_cast<Node*>(pNode); + } + return 0; + } + } + return const_cast<Node*>(findNode(it, path.end(), this, 0)); +} + + +Node* AbstractContainerNode::getNodeByPathNS(const XMLString& path, const NSMap& nsMap) const +{ + XMLString::const_iterator it = path.begin(); + if (it != path.end() && *it == '/') + { + ++it; + if (it != path.end() && *it == '/') + { + ++it; + XMLString name; + while (it != path.end() && *it != '/' && *it != '@' && *it != '[') name += *it++; + if (it != path.end() && *it == '/') ++it; + XMLString namespaceURI; + XMLString localName; + bool nameOK = true; + if (name.empty()) + { + namespaceURI = WILDCARD; + localName = WILDCARD; + } + else + { + nameOK = nsMap.processName(name, namespaceURI, localName, false); + } + if (nameOK) + { + AutoPtr<ElementsByTagNameListNS> pList = new ElementsByTagNameListNS(this, namespaceURI, localName); + unsigned long length = pList->length(); + for (unsigned long i = 0; i < length; i++) + { + XMLString::const_iterator beg = it; + const Node* pNode = findNode(beg, path.end(), pList->item(i), &nsMap); + if (pNode) return const_cast<Node*>(pNode); + } + } + return 0; + } + } + return const_cast<Node*>(findNode(it, path.end(), this, &nsMap)); +} + + +const Node* AbstractContainerNode::findNode(XMLString::const_iterator& it, const XMLString::const_iterator& end, const Node* pNode, const NSMap* pNSMap) +{ + if (pNode && it != end) + { + if (*it == '[') + { + ++it; + if (it != end && *it == '@') + { + ++it; + XMLString attr; + while (it != end && *it != ']' && *it != '=') attr += *it++; + if (it != end && *it == '=') + { + ++it; + XMLString value; + if (it != end && *it == '\'') + { + ++it; + while (it != end && *it != '\'') value += *it++; + if (it != end) ++it; + } + else + { + while (it != end && *it != ']') value += *it++; + } + if (it != end) ++it; + return findNode(it, end, findElement(attr, value, pNode, pNSMap), pNSMap); + } + else + { + if (it != end) ++it; + return findAttribute(attr, pNode, pNSMap); + } + } + else + { + XMLString index; + while (it != end && *it != ']') index += *it++; + if (it != end) ++it; +#ifdef XML_UNICODE_WCHAR_T + std::string idx; + Poco::UnicodeConverter::convert(index, idx); + int i = Poco::NumberParser::parse(idx); +#else + int i = Poco::NumberParser::parse(index); +#endif + return findNode(it, end, findElement(i, pNode, pNSMap), pNSMap); + } + } + else + { + while (it != end && *it == '/') ++it; + XMLString key; + while (it != end && *it != '/' && *it != '[') key += *it++; + + XMLString::const_iterator itStart(it); + const Node* pFound = 0; + const Node* pElem = findElement(key, pNode->firstChild(), pNSMap); + while (!pFound && pElem) + { + pFound = findNode(it, end, pElem, pNSMap); + if (!pFound) pElem = findElement(key, pElem->nextSibling(), pNSMap); + it = itStart; + } + return pFound; + } + } + else return pNode; +} + + +const Node* AbstractContainerNode::findElement(const XMLString& name, const Node* pNode, const NSMap* pNSMap) +{ + while (pNode) + { + if (pNode->nodeType() == Node::ELEMENT_NODE && namesAreEqual(pNode, name, pNSMap)) + return pNode; + pNode = pNode->nextSibling(); + } + return 0; +} + + +const Node* AbstractContainerNode::findElement(int index, const Node* pNode, const NSMap* pNSMap) +{ + const Node* pRefNode = pNode; + if (index > 0) + { + pNode = pNode->nextSibling(); + while (pNode) + { + if (namesAreEqual(pNode, pRefNode, pNSMap)) + { + if (--index == 0) break; + } + pNode = pNode->nextSibling(); + } + } + return pNode; +} + + +const Node* AbstractContainerNode::findElement(const XMLString& attr, const XMLString& value, const Node* pNode, const NSMap* pNSMap) +{ + const Node* pRefNode = pNode; + const Element* pElem = dynamic_cast<const Element*>(pNode); + if (!(pElem && pElem->hasAttributeValue(attr, value, pNSMap))) + { + pNode = pNode->nextSibling(); + while (pNode) + { + if (namesAreEqual(pNode, pRefNode, pNSMap)) + { + pElem = dynamic_cast<const Element*>(pNode); + if (pElem && pElem->hasAttributeValue(attr, value, pNSMap)) break; + } + pNode = pNode->nextSibling(); + } + } + return pNode; +} + + +const Attr* AbstractContainerNode::findAttribute(const XMLString& name, const Node* pNode, const NSMap* pNSMap) +{ + const Attr* pResult(0); + const Element* pElem = dynamic_cast<const Element*>(pNode); + if (pElem) + { + if (pNSMap) + { + XMLString namespaceURI; + XMLString localName; + if (pNSMap->processName(name, namespaceURI, localName, true)) + { + pResult = pElem->getAttributeNodeNS(namespaceURI, localName); + } + } + else + { + pResult = pElem->getAttributeNode(name); + } + } + return pResult; +} + + +bool AbstractContainerNode::hasAttributeValue(const XMLString& name, const XMLString& value, const NSMap* pNSMap) const +{ + const Attr* pAttr = findAttribute(name, this, pNSMap); + return pAttr && pAttr->getValue() == value; +} + + +bool AbstractContainerNode::namesAreEqual(const Node* pNode1, const Node* pNode2, const NSMap* pNSMap) +{ + if (pNSMap) + { + return pNode1->localName() == pNode2->localName() && pNode1->namespaceURI() == pNode2->namespaceURI(); + } + else + { + return pNode1->nodeName() == pNode2->nodeName(); + } +} + + +bool AbstractContainerNode::namesAreEqual(const Node* pNode, const XMLString& name, const NSMap* pNSMap) +{ + if (pNSMap) + { + XMLString namespaceURI; + XMLString localName; + if (name == WILDCARD) + { + return true; + } + else if (pNSMap->processName(name, namespaceURI, localName, false)) + { + return (pNode->namespaceURI() == namespaceURI || namespaceURI == WILDCARD) && (pNode->localName() == localName || localName == WILDCARD); + } + else return false; + } + else + { + return pNode->nodeName() == name || name == WILDCARD; + } +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/AbstractNode.cpp b/contrib/libs/poco/XML/src/AbstractNode.cpp new file mode 100644 index 0000000000..1897d69324 --- /dev/null +++ b/contrib/libs/poco/XML/src/AbstractNode.cpp @@ -0,0 +1,367 @@ +// +// AbstractNode.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/AbstractNode.h" +#include "Poco/DOM/Document.h" +#include "Poco/DOM/ChildNodesList.h" +#include "Poco/DOM/EventDispatcher.h" +#include "Poco/DOM/DOMException.h" +#include "Poco/DOM/EventException.h" +#include "Poco/DOM/DOMImplementation.h" +#include "Poco/DOM/Attr.h" +#include "Poco/XML/Name.h" +#include "Poco/DOM/AutoPtr.h" + + +namespace Poco { +namespace XML { + + +const XMLString AbstractNode::NODE_NAME = toXMLString("#node"); +const XMLString AbstractNode::EMPTY_STRING; + + +AbstractNode::AbstractNode(Document* pOwnerDocument): + _pParent(0), + _pNext(0), + _pOwner(pOwnerDocument), + _pEventDispatcher(0) +{ +} + + +AbstractNode::AbstractNode(Document* pOwnerDocument, const AbstractNode& /*node*/): + _pParent(0), + _pNext(0), + _pOwner(pOwnerDocument), + _pEventDispatcher(0) +{ +} + + +AbstractNode::~AbstractNode() +{ + delete _pEventDispatcher; + if (_pNext) _pNext->release(); +} + + +void AbstractNode::autoRelease() +{ + _pOwner->autoReleasePool().add(this); +} + + +const XMLString& AbstractNode::nodeName() const +{ + return NODE_NAME; +} + + +const XMLString& AbstractNode::getNodeValue() const +{ + return EMPTY_STRING; +} + + +void AbstractNode::setNodeValue(const XMLString& /*value*/) +{ + throw DOMException(DOMException::NO_DATA_ALLOWED_ERR); +} + + +Node* AbstractNode::parentNode() const +{ + return _pParent; +} + + +NodeList* AbstractNode::childNodes() const +{ + return new ChildNodesList(this); +} + + +Node* AbstractNode::firstChild() const +{ + return 0; +} + + +Node* AbstractNode::lastChild() const +{ + return 0; +} + + +Node* AbstractNode::previousSibling() const +{ + if (_pParent) + { + AbstractNode* pSibling = _pParent->_pFirstChild; + while (pSibling) + { + if (pSibling->_pNext == this) return pSibling; + pSibling = pSibling->_pNext; + } + } + return 0; +} + + +Node* AbstractNode::nextSibling() const +{ + return _pNext; +} + + +NamedNodeMap* AbstractNode::attributes() const +{ + return 0; +} + + +Document* AbstractNode::ownerDocument() const +{ + return _pOwner; +} + + +Node* AbstractNode::insertBefore(Node* /*newChild*/, Node* /*refChild*/) +{ + throw DOMException(DOMException::HIERARCHY_REQUEST_ERR); +} + + +Node* AbstractNode::replaceChild(Node* /*newChild*/, Node* /*oldChild*/) +{ + throw DOMException(DOMException::HIERARCHY_REQUEST_ERR); +} + + +Node* AbstractNode::removeChild(Node* /*oldChild*/) +{ + throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR); +} + + +Node* AbstractNode::appendChild(Node* /*newChild*/) +{ + throw DOMException(DOMException::HIERARCHY_REQUEST_ERR); +} + + +bool AbstractNode::hasChildNodes() const +{ + return false; +} + + +Node* AbstractNode::cloneNode(bool deep) const +{ + return copyNode(deep, _pOwner); +} + + +void AbstractNode::normalize() +{ +} + + +bool AbstractNode::isSupported(const XMLString& feature, const XMLString& version) const +{ + return DOMImplementation::instance().hasFeature(feature, version); +} + + +const XMLString& AbstractNode::namespaceURI() const +{ + return EMPTY_STRING; +} + + +XMLString AbstractNode::prefix() const +{ + return EMPTY_STRING; +} + + +const XMLString& AbstractNode::localName() const +{ + return EMPTY_STRING; +} + + +bool AbstractNode::hasAttributes() const +{ + return false; +} + + +XMLString AbstractNode::innerText() const +{ + return EMPTY_STRING; +} + + +Node* AbstractNode::getNodeByPath(const XMLString& /*path*/) const +{ + return 0; +} + + +Node* AbstractNode::getNodeByPathNS(const XMLString& /*path*/, const NSMap& /*nsMap*/) const +{ + return 0; +} + + +void AbstractNode::addEventListener(const XMLString& type, EventListener* listener, bool useCapture) +{ + if (_pEventDispatcher) + _pEventDispatcher->removeEventListener(type, listener, useCapture); + else + _pEventDispatcher = new EventDispatcher; + + _pEventDispatcher->addEventListener(type, listener, useCapture); +} + + +void AbstractNode::removeEventListener(const XMLString& type, EventListener* listener, bool useCapture) +{ + if (_pEventDispatcher) + _pEventDispatcher->removeEventListener(type, listener, useCapture); +} + + +bool AbstractNode::dispatchEvent(Event* evt) +{ + if (eventsSuspended()) return true; + + if (evt->type().empty()) throw EventException(EventException::UNSPECIFIED_EVENT_TYPE_ERR); + + evt->setTarget(this); + evt->setCurrentPhase(Event::CAPTURING_PHASE); + + if (_pParent) _pParent->captureEvent(evt); + + if (_pEventDispatcher && !evt->isStopped()) + { + evt->setCurrentPhase(Event::AT_TARGET); + evt->setCurrentTarget(this); + _pEventDispatcher->dispatchEvent(evt); + } + if (!evt->isStopped() && evt->bubbles() && _pParent) + { + evt->setCurrentPhase(Event::BUBBLING_PHASE); + _pParent->bubbleEvent(evt); + } + + return evt->isCanceled(); +} + + +void AbstractNode::captureEvent(Event* evt) +{ + if (_pParent) + _pParent->captureEvent(evt); + + if (_pEventDispatcher && !evt->isStopped()) + { + evt->setCurrentTarget(this); + _pEventDispatcher->captureEvent(evt); + } +} + + +void AbstractNode::bubbleEvent(Event* evt) +{ + evt->setCurrentTarget(this); + if (_pEventDispatcher) + { + _pEventDispatcher->bubbleEvent(evt); + } + if (_pParent && !evt->isStopped()) + _pParent->bubbleEvent(evt); +} + + +void AbstractNode::dispatchSubtreeModified() +{ + AutoPtr<MutationEvent> pEvent = new MutationEvent(_pOwner, MutationEvent::DOMSubtreeModified, this, true, false, 0); + dispatchEvent(pEvent.get()); +} + + +void AbstractNode::dispatchNodeInserted() +{ + AutoPtr<MutationEvent> pEvent = new MutationEvent(_pOwner, MutationEvent::DOMNodeInserted, this, true, false, parentNode()); + dispatchEvent(pEvent.get()); +} + + +void AbstractNode::dispatchNodeRemoved() +{ + AutoPtr<MutationEvent> pEvent = new MutationEvent(_pOwner, MutationEvent::DOMNodeRemoved, this, true, false, parentNode()); + dispatchEvent(pEvent.get()); +} + + +void AbstractNode::dispatchNodeRemovedFromDocument() +{ + AutoPtr<MutationEvent> pEvent = new MutationEvent(_pOwner, MutationEvent::DOMNodeRemovedFromDocument, this, false, false, 0); + dispatchEvent(pEvent.get()); +} + + +void AbstractNode::dispatchNodeInsertedIntoDocument() +{ + AutoPtr<MutationEvent> pEvent = new MutationEvent(_pOwner, MutationEvent::DOMNodeInsertedIntoDocument, this, false, false, 0); + dispatchEvent(pEvent.get()); +} + + +void AbstractNode::dispatchAttrModified(Attr* pAttr, MutationEvent::AttrChangeType changeType, const XMLString& prevValue, const XMLString& newValue) +{ + AutoPtr<MutationEvent> pEvent = new MutationEvent(_pOwner, MutationEvent::DOMAttrModified, this, true, false, pAttr, prevValue, newValue, pAttr->name(), changeType); + dispatchEvent(pEvent.get()); +} + + +void AbstractNode::dispatchCharacterDataModified(const XMLString& prevValue, const XMLString& newValue) +{ + AutoPtr<MutationEvent> pEvent = new MutationEvent(_pOwner, MutationEvent::DOMCharacterDataModified, this, true, false, 0, prevValue, newValue, EMPTY_STRING, MutationEvent::MODIFICATION); + dispatchEvent(pEvent.get()); +} + + +bool AbstractNode::events() const +{ + return _pOwner->events(); +} + + +bool AbstractNode::eventsSuspended() const +{ + return _pOwner->eventsSuspended(); +} + + +void AbstractNode::setOwnerDocument(Document* pOwnerDocument) +{ + _pOwner = pOwnerDocument; +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/Attr.cpp b/contrib/libs/poco/XML/src/Attr.cpp new file mode 100644 index 0000000000..2cce620bfd --- /dev/null +++ b/contrib/libs/poco/XML/src/Attr.cpp @@ -0,0 +1,133 @@ +// +// Attr.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/Attr.h" +#include "Poco/DOM/Document.h" +#include "Poco/XML/NamePool.h" + + +namespace Poco { +namespace XML { + + +Attr::Attr(Document* pOwnerDocument, Element* /*pOwnerElement*/, const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname, const XMLString& value, bool specified): + AbstractNode(pOwnerDocument), + _name(pOwnerDocument->namePool().insert(qname, namespaceURI, localName)), + _value(value), + _specified(specified) +{ +} + + +Attr::Attr(Document* pOwnerDocument, const Attr& attr): + AbstractNode(pOwnerDocument, attr), + _name(pOwnerDocument->namePool().insert(attr._name)), + _value(attr._value), + _specified(attr._specified) +{ +} + + +Attr::~Attr() +{ +} + + +void Attr::setValue(const XMLString& value) +{ + XMLString oldValue = _value; + _value = value; + _specified = true; + if (_pParent && !_pOwner->eventsSuspended()) + _pParent->dispatchAttrModified(this, MutationEvent::MODIFICATION, oldValue, value); +} + + +Node* Attr::parentNode() const +{ + return 0; +} + + +Node* Attr::previousSibling() const +{ + if (_pParent) + { + Attr* pSibling = static_cast<Element*>(_pParent)->_pFirstAttr; + while (pSibling) + { + if (pSibling->_pNext == const_cast<Attr*>(this)) return pSibling; + pSibling = static_cast<Attr*>(pSibling->_pNext); + } + return pSibling; + } + return 0; +} + + +const XMLString& Attr::nodeName() const +{ + return _name.qname(); +} + + +const XMLString& Attr::getNodeValue() const +{ + return _value; +} + + +void Attr::setNodeValue(const XMLString& value) +{ + setValue(value); +} + + +unsigned short Attr::nodeType() const +{ + return ATTRIBUTE_NODE; +} + + +const XMLString& Attr::namespaceURI() const +{ + return _name.namespaceURI(); +} + + +XMLString Attr::prefix() const +{ + return _name.prefix(); +} + + +const XMLString& Attr::localName() const +{ + return _name.localName(); +} + + +XMLString Attr::innerText() const +{ + return nodeValue(); +} + + +Node* Attr::copyNode(bool /*deep*/, Document* pOwnerDocument) const +{ + return new Attr(pOwnerDocument, *this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/AttrMap.cpp b/contrib/libs/poco/XML/src/AttrMap.cpp new file mode 100644 index 0000000000..cb3a24133d --- /dev/null +++ b/contrib/libs/poco/XML/src/AttrMap.cpp @@ -0,0 +1,123 @@ +// +// AttrMap.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/AttrMap.h" +#include "Poco/DOM/Attr.h" +#include "Poco/DOM/Element.h" +#include "Poco/DOM/Document.h" +#include "Poco/DOM/DOMException.h" + + +namespace Poco { +namespace XML { + + +AttrMap::AttrMap(Element* pElement): + _pElement(pElement) +{ + poco_check_ptr (pElement); + + _pElement->duplicate(); +} + + +AttrMap::~AttrMap() +{ + _pElement->release(); +} + + +Node* AttrMap::getNamedItem(const XMLString& name) const +{ + return _pElement->getAttributeNode(name); +} + + +Node* AttrMap::setNamedItem(Node* arg) +{ + poco_check_ptr (arg); + + if (arg->nodeType() != Node::ATTRIBUTE_NODE) + throw DOMException(DOMException::HIERARCHY_REQUEST_ERR); + + return _pElement->setAttributeNode(static_cast<Attr*>(arg)); +} + + +Node* AttrMap::removeNamedItem(const XMLString& name) +{ + Attr* pAttr = _pElement->getAttributeNode(name); + if (pAttr) + return _pElement->removeAttributeNode(pAttr); + else + return 0; +} + + +Node* AttrMap::item(unsigned long index) const +{ + AbstractNode* pAttr = _pElement->_pFirstAttr; + while (index-- > 0 && pAttr) pAttr = static_cast<AbstractNode*>(pAttr->nextSibling()); + return pAttr; +} + + +unsigned long AttrMap::length() const +{ + unsigned long result = 0; + AbstractNode* pAttr = _pElement->_pFirstAttr; + while (pAttr) + { + pAttr = static_cast<AbstractNode*>(pAttr->nextSibling()); + ++result; + } + return result; +} + + +Node* AttrMap::getNamedItemNS(const XMLString& namespaceURI, const XMLString& localName) const +{ + return _pElement->getAttributeNodeNS(namespaceURI, localName); +} + + +Node* AttrMap::setNamedItemNS(Node* arg) +{ + poco_check_ptr (arg); + + if (arg->nodeType() != Node::ATTRIBUTE_NODE) + throw DOMException(DOMException::HIERARCHY_REQUEST_ERR); + + return _pElement->setAttributeNodeNS(static_cast<Attr*>(arg)); +} + + +Node* AttrMap::removeNamedItemNS(const XMLString& namespaceURI, const XMLString& localName) +{ + Attr* pAttr = _pElement->getAttributeNodeNS(namespaceURI, localName); + if (pAttr) + return _pElement->removeAttributeNode(pAttr); + else + return 0; +} + + +void AttrMap::autoRelease() +{ + _pElement->ownerDocument()->autoReleasePool().add(this); +} + + +} } // namespace Poco::XML + diff --git a/contrib/libs/poco/XML/src/Attributes.cpp b/contrib/libs/poco/XML/src/Attributes.cpp new file mode 100644 index 0000000000..f2baf9ff20 --- /dev/null +++ b/contrib/libs/poco/XML/src/Attributes.cpp @@ -0,0 +1,27 @@ +// +// Attributes.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/Attributes.h" + + +namespace Poco { +namespace XML { + + +Attributes::~Attributes() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/AttributesImpl.cpp b/contrib/libs/poco/XML/src/AttributesImpl.cpp new file mode 100644 index 0000000000..0a96c1854f --- /dev/null +++ b/contrib/libs/poco/XML/src/AttributesImpl.cpp @@ -0,0 +1,280 @@ +// +// AttributesImpl.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/AttributesImpl.h" + + +namespace Poco { +namespace XML { + + +AttributesImpl::AttributesImpl() +{ + _empty.specified = false; + _empty.type = XML_LIT("CDATA"); +} + + +AttributesImpl::AttributesImpl(const Attributes& attributes) +{ + _empty.specified = false; + _empty.type = XML_LIT("CDATA"); + setAttributes(attributes); +} + + +AttributesImpl::AttributesImpl(const AttributesImpl& attributes): + _attributes(attributes._attributes), + _empty(attributes._empty) +{ +} + + +AttributesImpl::~AttributesImpl() +{ +} + + +AttributesImpl& AttributesImpl::operator = (const AttributesImpl& attributes) +{ + if (&attributes != this) + { + _attributes = attributes._attributes; + } + return *this; +} + + +int AttributesImpl::getIndex(const XMLString& qname) const +{ + int i = 0; + AttributeVec::const_iterator it; + for (it = _attributes.begin(); it != _attributes.end(); ++it) + { + if (it->qname == qname) return i; + ++i; + } + return -1; +} + + +int AttributesImpl::getIndex(const XMLString& namespaceURI, const XMLString& localName) const +{ + int i = 0; + AttributeVec::const_iterator it; + for (it = _attributes.begin(); it != _attributes.end(); ++it) + { + if (it->namespaceURI == namespaceURI && it->localName == localName) return i; + ++i; + } + return -1; +} + + +void AttributesImpl::setValue(int i, const XMLString& value) +{ + poco_assert (0 <= i && i < static_cast<int>(_attributes.size())); + _attributes[i].value = value; + _attributes[i].specified = true; +} + + +void AttributesImpl::setValue(const XMLString& qname, const XMLString& value) +{ + Attribute* pAttr = find(qname); + if (pAttr) + { + pAttr->value = value; + pAttr->specified = true; + } +} + + +void AttributesImpl::setValue(const XMLString& namespaceURI, const XMLString& localName, const XMLString& value) +{ + Attribute* pAttr = find(namespaceURI, localName); + if (pAttr) + { + pAttr->value = value; + pAttr->specified = true; + } +} + + +void AttributesImpl::setAttributes(const Attributes& attributes) +{ + if (&attributes != this) + { + int count = attributes.getLength(); + _attributes.clear(); + _attributes.reserve(count); + for (int i = 0; i < count; i++) + { + addAttribute(attributes.getURI(i), attributes.getLocalName(i), attributes.getQName(i), attributes.getType(i), attributes.getValue(i)); + } + } +} + + +void AttributesImpl::setAttribute(int i, const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname, const XMLString& type, const XMLString& value) +{ + poco_assert (0 <= i && i < static_cast<int>(_attributes.size())); + _attributes[i].namespaceURI = namespaceURI; + _attributes[i].localName = localName; + _attributes[i].qname = qname; + _attributes[i].type = type; + _attributes[i].value = value; + _attributes[i].specified = true; +} + + +void AttributesImpl::addAttribute(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname, const XMLString& type, const XMLString& value) +{ + AttributeVec::iterator it = _attributes.insert(_attributes.end(), Attribute()); + it->namespaceURI = namespaceURI; + it->localName = localName; + it->qname = qname; + it->value = value; + it->type = type; + it->specified = true; +} + + +void AttributesImpl::addAttribute(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname, const XMLString& type, const XMLString& value, bool specified) +{ + AttributeVec::iterator it = _attributes.insert(_attributes.end(), Attribute()); + it->namespaceURI = namespaceURI; + it->localName = localName; + it->qname = qname; + it->value = value; + it->type = type; + it->specified = specified; +} + + +void AttributesImpl::addAttribute(const XMLChar* namespaceURI, const XMLChar* localName, const XMLChar* qname, const XMLChar* type, const XMLChar* value, bool specified) +{ + AttributeVec::iterator it = _attributes.insert(_attributes.end(), Attribute()); + it->namespaceURI = namespaceURI; + it->localName = localName; + it->qname = qname; + it->value = value; + it->type = type; + it->specified = specified; +} + + +void AttributesImpl::removeAttribute(int i) +{ + int cur = 0; + for (AttributeVec::iterator it = _attributes.begin(); it != _attributes.end(); ++it, ++cur) + { + if (cur == i) + { + _attributes.erase(it); + break; + } + } +} + + +void AttributesImpl::removeAttribute(const XMLString& qname) +{ + for (AttributeVec::iterator it = _attributes.begin(); it != _attributes.end(); ++it) + { + if (it->qname == qname) + { + _attributes.erase(it); + break; + } + } +} + + +void AttributesImpl::removeAttribute(const XMLString& namespaceURI, const XMLString& localName) +{ + for (AttributeVec::iterator it = _attributes.begin(); it != _attributes.end(); ++it) + { + if (it->namespaceURI == namespaceURI && it->localName == localName) + { + _attributes.erase(it); + break; + } + } +} + + +void AttributesImpl::clear() +{ + _attributes.clear(); +} + + +void AttributesImpl::reserve(std::size_t capacity) +{ + _attributes.reserve(capacity); +} + + +void AttributesImpl::setLocalName(int i, const XMLString& localName) +{ + poco_assert (0 <= i && i < static_cast<int>(_attributes.size())); + _attributes[i].localName = localName; +} + + +void AttributesImpl::setQName(int i, const XMLString& qname) +{ + poco_assert (0 <= i && i < static_cast<int>(_attributes.size())); + _attributes[i].qname = qname; +} + + +void AttributesImpl::setType(int i, const XMLString& type) +{ + poco_assert (0 <= i && i < static_cast<int>(_attributes.size())); + _attributes[i].type = type; +} + + +void AttributesImpl::setURI(int i, const XMLString& namespaceURI) +{ + poco_assert (0 <= i && i < static_cast<int>(_attributes.size())); + _attributes[i].namespaceURI = namespaceURI; +} + + +AttributesImpl::Attribute* AttributesImpl::find(const XMLString& qname) const +{ + for (AttributeVec::const_iterator it = _attributes.begin(); it != _attributes.end(); ++it) + { + if (it->qname == qname) + return const_cast<Attribute*>(&(*it)); + } + return 0; +} + + +AttributesImpl::Attribute* AttributesImpl::find(const XMLString& namespaceURI, const XMLString& localName) const +{ + for (AttributeVec::const_iterator it = _attributes.begin(); it != _attributes.end(); ++it) + { + if (it->namespaceURI == namespaceURI && it->localName == localName) + return const_cast<Attribute*>(&(*it)); + } + return 0; +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/CDATASection.cpp b/contrib/libs/poco/XML/src/CDATASection.cpp new file mode 100644 index 0000000000..478b590a07 --- /dev/null +++ b/contrib/libs/poco/XML/src/CDATASection.cpp @@ -0,0 +1,74 @@ +// +// CDATASection.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/CDATASection.h" +#include "Poco/DOM/Document.h" +#include "Poco/DOM/DOMException.h" + + +namespace Poco { +namespace XML { + + +const XMLString CDATASection::NODE_NAME = toXMLString("#cdata-section"); + + +CDATASection::CDATASection(Document* pOwnerDocument, const XMLString& data): + Text(pOwnerDocument, data) +{ +} + + +CDATASection::CDATASection(Document* pOwnerDocument, const CDATASection& sec): + Text(pOwnerDocument, sec) +{ +} + + +CDATASection::~CDATASection() +{ +} + + +Text* CDATASection::splitText(unsigned long offset) +{ + Node* pParent = parentNode(); + if (!pParent) throw DOMException(DOMException::HIERARCHY_REQUEST_ERR); + int n = length() - offset; + Text* pNew = ownerDocument()->createCDATASection(substringData(offset, n)); + deleteData(offset, n); + pParent->insertBefore(pNew, nextSibling())->release(); + return pNew; +} + + +const XMLString& CDATASection::nodeName() const +{ + return NODE_NAME; +} + + +unsigned short CDATASection::nodeType() const +{ + return Node::CDATA_SECTION_NODE; +} + + +Node* CDATASection::copyNode(bool /*deep*/, Document* pOwnerDocument) const +{ + return new CDATASection(pOwnerDocument, *this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/CharacterData.cpp b/contrib/libs/poco/XML/src/CharacterData.cpp new file mode 100644 index 0000000000..f8a3ec324d --- /dev/null +++ b/contrib/libs/poco/XML/src/CharacterData.cpp @@ -0,0 +1,152 @@ +// +// CharacterData.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/CharacterData.h" +#include "Poco/DOM/DOMException.h" +#include "Poco/String.h" + + +namespace Poco { +namespace XML { + + +CharacterData::CharacterData(Document* pOwnerDocument, const XMLString& data): + AbstractNode(pOwnerDocument), + _data(data) +{ +} + + +CharacterData::CharacterData(Document* pOwnerDocument, const CharacterData& data): + AbstractNode(pOwnerDocument, data), + _data(data._data) +{ +} + + +CharacterData::~CharacterData() +{ +} + + +void CharacterData::setData(const XMLString& data) +{ + if (events()) + { + XMLString oldData = _data; + _data = data; + dispatchCharacterDataModified(oldData, _data); + } + else + { + _data = data; + } +} + + +XMLString CharacterData::substringData(unsigned long offset, unsigned long count) const +{ + if (offset >= _data.length()) + throw DOMException(DOMException::INDEX_SIZE_ERR); + + return _data.substr(offset, count); +} + + +void CharacterData::appendData(const XMLString& arg) +{ + if (events()) + { + XMLString oldData = _data; + _data.append(arg); + dispatchCharacterDataModified(oldData, _data); + } + else + { + _data.append(arg); + } +} + + +void CharacterData::insertData(unsigned long offset, const XMLString& arg) +{ + if (offset > _data.length()) + throw DOMException(DOMException::INDEX_SIZE_ERR); + + if (events()) + { + XMLString oldData = _data; + _data.insert(offset, arg); + dispatchCharacterDataModified(oldData, _data); + } + else + { + _data.insert(offset, arg); + } +} + + +void CharacterData::deleteData(unsigned long offset, unsigned long count) +{ + if (offset >= _data.length()) + throw DOMException(DOMException::INDEX_SIZE_ERR); + + if (events()) + { + XMLString oldData = _data; + _data.replace(offset, count, EMPTY_STRING); + dispatchCharacterDataModified(oldData, _data); + } + else + _data.replace(offset, count, EMPTY_STRING); +} + + +void CharacterData::replaceData(unsigned long offset, unsigned long count, const XMLString& arg) +{ + if (offset >= _data.length()) + throw DOMException(DOMException::INDEX_SIZE_ERR); + + if (events()) + { + XMLString oldData = _data; + _data.replace(offset, count, arg); + dispatchCharacterDataModified(oldData, _data); + } + else + { + _data.replace(offset, count, arg); + } +} + + +const XMLString& CharacterData::getNodeValue() const +{ + return _data; +} + + +void CharacterData::setNodeValue(const XMLString& value) +{ + setData(value); +} + + +XMLString CharacterData::trimmedData() const +{ + return Poco::trim(_data); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/ChildNodesList.cpp b/contrib/libs/poco/XML/src/ChildNodesList.cpp new file mode 100644 index 0000000000..aeacaf15ad --- /dev/null +++ b/contrib/libs/poco/XML/src/ChildNodesList.cpp @@ -0,0 +1,70 @@ +// +// ChildNodesList.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/ChildNodesList.h" +#include "Poco/DOM/Node.h" +#include "Poco/DOM/Document.h" + + +namespace Poco { +namespace XML { + + +ChildNodesList::ChildNodesList(const Node* pParent): + _pParent(pParent) +{ + poco_check_ptr (pParent); + + _pParent->duplicate(); +} + + +ChildNodesList::~ChildNodesList() +{ + _pParent->release(); +} + + +Node* ChildNodesList::item(unsigned long index) const +{ + unsigned long n = 0; + Node* pCur = _pParent->firstChild(); + while (pCur && n++ < index) + { + pCur = pCur->nextSibling(); + } + return pCur; +} + + +unsigned long ChildNodesList::length() const +{ + unsigned long n = 0; + Node* pCur = _pParent->firstChild(); + while (pCur) + { + ++n; + pCur = pCur->nextSibling(); + } + return n; +} + + +void ChildNodesList::autoRelease() +{ + _pParent->ownerDocument()->autoReleasePool().add(this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/Comment.cpp b/contrib/libs/poco/XML/src/Comment.cpp new file mode 100644 index 0000000000..20421cabca --- /dev/null +++ b/contrib/libs/poco/XML/src/Comment.cpp @@ -0,0 +1,60 @@ +// +// Comment.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/Comment.h" + + +namespace Poco { +namespace XML { + + +const XMLString Comment::NODE_NAME = toXMLString("#comment"); + + +Comment::Comment(Document* pOwnerDocument, const XMLString& data): + CharacterData(pOwnerDocument, data) +{ +} + + +Comment::Comment(Document* pOwnerDocument, const Comment& comment): + CharacterData(pOwnerDocument, comment) +{ +} + + +Comment::~Comment() +{ +} + + +const XMLString& Comment::nodeName() const +{ + return NODE_NAME; +} + + +unsigned short Comment::nodeType() const +{ + return Node::COMMENT_NODE; +} + + +Node* Comment::copyNode(bool /*deep*/, Document* pOwnerDocument) const +{ + return new Comment(pOwnerDocument, *this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/ContentHandler.cpp b/contrib/libs/poco/XML/src/ContentHandler.cpp new file mode 100644 index 0000000000..03177d11e7 --- /dev/null +++ b/contrib/libs/poco/XML/src/ContentHandler.cpp @@ -0,0 +1,27 @@ +// +// ContentHandler.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/ContentHandler.h" + + +namespace Poco { +namespace XML { + + +ContentHandler::~ContentHandler() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/DOMBuilder.cpp b/contrib/libs/poco/XML/src/DOMBuilder.cpp new file mode 100644 index 0000000000..862d473950 --- /dev/null +++ b/contrib/libs/poco/XML/src/DOMBuilder.cpp @@ -0,0 +1,312 @@ +// +// DOMBuilder.cpp +// +// Library: XML +// Package: DOM +// Module: DOMBuilder +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/DOMBuilder.h" +#include "Poco/DOM/Document.h" +#include "Poco/DOM/DocumentType.h" +#include "Poco/DOM/CharacterData.h" +#include "Poco/DOM/Text.h" +#include "Poco/DOM/Comment.h" +#include "Poco/DOM/CDATASection.h" +#include "Poco/DOM/Element.h" +#include "Poco/DOM/Attr.h" +#include "Poco/DOM/Entity.h" +#include "Poco/DOM/EntityReference.h" +#include "Poco/DOM/Notation.h" +#include "Poco/DOM/ProcessingInstruction.h" +#include "Poco/DOM/AutoPtr.h" +#include "Poco/SAX/XMLReader.h" +#include "Poco/SAX/AttributesImpl.h" + + +namespace Poco { +namespace XML { + + +const XMLString DOMBuilder::EMPTY_STRING; + + +DOMBuilder::DOMBuilder(XMLReader& xmlReader, NamePool* pNamePool): + _xmlReader(xmlReader), + _pNamePool(pNamePool), + _pDocument(0), + _pParent(0), + _pPrevious(0), + _inCDATA(false), + _namespaces(true) +{ + _xmlReader.setContentHandler(this); + _xmlReader.setDTDHandler(this); + _xmlReader.setProperty(XMLReader::PROPERTY_LEXICAL_HANDLER, static_cast<LexicalHandler*>(this)); + + if (_pNamePool) _pNamePool->duplicate(); +} + + +DOMBuilder::~DOMBuilder() +{ + if (_pNamePool) _pNamePool->release(); +} + + +Document* DOMBuilder::parse(const XMLString& uri) +{ + setupParse(); + _pDocument->suspendEvents(); + try + { + _xmlReader.parse(uri); + } + catch (...) + { + _pDocument->release(); + _pDocument = 0; + _pParent = 0; + _pPrevious = 0; + throw; + } + _pDocument->resumeEvents(); + _pDocument->collectGarbage(); + return _pDocument; +} + + +Document* DOMBuilder::parse(InputSource* pInputSource) +{ + setupParse(); + _pDocument->suspendEvents(); + try + { + _xmlReader.parse(pInputSource); + } + catch (...) + { + _pDocument->release(); + _pDocument = 0; + _pParent = 0; + _pPrevious = 0; + throw; + } + _pDocument->resumeEvents(); + _pDocument->collectGarbage(); + return _pDocument; +} + + +Document* DOMBuilder::parseMemoryNP(const char* xml, std::size_t size) +{ + setupParse(); + _pDocument->suspendEvents(); + try + { + _xmlReader.parseMemoryNP(xml, size); + } + catch (...) + { + _pDocument->release(); + _pDocument = 0; + _pParent = 0; + _pPrevious = 0; + throw; + } + _pDocument->resumeEvents(); + _pDocument->collectGarbage(); + return _pDocument; +} + + +void DOMBuilder::setupParse() +{ + _pDocument = new Document(_pNamePool); + _pParent = _pDocument; + _pPrevious = 0; + _inCDATA = false; + _namespaces = _xmlReader.getFeature(XMLReader::FEATURE_NAMESPACES); +} + + +inline void DOMBuilder::appendNode(AbstractNode* pNode) +{ + if (_pPrevious && _pPrevious != _pParent) + { + _pPrevious->_pNext = pNode; + pNode->_pParent = _pParent; + pNode->duplicate(); + } + else _pParent->appendChild(pNode); + _pPrevious = pNode; +} + + +void DOMBuilder::notationDecl(const XMLString& name, const XMLString* publicId, const XMLString* systemId) +{ + DocumentType* pDoctype = _pDocument->getDoctype(); + if (pDoctype) + { + AutoPtr<Notation> pNotation = _pDocument->createNotation(name, (publicId ? *publicId : EMPTY_STRING), (systemId ? *systemId : EMPTY_STRING)); + pDoctype->appendChild(pNotation); + } +} + + +void DOMBuilder::unparsedEntityDecl(const XMLString& name, const XMLString* publicId, const XMLString& systemId, const XMLString& notationName) +{ + DocumentType* pDoctype = _pDocument->getDoctype(); + if (pDoctype) + { + AutoPtr<Entity> pEntity = _pDocument->createEntity(name, publicId ? *publicId : EMPTY_STRING, systemId, notationName); + pDoctype->appendChild(pEntity); + } +} + + +void DOMBuilder::setDocumentLocator(const Locator* /*loc*/) +{ +} + + +void DOMBuilder::startDocument() +{ +} + + +void DOMBuilder::endDocument() +{ +} + + +void DOMBuilder::startElement(const XMLString& uri, const XMLString& localName, const XMLString& qname, const Attributes& attributes) +{ + AutoPtr<Element> pElem = _namespaces ? _pDocument->createElementNS(uri, qname.empty() ? localName : qname) : _pDocument->createElement(qname); + + const AttributesImpl& attrs = dynamic_cast<const AttributesImpl&>(attributes); + Attr* pPrevAttr = 0; + for (AttributesImpl::iterator it = attrs.begin(); it != attrs.end(); ++it) + { + AutoPtr<Attr> pAttr = new Attr(_pDocument, 0, it->namespaceURI, it->localName, it->qname, it->value, it->specified); + pPrevAttr = pElem->addAttributeNodeNP(pPrevAttr, pAttr); + } + appendNode(pElem); + _pParent = pElem; +} + + +void DOMBuilder::endElement(const XMLString& /*uri*/, const XMLString& /*localName*/, const XMLString& /*qname*/) +{ + _pPrevious = _pParent; + _pParent = static_cast<AbstractContainerNode*>(_pParent->parentNode()); +} + + +void DOMBuilder::characters(const XMLChar ch[], int start, int length) +{ + if (_inCDATA) + { + if (_pPrevious && _pPrevious->nodeType() == Node::CDATA_SECTION_NODE) + { + static_cast<CDATASection*>(_pPrevious)->appendData(XMLString(ch + start, length)); + } + else + { + AutoPtr<CDATASection> pCDATA = _pDocument->createCDATASection(XMLString(ch + start, length)); + appendNode(pCDATA); + } + } + else + { + if (_pPrevious && _pPrevious->nodeType() == Node::TEXT_NODE) + { + static_cast<Text*>(_pPrevious)->appendData(XMLString(ch + start, length)); + } + else + { + AutoPtr<Text> pText = _pDocument->createTextNode(XMLString(ch + start, length)); + appendNode(pText); + } + } +} + + +void DOMBuilder::ignorableWhitespace(const XMLChar ch[], int start, int length) +{ + characters(ch, start, length); +} + + +void DOMBuilder::processingInstruction(const XMLString& target, const XMLString& data) +{ + AutoPtr<ProcessingInstruction> pPI = _pDocument->createProcessingInstruction(target, data); + appendNode(pPI); +} + + +void DOMBuilder::startPrefixMapping(const XMLString& /*prefix*/, const XMLString& /*uri*/) +{ +} + + +void DOMBuilder::endPrefixMapping(const XMLString& /*prefix*/) +{ +} + + +void DOMBuilder::skippedEntity(const XMLString& name) +{ + AutoPtr<EntityReference> pER = _pDocument->createEntityReference(name); + appendNode(pER); +} + + +void DOMBuilder::startDTD(const XMLString& name, const XMLString& publicId, const XMLString& systemId) +{ + AutoPtr<DocumentType> pDoctype = new DocumentType(_pDocument, name, publicId, systemId); + _pDocument->setDoctype(pDoctype); +} + + +void DOMBuilder::endDTD() +{ +} + + +void DOMBuilder::startEntity(const XMLString& /*name*/) +{ +} + + +void DOMBuilder::endEntity(const XMLString& /*name*/) +{ +} + + +void DOMBuilder::startCDATA() +{ + _inCDATA = true; +} + + +void DOMBuilder::endCDATA() +{ + _inCDATA = false; +} + + +void DOMBuilder::comment(const XMLChar ch[], int start, int length) +{ + AutoPtr<Comment> pComment = _pDocument->createComment(XMLString(ch + start, length)); + appendNode(pComment); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/DOMException.cpp b/contrib/libs/poco/XML/src/DOMException.cpp new file mode 100644 index 0000000000..546a1e2aae --- /dev/null +++ b/contrib/libs/poco/XML/src/DOMException.cpp @@ -0,0 +1,107 @@ +// +// DOMException.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/DOMException.h" +#include <typeinfo> + + +namespace Poco { +namespace XML { + + +const std::string DOMException::MESSAGES[_NUMBER_OF_MESSAGES] = +{ + "Invalid DOM exception code", + "Index or size is negative or greater than allowed value", + "The specified range of text does not fit into a DOMString", + "A node is inserted somewhere it doesn't belong", + "A node is used in a different document than the one that created it", + "An invalid character is specified", + "Data is specified for a node which does not support data", + "An attempt is made to modify an object where modifications are not allowed", + "An attempt was made to reference a node in a context where it does not exist", + "The implementation does not support the type of object requested", + "An attempt is made to add an attribute that is already in use elsewhere", + "A parameter or an operation is not supported by the underlying object", + "An invalid or illegal string is specified", + "An attempt is made to modify the type of the underlying object", + "An attempt is made to create or change an object in a way which is incorrect with regard to namespaces", + "An attempt is made to use an object that is not, or is no longer, usable" +}; + + +DOMException::DOMException(unsigned short code): + XMLException(message(code)), + _code(code) +{ +} + + +DOMException::DOMException(const DOMException& exc): + XMLException(exc), + _code(exc._code) +{ +} + + +DOMException::~DOMException() noexcept +{ +} + + +DOMException& DOMException::operator = (const DOMException& exc) +{ + if (&exc != this) + { + XMLException::operator = (exc); + _code = exc._code; + } + return *this; +} + + +const char* DOMException::name() const noexcept +{ + return "DOMException"; +} + + +const char* DOMException::className() const noexcept +{ + return typeid(*this).name(); +} + + +Poco::Exception* DOMException::clone() const +{ + return new DOMException(*this); +} + + +void DOMException::rethrow() const +{ + throw *this; +} + + +const std::string& DOMException::message(unsigned short code) +{ + if (code >= 1 && code < _NUMBER_OF_MESSAGES) + return MESSAGES[code]; + else + return MESSAGES[0]; +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/DOMImplementation.cpp b/contrib/libs/poco/XML/src/DOMImplementation.cpp new file mode 100644 index 0000000000..b6a138d67e --- /dev/null +++ b/contrib/libs/poco/XML/src/DOMImplementation.cpp @@ -0,0 +1,86 @@ +// +// DOMImplementation.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/DOMImplementation.h" +#include "Poco/DOM/DocumentType.h" +#include "Poco/DOM/Document.h" +#include "Poco/DOM/Element.h" +#include "Poco/String.h" +#include "Poco/SingletonHolder.h" + + +namespace Poco { +namespace XML { + + +const XMLString DOMImplementation::FEATURE_XML = toXMLString("xml"); +const XMLString DOMImplementation::FEATURE_CORE = toXMLString("core"); +const XMLString DOMImplementation::FEATURE_EVENTS = toXMLString("events"); +const XMLString DOMImplementation::FEATURE_MUTATIONEVENTS = toXMLString("mutationevents"); +const XMLString DOMImplementation::FEATURE_TRAVERSAL = toXMLString("traversal"); +const XMLString DOMImplementation::VERSION_1_0 = toXMLString("1.0"); +const XMLString DOMImplementation::VERSION_2_0 = toXMLString("2.0"); + + +DOMImplementation::DOMImplementation() +{ +} + + +DOMImplementation::~DOMImplementation() +{ +} + + +bool DOMImplementation::hasFeature(const XMLString& feature, const XMLString& version) const +{ + XMLString lcFeature = Poco::toLower(feature); + return (lcFeature == FEATURE_XML && version == VERSION_1_0) || + (lcFeature == FEATURE_CORE && version == VERSION_2_0) || + (lcFeature == FEATURE_EVENTS && version == VERSION_2_0) || + (lcFeature == FEATURE_MUTATIONEVENTS && version == VERSION_2_0) || + (lcFeature == FEATURE_TRAVERSAL && version == VERSION_2_0); +} + + +DocumentType* DOMImplementation::createDocumentType(const XMLString& name, const XMLString& publicId, const XMLString& systemId) const +{ + return new DocumentType(0, name, publicId, systemId); +} + + +Document* DOMImplementation::createDocument(const XMLString& namespaceURI, const XMLString& qualifiedName, DocumentType* doctype) const +{ + Document* pDoc = new Document(doctype); + if (namespaceURI.empty()) + pDoc->appendChild(pDoc->createElement(qualifiedName))->release(); + else + pDoc->appendChild(pDoc->createElementNS(namespaceURI, qualifiedName))->release(); + return pDoc; +} + + +namespace +{ + static Poco::SingletonHolder<DOMImplementation> sh; +} + + +const DOMImplementation& DOMImplementation::instance() +{ + return *sh.get(); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/DOMObject.cpp b/contrib/libs/poco/XML/src/DOMObject.cpp new file mode 100644 index 0000000000..a82708f0dd --- /dev/null +++ b/contrib/libs/poco/XML/src/DOMObject.cpp @@ -0,0 +1,32 @@ +// +// DOMObject.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/DOMObject.h" + + +namespace Poco { +namespace XML { + + +DOMObject::DOMObject(): _rc(1) +{ +} + + +DOMObject::~DOMObject() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/DOMParser.cpp b/contrib/libs/poco/XML/src/DOMParser.cpp new file mode 100644 index 0000000000..5e222c6fd7 --- /dev/null +++ b/contrib/libs/poco/XML/src/DOMParser.cpp @@ -0,0 +1,157 @@ +// +// DOMParser.cpp +// +// Library: XML +// Package: DOM +// Module: DOMParser +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/DOMParser.h" +#include "Poco/DOM/DOMBuilder.h" +#include "Poco/SAX/WhitespaceFilter.h" +#include "Poco/SAX/InputSource.h" +#include "Poco/XML/NamePool.h" +#include <sstream> + + +namespace Poco { +namespace XML { + + +const XMLString DOMParser::FEATURE_FILTER_WHITESPACE = toXMLString("http://www.appinf.com/features/no-whitespace-in-element-content"); + + +DOMParser::DOMParser(NamePool* pNamePool): + _pNamePool(pNamePool), + _filterWhitespace(false) +{ + if (_pNamePool) _pNamePool->duplicate(); + _saxParser.setFeature(XMLReader::FEATURE_NAMESPACES, true); + _saxParser.setFeature(XMLReader::FEATURE_NAMESPACE_PREFIXES, true); +} + + +DOMParser::DOMParser(unsigned long namePoolSize): + _pNamePool(new NamePool(namePoolSize)), + _filterWhitespace(false) +{ + _saxParser.setFeature(XMLReader::FEATURE_NAMESPACES, true); + _saxParser.setFeature(XMLReader::FEATURE_NAMESPACE_PREFIXES, true); +} + + +DOMParser::~DOMParser() +{ + if (_pNamePool) _pNamePool->release(); +} + + +void DOMParser::setEncoding(const XMLString& encoding) +{ + _saxParser.setEncoding(encoding); +} + + +const XMLString& DOMParser::getEncoding() const +{ + return _saxParser.getEncoding(); +} + + +void DOMParser::addEncoding(const XMLString& name, Poco::TextEncoding* pEncoding) +{ + _saxParser.addEncoding(name, pEncoding); +} + + +void DOMParser::setFeature(const XMLString& name, bool state) +{ + if (name == FEATURE_FILTER_WHITESPACE) + _filterWhitespace = state; + else + _saxParser.setFeature(name, state); +} + + +bool DOMParser::getFeature(const XMLString& name) const +{ + if (name == FEATURE_FILTER_WHITESPACE) + return _filterWhitespace; + else + return _saxParser.getFeature(name); +} + + +Document* DOMParser::parse(const XMLString& uri) +{ + if (_filterWhitespace) + { + WhitespaceFilter filter(&_saxParser); + DOMBuilder builder(filter, _pNamePool); + return builder.parse(uri); + } + else + { + DOMBuilder builder(_saxParser, _pNamePool); + return builder.parse(uri); + } +} + + +Document* DOMParser::parse(InputSource* pInputSource) +{ + if (_filterWhitespace) + { + WhitespaceFilter filter(&_saxParser); + DOMBuilder builder(filter, _pNamePool); + return builder.parse(pInputSource); + } + else + { + DOMBuilder builder(_saxParser, _pNamePool); + return builder.parse(pInputSource); + } +} + + +Document* DOMParser::parseString(const std::string& xml) +{ + return parseMemory(xml.data(), xml.size()); +} + + +Document* DOMParser::parseMemory(const char* xml, std::size_t size) +{ + if (_filterWhitespace) + { + WhitespaceFilter filter(&_saxParser); + DOMBuilder builder(filter, _pNamePool); + return builder.parseMemoryNP(xml, size); + } + else + { + DOMBuilder builder(_saxParser, _pNamePool); + return builder.parseMemoryNP(xml, size); + } +} + + +EntityResolver* DOMParser::getEntityResolver() const +{ + return _saxParser.getEntityResolver(); +} + + +void DOMParser::setEntityResolver(EntityResolver* pEntityResolver) +{ + _saxParser.setEntityResolver(pEntityResolver); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/DOMSerializer.cpp b/contrib/libs/poco/XML/src/DOMSerializer.cpp new file mode 100644 index 0000000000..327b3132e0 --- /dev/null +++ b/contrib/libs/poco/XML/src/DOMSerializer.cpp @@ -0,0 +1,323 @@ +// +// DOMSerializer.cpp +// +// Library: XML +// Package: DOM +// Module: DOMSerializer +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/DOMSerializer.h" +#include "Poco/DOM/Document.h" +#include "Poco/DOM/DocumentType.h" +#include "Poco/DOM/DocumentFragment.h" +#include "Poco/DOM/Element.h" +#include "Poco/DOM/Attr.h" +#include "Poco/DOM/Text.h" +#include "Poco/DOM/CDATASection.h" +#include "Poco/DOM/Comment.h" +#include "Poco/DOM/ProcessingInstruction.h" +#include "Poco/DOM/Entity.h" +#include "Poco/DOM/Notation.h" +#include "Poco/DOM/NamedNodeMap.h" +#include "Poco/DOM/AutoPtr.h" +#include "Poco/SAX/EntityResolver.h" +#include "Poco/SAX/DTDHandler.h" +#include "Poco/SAX/ContentHandler.h" +#include "Poco/SAX/LexicalHandler.h" +#include "Poco/SAX/AttributesImpl.h" +#include "Poco/SAX/ErrorHandler.h" +#include "Poco/SAX/SAXException.h" + + +namespace Poco { +namespace XML { + + +const XMLString DOMSerializer::CDATA = toXMLString("CDATA"); + + +DOMSerializer::DOMSerializer(): + _pEntityResolver(0), + _pDTDHandler(0), + _pContentHandler(0), + _pErrorHandler(0), + _pDeclHandler(0), + _pLexicalHandler(0) +{ +} + + +DOMSerializer::~DOMSerializer() +{ +} + + +void DOMSerializer::setEntityResolver(EntityResolver* pEntityResolver) +{ + _pEntityResolver = pEntityResolver; +} + + +EntityResolver* DOMSerializer::getEntityResolver() const +{ + return _pEntityResolver; +} + + +void DOMSerializer::setDTDHandler(DTDHandler* pDTDHandler) +{ + _pDTDHandler = pDTDHandler; +} + + +DTDHandler* DOMSerializer::getDTDHandler() const +{ + return _pDTDHandler; +} + + +void DOMSerializer::setContentHandler(ContentHandler* pContentHandler) +{ + _pContentHandler = pContentHandler; +} + + +ContentHandler* DOMSerializer::getContentHandler() const +{ + return _pContentHandler; +} + + +void DOMSerializer::setErrorHandler(ErrorHandler* pErrorHandler) +{ + _pErrorHandler = pErrorHandler; +} + + +ErrorHandler* DOMSerializer::getErrorHandler() const +{ + return _pErrorHandler; +} + + +void DOMSerializer::setFeature(const XMLString& featureId, bool /*state*/) +{ + if (featureId == XMLReader::FEATURE_NAMESPACES) + throw SAXNotSupportedException(fromXMLString(XMLReader::FEATURE_NAMESPACES)); + else if (featureId == XMLReader::FEATURE_NAMESPACE_PREFIXES) + throw SAXNotSupportedException(fromXMLString(XMLReader::FEATURE_NAMESPACE_PREFIXES)); + else + throw SAXNotRecognizedException(fromXMLString(featureId)); +} + + +bool DOMSerializer::getFeature(const XMLString& featureId) const +{ + if (featureId == XMLReader::FEATURE_NAMESPACES) + throw SAXNotSupportedException(fromXMLString(XMLReader::FEATURE_NAMESPACES)); + else if (featureId == XMLReader::FEATURE_NAMESPACE_PREFIXES) + throw SAXNotSupportedException(fromXMLString(XMLReader::FEATURE_NAMESPACE_PREFIXES)); + else + throw SAXNotRecognizedException(fromXMLString(featureId)); +} + + +void DOMSerializer::setProperty(const XMLString& propertyId, const XMLString& /*value*/) +{ + if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER || propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) + throw SAXNotSupportedException(std::string("property does not take a string value: ") + fromXMLString(propertyId)); + else + throw SAXNotRecognizedException(fromXMLString(propertyId)); +} + + +void DOMSerializer::setProperty(const XMLString& propertyId, void* value) +{ + if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER) + _pDeclHandler = reinterpret_cast<DeclHandler*>(value); + else if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) + _pLexicalHandler = reinterpret_cast<LexicalHandler*>(value); + else throw SAXNotRecognizedException(fromXMLString(propertyId)); +} + + +void* DOMSerializer::getProperty(const XMLString& propertyId) const +{ + if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER) + return _pDeclHandler; + else if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) + return _pLexicalHandler; + else throw SAXNotSupportedException(fromXMLString(propertyId)); +} + + +void DOMSerializer::serialize(const Node* pNode) +{ + poco_check_ptr (pNode); + + handleNode(pNode); +} + + +void DOMSerializer::parse(InputSource* /*pSource*/) +{ + throw XMLException("The DOMSerializer cannot parse an InputSource"); +} + + +void DOMSerializer::parse(const XMLString& /*systemId*/) +{ + throw XMLException("The DOMSerializer cannot parse from a system identifier"); +} + + +void DOMSerializer::parseMemoryNP(const char* /*xml*/, std::size_t /*size*/) +{ + throw XMLException("The DOMSerializer cannot parse from memory"); +} + + +void DOMSerializer::iterate(const Node* pNode) const +{ + while (pNode) + { + handleNode(pNode); + pNode = pNode->nextSibling(); + } +} + + +void DOMSerializer::handleNode(const Node* pNode) const +{ + switch (pNode->nodeType()) + { + case Node::ELEMENT_NODE: + handleElement(static_cast<const Element*>(pNode)); + break; + case Node::TEXT_NODE: + handleCharacterData(static_cast<const Text*>(pNode)); + break; + case Node::CDATA_SECTION_NODE: + handleCDATASection(static_cast<const CDATASection*>(pNode)); + break; + case Node::ENTITY_NODE: + handleEntity(static_cast<const Entity*>(pNode)); + break; + case Node::PROCESSING_INSTRUCTION_NODE: + handlePI(static_cast<const ProcessingInstruction*>(pNode)); + break; + case Node::COMMENT_NODE: + handleComment(static_cast<const Comment*>(pNode)); + break; + case Node::DOCUMENT_NODE: + handleDocument(static_cast<const Document*>(pNode)); + break; + case Node::DOCUMENT_TYPE_NODE: + handleDocumentType(static_cast<const DocumentType*>(pNode)); + break; + case Node::DOCUMENT_FRAGMENT_NODE: + handleFragment(static_cast<const DocumentFragment*>(pNode)); + break; + case Node::NOTATION_NODE: + handleNotation(static_cast<const Notation*>(pNode)); + break; + } +} + + +void DOMSerializer::handleElement(const Element* pElement) const +{ + if (_pContentHandler) + { + AutoPtr<NamedNodeMap> pAttrs = pElement->attributes(); + AttributesImpl saxAttrs; + for (unsigned long i = 0; i < pAttrs->length(); ++i) + { + Attr* pAttr = static_cast<Attr*>(pAttrs->item(i)); + saxAttrs.addAttribute(pAttr->namespaceURI(), pAttr->localName(), pAttr->nodeName(), CDATA, pAttr->value(), pAttr->specified()); + } + _pContentHandler->startElement(pElement->namespaceURI(), pElement->localName(), pElement->tagName(), saxAttrs); + } + iterate(pElement->firstChild()); + if (_pContentHandler) + _pContentHandler->endElement(pElement->namespaceURI(), pElement->localName(), pElement->tagName()); +} + + +void DOMSerializer::handleCharacterData(const Text* pText) const +{ + if (_pContentHandler) + { + const XMLString& data = pText->data(); + _pContentHandler->characters(data.c_str(), 0, (int) data.length()); + } +} + + +void DOMSerializer::handleComment(const Comment* pComment) const +{ + if (_pLexicalHandler) + { + const XMLString& data = pComment->data(); + _pLexicalHandler->comment(data.c_str(), 0, (int) data.length()); + } +} + + +void DOMSerializer::handlePI(const ProcessingInstruction* pPI) const +{ + if (_pContentHandler) _pContentHandler->processingInstruction(pPI->target(), pPI->data()); +} + + +void DOMSerializer::handleCDATASection(const CDATASection* pCDATA) const +{ + if (_pLexicalHandler) _pLexicalHandler->startCDATA(); + handleCharacterData(pCDATA); + if (_pLexicalHandler) _pLexicalHandler->endCDATA(); +} + + +void DOMSerializer::handleDocument(const Document* pDocument) const +{ + if (_pContentHandler) _pContentHandler->startDocument(); + const DocumentType* pDoctype = pDocument->doctype(); + if (pDoctype) handleDocumentType(pDoctype); + iterate(pDocument->firstChild()); + if (_pContentHandler) _pContentHandler->endDocument(); +} + + +void DOMSerializer::handleDocumentType(const DocumentType* pDocumentType) const +{ + if (_pLexicalHandler) _pLexicalHandler->startDTD(pDocumentType->name(), pDocumentType->publicId(), pDocumentType->systemId()); + iterate(pDocumentType->firstChild()); + if (_pLexicalHandler) _pLexicalHandler->endDTD(); +} + + +void DOMSerializer::handleFragment(const DocumentFragment* pFragment) const +{ + iterate(pFragment->firstChild()); +} + + +void DOMSerializer::handleNotation(const Notation* pNotation) const +{ + if (_pDTDHandler) _pDTDHandler->notationDecl(pNotation->nodeName(), &pNotation->publicId(), &pNotation->systemId()); +} + + +void DOMSerializer::handleEntity(const Entity* pEntity) const +{ + if (_pDTDHandler) _pDTDHandler->unparsedEntityDecl(pEntity->nodeName(), &pEntity->publicId(), pEntity->systemId(), pEntity->notationName()); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/DOMWriter.cpp b/contrib/libs/poco/XML/src/DOMWriter.cpp new file mode 100644 index 0000000000..8a087643e8 --- /dev/null +++ b/contrib/libs/poco/XML/src/DOMWriter.cpp @@ -0,0 +1,102 @@ +// +// DOMWriter.cpp +// +// Library: XML +// Package: DOM +// Module: DOMWriter +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + + +#include "Poco/DOM/DOMWriter.h" +#include "Poco/XML/XMLWriter.h" +#include "Poco/DOM/Document.h" +#include "Poco/DOM/DocumentFragment.h" +#include "Poco/DOM/DocumentType.h" +#include "Poco/DOM/DOMException.h" +#include "Poco/DOM/DOMSerializer.h" +#include "Poco/SAX/LexicalHandler.h" +#include "Poco/XML/XMLException.h" +#include "Poco/Path.h" +#include "Poco/FileStream.h" + + +namespace Poco { +namespace XML { + + +DOMWriter::DOMWriter(): + _pTextEncoding(0), + _options(0), + _indent("\t") +{ +} + + +DOMWriter::~DOMWriter() +{ +} + + +void DOMWriter::setEncoding(const std::string& encodingName, Poco::TextEncoding& textEncoding) +{ + _encodingName = encodingName; + _pTextEncoding = &textEncoding; +} + + +void DOMWriter::setOptions(int options) +{ + _options = options; +} + + +void DOMWriter::setNewLine(const std::string& newLine) +{ + _newLine = newLine; +} + + +void DOMWriter::setIndent(const std::string& indent) +{ + _indent = indent; +} + + +void DOMWriter::writeNode(XMLByteOutputStream& ostr, const Node* pNode) +{ + poco_check_ptr (pNode); + + bool isFragment = pNode->nodeType() != Node::DOCUMENT_NODE; + + XMLWriter writer(ostr, _options, _encodingName, _pTextEncoding); + writer.setNewLine(_newLine); + writer.setIndent(_indent); + + DOMSerializer serializer; + serializer.setContentHandler(&writer); + serializer.setDTDHandler(&writer); + serializer.setProperty(XMLReader::PROPERTY_LEXICAL_HANDLER, static_cast<LexicalHandler*>(&writer)); + if (isFragment) writer.startFragment(); + serializer.serialize(pNode); + if (isFragment) writer.endFragment(); +} + + +void DOMWriter::writeNode(const std::string& systemId, const Node* pNode) +{ + Poco::FileOutputStream ostr(systemId); + if (ostr.good()) + writeNode(ostr, pNode); + else + throw Poco::CreateFileException(systemId); +} + + +} } // namespace Poco::XML + diff --git a/contrib/libs/poco/XML/src/DTDHandler.cpp b/contrib/libs/poco/XML/src/DTDHandler.cpp new file mode 100644 index 0000000000..5c478acc40 --- /dev/null +++ b/contrib/libs/poco/XML/src/DTDHandler.cpp @@ -0,0 +1,27 @@ +// +// DTDHandler.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/DTDHandler.h" + + +namespace Poco { +namespace XML { + + +DTDHandler::~DTDHandler() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/DTDMap.cpp b/contrib/libs/poco/XML/src/DTDMap.cpp new file mode 100644 index 0000000000..8b7136287a --- /dev/null +++ b/contrib/libs/poco/XML/src/DTDMap.cpp @@ -0,0 +1,117 @@ +// +// DTDMap.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/DTDMap.h" +#include "Poco/DOM/DocumentType.h" +#include "Poco/DOM/Document.h" +#include "Poco/DOM/DOMException.h" + + +namespace Poco { +namespace XML { + + +DTDMap::DTDMap(const DocumentType* pDocumentType, unsigned short type): + _pDocumentType(pDocumentType), + _type(type) +{ + poco_check_ptr (pDocumentType->ownerDocument()); +} + + +DTDMap::~DTDMap() +{ +} + + +Node* DTDMap::getNamedItem(const XMLString& name) const +{ + Node* pCur = _pDocumentType->firstChild(); + while (pCur) + { + if (pCur->nodeType() == _type && pCur->nodeName() == name) + return pCur; + pCur = pCur->nextSibling(); + } + return pCur; +} + + +Node* DTDMap::setNamedItem(Node* /*arg*/) +{ + throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR); +} + + +Node* DTDMap::removeNamedItem(const XMLString& /*name*/) +{ + throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR); +} + + +Node* DTDMap::item(unsigned long index) const +{ + unsigned long n = 0; + Node* pCur = _pDocumentType->firstChild(); + while (pCur) + { + if (pCur->nodeType() == _type) + { + if (n == index) return pCur; + ++n; + } + pCur = pCur->nextSibling(); + } + return pCur; +} + + +unsigned long DTDMap::length() const +{ + unsigned long n = 0; + Node* pCur = _pDocumentType->firstChild(); + while (pCur) + { + if (pCur->nodeType() == _type) ++n; + pCur = pCur->nextSibling(); + } + return n; +} + + +Node* DTDMap::getNamedItemNS(const XMLString& /*namespaceURI*/, const XMLString& /*localName*/) const +{ + return 0; +} + + +Node* DTDMap::setNamedItemNS(Node* /*arg*/) +{ + throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR); +} + + +Node* DTDMap::removeNamedItemNS(const XMLString& /*namespaceURI*/, const XMLString& /*localName*/) +{ + throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR); +} + + +void DTDMap::autoRelease() +{ + _pDocumentType->ownerDocument()->autoReleasePool().add(this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/DeclHandler.cpp b/contrib/libs/poco/XML/src/DeclHandler.cpp new file mode 100644 index 0000000000..d2164f430f --- /dev/null +++ b/contrib/libs/poco/XML/src/DeclHandler.cpp @@ -0,0 +1,27 @@ +// +// DeclHandler.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/DeclHandler.h" + + +namespace Poco { +namespace XML { + + +DeclHandler::~DeclHandler() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/DefaultHandler.cpp b/contrib/libs/poco/XML/src/DefaultHandler.cpp new file mode 100644 index 0000000000..80be56e1d6 --- /dev/null +++ b/contrib/libs/poco/XML/src/DefaultHandler.cpp @@ -0,0 +1,123 @@ +// +// DefaultHandler.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/DefaultHandler.h" + + +namespace Poco { +namespace XML { + + +DefaultHandler::DefaultHandler() +{ +} + + +DefaultHandler::~DefaultHandler() +{ +} + + +InputSource* DefaultHandler::resolveEntity(const XMLString* /*publicId*/, const XMLString& /*systemId*/) +{ + return 0; +} + + +void DefaultHandler::releaseInputSource(InputSource* /*pSource*/) +{ +} + + +void DefaultHandler::notationDecl(const XMLString& /*name*/, const XMLString* /*publicId*/, const XMLString* /*systemId*/) +{ +} + + +void DefaultHandler::unparsedEntityDecl(const XMLString& /*name*/, const XMLString* /*publicId*/, const XMLString& /*systemId*/, const XMLString& /*notationName*/) +{ +} + + +void DefaultHandler::setDocumentLocator(const Locator* /*loc*/) +{ +} + + +void DefaultHandler::startDocument() +{ +} + + +void DefaultHandler::endDocument() +{ +} + + +void DefaultHandler::startElement(const XMLString& /*uri*/, const XMLString& /*localName*/, const XMLString& /*qname*/, const Attributes& /*attributes*/) +{ +} + + +void DefaultHandler::endElement(const XMLString& /*uri*/, const XMLString& /*localName*/, const XMLString& /*qname*/) +{ +} + + +void DefaultHandler::characters(const XMLChar /*ch*/[], int /*start*/, int /*length*/) +{ +} + + +void DefaultHandler::ignorableWhitespace(const XMLChar /*ch*/[], int /*start*/, int /*length*/) +{ +} + + +void DefaultHandler::processingInstruction(const XMLString& /*target*/, const XMLString& /*data*/) +{ +} + + +void DefaultHandler::startPrefixMapping(const XMLString& /*prefix*/, const XMLString& /*uri*/) +{ +} + + +void DefaultHandler::endPrefixMapping(const XMLString& /*prefix*/) +{ +} + + +void DefaultHandler::skippedEntity(const XMLString& /*name*/) +{ +} + + +void DefaultHandler::warning(const SAXException& /*exc*/) +{ +} + + +void DefaultHandler::error(const SAXException& /*exc*/) +{ +} + + +void DefaultHandler::fatalError(const SAXException& /*exc*/) +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/Document.cpp b/contrib/libs/poco/XML/src/Document.cpp new file mode 100644 index 0000000000..a649c0b066 --- /dev/null +++ b/contrib/libs/poco/XML/src/Document.cpp @@ -0,0 +1,326 @@ +// +// Document.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/Document.h" +#include "Poco/DOM/DocumentType.h" +#include "Poco/DOM/DOMImplementation.h" +#include "Poco/DOM/Element.h" +#include "Poco/DOM/Attr.h" +#include "Poco/DOM/DocumentFragment.h" +#include "Poco/DOM/Text.h" +#include "Poco/DOM/Comment.h" +#include "Poco/DOM/CDATASection.h" +#include "Poco/DOM/ProcessingInstruction.h" +#include "Poco/DOM/EntityReference.h" +#include "Poco/DOM/DOMException.h" +#include "Poco/DOM/ElementsByTagNameList.h" +#include "Poco/DOM/Entity.h" +#include "Poco/DOM/Notation.h" +#include "Poco/XML/Name.h" +#include "Poco/XML/NamePool.h" + + +namespace Poco { +namespace XML { + + +const XMLString Document::NODE_NAME = toXMLString("#document"); + + +Document::Document(NamePool* pNamePool): + AbstractContainerNode(0), + _pDocumentType(0), + _eventSuspendLevel(0) +{ + if (pNamePool) + { + _pNamePool = pNamePool; + _pNamePool->duplicate(); + } + else + { + _pNamePool = new NamePool; + } +} + + +Document::Document(unsigned long namePoolSize): + AbstractContainerNode(0), + _pDocumentType(0), + _pNamePool(new NamePool(namePoolSize)), + _eventSuspendLevel(0) +{ +} + + +Document::Document(DocumentType* pDocumentType, NamePool* pNamePool): + AbstractContainerNode(0), + _pDocumentType(pDocumentType), + _eventSuspendLevel(0) +{ + if (pNamePool) + { + _pNamePool = pNamePool; + _pNamePool->duplicate(); + } + else + { + _pNamePool = new NamePool; + } + if (_pDocumentType) + { + _pDocumentType->duplicate(); + _pDocumentType->setOwnerDocument(this); + } +} + + +Document::Document(DocumentType* pDocumentType, unsigned long namePoolSize): + AbstractContainerNode(0), + _pDocumentType(pDocumentType), + _pNamePool(new NamePool(namePoolSize)), + _eventSuspendLevel(0) +{ + if (_pDocumentType) + { + _pDocumentType->duplicate(); + _pDocumentType->setOwnerDocument(this); + } +} + + +Document::~Document() +{ + if (_pDocumentType) _pDocumentType->release(); + _pNamePool->release(); +} + + +bool Document::dispatchEvent(Event* evt) +{ + return _eventSuspendLevel > 0 || AbstractContainerNode::dispatchEvent(evt); +} + + +void Document::collectGarbage() +{ + _autoReleasePool.release(); +} + + +void Document::suspendEvents() +{ + ++_eventSuspendLevel; +} + + +void Document::resumeEvents() +{ + poco_assert_dbg (_eventSuspendLevel > 0); + + --_eventSuspendLevel; +} + + +const DOMImplementation& Document::implementation() const +{ + return DOMImplementation::instance(); +} + + +Element* Document::documentElement() const +{ + // Skip non-element nodes before the document element + Node* pCur = firstChild(); + while (pCur) + { + if (dynamic_cast<Element*>(pCur)) + return static_cast<Element*>(pCur); + pCur = pCur->nextSibling(); + } + return 0; +} + + +Element* Document::createElement(const XMLString& tagName) const +{ + return new Element(const_cast<Document*>(this), EMPTY_STRING, EMPTY_STRING, tagName); +} + + +DocumentFragment* Document::createDocumentFragment() const +{ + return new DocumentFragment(const_cast<Document*>(this)); +} + + +Text* Document::createTextNode(const XMLString& data) const +{ + return new Text(const_cast<Document*>(this), data); +} + + +Comment* Document::createComment(const XMLString& data) const +{ + return new Comment(const_cast<Document*>(this), data); +} + + +CDATASection* Document::createCDATASection(const XMLString& data) const +{ + return new CDATASection(const_cast<Document*>(this), data); +} + + +ProcessingInstruction* Document::createProcessingInstruction(const XMLString& target, const XMLString& data) const +{ + return new ProcessingInstruction(const_cast<Document*>(this), target, data); +} + + +Attr* Document::createAttribute(const XMLString& name) const +{ + return new Attr(const_cast<Document*>(this), 0, EMPTY_STRING, EMPTY_STRING, name, EMPTY_STRING); +} + + +EntityReference* Document::createEntityReference(const XMLString& name) const +{ + return new EntityReference(const_cast<Document*>(this), name); +} + + +NodeList* Document::getElementsByTagName(const XMLString& name) const +{ + return new ElementsByTagNameList(const_cast<Document*>(this), name); +} + + +const XMLString& Document::nodeName() const +{ + return NODE_NAME; +} + + +unsigned short Document::nodeType() const +{ + return Node::DOCUMENT_NODE; +} + + +Node* Document::importNode(Node* importedNode, bool deep) +{ + return static_cast<AbstractNode*>(importedNode)->copyNode(deep, this); +} + + +Element* Document::createElementNS(const XMLString& namespaceURI, const XMLString& qualifiedName) const +{ + return new Element(const_cast<Document*>(this), namespaceURI, Name::localName(qualifiedName), qualifiedName); +} + + +Attr* Document::createAttributeNS(const XMLString& namespaceURI, const XMLString& qualifiedName) const +{ + return new Attr(const_cast<Document*>(this), 0, namespaceURI, Name::localName(qualifiedName), qualifiedName, EMPTY_STRING); +} + + +NodeList* Document::getElementsByTagNameNS(const XMLString& namespaceURI, const XMLString& localName) const +{ + return new ElementsByTagNameListNS(const_cast<Document*>(this), namespaceURI, localName); +} + + +Element* Document::getElementById(const XMLString& /*elementId*/) const +{ + return 0; +} + + +Event* Document::createEvent(const XMLString& eventType) const +{ + if (eventType == MutationEvent::DOMSubtreeModified || + eventType == MutationEvent::DOMNodeInserted || + eventType == MutationEvent::DOMNodeRemoved || + eventType == MutationEvent::DOMNodeRemovedFromDocument || + eventType == MutationEvent::DOMNodeInsertedIntoDocument || + eventType == MutationEvent::DOMAttrModified || + eventType == MutationEvent::DOMCharacterDataModified) + { + return new MutationEvent(const_cast<Document*>(this), eventType); + } + throw DOMException(DOMException::NOT_SUPPORTED_ERR); +} + + +Node* Document::copyNode(bool /*deep*/, Document* /*pOwnerDocument*/) const +{ + throw DOMException(DOMException::NOT_SUPPORTED_ERR); +} + + +void Document::setDoctype(DocumentType* pDoctype) +{ + if (_pDocumentType) _pDocumentType->release(); + _pDocumentType = pDoctype; + if (_pDocumentType) + { + _pDocumentType->duplicate(); + _pDocumentType->setOwnerDocument(this); + } +} + + +bool Document::eventsSuspended() const +{ + return _eventSuspendLevel > 0; +} + + +bool Document::events() const +{ + return _eventSuspendLevel == 0; +} + + +Entity* Document::createEntity(const XMLString& name, const XMLString& publicId, const XMLString& systemId, const XMLString& notationName) const +{ + return new Entity(const_cast<Document*>(this), name, publicId, systemId, notationName); +} + + +Notation* Document::createNotation(const XMLString& name, const XMLString& publicId, const XMLString& systemId) const +{ + return new Notation(const_cast<Document*>(this), name, publicId, systemId); +} + + +Element* Document::getElementById(const XMLString& elementId, const XMLString& idAttribute) const +{ + Element* pElem = documentElement(); + if (pElem) pElem = pElem->getElementById(elementId, idAttribute); + return pElem; +} + + +Element* Document::getElementByIdNS(const XMLString& elementId, const XMLString& idAttributeURI, const XMLString& idAttributeLocalName) const +{ + Element* pElem = documentElement(); + if (pElem) pElem = pElem->getElementByIdNS(elementId, idAttributeURI, idAttributeLocalName); + return pElem; +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/DocumentEvent.cpp b/contrib/libs/poco/XML/src/DocumentEvent.cpp new file mode 100644 index 0000000000..943e69f67d --- /dev/null +++ b/contrib/libs/poco/XML/src/DocumentEvent.cpp @@ -0,0 +1,27 @@ +// +// DocumentEvent.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/DocumentEvent.h" + + +namespace Poco { +namespace XML { + + +DocumentEvent::~DocumentEvent() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/DocumentFragment.cpp b/contrib/libs/poco/XML/src/DocumentFragment.cpp new file mode 100644 index 0000000000..462be5292e --- /dev/null +++ b/contrib/libs/poco/XML/src/DocumentFragment.cpp @@ -0,0 +1,70 @@ +// +// DocumentFragment.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/DocumentFragment.h" + + +namespace Poco { +namespace XML { + + +const XMLString DocumentFragment::NODE_NAME = toXMLString("#document-fragment"); + + +DocumentFragment::DocumentFragment(Document* pOwnerDocument): + AbstractContainerNode(pOwnerDocument) +{ +} + + +DocumentFragment::DocumentFragment( Document* pOwnerDocument, const DocumentFragment& fragment): + AbstractContainerNode(pOwnerDocument, fragment) +{ +} + + +DocumentFragment::~DocumentFragment() +{ +} + + +const XMLString& DocumentFragment::nodeName() const +{ + return NODE_NAME; +} + + +unsigned short DocumentFragment::nodeType() const +{ + return Node::DOCUMENT_FRAGMENT_NODE; +} + + +Node* DocumentFragment::copyNode(bool deep, Document* pOwnerDocument) const +{ + DocumentFragment* pClone = new DocumentFragment(pOwnerDocument, *this); + if (deep) + { + Node* pCur = firstChild(); + while (pCur) + { + pClone->appendChild(static_cast<AbstractNode*>(pCur)->copyNode(deep, pOwnerDocument))->release(); + pCur = pCur->nextSibling(); + } + } + return pClone; +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/DocumentType.cpp b/contrib/libs/poco/XML/src/DocumentType.cpp new file mode 100644 index 0000000000..cc55f59586 --- /dev/null +++ b/contrib/libs/poco/XML/src/DocumentType.cpp @@ -0,0 +1,84 @@ +// +// DocumentType.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/DocumentType.h" +#include "Poco/DOM/Document.h" +#include "Poco/DOM/DTDMap.h" +#include "Poco/DOM/DOMException.h" + + +namespace Poco { +namespace XML { + + +DocumentType::DocumentType(Document* pOwner, const XMLString& name, const XMLString& publicId, const XMLString& systemId): + AbstractContainerNode(pOwner), + _name(name), + _publicId(publicId), + _systemId(systemId) +{ +} + + +DocumentType::DocumentType(Document* pOwner, const DocumentType& doctype): + AbstractContainerNode(pOwner, doctype), + _name(doctype._name), + _publicId(doctype._publicId), + _systemId(doctype._systemId) +{ +} + + +DocumentType::~DocumentType() +{ +} + + +NamedNodeMap* DocumentType::entities() const +{ + return new DTDMap(this, Node::ENTITY_NODE); +} + + +NamedNodeMap* DocumentType::notations() const +{ + return new DTDMap(this, Node::NOTATION_NODE); +} + + +const XMLString& DocumentType::nodeName() const +{ + return _name; +} + + +unsigned short DocumentType::nodeType() const +{ + return Node::DOCUMENT_TYPE_NODE; +} + + +const XMLString& DocumentType::internalSubset() const +{ + return EMPTY_STRING; +} + + +Node* DocumentType::copyNode(bool /*deep*/, Document* pOwnerDocument) const +{ + return new DocumentType(pOwnerDocument, *this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/Element.cpp b/contrib/libs/poco/XML/src/Element.cpp new file mode 100644 index 0000000000..e66039ade3 --- /dev/null +++ b/contrib/libs/poco/XML/src/Element.cpp @@ -0,0 +1,444 @@ +// +// Element.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/Element.h" +#include "Poco/DOM/Document.h" +#include "Poco/DOM/Attr.h" +#include "Poco/DOM/DOMException.h" +#include "Poco/DOM/ElementsByTagNameList.h" +#include "Poco/DOM/Text.h" +#include "Poco/DOM/AttrMap.h" + + +namespace Poco { +namespace XML { + + +Element::Element(Document* pOwnerDocument, const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname): + AbstractContainerNode(pOwnerDocument), + _name(pOwnerDocument->namePool().insert(qname, namespaceURI, localName)), + _pFirstAttr(0) +{ +} + + +Element::Element(Document* pOwnerDocument, const Element& element): + AbstractContainerNode(pOwnerDocument, element), + _name(pOwnerDocument->namePool().insert(element._name)), + _pFirstAttr(0) +{ + Attr* pAttr = element._pFirstAttr; + while (pAttr) + { + Attr* pClonedAttr = static_cast<Attr*>(pAttr->copyNode(false, pOwnerDocument)); + setAttributeNode(pClonedAttr); + pClonedAttr->release(); + pAttr = static_cast<Attr*>(pAttr->_pNext); + } +} + + +Element::~Element() +{ + if (_pFirstAttr) _pFirstAttr->release(); +} + + +const XMLString& Element::getAttribute(const XMLString& name) const +{ + Attr* pAttr = getAttributeNode(name); + if (pAttr) + return pAttr->getValue(); + else + return EMPTY_STRING; +} + + +void Element::setAttribute(const XMLString& name, const XMLString& value) +{ + Attr* pAttr = getAttributeNode(name); + if (pAttr) + { + pAttr->setValue(value); + } + else + { + pAttr = ownerDocument()->createAttribute(name); + pAttr->setValue(value); + setAttributeNode(pAttr); + pAttr->release(); + } +} + + +void Element::removeAttribute(const XMLString& name) +{ + Attr* pAttr = getAttributeNode(name); + if (pAttr) removeAttributeNode(pAttr); +} + + +Attr* Element::getAttributeNode(const XMLString& name) const +{ + Attr* pAttr = _pFirstAttr; + while (pAttr && pAttr->_name.qname() != name) pAttr = static_cast<Attr*>(pAttr->_pNext); + return pAttr; +} + + +Attr* Element::setAttributeNode(Attr* newAttr) +{ + poco_check_ptr (newAttr); + + if (newAttr->ownerDocument() != ownerDocument()) + throw DOMException(DOMException::WRONG_DOCUMENT_ERR); + if (newAttr->ownerElement()) + throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR); + + Attr* oldAttr = getAttributeNode(newAttr->name()); + if (oldAttr) removeAttributeNode(oldAttr); + + Attr* pCur = _pFirstAttr; + if (pCur) + { + while (pCur->_pNext) pCur = static_cast<Attr*>(pCur->_pNext); + pCur->_pNext = newAttr; + } + else _pFirstAttr = newAttr; + newAttr->duplicate(); + newAttr->_pParent = this; + if (_pOwner->events()) + dispatchAttrModified(newAttr, MutationEvent::ADDITION, EMPTY_STRING, newAttr->getValue()); + + return oldAttr; +} + + +Attr* Element::removeAttributeNode(Attr* oldAttr) +{ + poco_check_ptr (oldAttr); + + if (_pOwner->events()) + dispatchAttrModified(oldAttr, MutationEvent::REMOVAL, oldAttr->getValue(), EMPTY_STRING); + + if (oldAttr != _pFirstAttr) + { + Attr* pCur = _pFirstAttr; + while (pCur->_pNext != oldAttr) pCur = static_cast<Attr*>(pCur->_pNext); + if (pCur) + { + pCur->_pNext = static_cast<Attr*>(pCur->_pNext->_pNext); + } + else throw DOMException(DOMException::NOT_FOUND_ERR); + } + else _pFirstAttr = static_cast<Attr*>(_pFirstAttr->_pNext); + oldAttr->_pNext = 0; + oldAttr->_pParent = 0; + oldAttr->autoRelease(); + + return oldAttr; +} + + +Attr* Element::addAttributeNodeNP(Attr* oldAttr, Attr* newAttr) +{ + newAttr->_pParent = this; + if (oldAttr) + { + oldAttr->_pNext = newAttr; + } + else if (_pFirstAttr) + { + newAttr->_pNext = _pFirstAttr; + _pFirstAttr = newAttr; + } + else + { + _pFirstAttr = newAttr; + } + newAttr->duplicate(); + return newAttr; +} + + +NodeList* Element::getElementsByTagName(const XMLString& name) const +{ + return new ElementsByTagNameList(this, name); +} + + +NodeList* Element::getElementsByTagNameNS(const XMLString& namespaceURI, const XMLString& localName) const +{ + return new ElementsByTagNameListNS(this, namespaceURI, localName); +} + + +void Element::normalize() +{ + Node* pCur = firstChild(); + while (pCur) + { + if (pCur->nodeType() == Node::ELEMENT_NODE) + { + pCur->normalize(); + } + else if (pCur->nodeType() == Node::TEXT_NODE) + { + Node* pNext = pCur->nextSibling(); + while (pNext && pNext->nodeType() == Node::TEXT_NODE) + { + static_cast<Text*>(pCur)->appendData(pNext->nodeValue()); + removeChild(pNext); + pNext = pCur->nextSibling(); + } + } + pCur = pCur->nextSibling(); + } +} + + +const XMLString& Element::nodeName() const +{ + return tagName(); +} + + +NamedNodeMap* Element::attributes() const +{ + return new AttrMap(const_cast<Element*>(this)); +} + + +unsigned short Element::nodeType() const +{ + return Node::ELEMENT_NODE; +} + + +const XMLString& Element::getAttributeNS(const XMLString& namespaceURI, const XMLString& localName) const +{ + Attr* pAttr = getAttributeNodeNS(namespaceURI, localName); + if (pAttr) + return pAttr->getValue(); + else + return EMPTY_STRING; +} + + +void Element::setAttributeNS(const XMLString& namespaceURI, const XMLString& qualifiedName, const XMLString& value) +{ + Attr* pAttr = getAttributeNodeNS(namespaceURI, qualifiedName); + if (pAttr) + { + pAttr->setValue(value); + } + else + { + pAttr = _pOwner->createAttributeNS(namespaceURI, qualifiedName); + pAttr->setValue(value); + setAttributeNodeNS(pAttr); + pAttr->release(); + } +} + + +void Element::removeAttributeNS(const XMLString& namespaceURI, const XMLString& localName) +{ + Attr* pAttr = getAttributeNodeNS(namespaceURI, localName); + if (pAttr) removeAttributeNode(pAttr); +} + + +Attr* Element::getAttributeNodeNS(const XMLString& namespaceURI, const XMLString& localName) const +{ + Attr* pAttr = _pFirstAttr; + while (pAttr && (pAttr->_name.namespaceURI() != namespaceURI || pAttr->_name.localName() != localName)) pAttr = static_cast<Attr*>(pAttr->_pNext); + return pAttr; +} + + +Attr* Element::setAttributeNodeNS(Attr* newAttr) +{ + poco_check_ptr (newAttr); + + if (newAttr->ownerDocument() != ownerDocument()) + throw DOMException(DOMException::WRONG_DOCUMENT_ERR); + if (newAttr->ownerElement()) + throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR); + + Attr* oldAttr = getAttributeNodeNS(newAttr->namespaceURI(), newAttr->localName()); + if (oldAttr) removeAttributeNode(oldAttr); + + Attr* pCur = _pFirstAttr; + if (pCur) + { + while (pCur->_pNext) pCur = static_cast<Attr*>(pCur->_pNext); + pCur->_pNext = newAttr; + } + else _pFirstAttr = newAttr; + newAttr->_pParent = this; + newAttr->duplicate(); + if (_pOwner->events()) + dispatchAttrModified(newAttr, MutationEvent::ADDITION, EMPTY_STRING, newAttr->getValue()); + + return oldAttr; +} + + +bool Element::hasAttribute(const XMLString& name) const +{ + return getAttributeNode(name) != 0; +} + + +bool Element::hasAttributeNS(const XMLString& namespaceURI, const XMLString& localName) const +{ + return getAttributeNodeNS(namespaceURI, localName) != 0; +} + + +const XMLString& Element::namespaceURI() const +{ + return _name.namespaceURI(); +} + + +XMLString Element::prefix() const +{ + return _name.prefix(); +} + + +const XMLString& Element::localName() const +{ + return _name.localName(); +} + + +bool Element::hasAttributes() const +{ + return _pFirstAttr != 0; +} + + +XMLString Element::innerText() const +{ + XMLString result; + Node* pChild = firstChild(); + while (pChild) + { + result.append(pChild->innerText()); + pChild = pChild->nextSibling(); + } + return result; +} + + +Element* Element::getChildElement(const XMLString& name) const +{ + Node* pNode = firstChild(); + while (pNode && !(pNode->nodeType() == Node::ELEMENT_NODE && pNode->nodeName() == name)) + pNode = pNode->nextSibling(); + return static_cast<Element*>(pNode); +} + + +Element* Element::getChildElementNS(const XMLString& namespaceURI, const XMLString& localName) const +{ + Node* pNode = firstChild(); + while (pNode && !(pNode->nodeType() == Node::ELEMENT_NODE && pNode->namespaceURI() == namespaceURI && pNode->localName() == localName)) + pNode = pNode->nextSibling(); + return static_cast<Element*>(pNode); +} + + +void Element::dispatchNodeRemovedFromDocument() +{ + AbstractContainerNode::dispatchNodeRemovedFromDocument(); + Attr* pAttr = _pFirstAttr; + while (pAttr) + { + pAttr->dispatchNodeRemovedFromDocument(); + pAttr = static_cast<Attr*>(pAttr->_pNext); + } +} + + +void Element::dispatchNodeInsertedIntoDocument() +{ + AbstractContainerNode::dispatchNodeInsertedIntoDocument(); + Attr* pAttr = _pFirstAttr; + while (pAttr) + { + pAttr->dispatchNodeInsertedIntoDocument(); + pAttr = static_cast<Attr*>(pAttr->_pNext); + } +} + + +Node* Element::copyNode(bool deep, Document* pOwnerDocument) const +{ + Element* pClone = new Element(pOwnerDocument, *this); + if (deep) + { + Node* pNode = firstChild(); + while (pNode) + { + pClone->appendChild(static_cast<AbstractNode*>(pNode)->copyNode(true, pOwnerDocument))->release(); + pNode = pNode->nextSibling(); + } + } + return pClone; +} + + +Element* Element::getElementById(const XMLString& elementId, const XMLString& idAttribute) const +{ + if (getAttribute(idAttribute) == elementId) + return const_cast<Element*>(this); + + Node* pNode = firstChild(); + while (pNode) + { + if (pNode->nodeType() == Node::ELEMENT_NODE) + { + Element* pResult = static_cast<Element*>(pNode)->getElementById(elementId, idAttribute); + if (pResult) return pResult; + } + pNode = pNode->nextSibling(); + } + return 0; +} + + +Element* Element::getElementByIdNS(const XMLString& elementId, const XMLString& idAttributeURI, const XMLString& idAttributeLocalName) const +{ + if (getAttributeNS(idAttributeURI, idAttributeLocalName) == elementId) + return const_cast<Element*>(this); + + Node* pNode = firstChild(); + while (pNode) + { + if (pNode->nodeType() == Node::ELEMENT_NODE) + { + Element* pResult = static_cast<Element*>(pNode)->getElementByIdNS(elementId, idAttributeURI, idAttributeLocalName); + if (pResult) return pResult; + } + pNode = pNode->nextSibling(); + } + return 0; +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/ElementsByTagNameList.cpp b/contrib/libs/poco/XML/src/ElementsByTagNameList.cpp new file mode 100644 index 0000000000..d6bc382ff6 --- /dev/null +++ b/contrib/libs/poco/XML/src/ElementsByTagNameList.cpp @@ -0,0 +1,151 @@ +// +// ElementsByTagNameList.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/ElementsByTagNameList.h" +#include "Poco/DOM/Node.h" +#include "Poco/DOM/Document.h" +#include <climits> + + +namespace Poco { +namespace XML { + + +ElementsByTagNameList::ElementsByTagNameList(const Node* pParent, const XMLString& name): + _pParent(pParent), + _name(name), + _count(0) +{ + poco_check_ptr (pParent); + + _pParent->duplicate(); +} + + +ElementsByTagNameList::~ElementsByTagNameList() +{ + _pParent->release(); +} + + +Node* ElementsByTagNameList::item(unsigned long index) const +{ + _count = 0; + return find(_pParent, index); +} + + +unsigned long ElementsByTagNameList::length() const +{ + _count = 0; + find(_pParent, ULONG_MAX); + return _count; +} + + +namespace +{ + static const XMLString asterisk = toXMLString("*"); +} + + +Node* ElementsByTagNameList::find(const Node* pParent, unsigned long index) const +{ + if (!pParent) return 0; + + // preorder search + Node* pCur = pParent->firstChild(); + while (pCur) + { + if (pCur->nodeType() == Node::ELEMENT_NODE && (_name == asterisk || pCur->nodeName() == _name)) + { + if (_count == index) return pCur; + _count++; + } + Node* pNode = find(pCur, index); + if (pNode) return pNode; + pCur = pCur->nextSibling(); + } + return pCur; +} + + +void ElementsByTagNameList::autoRelease() +{ + _pParent->ownerDocument()->autoReleasePool().add(this); +} + + +ElementsByTagNameListNS::ElementsByTagNameListNS(const Node* pParent, const XMLString& namespaceURI, const XMLString& localName): + _pParent(pParent), + _localName(localName), + _namespaceURI(namespaceURI), + _count(0) +{ + poco_check_ptr (pParent); + + _pParent->duplicate(); +} + + + +ElementsByTagNameListNS::~ElementsByTagNameListNS() +{ + _pParent->release(); +} + + +Node* ElementsByTagNameListNS::item(unsigned long index) const +{ + _count = 0; + return find(_pParent, index); +} + + +unsigned long ElementsByTagNameListNS::length() const +{ + _count = 0; + find(_pParent, ULONG_MAX); + return _count; +} + + +Node* ElementsByTagNameListNS::find(const Node* pParent, unsigned long index) const +{ + if (!pParent) return 0; + + // preorder search + Node* pCur = pParent->firstChild(); + while (pCur) + { + if (pCur->nodeType() == Node::ELEMENT_NODE && (_localName == asterisk || pCur->localName() == _localName) && (_namespaceURI == asterisk || pCur->namespaceURI() == _namespaceURI)) + { + if (_count == index) return pCur; + _count++; + } + Node* pNode = find(pCur, index); + if (pNode) return pNode; + pCur = pCur->nextSibling(); + } + return pCur; +} + + +void ElementsByTagNameListNS::autoRelease() +{ + _pParent->ownerDocument()->autoReleasePool().add(this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/Entity.cpp b/contrib/libs/poco/XML/src/Entity.cpp new file mode 100644 index 0000000000..e90a2497e7 --- /dev/null +++ b/contrib/libs/poco/XML/src/Entity.cpp @@ -0,0 +1,68 @@ +// +// Entity.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/Entity.h" + + +namespace Poco { +namespace XML { + + +const XMLString Entity::NODE_NAME = toXMLString("#entity"); + + +Entity::Entity(Document* pOwnerDocument, const XMLString& name, const XMLString& publicId, const XMLString& systemId, const XMLString& notationName): + AbstractContainerNode(pOwnerDocument), + _name(name), + _publicId(publicId), + _systemId(systemId), + _notationName(notationName) +{ +} + + +Entity::Entity(Document* pOwnerDocument, const Entity& entity): + AbstractContainerNode(pOwnerDocument, entity), + _name(entity._name), + _publicId(entity._publicId), + _systemId(entity._systemId), + _notationName(entity._notationName) +{ +} + + +Entity::~Entity() +{ +} + + +const XMLString& Entity::nodeName() const +{ + return _name; +} + + +unsigned short Entity::nodeType() const +{ + return Node::ENTITY_NODE; +} + + +Node* Entity::copyNode(bool /*deep*/, Document* pOwnerDocument) const +{ + return new Entity(pOwnerDocument, *this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/EntityReference.cpp b/contrib/libs/poco/XML/src/EntityReference.cpp new file mode 100644 index 0000000000..86fa052ab5 --- /dev/null +++ b/contrib/libs/poco/XML/src/EntityReference.cpp @@ -0,0 +1,59 @@ +// +// EntityReference.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/EntityReference.h" + + +namespace Poco { +namespace XML { + + +EntityReference::EntityReference(Document* pOwnerDocument, const XMLString& name): + AbstractNode(pOwnerDocument), + _name(name) +{ +} + + +EntityReference::EntityReference(Document* pOwnerDocument, const EntityReference& ref): + AbstractNode(pOwnerDocument, ref), + _name(ref._name) +{ +} + + +EntityReference::~EntityReference() +{ +} + + +const XMLString& EntityReference::nodeName() const +{ + return _name; +} + + +unsigned short EntityReference::nodeType() const +{ + return Node::ENTITY_REFERENCE_NODE; +} + + +Node* EntityReference::copyNode(bool /*deep*/, Document* pOwnerDocument) const +{ + return new EntityReference(pOwnerDocument, *this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/EntityResolver.cpp b/contrib/libs/poco/XML/src/EntityResolver.cpp new file mode 100644 index 0000000000..80e1bde9c2 --- /dev/null +++ b/contrib/libs/poco/XML/src/EntityResolver.cpp @@ -0,0 +1,27 @@ +// +// EntityResolver.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/EntityResolver.h" + + +namespace Poco { +namespace XML { + + +EntityResolver::~EntityResolver() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/EntityResolverImpl.cpp b/contrib/libs/poco/XML/src/EntityResolverImpl.cpp new file mode 100644 index 0000000000..a072df5e52 --- /dev/null +++ b/contrib/libs/poco/XML/src/EntityResolverImpl.cpp @@ -0,0 +1,78 @@ +// +// EntityResolverImpl.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/EntityResolverImpl.h" +#include "Poco/SAX/InputSource.h" +#include "Poco/XML/XMLString.h" +#include "Poco/URI.h" +#include "Poco/Path.h" +#include "Poco/Exception.h" + + +using Poco::URIStreamOpener; +using Poco::URI; +using Poco::Path; +using Poco::Exception; +using Poco::IOException; +using Poco::OpenFileException; + + +namespace Poco { +namespace XML { + + +EntityResolverImpl::EntityResolverImpl(): + _opener(URIStreamOpener::defaultOpener()) +{ +} + + +EntityResolverImpl::EntityResolverImpl(const URIStreamOpener& opener): + _opener(opener) +{ +} + + +EntityResolverImpl::~EntityResolverImpl() +{ +} + + +InputSource* EntityResolverImpl::resolveEntity(const XMLString* publicId, const XMLString& systemId) +{ + std::istream* pIstr = resolveSystemId(systemId); + InputSource* pInputSource = new InputSource(systemId); + if (publicId) pInputSource->setPublicId(*publicId); + pInputSource->setByteStream(*pIstr); + return pInputSource; +} + + +void EntityResolverImpl::releaseInputSource(InputSource* pSource) +{ + poco_check_ptr (pSource); + + delete pSource->getByteStream(); + delete pSource; +} + + +std::istream* EntityResolverImpl::resolveSystemId(const XMLString& systemId) +{ + std::string sid = fromXMLString(systemId); + return _opener.open(sid); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/ErrorHandler.cpp b/contrib/libs/poco/XML/src/ErrorHandler.cpp new file mode 100644 index 0000000000..6a497a3816 --- /dev/null +++ b/contrib/libs/poco/XML/src/ErrorHandler.cpp @@ -0,0 +1,27 @@ +// +// ErrorHandler.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/ErrorHandler.h" + + +namespace Poco { +namespace XML { + + +ErrorHandler::~ErrorHandler() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/Event.cpp b/contrib/libs/poco/XML/src/Event.cpp new file mode 100644 index 0000000000..ffdff7385e --- /dev/null +++ b/contrib/libs/poco/XML/src/Event.cpp @@ -0,0 +1,102 @@ +// +// Event.cpp +// +// Library: XML +// Package: DOM +// Module: DOMEvents +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/Event.h" +#include "Poco/DOM/Document.h" + + +namespace Poco { +namespace XML { + + +Event::Event(Document* pOwnerDocument, const XMLString& type): + _pOwner(pOwnerDocument), + _type(type), + _pTarget(0), + _pCurrentTarget(0), + _currentPhase(CAPTURING_PHASE), + _bubbles(true), + _cancelable(true), + _canceled(false), + _stopped(false) +{ +} + + +Event::Event(Document* pOwnerDocument, const XMLString& type, EventTarget* pTarget, bool canBubble, bool isCancelable): + _pOwner(pOwnerDocument), + _type(type), + _pTarget(pTarget), + _pCurrentTarget(0), + _currentPhase(CAPTURING_PHASE), + _bubbles(canBubble), + _cancelable(isCancelable), + _canceled(false), + _stopped(false) +{ +} + + +Event::~Event() +{ +} + + +void Event::stopPropagation() +{ + _stopped = true; +} + + +void Event::preventDefault() +{ + _canceled = true; +} + + +void Event::initEvent(const XMLString& eventType, bool canBubble, bool isCancelable) +{ + _type = eventType; + _bubbles = canBubble; + _cancelable = isCancelable; + _canceled = false; + _stopped = false; +} + + +void Event::setTarget(EventTarget* pTarget) +{ + _pTarget = pTarget; +} + + +void Event::setCurrentPhase(PhaseType phase) +{ + _currentPhase = phase; +} + + +void Event::setCurrentTarget(EventTarget* pTarget) +{ + _pCurrentTarget = pTarget; +} + + +void Event::autoRelease() +{ + _pOwner->autoReleasePool().add(this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/EventDispatcher.cpp b/contrib/libs/poco/XML/src/EventDispatcher.cpp new file mode 100644 index 0000000000..4656f9b45f --- /dev/null +++ b/contrib/libs/poco/XML/src/EventDispatcher.cpp @@ -0,0 +1,146 @@ +// +// EventDispatcher.cpp +// +// Library: XML +// Package: DOM +// Module: DOMEvents +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/EventDispatcher.h" +#include "Poco/DOM/Event.h" +#include "Poco/DOM/EventListener.h" + + +namespace +{ + class DispatchGuard + { + public: + DispatchGuard(int& count): + _count(count) + { + ++_count; + } + + ~DispatchGuard() + { + --_count; + } + + private: + int& _count; + }; +} + + +namespace Poco { +namespace XML { + + +EventDispatcher::EventDispatcher(): + _inDispatch(0) +{ +} + + +EventDispatcher::~EventDispatcher() +{ +} + + +void EventDispatcher::addEventListener(const XMLString& type, EventListener* listener, bool useCapture) +{ + EventListenerItem item; + item.type = type; + item.pListener = listener; + item.useCapture = useCapture; + _listeners.push_front(item); +} + + +void EventDispatcher::removeEventListener(const XMLString& type, EventListener* listener, bool useCapture) +{ + EventListenerList::iterator it = _listeners.begin(); + while (it != _listeners.end()) + { + if (it->type == type && it->pListener == listener && it->useCapture == useCapture) + { + it->pListener = 0; + } + if (!_inDispatch && !it->pListener) + { + EventListenerList::iterator del = it++; + _listeners.erase(del); + } + else ++it; + } +} + + +void EventDispatcher::dispatchEvent(Event* evt) +{ + DispatchGuard guard(_inDispatch); + EventListenerList::iterator it = _listeners.begin(); + while (it != _listeners.end()) + { + if (it->pListener && it->type == evt->type()) + { + it->pListener->handleEvent(evt); + } + if (!it->pListener) + { + EventListenerList::iterator del = it++; + _listeners.erase(del); + } + else ++it; + } +} + + +void EventDispatcher::captureEvent(Event* evt) +{ + DispatchGuard guard(_inDispatch); + EventListenerList::iterator it = _listeners.begin(); + while (it != _listeners.end()) + { + if (it->pListener && it->useCapture && it->type == evt->type()) + { + it->pListener->handleEvent(evt); + } + if (!it->pListener) + { + EventListenerList::iterator del = it++; + _listeners.erase(del); + } + else ++it; + } +} + + +void EventDispatcher::bubbleEvent(Event* evt) +{ + DispatchGuard guard(_inDispatch); + EventListenerList::iterator it = _listeners.begin(); + while (it != _listeners.end()) + { + if (it->pListener && !it->useCapture && it->type == evt->type()) + { + it->pListener->handleEvent(evt); + } + if (!it->pListener) + { + EventListenerList::iterator del = it++; + _listeners.erase(del); + } + else ++it; + } +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/EventException.cpp b/contrib/libs/poco/XML/src/EventException.cpp new file mode 100644 index 0000000000..d2d07bd1c6 --- /dev/null +++ b/contrib/libs/poco/XML/src/EventException.cpp @@ -0,0 +1,65 @@ +// +// EventException.cpp +// +// Library: XML +// Package: DOM +// Module: DOMEvents +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/EventException.h" +#include <typeinfo> + + +namespace Poco { +namespace XML { + + +EventException::EventException(int code): + XMLException("Unspecified event type", code) +{ +} + + +EventException::EventException(const EventException& exc): + XMLException(exc) +{ +} + + +EventException::~EventException() noexcept +{ +} + + +EventException& EventException::operator = (const EventException& exc) +{ + XMLException::operator = (exc); + return *this; +} + + +const char* EventException::name() const noexcept +{ + return "EventException"; +} + + +const char* EventException::className() const noexcept +{ + return typeid(*this).name(); +} + + +Poco::Exception* EventException::clone() const +{ + return new EventException(*this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/EventListener.cpp b/contrib/libs/poco/XML/src/EventListener.cpp new file mode 100644 index 0000000000..b6c3988818 --- /dev/null +++ b/contrib/libs/poco/XML/src/EventListener.cpp @@ -0,0 +1,27 @@ +// +// EventListener.cpp +// +// Library: XML +// Package: DOM +// Module: DOMEvents +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/EventListener.h" + + +namespace Poco { +namespace XML { + + +EventListener::~EventListener() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/EventTarget.cpp b/contrib/libs/poco/XML/src/EventTarget.cpp new file mode 100644 index 0000000000..2aa76a0dad --- /dev/null +++ b/contrib/libs/poco/XML/src/EventTarget.cpp @@ -0,0 +1,27 @@ +// +// EventTarget.cpp +// +// Library: XML +// Package: DOM +// Module: DOMEvents +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/EventTarget.h" + + +namespace Poco { +namespace XML { + + +EventTarget::~EventTarget() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/InputSource.cpp b/contrib/libs/poco/XML/src/InputSource.cpp new file mode 100644 index 0000000000..1ec8cfc0be --- /dev/null +++ b/contrib/libs/poco/XML/src/InputSource.cpp @@ -0,0 +1,80 @@ +// +// InputSource.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/InputSource.h" + + +namespace Poco { +namespace XML { + + +InputSource::InputSource(): + _bistr(0), + _cistr(0) +{ +} + + +InputSource::InputSource(const XMLString& systemId): + _systemId(systemId), + _bistr(0), + _cistr(0) +{ +} + + +InputSource::InputSource(XMLByteInputStream& bistr): + _bistr(&bistr), + _cistr(0) +{ +} + + +InputSource::~InputSource() +{ +} + + +void InputSource::setPublicId(const XMLString& publicId) +{ + _publicId = publicId; +} + + +void InputSource::setSystemId(const XMLString& systemId) +{ + _systemId = systemId; +} + + +void InputSource::setEncoding(const XMLString& encoding) +{ + _encoding = encoding; +} + + +void InputSource::setByteStream(XMLByteInputStream& bistr) +{ + _bistr = &bistr; +} + + +void InputSource::setCharacterStream(XMLCharInputStream& cistr) +{ + _cistr = &cistr; +} + + +} } // namespace Poco::XML + diff --git a/contrib/libs/poco/XML/src/LexicalHandler.cpp b/contrib/libs/poco/XML/src/LexicalHandler.cpp new file mode 100644 index 0000000000..52de41d742 --- /dev/null +++ b/contrib/libs/poco/XML/src/LexicalHandler.cpp @@ -0,0 +1,27 @@ +// +// LexicalHandler.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/LexicalHandler.h" + + +namespace Poco { +namespace XML { + + +LexicalHandler::~LexicalHandler() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/Locator.cpp b/contrib/libs/poco/XML/src/Locator.cpp new file mode 100644 index 0000000000..3be93bf795 --- /dev/null +++ b/contrib/libs/poco/XML/src/Locator.cpp @@ -0,0 +1,27 @@ +// +// Locator.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/Locator.h" + + +namespace Poco { +namespace XML { + + +Locator::~Locator() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/LocatorImpl.cpp b/contrib/libs/poco/XML/src/LocatorImpl.cpp new file mode 100644 index 0000000000..a77cc43f60 --- /dev/null +++ b/contrib/libs/poco/XML/src/LocatorImpl.cpp @@ -0,0 +1,104 @@ +// +// LocatorImpl.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/LocatorImpl.h" + + +namespace Poco { +namespace XML { + + +LocatorImpl::LocatorImpl() +{ + _lineNumber = 0; + _columnNumber = 0; +} + + +LocatorImpl::LocatorImpl(const Locator& loc) +{ + _publicId = loc.getPublicId(); + _systemId = loc.getSystemId(); + _lineNumber = loc.getLineNumber(); + _columnNumber = loc.getColumnNumber(); +} + + +LocatorImpl::~LocatorImpl() +{ +} + + +LocatorImpl& LocatorImpl::operator = (const Locator& loc) +{ + if (&loc != this) + { + _publicId = loc.getPublicId(); + _systemId = loc.getSystemId(); + _lineNumber = loc.getLineNumber(); + _columnNumber = loc.getColumnNumber(); + } + return *this; +} + + +XMLString LocatorImpl::getPublicId() const +{ + return _publicId; +} + + +XMLString LocatorImpl::getSystemId() const +{ + return _systemId; +} + + +int LocatorImpl::getLineNumber() const +{ + return _lineNumber; +} + + +int LocatorImpl::getColumnNumber() const +{ + return _columnNumber; +} + + +void LocatorImpl::setPublicId(const XMLString& publicId) +{ + _publicId = publicId; +} + + +void LocatorImpl::setSystemId(const XMLString& systemId) +{ + _systemId = systemId; +} + + +void LocatorImpl::setLineNumber(int lineNumber) +{ + _lineNumber = lineNumber; +} + + +void LocatorImpl::setColumnNumber(int columnNumber) +{ + _columnNumber = columnNumber; +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/MutationEvent.cpp b/contrib/libs/poco/XML/src/MutationEvent.cpp new file mode 100644 index 0000000000..485836e6b7 --- /dev/null +++ b/contrib/libs/poco/XML/src/MutationEvent.cpp @@ -0,0 +1,76 @@ +// +// MutationEvent.cpp +// +// Library: XML +// Package: DOM +// Module: DOMEvents +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/MutationEvent.h" + + +namespace Poco { +namespace XML { + + +const XMLString MutationEvent::DOMSubtreeModified = toXMLString("DOMSubtreeModified"); +const XMLString MutationEvent::DOMNodeInserted = toXMLString("DOMNodeInserted"); +const XMLString MutationEvent::DOMNodeRemoved = toXMLString("DOMNodeRemoved"); +const XMLString MutationEvent::DOMNodeRemovedFromDocument = toXMLString("DOMNodeRemovedFromDocument"); +const XMLString MutationEvent::DOMNodeInsertedIntoDocument = toXMLString("DOMNodeInsertedIntoDocument"); +const XMLString MutationEvent::DOMAttrModified = toXMLString("DOMAttrModified"); +const XMLString MutationEvent::DOMCharacterDataModified = toXMLString("DOMCharacterDataModified"); + + +MutationEvent::MutationEvent(Document* pOwnerDocument, const XMLString& type): + Event(pOwnerDocument, type, 0, true, false), + _change(MODIFICATION), + _pRelatedNode(0) +{ +} + + +MutationEvent::MutationEvent(Document* pOwnerDocument, const XMLString& type, EventTarget* pTarget, bool canBubble, bool cancelable, Node* relatedNode): + Event(pOwnerDocument, type, pTarget, canBubble, cancelable), + _change(MODIFICATION), + _pRelatedNode(relatedNode) +{ +} + + +MutationEvent::MutationEvent(Document* pOwnerDocument, const XMLString& type, EventTarget* pTarget, bool canBubble, bool cancelable, Node* relatedNode, + const XMLString& prevValue, const XMLString& newValue, const XMLString& attrName, AttrChangeType change): + Event(pOwnerDocument, type, pTarget, canBubble, cancelable), + _prevValue(prevValue), + _newValue(newValue), + _attrName(attrName), + _change(change), + _pRelatedNode(relatedNode) +{ +} + + +MutationEvent::~MutationEvent() +{ +} + + +void MutationEvent::initMutationEvent(const XMLString& type, bool canBubble, bool cancelable, Node* relatedNode, + const XMLString& prevValue, const XMLString& newValue, const XMLString& attrName, AttrChangeType change) +{ + initEvent(type, canBubble, cancelable); + _pRelatedNode = relatedNode; + _prevValue = prevValue; + _newValue = newValue; + _attrName = attrName; + _change = change; +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/Name.cpp b/contrib/libs/poco/XML/src/Name.cpp new file mode 100644 index 0000000000..832afec8df --- /dev/null +++ b/contrib/libs/poco/XML/src/Name.cpp @@ -0,0 +1,170 @@ +// +// Name.cpp +// +// Library: XML +// Package: XML +// Module: Name +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/XML/Name.h" +#include <algorithm> + + +namespace Poco { +namespace XML { + + +const XMLString Name::EMPTY_NAME; + + +Name::Name() +{ +} + + +Name::Name(const XMLString& qname): + _qname(qname) +{ +} + + +Name::Name(const XMLString& qname, const XMLString& namespaceURI): + _qname(qname), + _namespaceURI(namespaceURI), + _localName(localName(qname)) +{ +} + + +Name::Name(const XMLString& qname, const XMLString& namespaceURI, const XMLString& localName): + _qname(qname), + _namespaceURI(namespaceURI), + _localName(localName) +{ +} + + +Name::Name(const Name& name): + _qname(name._qname), + _namespaceURI(name._namespaceURI), + _localName(name._localName) +{ +} + + +Name::~Name() +{ +} + + +Name& Name::operator = (const Name& name) +{ + if (this != &name) + { + _qname = name._qname; + _namespaceURI = name._namespaceURI; + _localName = name._localName; + } + return *this; +} + + +void Name::swap(Name& name) +{ + std::swap(_qname, name._qname); + std::swap(_namespaceURI, name._namespaceURI); + std::swap(_localName, name._localName); +} + + +void Name::assign(const XMLString& qname) +{ + _qname = qname; + _namespaceURI.clear(); + _localName.clear(); +} + + +void Name::assign(const XMLString& qname, const XMLString& namespaceURI) +{ + _qname = qname; + _namespaceURI = namespaceURI; + _localName = localName(qname); +} + + +void Name::assign(const XMLString& qname, const XMLString& namespaceURI, const XMLString& localName) +{ + _qname = qname; + _namespaceURI = namespaceURI; + _localName = localName; +} + + +bool Name::equals(const Name& name) const +{ + return name._namespaceURI == _namespaceURI && name._localName == _localName && name._qname == _qname; +} + + +bool Name::equals(const XMLString& qname, const XMLString& namespaceURI, const XMLString& localName) const +{ + return _namespaceURI == namespaceURI && _localName == localName && _qname == qname; +} + + +bool Name::equalsWeakly(const XMLString& qname, const XMLString& namespaceURI, const XMLString& localName) const +{ + return (_qname == qname && !qname.empty()) || (_namespaceURI == namespaceURI && _localName == localName && !_localName.empty()); +} + + +XMLString Name::prefix() const +{ + return prefix(_qname); +} + + +void Name::split(const XMLString& qname, XMLString& prefix, XMLString& localName) +{ + XMLString::size_type pos = qname.find(':'); + if (pos != XMLString::npos) + { + prefix.assign(qname, 0, pos); + localName.assign(qname, pos + 1, qname.size() - pos - 1); + } + else + { + prefix.clear(); + localName.assign(qname); + } +} + + +XMLString Name::localName(const XMLString& qname) +{ + XMLString::size_type pos = qname.find(':'); + if (pos != XMLString::npos) + return XMLString(qname, pos + 1, qname.size() - pos - 1); + else + return qname; +} + + +XMLString Name::prefix(const XMLString& qname) +{ + XMLString::size_type pos = qname.find(':'); + if (pos != XMLString::npos) + return XMLString(qname, 0, pos); + else + return EMPTY_NAME; +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/NamePool.cpp b/contrib/libs/poco/XML/src/NamePool.cpp new file mode 100644 index 0000000000..4e234eabf9 --- /dev/null +++ b/contrib/libs/poco/XML/src/NamePool.cpp @@ -0,0 +1,132 @@ +// +// NamePool.cpp +// +// Library: XML +// Package: XML +// Module: NamePool +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/XML/NamePool.h" +#include "Poco/Exception.h" +#include "Poco/Random.h" + + +namespace Poco { +namespace XML { + + +class NamePoolItem +{ +public: + NamePoolItem(): _used(false) + { + } + + ~NamePoolItem() + { + } + + bool set(const XMLString& qname, const XMLString& namespaceURI, const XMLString& localName) + { + if (!_used) + { + _name.assign(qname, namespaceURI, localName); + _used = true; + return true; + } + else return _name.equals(qname, namespaceURI, localName); + } + + const Name& get() const + { + return _name; + } + + bool used() const + { + return _used; + } + +private: + Name _name; + bool _used; +}; + + +NamePool::NamePool(unsigned long size): + _size(size), + _salt(0), + _rc(1) +{ + poco_assert (size > 1); + + _pItems = new NamePoolItem[size]; + + Poco::Random rnd; + rnd.seed(); + _salt = rnd.next(); +} + + +NamePool::~NamePool() +{ + delete [] _pItems; +} + + +void NamePool::duplicate() +{ + ++_rc; +} + + +void NamePool::release() +{ + if (--_rc == 0) + delete this; +} + + +const Name& NamePool::insert(const XMLString& qname, const XMLString& namespaceURI, const XMLString& localName) +{ + unsigned long i = 0; + unsigned long n = (hash(qname, namespaceURI, localName) ^ _salt) % _size; + + while (!_pItems[n].set(qname, namespaceURI, localName) && i++ < _size) + n = (n + 1) % _size; + + if (i > _size) throw Poco::PoolOverflowException("XML name pool"); + + return _pItems[n].get(); +} + + +const Name& NamePool::insert(const Name& name) +{ + return insert(name.qname(), name.namespaceURI(), name.localName()); +} + + +unsigned long NamePool::hash(const XMLString& qname, const XMLString& namespaceURI, const XMLString& localName) +{ + unsigned long h = 0; + XMLString::const_iterator it = qname.begin(); + XMLString::const_iterator end = qname.end(); + while (it != end) h = (h << 5) + h + (unsigned long) *it++; + it = namespaceURI.begin(); + end = namespaceURI.end(); + while (it != end) h = (h << 5) + h + (unsigned long) *it++; + it = localName.begin(); + end = localName.end(); + while (it != end) h = (h << 5) + h + (unsigned long) *it++; + return h; +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/NamedNodeMap.cpp b/contrib/libs/poco/XML/src/NamedNodeMap.cpp new file mode 100644 index 0000000000..91108bf534 --- /dev/null +++ b/contrib/libs/poco/XML/src/NamedNodeMap.cpp @@ -0,0 +1,27 @@ +// +// NamedNodeMap.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/NamedNodeMap.h" + + +namespace Poco { +namespace XML { + + +NamedNodeMap::~NamedNodeMap() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/NamespaceStrategy.cpp b/contrib/libs/poco/XML/src/NamespaceStrategy.cpp new file mode 100644 index 0000000000..cfdccd6eca --- /dev/null +++ b/contrib/libs/poco/XML/src/NamespaceStrategy.cpp @@ -0,0 +1,195 @@ +// +// NamespaceStrategy.cpp +// +// Library: XML +// Package: XML +// Module: NamespaceStrategy +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/XML/NamespaceStrategy.h" +#include "Poco/SAX/AttributesImpl.h" +#include "Poco/SAX/ContentHandler.h" +#include "Poco/XML/XMLException.h" +#include "Poco/XML/Name.h" + + +namespace Poco { +namespace XML { + + +const XMLString NamespaceStrategy::NOTHING; + + +NamespaceStrategy::~NamespaceStrategy() +{ +} + + +void NamespaceStrategy::splitName(const XMLChar* qname, XMLString& uri, XMLString& localName) +{ + for (const XMLChar* p = qname; *p; ++p) + { + if (*p == '\t') + { + uri.assign(qname, p - qname); + localName.assign(p + 1); + return; + } + } + localName = qname; +} + + +void NamespaceStrategy::splitName(const XMLChar* qname, XMLString& uri, XMLString& localName, XMLString& prefix) +{ + const XMLChar* p = qname; + while (*p && *p != '\t') ++p; + if (*p) + { + uri.assign(qname, p - qname); + ++p; + const XMLChar* loc = p; + while (*p && *p != '\t') ++p; + localName.assign(loc, p - loc); + if (*p) + prefix.assign(++p); + else + prefix.assign(XML_LIT("")); + } + else + { + uri.assign(XML_LIT("")); + localName = qname; + prefix.assign(XML_LIT("")); + } +} + + +NoNamespacesStrategy::NoNamespacesStrategy() +{ + _attrs.reserve(32); +} + + +NoNamespacesStrategy::~NoNamespacesStrategy() +{ +} + + +void NoNamespacesStrategy::startElement(const XMLChar* name, const XMLChar** atts, int specifiedCount, ContentHandler* pContentHandler) +{ + poco_assert_dbg (name && atts && pContentHandler); + + _attrs.clear(); + for (int i = 0; *atts; ++i) + { + AttributesImpl::Attribute& attr = _attrs.addAttribute(); + attr.qname.assign(*atts++); + attr.value.assign(*atts++); + attr.specified = i < specifiedCount; + } + _name.assign(name); + pContentHandler->startElement(NOTHING, NOTHING, _name, _attrs); +} + + +void NoNamespacesStrategy::endElement(const XMLChar* name, ContentHandler* pContentHandler) +{ + poco_assert_dbg (name && pContentHandler); + + _name.assign(name); + pContentHandler->endElement(NOTHING, NOTHING, _name); +} + + +NoNamespacePrefixesStrategy::NoNamespacePrefixesStrategy() +{ + _attrs.reserve(32); +} + + +NoNamespacePrefixesStrategy::~NoNamespacePrefixesStrategy() +{ +} + + +void NoNamespacePrefixesStrategy::startElement(const XMLChar* name, const XMLChar** atts, int specifiedCount, ContentHandler* pContentHandler) +{ + poco_assert_dbg (name && atts && pContentHandler); + + _attrs.clear(); + for (int i = 0; *atts; ++i) + { + const XMLChar* attrName = *atts++; + const XMLChar* attrValue = *atts++; + AttributesImpl::Attribute& attr = _attrs.addAttribute(); + splitName(attrName, attr.namespaceURI, attr.localName); + attr.value.assign(attrValue); + attr.specified = i < specifiedCount; + } + splitName(name, _uri, _local); + pContentHandler->startElement(_uri, _local, NOTHING, _attrs); +} + + +void NoNamespacePrefixesStrategy::endElement(const XMLChar* name, ContentHandler* pContentHandler) +{ + poco_assert_dbg (name && pContentHandler); + + splitName(name, _uri, _local); + pContentHandler->endElement(_uri, _local, NOTHING); +} + + +NamespacePrefixesStrategy::NamespacePrefixesStrategy() +{ + _attrs.reserve(32); +} + + +NamespacePrefixesStrategy::~NamespacePrefixesStrategy() +{ +} + + +void NamespacePrefixesStrategy::startElement(const XMLChar* name, const XMLChar** atts, int specifiedCount, ContentHandler* pContentHandler) +{ + poco_assert_dbg (name && atts && pContentHandler); + + _attrs.clear(); + for (int i = 0; *atts; ++i) + { + const XMLChar* attrName = *atts++; + const XMLChar* attrValue = *atts++; + AttributesImpl::Attribute& attr = _attrs.addAttribute(); + splitName(attrName, attr.namespaceURI, attr.localName, attr.qname); + if (!attr.qname.empty()) attr.qname += ':'; + attr.qname.append(attr.localName); + attr.value.assign(attrValue); + attr.specified = i < specifiedCount; + } + splitName(name, _uri, _local, _qname); + if (!_qname.empty()) _qname += ':'; + _qname.append(_local); + pContentHandler->startElement(_uri, _local, _qname, _attrs); +} + + +void NamespacePrefixesStrategy::endElement(const XMLChar* name, ContentHandler* pContentHandler) +{ + poco_assert_dbg (name && pContentHandler); + + splitName(name, _uri, _local, _qname); + if (!_qname.empty()) _qname += ':'; + _qname.append(_local); + pContentHandler->endElement(_uri, _local, _qname); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/NamespaceSupport.cpp b/contrib/libs/poco/XML/src/NamespaceSupport.cpp new file mode 100644 index 0000000000..cfc752885f --- /dev/null +++ b/contrib/libs/poco/XML/src/NamespaceSupport.cpp @@ -0,0 +1,187 @@ +// +// NamespaceSupport.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/NamespaceSupport.h" +#include "Poco/XML/Name.h" + + +namespace Poco { +namespace XML { + + +const XMLString NamespaceSupport::EMPTY_STRING; +const XMLString NamespaceSupport::XML_NAMESPACE = toXMLString("http://www.w3.org/XML/1998/namespace"); +const XMLString NamespaceSupport::XML_NAMESPACE_PREFIX = toXMLString("xml"); +const XMLString NamespaceSupport::XMLNS_NAMESPACE = toXMLString("http://www.w3.org/xmlns/2000/"); +const XMLString NamespaceSupport::XMLNS_NAMESPACE_PREFIX = toXMLString("xmlns"); + + +NamespaceSupport::NamespaceSupport() +{ + reset(); +} + + +NamespaceSupport::~NamespaceSupport() +{ +} + + +bool NamespaceSupport::declarePrefix(const XMLString& prefix, const XMLString& namespaceURI) +{ + poco_assert (_contexts.size() > 0); + + Context& ctx = _contexts.back(); + if (ctx.find(prefix) == ctx.end()) + { + ctx.insert(Context::value_type(prefix, namespaceURI)); + return true; + } + else return false; +} + + +bool NamespaceSupport::undeclarePrefix(const XMLString& prefix) +{ + for (ContextVec::reverse_iterator rit = _contexts.rbegin(); rit != _contexts.rend(); ++rit) + { + Context::iterator it = rit->find(prefix); + if (it != rit->end()) + { + rit->erase(it); + return true; + } + } + return false; +} + + +void NamespaceSupport::getDeclaredPrefixes(PrefixSet& prefixes) const +{ + prefixes.clear(); + const Context& ctx = _contexts.back(); + for (Context::const_iterator it = ctx.begin(); it != ctx.end(); ++it) + prefixes.insert(it->first); +} + + +const XMLString& NamespaceSupport::getPrefix(const XMLString& namespaceURI) const +{ + for (ContextVec::const_reverse_iterator rit = _contexts.rbegin(); rit != _contexts.rend(); ++rit) + { + for (Context::const_iterator it = rit->begin(); it != rit->end(); ++it) + { + if (it->second == namespaceURI) + return it->first; + } + } + return EMPTY_STRING; +} + + +bool NamespaceSupport::isMapped(const XMLString& namespaceURI) const +{ + for (ContextVec::const_reverse_iterator rit = _contexts.rbegin(); rit != _contexts.rend(); ++rit) + { + for (Context::const_iterator it = rit->begin(); it != rit->end(); ++it) + { + if (it->second == namespaceURI) + return true; + } + } + return false; +} + + +void NamespaceSupport::getPrefixes(PrefixSet& prefixes) const +{ + prefixes.clear(); + for (ContextVec::const_reverse_iterator rit = _contexts.rbegin(); rit != _contexts.rend(); ++rit) + { + for (Context::const_iterator it = rit->begin(); it != rit->end(); ++it) + { + const XMLString& prefix = it->first; + if (!prefix.empty() && prefixes.find(prefix) == prefixes.end()) + prefixes.insert(it->first); + } + } +} + + +void NamespaceSupport::getPrefixes(const XMLString& namespaceURI, PrefixSet& prefixes) const +{ + prefixes.clear(); + for (ContextVec::const_reverse_iterator rit = _contexts.rbegin(); rit != _contexts.rend(); ++rit) + { + for (Context::const_iterator it = rit->begin(); it != rit->end(); ++it) + { + const XMLString& prefix = it->first; + if (it->second == namespaceURI && !prefix.empty() && prefixes.find(prefix) == prefixes.end()) + prefixes.insert(it->first); + } + } +} + + +const XMLString& NamespaceSupport::getURI(const XMLString& prefix) const +{ + for (ContextVec::const_reverse_iterator rit = _contexts.rbegin(); rit != _contexts.rend(); ++rit) + { + Context::const_iterator it = rit->find(prefix); + if (it != rit->end()) + return it->second; + } + return EMPTY_STRING; +} + + +void NamespaceSupport::pushContext() +{ + _contexts.push_back(Context()); +} + + +void NamespaceSupport::popContext() +{ + _contexts.pop_back(); +} + + +bool NamespaceSupport::processName(const XMLString& qname, XMLString& namespaceURI, XMLString& localName, bool isAttribute) const +{ + XMLString prefix; + Name::split(qname, prefix, localName); + if (prefix.empty() && isAttribute) + { + namespaceURI.clear(); + return true; + } + else + { + namespaceURI = getURI(prefix); + return !namespaceURI.empty() || prefix.empty(); + } +} + + +void NamespaceSupport::reset() +{ + _contexts.clear(); + pushContext(); + declarePrefix(XML_NAMESPACE_PREFIX, XML_NAMESPACE); + declarePrefix(XMLNS_NAMESPACE_PREFIX, XMLNS_NAMESPACE); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/Node.cpp b/contrib/libs/poco/XML/src/Node.cpp new file mode 100644 index 0000000000..4134fcfa29 --- /dev/null +++ b/contrib/libs/poco/XML/src/Node.cpp @@ -0,0 +1,27 @@ +// +// Node.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/Node.h" + + +namespace Poco { +namespace XML { + + +Node::~Node() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/NodeAppender.cpp b/contrib/libs/poco/XML/src/NodeAppender.cpp new file mode 100644 index 0000000000..e0582b89cf --- /dev/null +++ b/contrib/libs/poco/XML/src/NodeAppender.cpp @@ -0,0 +1,82 @@ +// +// NodeAppender.cpp +// +// Library: XML +// Package: DOM +// Module: NodeAppender +// +// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/NodeAppender.h" +#include "Poco/DOM/Element.h" +#include "Poco/DOM/DOMException.h" + + +namespace Poco { +namespace XML { + + +NodeAppender::NodeAppender(Element* parent): + _pParent(parent), + _pLast(0) +{ + poco_check_ptr (parent); + + _pLast = static_cast<AbstractNode*>(_pParent->lastChild()); +} + + +NodeAppender::~NodeAppender() +{ +} + + +void NodeAppender::appendChild(Node* newChild) +{ + poco_check_ptr (newChild); + poco_assert (_pLast == 0 || _pLast->_pNext == 0); + + if (static_cast<AbstractNode*>(newChild)->_pOwner != _pParent->_pOwner) + throw DOMException(DOMException::WRONG_DOCUMENT_ERR); + + if (newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE) + { + AbstractContainerNode* pFrag = static_cast<AbstractContainerNode*>(newChild); + AbstractNode* pChild = pFrag->_pFirstChild; + if (pChild) + { + if (_pLast) + _pLast->_pNext = pChild; + else + _pParent->_pFirstChild = pChild; + while (pChild) + { + _pLast = pChild; + pChild->_pParent = _pParent; + pChild = pChild->_pNext; + } + pFrag->_pFirstChild = 0; + } + } + else + { + AbstractNode* pAN = static_cast<AbstractNode*>(newChild); + pAN->duplicate(); + if (pAN->_pParent) + pAN->_pParent->removeChild(pAN); + pAN->_pParent = _pParent; + if (_pLast) + _pLast->_pNext = pAN; + else + _pParent->_pFirstChild = pAN; + _pLast = pAN; + } +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/NodeFilter.cpp b/contrib/libs/poco/XML/src/NodeFilter.cpp new file mode 100644 index 0000000000..7239f43407 --- /dev/null +++ b/contrib/libs/poco/XML/src/NodeFilter.cpp @@ -0,0 +1,27 @@ +// +// NodeFilter.cpp +// +// Library: XML +// Package: DOM +// Module: NodeFilter +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/NodeFilter.h" + + +namespace Poco { +namespace XML { + + +NodeFilter::~NodeFilter() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/NodeIterator.cpp b/contrib/libs/poco/XML/src/NodeIterator.cpp new file mode 100644 index 0000000000..69685f9f4e --- /dev/null +++ b/contrib/libs/poco/XML/src/NodeIterator.cpp @@ -0,0 +1,176 @@ +// +// NodeIterator.cpp +// +// Library: XML +// Package: DOM +// Module: NodeIterator +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/NodeIterator.h" +#include "Poco/DOM/AbstractNode.h" +#include "Poco/DOM/NodeFilter.h" +#include "Poco/DOM/DOMException.h" + + +namespace Poco { +namespace XML { + + +NodeIterator::NodeIterator(Node* root, unsigned long whatToShow, NodeFilter* pFilter): + _pRoot(root), + _whatToShow(whatToShow), + _pFilter(pFilter), + _pCurrent(0) +{ +} + + +NodeIterator::NodeIterator(const NodeIterator& iterator): + _pRoot(iterator._pRoot), + _whatToShow(iterator._whatToShow), + _pFilter(iterator._pFilter), + _pCurrent(iterator._pCurrent) +{ +} + + +NodeIterator& NodeIterator::operator = (const NodeIterator& iterator) +{ + if (&iterator != this) + { + _pRoot = iterator._pRoot; + _whatToShow = iterator._whatToShow; + _pFilter = iterator._pFilter; + _pCurrent = iterator._pCurrent; + } + return *this; +} + + +NodeIterator::~NodeIterator() +{ +} + + +Node* NodeIterator::nextNode() +{ + if (!_pRoot) throw DOMException(DOMException::INVALID_STATE_ERR); + + if (_pCurrent) + _pCurrent = next(); + else + _pCurrent = _pRoot; + while (_pCurrent && !accept(_pCurrent)) + _pCurrent = next(); + return _pCurrent; +} + + +Node* NodeIterator::previousNode() +{ + if (!_pRoot) throw DOMException(DOMException::INVALID_STATE_ERR); + + if (_pCurrent) + _pCurrent = previous(); + else + _pCurrent = last(); + while (_pCurrent && !accept(_pCurrent)) + _pCurrent = previous(); + return _pCurrent; +} + + +void NodeIterator::detach() +{ + _pRoot = 0; + _pCurrent = 0; +} + + +bool NodeIterator::accept(Node* pNode) const +{ + bool accept = false; + switch (pNode->nodeType()) + { + case Node::ELEMENT_NODE: + accept = (_whatToShow & NodeFilter::SHOW_ELEMENT) != 0; break; + case Node::ATTRIBUTE_NODE: + accept = (_whatToShow & NodeFilter::SHOW_ATTRIBUTE) != 0; break; + case Node::TEXT_NODE: + accept = (_whatToShow & NodeFilter::SHOW_TEXT) != 0; break; + case Node::CDATA_SECTION_NODE: + accept = (_whatToShow & NodeFilter::SHOW_CDATA_SECTION) != 0; break; + case Node::ENTITY_REFERENCE_NODE: + accept = (_whatToShow & NodeFilter::SHOW_ENTITY_REFERENCE) != 0; break; + case Node::ENTITY_NODE: + accept = (_whatToShow & NodeFilter::SHOW_ENTITY) != 0; break; + case Node::PROCESSING_INSTRUCTION_NODE: + accept = (_whatToShow & NodeFilter::SHOW_PROCESSING_INSTRUCTION) != 0; break; + case Node::COMMENT_NODE: + accept = (_whatToShow & NodeFilter::SHOW_COMMENT) != 0; break; + case Node::DOCUMENT_NODE: + accept = (_whatToShow & NodeFilter::SHOW_DOCUMENT) != 0; break; + case Node::DOCUMENT_TYPE_NODE: + accept = (_whatToShow & NodeFilter::SHOW_DOCUMENT_TYPE) != 0; break; + case Node::DOCUMENT_FRAGMENT_NODE: + accept = (_whatToShow & NodeFilter::SHOW_DOCUMENT_FRAGMENT) != 0; break; + case Node::NOTATION_NODE: + accept = (_whatToShow & NodeFilter::SHOW_NOTATION) != 0; break; + } + if (accept && _pFilter) + accept = _pFilter->acceptNode(pNode) == NodeFilter::FILTER_ACCEPT; + return accept; +} + + +Node* NodeIterator::next() const +{ + Node* pNext = _pCurrent->firstChild(); + if (pNext) return pNext; + pNext = _pCurrent; + while (pNext && pNext != _pRoot) + { + Node* pSibling = pNext->nextSibling(); + if (pSibling) return pSibling; + pNext = pNext->parentNode(); + } + return 0; +} + + +Node* NodeIterator::previous() const +{ + if (_pCurrent == _pRoot) return 0; + Node* pPrev = _pCurrent->previousSibling(); + while (pPrev) + { + Node* pLastChild = pPrev->lastChild(); + if (pLastChild) + pPrev = pLastChild; + else + return pPrev; + } + return _pCurrent->parentNode(); +} + + +Node* NodeIterator::last() +{ + _pCurrent = _pRoot; + Node* pLast = 0; + while (_pCurrent) + { + pLast = _pCurrent; + _pCurrent = next(); + } + return pLast; +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/NodeList.cpp b/contrib/libs/poco/XML/src/NodeList.cpp new file mode 100644 index 0000000000..e56b37ce19 --- /dev/null +++ b/contrib/libs/poco/XML/src/NodeList.cpp @@ -0,0 +1,27 @@ +// +// NodeList.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/NodeList.h" + + +namespace Poco { +namespace XML { + + +NodeList::~NodeList() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/Notation.cpp b/contrib/libs/poco/XML/src/Notation.cpp new file mode 100644 index 0000000000..ec38a5ade3 --- /dev/null +++ b/contrib/libs/poco/XML/src/Notation.cpp @@ -0,0 +1,63 @@ +// +// Notation.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/Notation.h" + + +namespace Poco { +namespace XML { + + +Notation::Notation(Document* pOwnerDocument, const XMLString& name, const XMLString& publicId, const XMLString& systemId): + AbstractNode(pOwnerDocument), + _name(name), + _publicId(publicId), + _systemId(systemId) +{ +} + + +Notation::Notation(Document* pOwnerDocument, const Notation& notation): + AbstractNode(pOwnerDocument, notation), + _name(notation._name), + _publicId(notation._publicId), + _systemId(notation._systemId) +{ +} + + +Notation::~Notation() +{ +} + + +const XMLString& Notation::nodeName() const +{ + return _name; +} + + +unsigned short Notation::nodeType() const +{ + return Node::NOTATION_NODE; +} + + +Node* Notation::copyNode(bool /*deep*/, Document* pOwnerDocument) const +{ + return new Notation(pOwnerDocument, *this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/ParserEngine.cpp b/contrib/libs/poco/XML/src/ParserEngine.cpp new file mode 100644 index 0000000000..95361a4cde --- /dev/null +++ b/contrib/libs/poco/XML/src/ParserEngine.cpp @@ -0,0 +1,896 @@ +// +// ParserEngine.cpp +// +// Library: XML +// Package: XML +// Module: ParserEngine +// +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/XML/ParserEngine.h" +#include "Poco/XML/NamespaceStrategy.h" +#include "Poco/XML/XMLException.h" +#include "Poco/SAX/EntityResolver.h" +#include "Poco/SAX/EntityResolverImpl.h" +#include "Poco/SAX/DTDHandler.h" +#include "Poco/SAX/DeclHandler.h" +#include "Poco/SAX/ContentHandler.h" +#include "Poco/SAX/LexicalHandler.h" +#include "Poco/SAX/ErrorHandler.h" +#include "Poco/SAX/InputSource.h" +#include "Poco/SAX/Locator.h" +#include "Poco/SAX/LocatorImpl.h" +#include "Poco/SAX/SAXException.h" +#include "Poco/URI.h" +#include <cstring> + + +using Poco::URI; +using Poco::TextEncoding; + + +namespace Poco { +namespace XML { + + +class ContextLocator: public Locator +{ +public: + ContextLocator(XML_Parser parser, const XMLString& publicId, const XMLString& systemId): + _parser(parser), + _publicId(publicId), + _systemId(systemId) + { + } + + ~ContextLocator() + { + } + + XMLString getPublicId() const + { + return _publicId; + } + + XMLString getSystemId() const + { + return _systemId; + } + + int getLineNumber() const + { + return XML_GetCurrentLineNumber(_parser); + } + + int getColumnNumber() const + { + return XML_GetCurrentColumnNumber(_parser); + } + +private: + XML_Parser _parser; + XMLString _publicId; + XMLString _systemId; +}; + + +const int ParserEngine::PARSE_BUFFER_SIZE = 4096; +const XMLString ParserEngine::EMPTY_STRING; + + +ParserEngine::ParserEngine(): + _parser(0), + _pBuffer(0), + _encodingSpecified(false), + _expandInternalEntities(true), + _externalGeneralEntities(false), + _externalParameterEntities(false), + _enablePartialReads(false), + _pNamespaceStrategy(new NoNamespacesStrategy()), + _pEntityResolver(0), + _pDTDHandler(0), + _pDeclHandler(0), + _pContentHandler(0), + _pLexicalHandler(0), + _pErrorHandler(0) +{ +} + + +ParserEngine::ParserEngine(const XMLString& encoding): + _parser(0), + _pBuffer(0), + _encodingSpecified(true), + _encoding(encoding), + _expandInternalEntities(true), + _externalGeneralEntities(false), + _externalParameterEntities(false), + _enablePartialReads(false), + _pNamespaceStrategy(new NoNamespacesStrategy()), + _pEntityResolver(0), + _pDTDHandler(0), + _pDeclHandler(0), + _pContentHandler(0), + _pLexicalHandler(0), + _pErrorHandler(0) +{ +} + + +ParserEngine::~ParserEngine() +{ + resetContext(); + if (_parser) XML_ParserFree(_parser); + delete [] _pBuffer; + delete _pNamespaceStrategy; +} + + +void ParserEngine::setEncoding(const XMLString& encoding) +{ + _encoding = encoding; + _encodingSpecified = true; +} + + +void ParserEngine::addEncoding(const XMLString& name, TextEncoding* pEncoding) +{ + poco_check_ptr (pEncoding); + + if (_encodings.find(name) == _encodings.end()) + _encodings[name] = pEncoding; + else + throw XMLException("Encoding already defined"); +} + + +void ParserEngine::setNamespaceStrategy(NamespaceStrategy* pStrategy) +{ + poco_check_ptr (pStrategy); + + delete _pNamespaceStrategy; + _pNamespaceStrategy = pStrategy; +} + + +void ParserEngine::setExpandInternalEntities(bool flag) +{ + _expandInternalEntities = flag; +} + + +void ParserEngine::setExternalGeneralEntities(bool flag) +{ + _externalGeneralEntities = flag; +} + + +void ParserEngine::setExternalParameterEntities(bool flag) +{ + _externalParameterEntities = flag; +} + + +void ParserEngine::setEntityResolver(EntityResolver* pResolver) +{ + _pEntityResolver = pResolver; +} + + +void ParserEngine::setDTDHandler(DTDHandler* pDTDHandler) +{ + _pDTDHandler = pDTDHandler; +} + + +void ParserEngine::setDeclHandler(DeclHandler* pDeclHandler) +{ + _pDeclHandler = pDeclHandler; +} + + +void ParserEngine::setContentHandler(ContentHandler* pContentHandler) +{ + _pContentHandler = pContentHandler; +} + + +void ParserEngine::setLexicalHandler(LexicalHandler* pLexicalHandler) +{ + _pLexicalHandler = pLexicalHandler; +} + + +void ParserEngine::setErrorHandler(ErrorHandler* pErrorHandler) +{ + _pErrorHandler = pErrorHandler; +} + + +void ParserEngine::setEnablePartialReads(bool flag) +{ + _enablePartialReads = flag; +} + + +void ParserEngine::parse(InputSource* pInputSource) +{ + init(); + resetContext(); + pushContext(_parser, pInputSource); + if (_pContentHandler) _pContentHandler->setDocumentLocator(this); + if (_pContentHandler) _pContentHandler->startDocument(); + if (pInputSource->getCharacterStream()) + parseCharInputStream(*pInputSource->getCharacterStream()); + else if (pInputSource->getByteStream()) + parseByteInputStream(*pInputSource->getByteStream()); + else throw XMLException("Input source has no stream"); + if (_pContentHandler) _pContentHandler->endDocument(); + popContext(); +} + + +void ParserEngine::parse(const char* pBuffer, std::size_t size) +{ + init(); + resetContext(); + InputSource src; + pushContext(_parser, &src); + if (_pContentHandler) _pContentHandler->setDocumentLocator(this); + if (_pContentHandler) _pContentHandler->startDocument(); + std::size_t processed = 0; + while (processed < size) + { + const int bufferSize = processed + PARSE_BUFFER_SIZE < size ? PARSE_BUFFER_SIZE : static_cast<int>(size - processed); + if (!XML_Parse(_parser, pBuffer + processed, bufferSize, 0)) + handleError(XML_GetErrorCode(_parser)); + processed += bufferSize; + } + if (!XML_Parse(_parser, pBuffer+processed, 0, 1)) + handleError(XML_GetErrorCode(_parser)); + if (_pContentHandler) _pContentHandler->endDocument(); + popContext(); +} + + +void ParserEngine::parseByteInputStream(XMLByteInputStream& istr) +{ + std::streamsize n = readBytes(istr, _pBuffer, PARSE_BUFFER_SIZE); + while (n > 0) + { + if (!XML_Parse(_parser, _pBuffer, static_cast<int>(n), 0)) + handleError(XML_GetErrorCode(_parser)); + if (istr.good()) + n = readBytes(istr, _pBuffer, PARSE_BUFFER_SIZE); + else + n = 0; + } + if (!XML_Parse(_parser, _pBuffer, 0, 1)) + handleError(XML_GetErrorCode(_parser)); +} + + +void ParserEngine::parseCharInputStream(XMLCharInputStream& istr) +{ + std::streamsize n = readChars(istr, reinterpret_cast<XMLChar*>(_pBuffer), PARSE_BUFFER_SIZE/sizeof(XMLChar)); + while (n > 0) + { + if (!XML_Parse(_parser, _pBuffer, static_cast<int>(n*sizeof(XMLChar)), 0)) + handleError(XML_GetErrorCode(_parser)); + if (istr.good()) + n = readChars(istr, reinterpret_cast<XMLChar*>(_pBuffer), PARSE_BUFFER_SIZE/sizeof(XMLChar)); + else + n = 0; + } + if (!XML_Parse(_parser, _pBuffer, 0, 1)) + handleError(XML_GetErrorCode(_parser)); +} + + +void ParserEngine::parseExternal(XML_Parser extParser, InputSource* pInputSource) +{ + pushContext(extParser, pInputSource); + if (pInputSource->getCharacterStream()) + parseExternalCharInputStream(extParser, *pInputSource->getCharacterStream()); + else if (pInputSource->getByteStream()) + parseExternalByteInputStream(extParser, *pInputSource->getByteStream()); + else throw XMLException("Input source has no stream"); + popContext(); +} + + +void ParserEngine::parseExternalByteInputStream(XML_Parser extParser, XMLByteInputStream& istr) +{ + char *pBuffer = new char[PARSE_BUFFER_SIZE]; + try + { + std::streamsize n = readBytes(istr, pBuffer, PARSE_BUFFER_SIZE); + while (n > 0) + { + if (!XML_Parse(extParser, pBuffer, static_cast<int>(n), 0)) + handleError(XML_GetErrorCode(extParser)); + if (istr.good()) + n = readBytes(istr, pBuffer, PARSE_BUFFER_SIZE); + else + n = 0; + } + if (!XML_Parse(extParser, pBuffer, 0, 1)) + handleError(XML_GetErrorCode(extParser)); + } + catch (...) + { + delete [] pBuffer; + throw; + } + delete [] pBuffer; +} + + +void ParserEngine::parseExternalCharInputStream(XML_Parser extParser, XMLCharInputStream& istr) +{ + XMLChar *pBuffer = new XMLChar[PARSE_BUFFER_SIZE/sizeof(XMLChar)]; + try + { + std::streamsize n = readChars(istr, pBuffer, PARSE_BUFFER_SIZE/sizeof(XMLChar)); + while (n > 0) + { + if (!XML_Parse(extParser, reinterpret_cast<char*>(pBuffer), static_cast<int>(n*sizeof(XMLChar)), 0)) + handleError(XML_GetErrorCode(extParser)); + if (istr.good()) + n = readChars(istr, pBuffer, static_cast<int>(PARSE_BUFFER_SIZE/sizeof(XMLChar))); + else + n = 0; + } + if (!XML_Parse(extParser, reinterpret_cast<char*>(pBuffer), 0, 1)) + handleError(XML_GetErrorCode(extParser)); + } + catch (...) + { + delete [] pBuffer; + throw; + } + delete [] pBuffer; +} + + +std::streamsize ParserEngine::readBytes(XMLByteInputStream& istr, char* pBuffer, std::streamsize bufferSize) +{ + if (_enablePartialReads) + { + istr.read(pBuffer, 1); + if (istr.gcount() == 1) + { + std::streamsize n = istr.readsome(pBuffer + 1, bufferSize - 1); + return n + 1; + } + else return 0; + } + else + { + istr.read(pBuffer, bufferSize); + return istr.gcount(); + } +} + + +std::streamsize ParserEngine::readChars(XMLCharInputStream& istr, XMLChar* pBuffer, std::streamsize bufferSize) +{ + if (_enablePartialReads) + { + istr.read(pBuffer, 1); + if (istr.gcount() == 1) + { + std::streamsize n = istr.readsome(pBuffer + 1, bufferSize - 1); + return n + 1; + } + else return 0; + } + else + { + istr.read(pBuffer, bufferSize); + return istr.gcount(); + } +} + + +XMLString ParserEngine::getPublicId() const +{ + return locator().getPublicId(); +} + + +XMLString ParserEngine::getSystemId() const +{ + return locator().getSystemId(); +} + + +int ParserEngine::getLineNumber() const +{ + return locator().getLineNumber(); +} + + +int ParserEngine::getColumnNumber() const +{ + return locator().getColumnNumber(); +} + + +namespace +{ + static LocatorImpl nullLocator; +} + + +const Locator& ParserEngine::locator() const +{ + if (_context.empty()) + return nullLocator; + else + return *_context.back(); +} + + +void ParserEngine::init() +{ + if (_parser) + XML_ParserFree(_parser); + + if (!_pBuffer) + _pBuffer = new char[PARSE_BUFFER_SIZE]; + + if (dynamic_cast<NoNamespacePrefixesStrategy*>(_pNamespaceStrategy)) + { + _parser = XML_ParserCreateNS(_encodingSpecified ? _encoding.c_str() : 0, '\t'); + if (_parser) + { + XML_SetNamespaceDeclHandler(_parser, handleStartNamespaceDecl, handleEndNamespaceDecl); + } + } + else if (dynamic_cast<NamespacePrefixesStrategy*>(_pNamespaceStrategy)) + { + _parser = XML_ParserCreateNS(_encodingSpecified ? _encoding.c_str() : 0, '\t'); + if (_parser) + { + XML_SetReturnNSTriplet(_parser, 1); + XML_SetNamespaceDeclHandler(_parser, handleStartNamespaceDecl, handleEndNamespaceDecl); + } + } + else + { + _parser = XML_ParserCreate(_encodingSpecified ? _encoding.c_str() : 0); + } + + if (!_parser) throw XMLException("Cannot create Expat parser"); + + XML_SetUserData(_parser, this); + XML_SetElementHandler(_parser, handleStartElement, handleEndElement); + XML_SetCharacterDataHandler(_parser, handleCharacterData); + XML_SetProcessingInstructionHandler(_parser, handleProcessingInstruction); + if (_expandInternalEntities) + XML_SetDefaultHandlerExpand(_parser, handleDefault); + else + XML_SetDefaultHandler(_parser, handleDefault); + XML_SetUnparsedEntityDeclHandler(_parser, handleUnparsedEntityDecl); + XML_SetNotationDeclHandler(_parser, handleNotationDecl); + XML_SetExternalEntityRefHandler(_parser, handleExternalEntityRef); + XML_SetCommentHandler(_parser, handleComment); + XML_SetCdataSectionHandler(_parser, handleStartCdataSection, handleEndCdataSection); + XML_SetDoctypeDeclHandler(_parser, handleStartDoctypeDecl, handleEndDoctypeDecl); + XML_SetEntityDeclHandler(_parser, handleEntityDecl); + XML_SetSkippedEntityHandler(_parser, handleSkippedEntity); + XML_SetParamEntityParsing(_parser, _externalParameterEntities ? XML_PARAM_ENTITY_PARSING_ALWAYS : XML_PARAM_ENTITY_PARSING_NEVER); + XML_SetUnknownEncodingHandler(_parser, handleUnknownEncoding, this); +} + + +void ParserEngine::handleError(int errorNo) +{ + try + { + switch (errorNo) + { + case XML_ERROR_NO_MEMORY: + throw XMLException("No memory"); + case XML_ERROR_SYNTAX: + throw SAXParseException("Syntax error", locator()); + case XML_ERROR_NO_ELEMENTS: + throw SAXParseException("No element found", locator()); + case XML_ERROR_INVALID_TOKEN: + throw SAXParseException("Invalid token", locator()); + case XML_ERROR_UNCLOSED_TOKEN: + throw SAXParseException("Unclosed token", locator()); + case XML_ERROR_PARTIAL_CHAR: + throw SAXParseException("Partial character", locator()); + case XML_ERROR_TAG_MISMATCH: + throw SAXParseException("Tag mismatch", locator()); + case XML_ERROR_DUPLICATE_ATTRIBUTE: + throw SAXParseException("Duplicate attribute", locator()); + case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: + throw SAXParseException("Junk after document element", locator()); + case XML_ERROR_PARAM_ENTITY_REF: + throw SAXParseException("Illegal parameter entity reference", locator()); + case XML_ERROR_UNDEFINED_ENTITY: + throw SAXParseException("Undefined entity", locator()); + case XML_ERROR_RECURSIVE_ENTITY_REF: + throw SAXParseException("Recursive entity reference", locator()); + case XML_ERROR_ASYNC_ENTITY: + throw SAXParseException("Asynchronous entity", locator()); + case XML_ERROR_BAD_CHAR_REF: + throw SAXParseException("Reference to invalid character number", locator()); + case XML_ERROR_BINARY_ENTITY_REF: + throw SAXParseException("Reference to binary entity", locator()); + case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: + throw SAXParseException("Reference to external entity in attribute", locator()); + case XML_ERROR_MISPLACED_XML_PI: + throw SAXParseException("XML processing instruction not at start of external entity", locator()); + case XML_ERROR_UNKNOWN_ENCODING: + throw SAXParseException("Unknown encoding", locator()); + case XML_ERROR_INCORRECT_ENCODING: + throw SAXParseException("Encoding specified in XML declaration is incorrect", locator()); + case XML_ERROR_UNCLOSED_CDATA_SECTION: + throw SAXParseException("Unclosed CDATA section", locator()); + case XML_ERROR_EXTERNAL_ENTITY_HANDLING: + throw SAXParseException("Error in processing external entity reference", locator()); + case XML_ERROR_NOT_STANDALONE: + throw SAXParseException("Document is not standalone", locator()); + case XML_ERROR_UNEXPECTED_STATE: + throw SAXParseException("Unexpected parser state - please send a bug report", locator()); + case XML_ERROR_ENTITY_DECLARED_IN_PE: + throw SAXParseException("Entity declared in parameter entity", locator()); + case XML_ERROR_FEATURE_REQUIRES_XML_DTD: + throw SAXParseException("Requested feature requires XML_DTD support in Expat", locator()); + case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: + throw SAXParseException("Cannot change setting once parsing has begun", locator()); + case XML_ERROR_UNBOUND_PREFIX: + throw SAXParseException("Unbound prefix", locator()); + case XML_ERROR_UNDECLARING_PREFIX: + throw SAXParseException("Must not undeclare prefix", locator()); + case XML_ERROR_INCOMPLETE_PE: + throw SAXParseException("Incomplete markup in parameter entity", locator()); + case XML_ERROR_XML_DECL: + throw SAXParseException("XML declaration not well-formed", locator()); + case XML_ERROR_TEXT_DECL: + throw SAXParseException("Text declaration not well-formed", locator()); + case XML_ERROR_PUBLICID: + throw SAXParseException("Illegal character(s) in public identifier", locator()); + case XML_ERROR_SUSPENDED: + throw SAXParseException("Parser suspended", locator()); + case XML_ERROR_NOT_SUSPENDED: + throw SAXParseException("Parser not suspended", locator()); + case XML_ERROR_ABORTED: + throw SAXParseException("Parsing aborted", locator()); + case XML_ERROR_FINISHED: + throw SAXParseException("Parsing finished", locator()); + case XML_ERROR_SUSPEND_PE: + throw SAXParseException("Cannot suspend in external parameter entity", locator()); + } + throw XMLException("Unknown Expat error code"); + } + catch (SAXException& exc) + { + if (_pErrorHandler) _pErrorHandler->error(exc); + throw; + } + catch (Poco::Exception& exc) + { + if (_pErrorHandler) _pErrorHandler->fatalError(SAXParseException("Fatal error", locator(), exc)); + throw; + } +} + + +void ParserEngine::pushContext(XML_Parser parser, InputSource* pInputSource) +{ + ContextLocator* pLocator = new ContextLocator(parser, pInputSource->getPublicId(), pInputSource->getSystemId()); + _context.push_back(pLocator); +} + + +void ParserEngine::popContext() +{ + poco_assert (!_context.empty()); + delete _context.back(); + _context.pop_back(); +} + + +void ParserEngine::resetContext() +{ + for (ContextStack::iterator it = _context.begin(); it != _context.end(); ++it) + { + delete *it; + } + _context.clear(); +} + + +void ParserEngine::handleStartElement(void* userData, const XML_Char* name, const XML_Char** atts) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + if (pThis->_pContentHandler) + { + try + { + pThis->_pNamespaceStrategy->startElement(name, atts, XML_GetSpecifiedAttributeCount(pThis->_parser)/2, pThis->_pContentHandler); + } + catch (XMLException& exc) + { + throw SAXParseException(exc.message(), pThis->locator()); + } + } +} + + +void ParserEngine::handleEndElement(void* userData, const XML_Char* name) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + if (pThis->_pContentHandler) + { + try + { + pThis->_pNamespaceStrategy->endElement(name, pThis->_pContentHandler); + } + catch (XMLException& exc) + { + throw SAXParseException(exc.message(), pThis->locator()); + } + } +} + + +void ParserEngine::handleCharacterData(void* userData, const XML_Char* s, int len) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + if (pThis->_pContentHandler) + pThis->_pContentHandler->characters(s, 0, len); +} + + +void ParserEngine::handleProcessingInstruction(void* userData, const XML_Char* target, const XML_Char* data) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + if (pThis->_pContentHandler) + pThis->_pContentHandler->processingInstruction(target, data); +} + + +void ParserEngine::handleDefault(void* /*userData*/, const XML_Char* /*s*/, int /*len*/) +{ +} + + +void ParserEngine::handleUnparsedEntityDecl(void* userData, const XML_Char* entityName, const XML_Char* /*base*/, const XML_Char* systemId, const XML_Char* publicId, const XML_Char* notationName) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + XMLString pubId; + if (publicId) pubId.assign(publicId); + if (pThis->_pDTDHandler) + pThis->_pDTDHandler->unparsedEntityDecl(entityName, publicId ? &pubId : 0, systemId, notationName); +} + + +void ParserEngine::handleNotationDecl(void* userData, const XML_Char* notationName, const XML_Char* /*base*/, const XML_Char* systemId, const XML_Char* publicId) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + XMLString pubId; + if (publicId) pubId.assign(publicId); + XMLString sysId; + if (systemId) sysId.assign(systemId); + if (pThis->_pDTDHandler) + pThis->_pDTDHandler->notationDecl(notationName, publicId ? &pubId : 0, systemId ? &sysId : 0); +} + + +int ParserEngine::handleExternalEntityRef(XML_Parser parser, const XML_Char* context, const XML_Char* /*base*/, const XML_Char* systemId, const XML_Char* publicId) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(XML_GetUserData(parser)); + + if (!context && !pThis->_externalParameterEntities) return XML_STATUS_ERROR; + if (context && !pThis->_externalGeneralEntities) return XML_STATUS_ERROR; + + InputSource* pInputSource = 0; + EntityResolver* pEntityResolver = 0; + EntityResolverImpl defaultResolver; + + XMLString sysId(systemId); + XMLString pubId; + if (publicId) pubId.assign(publicId); + + URI uri(fromXMLString(pThis->_context.back()->getSystemId())); + uri.resolve(fromXMLString(sysId)); + + if (pThis->_pEntityResolver) + { + pEntityResolver = pThis->_pEntityResolver; + pInputSource = pEntityResolver->resolveEntity(publicId ? &pubId : 0, toXMLString(uri.toString())); + } + if (!pInputSource && pThis->_externalGeneralEntities) + { + pEntityResolver = &defaultResolver; + pInputSource = pEntityResolver->resolveEntity(publicId ? &pubId : 0, toXMLString(uri.toString())); + } + + if (pInputSource) + { + XML_Parser extParser = XML_ExternalEntityParserCreate(pThis->_parser, context, 0); + if (!extParser) throw XMLException("Cannot create external entity parser"); + + try + { + pThis->parseExternal(extParser, pInputSource); + } + catch (XMLException&) + { + pEntityResolver->releaseInputSource(pInputSource); + XML_ParserFree(extParser); + throw; + } + pEntityResolver->releaseInputSource(pInputSource); + XML_ParserFree(extParser); + return XML_STATUS_OK; + } + else return XML_STATUS_ERROR; +} + + +int ParserEngine::handleUnknownEncoding(void* encodingHandlerData, const XML_Char* name, XML_Encoding* info) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(encodingHandlerData); + + XMLString encoding(name); + TextEncoding* knownEncoding = 0; + + EncodingMap::const_iterator it = pThis->_encodings.find(encoding); + if (it != pThis->_encodings.end()) + knownEncoding = it->second; + else + knownEncoding = Poco::TextEncoding::find(fromXMLString(encoding)); + + if (knownEncoding) + { + const TextEncoding::CharacterMap& map = knownEncoding->characterMap(); + for (int i = 0; i < 256; ++i) + info->map[i] = map[i]; + + info->data = knownEncoding; + info->convert = &ParserEngine::convert; + info->release = 0; + return XML_STATUS_OK; + } + else return XML_STATUS_ERROR; +} + + +void ParserEngine::handleComment(void* userData, const XML_Char* data) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + +#if defined(XML_UNICODE_WCHAR_T) + if (pThis->_pLexicalHandler) + pThis->_pLexicalHandler->comment(data, 0, (int) std::wcslen(data)); +#else + if (pThis->_pLexicalHandler) + pThis->_pLexicalHandler->comment(data, 0, (int) std::strlen(data)); +#endif +} + + +void ParserEngine::handleStartCdataSection(void* userData) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + if (pThis->_pLexicalHandler) + pThis->_pLexicalHandler->startCDATA(); +} + + +void ParserEngine::handleEndCdataSection(void* userData) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + if (pThis->_pLexicalHandler) + pThis->_pLexicalHandler->endCDATA(); +} + + +void ParserEngine::handleStartNamespaceDecl(void* userData, const XML_Char* prefix, const XML_Char* uri) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + if (pThis->_pContentHandler) + pThis->_pContentHandler->startPrefixMapping((prefix ? XMLString(prefix) : EMPTY_STRING), (uri ? XMLString(uri) : EMPTY_STRING)); +} + + +void ParserEngine::handleEndNamespaceDecl(void* userData, const XML_Char* prefix) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + if (pThis->_pContentHandler) + pThis->_pContentHandler->endPrefixMapping(prefix ? XMLString(prefix) : EMPTY_STRING); +} + + +void ParserEngine::handleStartDoctypeDecl(void* userData, const XML_Char* doctypeName, const XML_Char *systemId, const XML_Char* publicId, int /*hasInternalSubset*/) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + if (pThis->_pLexicalHandler) + { + XMLString sysId = systemId ? XMLString(systemId) : EMPTY_STRING; + XMLString pubId = publicId ? XMLString(publicId) : EMPTY_STRING; + pThis->_pLexicalHandler->startDTD(doctypeName, pubId, sysId); + } +} + + +void ParserEngine::handleEndDoctypeDecl(void* userData) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + if (pThis->_pLexicalHandler) + pThis->_pLexicalHandler->endDTD(); +} + + +void ParserEngine::handleEntityDecl(void *userData, const XML_Char *entityName, int /*isParamEntity*/, const XML_Char *value, int valueLength, + const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId, const XML_Char* /*notationName*/) +{ + if (value) + handleInternalParsedEntityDecl(userData, entityName, value, valueLength); + else + handleExternalParsedEntityDecl(userData, entityName, base, systemId, publicId); +} + + +void ParserEngine::handleExternalParsedEntityDecl(void* userData, const XML_Char* entityName, const XML_Char* /*base*/, const XML_Char* systemId, const XML_Char* publicId) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + XMLString pubId; + if (publicId) pubId.assign(publicId); + if (pThis->_pDeclHandler) + pThis->_pDeclHandler->externalEntityDecl(entityName, publicId ? &pubId : 0, systemId); +} + + +void ParserEngine::handleInternalParsedEntityDecl(void* userData, const XML_Char* entityName, const XML_Char* replacementText, int replacementTextLength) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + XMLString replText(replacementText, replacementTextLength); + if (pThis->_pDeclHandler) + pThis->_pDeclHandler->internalEntityDecl(entityName, replText); +} + + +void ParserEngine::handleSkippedEntity(void* userData, const XML_Char* entityName, int /*isParameterEntity*/) +{ + ParserEngine* pThis = reinterpret_cast<ParserEngine*>(userData); + + if (pThis->_pContentHandler) + pThis->_pContentHandler->skippedEntity(entityName); +} + + +int ParserEngine::convert(void* data, const char* s) +{ + TextEncoding* pEncoding = reinterpret_cast<TextEncoding*>(data); + return pEncoding->convert((const unsigned char*) s); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/ProcessingInstruction.cpp b/contrib/libs/poco/XML/src/ProcessingInstruction.cpp new file mode 100644 index 0000000000..ebfc7c158b --- /dev/null +++ b/contrib/libs/poco/XML/src/ProcessingInstruction.cpp @@ -0,0 +1,79 @@ +// +// ProcessingInstruction.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/ProcessingInstruction.h" + + +namespace Poco { +namespace XML { + + +ProcessingInstruction::ProcessingInstruction(Document* pOwnerDocument, const XMLString& target, const XMLString& data): + AbstractNode(pOwnerDocument), + _target(target), + _data(data) +{ +} + + +ProcessingInstruction::ProcessingInstruction(Document* pOwnerDocument, const ProcessingInstruction& processingInstruction): + AbstractNode(pOwnerDocument, processingInstruction), + _target(processingInstruction._target), + _data(processingInstruction._data) +{ +} + + +ProcessingInstruction::~ProcessingInstruction() +{ +} + + +void ProcessingInstruction::setData(const XMLString& data) +{ + _data = data; +} + + +const XMLString& ProcessingInstruction::nodeName() const +{ + return _target; +} + + +const XMLString& ProcessingInstruction::getNodeValue() const +{ + return _data; +} + + +void ProcessingInstruction::setNodeValue(const XMLString& data) +{ + setData(data); +} + + +unsigned short ProcessingInstruction::nodeType() const +{ + return Node::PROCESSING_INSTRUCTION_NODE; +} + + +Node* ProcessingInstruction::copyNode(bool deep, Document* pOwnerDocument) const +{ + return new ProcessingInstruction(pOwnerDocument, *this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/QName.cpp b/contrib/libs/poco/XML/src/QName.cpp new file mode 100644 index 0000000000..276b1c3fc4 --- /dev/null +++ b/contrib/libs/poco/XML/src/QName.cpp @@ -0,0 +1,72 @@ +// +// QName.cpp +// +// Library: XML +// Package: XML +// Module: QName +// +// Copyright (c) 2015, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Based on libstudxml (http://www.codesynthesis.com/projects/libstudxml/). +// Copyright (c) 2009-2013 Code Synthesis Tools CC. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/XML/QName.h" +#include <ostream> + + +namespace Poco { +namespace XML { + + +QName::QName() +{ +} + + +QName::QName(const std::string& name) : + _name(name) +{ +} + + +QName::QName(const std::string& ns, const std::string& name) : + _ns(ns), + _name(name) +{ +} + + +QName::QName(const std::string& ns, const std::string& name, const std::string& prefix) : + _ns(ns), + _name(name), + _prefix(prefix) +{ +} + + +std::string QName::toString() const +{ + std::string r; + if (!_ns.empty()) + { + r += _ns; + r += '#'; + } + + r += _name; + return r; +} + + +std::ostream& operator << (std::ostream& os, const QName& qn) +{ + return os << qn.toString(); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/SAXException.cpp b/contrib/libs/poco/XML/src/SAXException.cpp new file mode 100644 index 0000000000..112747b08f --- /dev/null +++ b/contrib/libs/poco/XML/src/SAXException.cpp @@ -0,0 +1,138 @@ +// +// SAXException.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/SAXException.h" +#include "Poco/SAX/Locator.h" +#include <typeinfo> +#include <sstream> + + +namespace Poco { +namespace XML { + + +POCO_IMPLEMENT_EXCEPTION(SAXException, XMLException, "SAX Exception") +POCO_IMPLEMENT_EXCEPTION(SAXNotRecognizedException, SAXException, "Unrecognized SAX feature or property identifier") +POCO_IMPLEMENT_EXCEPTION(SAXNotSupportedException, SAXException, "Unsupported SAX feature or property identifier") + + +SAXParseException::SAXParseException(const std::string& msg, const Locator& loc): + SAXException(buildMessage(msg, loc.getPublicId(), loc.getSystemId(), loc.getLineNumber(), loc.getColumnNumber())), + _publicId(loc.getPublicId()), + _systemId(loc.getSystemId()), + _lineNumber(loc.getLineNumber()), + _columnNumber(loc.getColumnNumber()) +{ +} + + +SAXParseException::SAXParseException(const std::string& msg, const Locator& loc, const Poco::Exception& exc): + SAXException(buildMessage(msg, loc.getPublicId(), loc.getSystemId(), loc.getLineNumber(), loc.getColumnNumber()), exc), + _publicId(loc.getPublicId()), + _systemId(loc.getSystemId()), + _lineNumber(loc.getLineNumber()), + _columnNumber(loc.getColumnNumber()) +{ +} + + +SAXParseException::SAXParseException(const std::string& msg, const XMLString& publicId, const XMLString& systemId, int lineNumber, int columnNumber): + SAXException(buildMessage(msg, publicId, systemId, lineNumber, columnNumber)), + _publicId(publicId), + _systemId(systemId), + _lineNumber(lineNumber), + _columnNumber(columnNumber) +{ +} + + +SAXParseException::SAXParseException(const std::string& msg, const XMLString& publicId, const XMLString& systemId, int lineNumber, int columnNumber, const Poco::Exception& exc): + SAXException(buildMessage(msg, publicId, systemId, lineNumber, columnNumber), exc), + _publicId(publicId), + _systemId(systemId), + _lineNumber(lineNumber), + _columnNumber(columnNumber) +{ +} + + +SAXParseException::SAXParseException(const SAXParseException& exc): + SAXException(exc), + _publicId(exc._publicId), + _systemId(exc._systemId), + _lineNumber(exc._lineNumber), + _columnNumber(exc._columnNumber) +{ +} + + +SAXParseException::~SAXParseException() noexcept +{ +} + + +SAXParseException& SAXParseException::operator = (const SAXParseException& exc) +{ + if (&exc != this) + { + SAXException::operator = (exc); + _publicId = exc._publicId; + _systemId = exc._systemId; + _lineNumber = exc._lineNumber; + _columnNumber = exc._columnNumber; + } + return *this; +} + + +const char* SAXParseException::name() const noexcept +{ + return "SAXParseException"; +} + + +const char* SAXParseException::className() const noexcept +{ + return typeid(*this).name(); +} + + +Poco::Exception* SAXParseException::clone() const +{ + return new SAXParseException(*this); +} + + +void SAXParseException::rethrow() const +{ + throw *this; +} + + +std::string SAXParseException::buildMessage(const std::string& msg, const XMLString& publicId, const XMLString& systemId, int lineNumber, int columnNumber) +{ + std::ostringstream result; + if (!msg.empty()) result << msg << " "; + result << "in "; + if (!systemId.empty()) + result << "'" << fromXMLString(systemId) << "', "; + else if (!publicId.empty()) + result << "'" << fromXMLString(publicId) << "', "; + if (lineNumber > 0) + result << "line " << lineNumber << " column " << columnNumber; + return result.str(); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/SAXParser.cpp b/contrib/libs/poco/XML/src/SAXParser.cpp new file mode 100644 index 0000000000..e03959a845 --- /dev/null +++ b/contrib/libs/poco/XML/src/SAXParser.cpp @@ -0,0 +1,238 @@ +// +// SAXParser.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/SAXParser.h" +#include "Poco/SAX/SAXException.h" +#include "Poco/SAX/EntityResolverImpl.h" +#include "Poco/SAX/InputSource.h" +#include "Poco/XML/NamespaceStrategy.h" +#include <sstream> + + +namespace Poco { +namespace XML { + + +const XMLString SAXParser::FEATURE_PARTIAL_READS = toXMLString("http://www.appinf.com/features/enable-partial-reads"); + + +SAXParser::SAXParser(): + _namespaces(true), + _namespacePrefixes(false) +{ +} + + +SAXParser::SAXParser(const XMLString& encoding): + _engine(encoding), + _namespaces(true), + _namespacePrefixes(false) +{ +} + + +SAXParser::~SAXParser() +{ +} + + +void SAXParser::setEncoding(const XMLString& encoding) +{ + _engine.setEncoding(encoding); +} + + +const XMLString& SAXParser::getEncoding() const +{ + return _engine.getEncoding(); +} + + +void SAXParser::addEncoding(const XMLString& name, Poco::TextEncoding* pEncoding) +{ + _engine.addEncoding(name, pEncoding); +} + + +void SAXParser::setEntityResolver(EntityResolver* pResolver) +{ + _engine.setEntityResolver(pResolver); +} + + +EntityResolver* SAXParser::getEntityResolver() const +{ + return _engine.getEntityResolver(); +} + + +void SAXParser::setDTDHandler(DTDHandler* pDTDHandler) +{ + _engine.setDTDHandler(pDTDHandler); +} + + +DTDHandler* SAXParser::getDTDHandler() const +{ + return _engine.getDTDHandler(); +} + + +void SAXParser::setContentHandler(ContentHandler* pContentHandler) +{ + _engine.setContentHandler(pContentHandler); +} + + +ContentHandler* SAXParser::getContentHandler() const +{ + return _engine.getContentHandler(); +} + + +void SAXParser::setErrorHandler(ErrorHandler* pErrorHandler) +{ + _engine.setErrorHandler(pErrorHandler); +} + + +ErrorHandler* SAXParser::getErrorHandler() const +{ + return _engine.getErrorHandler(); +} + + +void SAXParser::setFeature(const XMLString& featureId, bool state) +{ + if (featureId == XMLReader::FEATURE_VALIDATION || featureId == XMLReader::FEATURE_STRING_INTERNING) + throw SAXNotSupportedException(fromXMLString(XMLReader::FEATURE_VALIDATION)); + else if (featureId == XMLReader::FEATURE_EXTERNAL_GENERAL_ENTITIES) + _engine.setExternalGeneralEntities(state); + else if (featureId == XMLReader::FEATURE_EXTERNAL_PARAMETER_ENTITIES) + _engine.setExternalParameterEntities(state); + else if (featureId == XMLReader::FEATURE_NAMESPACES) + _namespaces = state; + else if (featureId == XMLReader::FEATURE_NAMESPACE_PREFIXES) + _namespacePrefixes = state; + else if (featureId == FEATURE_PARTIAL_READS) + _engine.setEnablePartialReads(state); + else throw SAXNotRecognizedException(fromXMLString(featureId)); +} + + +bool SAXParser::getFeature(const XMLString& featureId) const +{ + if (featureId == XMLReader::FEATURE_VALIDATION || featureId == XMLReader::FEATURE_STRING_INTERNING) + throw SAXNotSupportedException(fromXMLString(XMLReader::FEATURE_VALIDATION)); + else if (featureId == XMLReader::FEATURE_EXTERNAL_GENERAL_ENTITIES) + return _engine.getExternalGeneralEntities(); + else if (featureId == XMLReader::FEATURE_EXTERNAL_PARAMETER_ENTITIES) + return _engine.getExternalParameterEntities(); + else if (featureId == XMLReader::FEATURE_NAMESPACES) + return _namespaces; + else if (featureId == XMLReader::FEATURE_NAMESPACE_PREFIXES) + return _namespacePrefixes; + else if (featureId == FEATURE_PARTIAL_READS) + return _engine.getEnablePartialReads(); + else throw SAXNotRecognizedException(fromXMLString(featureId)); +} + + +void SAXParser::setProperty(const XMLString& propertyId, const XMLString& /*value*/) +{ + if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER || propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) + throw SAXNotSupportedException(std::string("property does not take a string value: ") + fromXMLString(propertyId)); + else + throw SAXNotRecognizedException(fromXMLString(propertyId)); +} + + +void SAXParser::setProperty(const XMLString& propertyId, void* value) +{ + if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER) + _engine.setDeclHandler(reinterpret_cast<DeclHandler*>(value)); + else if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) + _engine.setLexicalHandler(reinterpret_cast<LexicalHandler*>(value)); + else throw SAXNotRecognizedException(fromXMLString(propertyId)); +} + + +void* SAXParser::getProperty(const XMLString& propertyId) const +{ + if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER) + return _engine.getDeclHandler(); + else if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) + return _engine.getLexicalHandler(); + else throw SAXNotSupportedException(fromXMLString(propertyId)); +} + + +void SAXParser::parse(InputSource* pInputSource) +{ + if (pInputSource->getByteStream() || pInputSource->getCharacterStream()) + { + setupParse(); + _engine.parse(pInputSource); + } + else parse(pInputSource->getSystemId()); +} + + +void SAXParser::parse(const XMLString& systemId) +{ + setupParse(); + EntityResolverImpl entityResolver; + InputSource* pInputSource = entityResolver.resolveEntity(0, systemId); + if (pInputSource) + { + try + { + _engine.parse(pInputSource); + } + catch (...) + { + entityResolver.releaseInputSource(pInputSource); + throw; + } + entityResolver.releaseInputSource(pInputSource); + } + else throw XMLException("Cannot resolve system identifier", fromXMLString(systemId)); +} + + +void SAXParser::parseString(const std::string& xml) +{ + parseMemoryNP(xml.data(), xml.size()); +} + + +void SAXParser::parseMemoryNP(const char* xml, std::size_t size) +{ + setupParse(); + _engine.parse(xml, size); +} + + +void SAXParser::setupParse() +{ + if (_namespaces && !_namespacePrefixes) + _engine.setNamespaceStrategy(new NoNamespacePrefixesStrategy); + else if (_namespaces && _namespacePrefixes) + _engine.setNamespaceStrategy(new NamespacePrefixesStrategy); + else + _engine.setNamespaceStrategy(new NoNamespacesStrategy); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/Text.cpp b/contrib/libs/poco/XML/src/Text.cpp new file mode 100644 index 0000000000..abdff3a4e9 --- /dev/null +++ b/contrib/libs/poco/XML/src/Text.cpp @@ -0,0 +1,80 @@ +// +// Text.cpp +// +// Library: XML +// Package: DOM +// Module: DOM +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/Text.h" +#include "Poco/DOM/Document.h" +#include "Poco/DOM/DOMException.h" + + +namespace Poco { +namespace XML { + + +const XMLString Text::NODE_NAME = toXMLString("#text"); + + +Text::Text(Document* pOwnerDocument, const XMLString& data): + CharacterData(pOwnerDocument, data) +{ +} + + +Text::Text(Document* pOwnerDocument, const Text& text): + CharacterData(pOwnerDocument, text) +{ +} + + +Text::~Text() +{ +} + + +Text* Text::splitText(unsigned long offset) +{ + Node* pParent = parentNode(); + if (!pParent) throw DOMException(DOMException::HIERARCHY_REQUEST_ERR); + int n = length() - offset; + Text* pNew = ownerDocument()->createTextNode(substringData(offset, n)); + deleteData(offset, n); + pParent->insertBefore(pNew, nextSibling())->release(); + return pNew; +} + + +const XMLString& Text::nodeName() const +{ + return NODE_NAME; +} + + +unsigned short Text::nodeType() const +{ + return Node::TEXT_NODE; +} + + +XMLString Text::innerText() const +{ + return nodeValue(); +} + + +Node* Text::copyNode(bool /*deep*/, Document* pOwnerDocument) const +{ + return new Text(pOwnerDocument, *this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/TreeWalker.cpp b/contrib/libs/poco/XML/src/TreeWalker.cpp new file mode 100644 index 0000000000..69c0556cda --- /dev/null +++ b/contrib/libs/poco/XML/src/TreeWalker.cpp @@ -0,0 +1,227 @@ +// +// TreeWalker.cpp +// +// Library: XML +// Package: DOM +// Module: TreeWalker +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DOM/TreeWalker.h" +#include "Poco/DOM/Node.h" +#include "Poco/DOM/NodeFilter.h" + + +namespace Poco { +namespace XML { + + +TreeWalker::TreeWalker(Node* root, unsigned long whatToShow, NodeFilter* pFilter): + _pRoot(root), + _whatToShow(whatToShow), + _pFilter(pFilter), + _pCurrent(root) +{ +} + + +TreeWalker::TreeWalker(const TreeWalker& walker): + _pRoot(walker._pRoot), + _whatToShow(walker._whatToShow), + _pFilter(walker._pFilter), + _pCurrent(walker._pCurrent) +{ +} + + +TreeWalker& TreeWalker::operator = (const TreeWalker& walker) +{ + if (&walker != this) + { + _pRoot = walker._pRoot; + _whatToShow = walker._whatToShow; + _pFilter = walker._pFilter; + _pCurrent = walker._pCurrent; + } + return *this; +} + + +TreeWalker::~TreeWalker() +{ +} + + +void TreeWalker::setCurrentNode(Node* pNode) +{ + _pCurrent = pNode; +} + + +Node* TreeWalker::parentNode() +{ + if (!_pCurrent || _pCurrent == _pRoot) return 0; + + Node* pParent = _pCurrent->parentNode(); + while (pParent && pParent != _pRoot && accept(pParent) != NodeFilter::FILTER_ACCEPT) + pParent = pParent->parentNode(); + if (pParent && accept(pParent) == NodeFilter::FILTER_ACCEPT) + _pCurrent = pParent; + else + pParent = 0; + return pParent; +} + + +Node* TreeWalker::firstChild() +{ + if (!_pCurrent) return 0; + + Node* pNode = accept(_pCurrent) != NodeFilter::FILTER_REJECT ? _pCurrent->firstChild() : 0; + while (pNode && accept(pNode) != NodeFilter::FILTER_ACCEPT) + pNode = pNode->nextSibling(); + if (pNode) + _pCurrent = pNode; + return pNode; +} + + +Node* TreeWalker::lastChild() +{ + if (!_pCurrent) return 0; + + Node* pNode = accept(_pCurrent) != NodeFilter::FILTER_REJECT ? _pCurrent->lastChild() : 0; + while (pNode && accept(pNode) != NodeFilter::FILTER_ACCEPT) + pNode = pNode->previousSibling(); + if (pNode) + _pCurrent = pNode; + return pNode; +} + + +Node* TreeWalker::previousSibling() +{ + if (!_pCurrent) return 0; + + Node* pNode = _pCurrent->previousSibling(); + while (pNode && accept(pNode) != NodeFilter::FILTER_ACCEPT) + pNode = pNode->previousSibling(); + if (pNode) + _pCurrent = pNode; + return pNode; +} + + +Node* TreeWalker::nextSibling() +{ + if (!_pCurrent) return 0; + + Node* pNode = _pCurrent->nextSibling(); + while (pNode && accept(pNode) != NodeFilter::FILTER_ACCEPT) + pNode = pNode->nextSibling(); + if (pNode) + _pCurrent = pNode; + return pNode; +} + + +Node* TreeWalker::previousNode() +{ + if (!_pCurrent) return 0; + + Node* pPrev = previous(_pCurrent); + while (pPrev && accept(pPrev) != NodeFilter::FILTER_ACCEPT) + pPrev = previous(pPrev); + if (pPrev) + _pCurrent = pPrev; + return pPrev; +} + + +Node* TreeWalker::nextNode() +{ + if (!_pCurrent) return 0; + + Node* pNext = next(_pCurrent); + while (pNext && accept(pNext) != NodeFilter::FILTER_ACCEPT) + pNext = next(pNext); + if (pNext) + _pCurrent = pNext; + return pNext; +} + + +int TreeWalker::accept(Node* pNode) const +{ + bool accept = false; + switch (pNode->nodeType()) + { + case Node::ELEMENT_NODE: + accept = (_whatToShow & NodeFilter::SHOW_ELEMENT) != 0; break; + case Node::ATTRIBUTE_NODE: + accept = (_whatToShow & NodeFilter::SHOW_ATTRIBUTE) != 0; break; + case Node::TEXT_NODE: + accept = (_whatToShow & NodeFilter::SHOW_TEXT) != 0; break; + case Node::CDATA_SECTION_NODE: + accept = (_whatToShow & NodeFilter::SHOW_CDATA_SECTION) != 0; break; + case Node::ENTITY_REFERENCE_NODE: + accept = (_whatToShow & NodeFilter::SHOW_ENTITY_REFERENCE) != 0; break; + case Node::ENTITY_NODE: + accept = (_whatToShow & NodeFilter::SHOW_ENTITY) != 0; break; + case Node::PROCESSING_INSTRUCTION_NODE: + accept = (_whatToShow & NodeFilter::SHOW_PROCESSING_INSTRUCTION) != 0; break; + case Node::COMMENT_NODE: + accept = (_whatToShow & NodeFilter::SHOW_COMMENT) != 0; break; + case Node::DOCUMENT_NODE: + accept = (_whatToShow & NodeFilter::SHOW_DOCUMENT) != 0; break; + case Node::DOCUMENT_TYPE_NODE: + accept = (_whatToShow & NodeFilter::SHOW_DOCUMENT_TYPE) != 0; break; + case Node::DOCUMENT_FRAGMENT_NODE: + accept = (_whatToShow & NodeFilter::SHOW_DOCUMENT_FRAGMENT) != 0; break; + case Node::NOTATION_NODE: + accept = (_whatToShow & NodeFilter::SHOW_NOTATION) != 0; break; + } + if (accept && _pFilter) + return _pFilter->acceptNode(pNode); + else + return accept ? NodeFilter::FILTER_ACCEPT : NodeFilter::FILTER_REJECT; +} + + +Node* TreeWalker::next(Node* pNode) const +{ + Node* pNext = accept(pNode) != NodeFilter::FILTER_REJECT ? pNode->firstChild() : 0; + if (pNext) return pNext; + pNext = pNode; + while (pNext && pNext != _pRoot) + { + Node* pSibling = pNext->nextSibling(); + if (pSibling) return pSibling; + pNext = pNext->parentNode(); + } + return 0; +} + + +Node* TreeWalker::previous(Node* pNode) const +{ + if (pNode == _pRoot) return 0; + Node* pPrev = pNode->previousSibling(); + while (pPrev) + { + Node* pLastChild = accept(pPrev) != NodeFilter::FILTER_REJECT ? pPrev->lastChild() : 0; + if (pLastChild) + pPrev = pLastChild; + else + return pPrev; + } + return pNode->parentNode(); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/ValueTraits.cpp b/contrib/libs/poco/XML/src/ValueTraits.cpp new file mode 100644 index 0000000000..c9b5b3efb8 --- /dev/null +++ b/contrib/libs/poco/XML/src/ValueTraits.cpp @@ -0,0 +1,39 @@ +// +// ValueTraits.cpp +// +// Library: XML +// Package: XML +// Module: ValueTraits +// +// Definition of the ValueTraits templates. +// +// Copyright (c) 2015, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Based on libstudxml (http://www.codesynthesis.com/projects/libstudxml/). +// Copyright (c) 2009-2013 Code Synthesis Tools CC. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/XML/XMLStreamParser.h" +#include "Poco/XML/XMLStreamParserException.h" + + +namespace Poco { +namespace XML { + + +bool DefaultValueTraits<bool>::parse(std::string s, const XMLStreamParser& p) +{ + if (s == "true" || s == "1" || s == "True" || s == "TRUE") + return true; + else if (s == "false" || s == "0" || s == "False" || s == "FALSE") + return false; + else + throw XMLStreamParserException(p, "invalid bool value '" + s + "'"); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/WhitespaceFilter.cpp b/contrib/libs/poco/XML/src/WhitespaceFilter.cpp new file mode 100644 index 0000000000..7aba9f5f7e --- /dev/null +++ b/contrib/libs/poco/XML/src/WhitespaceFilter.cpp @@ -0,0 +1,212 @@ +// +// WhitespaceFilter.cpp +// +// Library: XML +// Package: SAX +// Module: WhitespaceFilter +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/WhitespaceFilter.h" +#include "Poco/SAX/SAXException.h" + + +namespace Poco { +namespace XML { + + +WhitespaceFilter::WhitespaceFilter(): + _pLexicalHandler(0), + _filter(true) +{ +} + + +WhitespaceFilter::WhitespaceFilter(XMLReader* pReader): + XMLFilterImpl(pReader), + _pLexicalHandler(0), + _filter(true) +{ +} + + +WhitespaceFilter::~WhitespaceFilter() +{ +} + + +void WhitespaceFilter::setProperty(const XMLString& propertyId, const XMLString& value) +{ + if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) + throw SAXNotSupportedException(std::string("property does not take a string value: ") + fromXMLString(propertyId)); + else + XMLFilterImpl::setProperty(propertyId, value); + +} + + +void WhitespaceFilter::setProperty(const XMLString& propertyId, void* value) +{ + if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) + _pLexicalHandler = reinterpret_cast<LexicalHandler*>(value); + else + XMLFilterImpl::setProperty(propertyId, value); +} + + +void* WhitespaceFilter::getProperty(const XMLString& propertyId) const +{ + if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) + return _pLexicalHandler; + else + return XMLFilterImpl::getProperty(propertyId); +} + + +void WhitespaceFilter::startDocument() +{ + XMLFilterImpl::startDocument(); + _filter = true; + _data.clear(); +} + + +void WhitespaceFilter::endDocument() +{ + XMLFilterImpl::endDocument(); + _filter = true; + _data.clear(); +} + + +void WhitespaceFilter::startElement(const XMLString& uri, const XMLString& localName, const XMLString& qname, const Attributes& attrList) +{ + XMLFilterImpl::startElement(uri, localName, qname, attrList); + _filter = true; + _data.clear(); +} + + +void WhitespaceFilter::endElement(const XMLString& uri, const XMLString& localName, const XMLString& qname) +{ + XMLFilterImpl::endElement(uri, localName, qname); + _filter = true; + _data.clear(); +} + + +void WhitespaceFilter::characters(const XMLChar ch[], int start, int length) +{ + if (_filter) + { + bool ws = true; + const XMLChar* it = ch + start; + const XMLChar* end = ch + start + length; + _data.append(it, end); + while (it != end) + { + if (*it != '\r' && *it != '\n' && *it != '\t' && *it != ' ') + { + ws = false; + break; + } + ++it; + } + if (!ws) + { + XMLFilterImpl::characters(_data.data(), 0, (int) _data.length()); + _filter = false; + _data.clear(); + } + } + else XMLFilterImpl::characters(ch, start, length); +} + + +void WhitespaceFilter::ignorableWhitespace(const XMLChar /*ch*/[], int /*start*/, int /*length*/) +{ + // the handler name already says that this data can be ignored +} + + +void WhitespaceFilter::processingInstruction(const XMLString& target, const XMLString& data) +{ + XMLFilterImpl::processingInstruction(target, data); + _filter = true; + _data.clear(); +} + + +void WhitespaceFilter::startDTD(const XMLString& name, const XMLString& publicId, const XMLString& systemId) +{ + if (_pLexicalHandler) + _pLexicalHandler->startDTD(name, publicId, systemId); +} + + +void WhitespaceFilter::endDTD() +{ + if (_pLexicalHandler) + _pLexicalHandler->endDTD(); +} + + +void WhitespaceFilter::startEntity(const XMLString& name) +{ + if (_pLexicalHandler) + _pLexicalHandler->startEntity(name); + _filter = true; + _data.clear(); +} + + +void WhitespaceFilter::endEntity(const XMLString& name) +{ + if (_pLexicalHandler) + _pLexicalHandler->endEntity(name); + _filter = true; + _data.clear(); +} + + +void WhitespaceFilter::startCDATA() +{ + if (_pLexicalHandler) + _pLexicalHandler->startCDATA(); + _filter = false; + _data.clear(); +} + + +void WhitespaceFilter::endCDATA() +{ + if (_pLexicalHandler) + _pLexicalHandler->endCDATA(); + _filter = true; + _data.clear(); +} + + +void WhitespaceFilter::comment(const XMLChar ch[], int start, int length) +{ + if (_pLexicalHandler) + _pLexicalHandler->comment(ch, start, length); + _filter = true; + _data.clear(); +} + + +void WhitespaceFilter::setupParse() +{ + XMLFilterImpl::setupParse(); + + parent()->setProperty(XMLReader::PROPERTY_LEXICAL_HANDLER, static_cast<LexicalHandler*>(this)); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/XMLException.cpp b/contrib/libs/poco/XML/src/XMLException.cpp new file mode 100644 index 0000000000..62ba990cda --- /dev/null +++ b/contrib/libs/poco/XML/src/XMLException.cpp @@ -0,0 +1,29 @@ +// +// XMLException.cpp +// +// Library: XML +// Package: XML +// Module: XMLException +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/XML/XMLException.h" +#include <typeinfo> + + +using Poco::RuntimeException; + + +namespace Poco { +namespace XML { + + +POCO_IMPLEMENT_EXCEPTION(XMLException, RuntimeException, "XML Exception") + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/XMLFilter.cpp b/contrib/libs/poco/XML/src/XMLFilter.cpp new file mode 100644 index 0000000000..a409db1e8b --- /dev/null +++ b/contrib/libs/poco/XML/src/XMLFilter.cpp @@ -0,0 +1,27 @@ +// +// XMLFilter.cpp +// +// Library: XML +// Package: SAX +// Module: SAXFilters +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/XMLFilter.h" + + +namespace Poco { +namespace XML { + + +XMLFilter::~XMLFilter() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/XMLFilterImpl.cpp b/contrib/libs/poco/XML/src/XMLFilterImpl.cpp new file mode 100644 index 0000000000..2256f24584 --- /dev/null +++ b/contrib/libs/poco/XML/src/XMLFilterImpl.cpp @@ -0,0 +1,313 @@ +// +// XMLFilterImpl.cpp +// +// Library: XML +// Package: SAX +// Module: SAXFilters +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/XMLFilterImpl.h" +#include "Poco/SAX/SAXException.h" + + +namespace Poco { +namespace XML { + + +XMLFilterImpl::XMLFilterImpl(): + _pParent(0), + _pEntityResolver(0), + _pDTDHandler(0), + _pContentHandler(0), + _pErrorHandler(0) +{ +} + + +XMLFilterImpl::XMLFilterImpl(XMLReader* pParent): + _pParent(pParent), + _pEntityResolver(0), + _pDTDHandler(0), + _pContentHandler(0), + _pErrorHandler(0) +{ +} + + +XMLFilterImpl::~XMLFilterImpl() +{ +} + + +XMLReader* XMLFilterImpl::getParent() const +{ + return _pParent; +} + + +void XMLFilterImpl::setParent(XMLReader* pParent) +{ + _pParent = pParent; +} + + +void XMLFilterImpl::setEntityResolver(EntityResolver* pResolver) +{ + _pEntityResolver = pResolver; +} + + +EntityResolver* XMLFilterImpl::getEntityResolver() const +{ + return _pEntityResolver; +} + + +void XMLFilterImpl::setDTDHandler(DTDHandler* pDTDHandler) +{ + _pDTDHandler = pDTDHandler; +} + + +DTDHandler* XMLFilterImpl::getDTDHandler() const +{ + return _pDTDHandler; +} + + +void XMLFilterImpl::setContentHandler(ContentHandler* pContentHandler) +{ + _pContentHandler = pContentHandler; +} + + +ContentHandler* XMLFilterImpl::getContentHandler() const +{ + return _pContentHandler; +} + + +void XMLFilterImpl::setErrorHandler(ErrorHandler* pErrorHandler) +{ + _pErrorHandler = pErrorHandler; +} + + +ErrorHandler* XMLFilterImpl::getErrorHandler() const +{ + return _pErrorHandler; +} + + +void XMLFilterImpl::setFeature(const XMLString& featureId, bool state) +{ + if (_pParent) + _pParent->setFeature(featureId, state); + else + throw SAXNotRecognizedException(fromXMLString(featureId)); +} + + +bool XMLFilterImpl::getFeature(const XMLString& featureId) const +{ + if (_pParent) + return _pParent->getFeature(featureId); + else + throw SAXNotRecognizedException(fromXMLString(featureId)); +} + + +void XMLFilterImpl::setProperty(const XMLString& propertyId, const XMLString& value) +{ + if (_pParent) + _pParent->setProperty(propertyId, value); + else + throw SAXNotRecognizedException(fromXMLString(propertyId)); +} + + +void XMLFilterImpl::setProperty(const XMLString& propertyId, void* value) +{ + if (_pParent) + _pParent->setProperty(propertyId, value); + else + throw SAXNotRecognizedException(fromXMLString(propertyId)); +} + + +void* XMLFilterImpl::getProperty(const XMLString& propertyId) const +{ + if (_pParent) + return _pParent->getProperty(propertyId); + else + throw SAXNotRecognizedException(fromXMLString(propertyId)); +} + + +void XMLFilterImpl::parse(InputSource* pSource) +{ + setupParse(); + _pParent->parse(pSource); +} + + +void XMLFilterImpl::parse(const XMLString& systemId) +{ + setupParse(); + _pParent->parse(systemId); +} + + +void XMLFilterImpl::parseMemoryNP(const char* xml, std::size_t size) +{ + setupParse(); + _pParent->parseMemoryNP(xml, size); +} + + +InputSource* XMLFilterImpl::resolveEntity(const XMLString* publicId, const XMLString& systemId) +{ + if (_pEntityResolver) + return _pEntityResolver->resolveEntity(publicId, systemId); + else + return 0; +} + + +void XMLFilterImpl::releaseInputSource(InputSource* pSource) +{ + if (_pEntityResolver) + _pEntityResolver->releaseInputSource(pSource); +} + + +void XMLFilterImpl::notationDecl(const XMLString& name, const XMLString* publicId, const XMLString* systemId) +{ + if (_pDTDHandler) + _pDTDHandler->notationDecl(name, publicId, systemId); +} + + +void XMLFilterImpl::unparsedEntityDecl(const XMLString& name, const XMLString* publicId, const XMLString& systemId, const XMLString& notationName) +{ + if (_pDTDHandler) + _pDTDHandler->unparsedEntityDecl(name, publicId, systemId, notationName); +} + + +void XMLFilterImpl::setDocumentLocator(const Locator* loc) +{ + if (_pContentHandler) + _pContentHandler->setDocumentLocator(loc); +} + + +void XMLFilterImpl::startDocument() +{ + if (_pContentHandler) + _pContentHandler->startDocument(); +} + + +void XMLFilterImpl::endDocument() +{ + if (_pContentHandler) + _pContentHandler->endDocument(); +} + + +void XMLFilterImpl::startElement(const XMLString& uri, const XMLString& localName, const XMLString& qname, const Attributes& attrList) +{ + if (_pContentHandler) + _pContentHandler->startElement(uri, localName, qname, attrList); +} + + +void XMLFilterImpl::endElement(const XMLString& uri, const XMLString& localName, const XMLString& qname) +{ + if (_pContentHandler) + _pContentHandler->endElement(uri, localName, qname); +} + + +void XMLFilterImpl::characters(const XMLChar ch[], int start, int length) +{ + if (_pContentHandler) + _pContentHandler->characters(ch, start, length); +} + + +void XMLFilterImpl::ignorableWhitespace(const XMLChar ch[], int start, int length) +{ + if (_pContentHandler) + _pContentHandler->ignorableWhitespace(ch, start, length); +} + + +void XMLFilterImpl::processingInstruction(const XMLString& target, const XMLString& data) +{ + if (_pContentHandler) + _pContentHandler->processingInstruction(target, data); +} + + +void XMLFilterImpl::startPrefixMapping(const XMLString& prefix, const XMLString& uri) +{ + if (_pContentHandler) + _pContentHandler->startPrefixMapping(prefix, uri); +} + + +void XMLFilterImpl::endPrefixMapping(const XMLString& prefix) +{ + if (_pContentHandler) + _pContentHandler->endPrefixMapping(prefix); +} + + +void XMLFilterImpl::skippedEntity(const XMLString& prefix) +{ + if (_pContentHandler) + _pContentHandler->skippedEntity(prefix); +} + + +void XMLFilterImpl::warning(const SAXException& e) +{ + if (_pErrorHandler) + _pErrorHandler->warning(e); +} + + +void XMLFilterImpl::error(const SAXException& e) +{ + if (_pErrorHandler) + _pErrorHandler->error(e); +} + + +void XMLFilterImpl::fatalError(const SAXException& e) +{ + if (_pErrorHandler) + _pErrorHandler->fatalError(e); +} + + +void XMLFilterImpl::setupParse() +{ + poco_check_ptr (_pParent); + + _pParent->setEntityResolver(this); + _pParent->setDTDHandler(this); + _pParent->setContentHandler(this); + _pParent->setErrorHandler(this); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/XMLReader.cpp b/contrib/libs/poco/XML/src/XMLReader.cpp new file mode 100644 index 0000000000..d6cd767d7d --- /dev/null +++ b/contrib/libs/poco/XML/src/XMLReader.cpp @@ -0,0 +1,37 @@ +// +// XMLReader.cpp +// +// Library: XML +// Package: SAX +// Module: SAX +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/SAX/XMLReader.h" + + +namespace Poco { +namespace XML { + + +const XMLString XMLReader::FEATURE_VALIDATION = toXMLString("http://xml.org/sax/features/validation"); +const XMLString XMLReader::FEATURE_NAMESPACES = toXMLString("http://xml.org/sax/features/namespaces"); +const XMLString XMLReader::FEATURE_NAMESPACE_PREFIXES = toXMLString("http://xml.org/sax/features/namespace-prefixes"); +const XMLString XMLReader::FEATURE_EXTERNAL_GENERAL_ENTITIES = toXMLString("http://xml.org/sax/features/external-general-entities"); +const XMLString XMLReader::FEATURE_EXTERNAL_PARAMETER_ENTITIES = toXMLString("http://xml.org/sax/features/external-parameter-entities"); +const XMLString XMLReader::FEATURE_STRING_INTERNING = toXMLString("http://xml.org/sax/features/string-interning"); +const XMLString XMLReader::PROPERTY_DECLARATION_HANDLER = toXMLString("http://xml.org/sax/properties/declaration-handler"); +const XMLString XMLReader::PROPERTY_LEXICAL_HANDLER = toXMLString("http://xml.org/sax/properties/lexical-handler"); + + +XMLReader::~XMLReader() +{ +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/XMLStreamParser.cpp b/contrib/libs/poco/XML/src/XMLStreamParser.cpp new file mode 100644 index 0000000000..850657d79d --- /dev/null +++ b/contrib/libs/poco/XML/src/XMLStreamParser.cpp @@ -0,0 +1,939 @@ +// +// XMLStreamParser.cpp +// +// Library: XML +// Package: XML +// Module: XMLStreamParser +// +// Copyright (c) 2015, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Based on libstudxml (http://www.codesynthesis.com/projects/libstudxml/). +// Copyright (c) 2009-2013 Code Synthesis Tools CC. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/XML/XMLStreamParser.h" +#include <new> +#include <cstring> +#include <istream> +#include <ostream> +#include <sstream> + + +namespace Poco { +namespace XML { + + +struct StreamExceptionController +{ + StreamExceptionController(std::istream& is): + _istr(is), + _oldState(_istr.exceptions()) + { + _istr.exceptions(_oldState & ~std::istream::failbit); + } + + ~StreamExceptionController() + { + std::istream::iostate s = _istr.rdstate(); + s &= ~std::istream::failbit; + + // If our error state (sans failbit) intersects with the + // exception state then that means we have an active + // exception and changing error/exception state will + // cause another to be thrown. + if (!(_oldState & s)) + { + // Clear failbit if it was caused by eof. + // + if (_istr.fail() && _istr.eof()) + _istr.clear(s); + + _istr.exceptions(_oldState); + } + } + +private: + StreamExceptionController(const StreamExceptionController&); + StreamExceptionController& operator = (const StreamExceptionController&); + +private: + std::istream& _istr; + std::istream::iostate _oldState; +}; + + +static const char* parserEventStrings[] = +{ + "start element", + "end element", + "start attribute", + "end attribute", + "characters", + "start namespace declaration", + "end namespace declaration", + "end of file" +}; + + +std::ostream& operator << (std::ostream& os, XMLStreamParser::EventType e) +{ + return os << parserEventStrings[e]; +} + + +XMLStreamParser::XMLStreamParser(std::istream& is, const std::string& iname, FeatureType f): + _size(0), + _inputName(iname), + _feature(f) +{ + _data.is = &is; + init(); +} + + +XMLStreamParser::XMLStreamParser(const void* data, std::size_t size, const std::string& iname, FeatureType f): + _size(size), + _inputName(iname), + _feature(f) +{ + poco_assert(data != 0 && size != 0); + + _data.buf = data; + init(); +} + + +XMLStreamParser::~XMLStreamParser() +{ + if (_parser) XML_ParserFree(_parser); +} + + +void XMLStreamParser::init() +{ + _depth = 0; + _parserState = state_next; + _currentEvent = EV_EOF; + _queue = EV_EOF; + + _qualifiedName = &_qname; + _pvalue = &_value; + + _line = 0; + _column = 0; + + _currentAttributeIndex = 0; + _startNamespaceIndex = 0; + _endNamespaceIndex = 0; + + if ((_feature & RECEIVE_ATTRIBUTE_MAP) != 0 && (_feature & RECEIVE_ATTRIBUTES_EVENT) != 0) + _feature &= ~RECEIVE_ATTRIBUTE_MAP; + + // Allocate the XMLStreamParser. Make sure nothing else can throw after + // this call since otherwise we will leak it. + // + _parser = XML_ParserCreateNS(0, XML_Char(' ')); + + if (_parser == 0) + throw std::bad_alloc(); + + // Get prefixes in addition to namespaces and local names. + // + XML_SetReturnNSTriplet(_parser, true); + + // Set handlers. + // + XML_SetUserData(_parser, this); + + if ((_feature & RECEIVE_ELEMENTS) != 0) + { + XML_SetStartElementHandler(_parser, &handleStartElement); + XML_SetEndElementHandler(_parser, &handleEndElement); + } + + if ((_feature & RECEIVE_CHARACTERS) != 0) + XML_SetCharacterDataHandler(_parser, &handleCharacters); + + if ((_feature & RECEIVE_NAMESPACE_DECLS) != 0) + XML_SetNamespaceDeclHandler(_parser, &handleStartNamespaceDecl, &handleEndNamespaceDecl); +} + + +void XMLStreamParser::handleError() +{ + XML_Error e(XML_GetErrorCode(_parser)); + + if (e == XML_ERROR_ABORTED) + { + // For now we only abort the XMLStreamParser in the handleCharacters() and + // handleStartElement() handlers. + // + switch (content()) + { + case Content::Empty: + throw XMLStreamParserException(*this, "characters in empty content"); + case Content::Simple: + throw XMLStreamParserException(*this, "element in simple content"); + case Content::Complex: + throw XMLStreamParserException(*this, "characters in complex content"); + default: + poco_assert(false); + } + } + else + throw XMLStreamParserException(_inputName, XML_GetCurrentLineNumber(_parser), XML_GetCurrentColumnNumber(_parser), XML_ErrorString(e)); +} + + +XMLStreamParser::EventType XMLStreamParser::next() +{ + if (_parserState == state_next) + return nextImpl(false); + else + { + // If we previously peeked at start/end_element, then adjust + // state accordingly. + // + switch (_currentEvent) + { + case EV_END_ELEMENT: + { + if (!_elementState.empty() && _elementState.back().depth == _depth) + popElement(); + + _depth--; + break; + } + case EV_START_ELEMENT: + { + _depth++; + break; + } + default: + break; + } + + _parserState = state_next; + return _currentEvent; + } +} + + +const std::string& XMLStreamParser::attribute(const QName& qn) const +{ + if (const ElementEntry* e = getElement()) + { + AttributeMapType::const_iterator i(e->attributeMap.find(qn)); + + if (i != e->attributeMap.end()) + { + if (!i->second.handled) + { + i->second.handled = true; + e->attributesUnhandled--; + } + return i->second.value; + } + } + + throw XMLStreamParserException(*this, "attribute '" + qn.toString() + "' expected"); +} + + +std::string XMLStreamParser::attribute(const QName& qn, const std::string& dv) const +{ + if (const ElementEntry* e = getElement()) + { + AttributeMapType::const_iterator i(e->attributeMap.find(qn)); + + if (i != e->attributeMap.end()) + { + if (!i->second.handled) + { + i->second.handled = true; + e->attributesUnhandled--; + } + return i->second.value; + } + } + + return dv; +} + + +bool XMLStreamParser::attributePresent(const QName& qn) const +{ + if (const ElementEntry* e = getElement()) + { + AttributeMapType::const_iterator i(e->attributeMap.find(qn)); + + if (i != e->attributeMap.end()) + { + if (!i->second.handled) + { + i->second.handled = true; + e->attributesUnhandled--; + } + return true; + } + } + + return false; +} + + +void XMLStreamParser::nextExpect(EventType e) +{ + if (next() != e) + throw XMLStreamParserException(*this, std::string(parserEventStrings[e]) + " expected"); +} + + +void XMLStreamParser::nextExpect(EventType e, const std::string& ns, const std::string& n) +{ + if (next() != e || namespaceURI() != ns || localName() != n) + throw XMLStreamParserException(*this, std::string(parserEventStrings[e]) + " '" + QName(ns, n).toString() + "' expected"); +} + + +std::string XMLStreamParser::element() +{ + content(Content::Simple); + std::string r; + + // The content of the element can be empty in which case there + // will be no characters event. + // + EventType e(next()); + if (e == EV_CHARACTERS) + { + r.swap(value()); + e = next(); + } + + // We cannot really get anything other than end_element since + // the simple content validation won't allow it. + // + poco_assert(e == EV_END_ELEMENT); + + return r; +} + + +std::string XMLStreamParser::element(const QName& qn, const std::string& dv) +{ + if (peek() == EV_START_ELEMENT && getQName() == qn) + { + next(); + return element(); + } + + return dv; +} + + +const XMLStreamParser::ElementEntry* XMLStreamParser::getElementImpl() const +{ + // The handleStartElement() Expat handler may have already provisioned + // an entry in the element stack. In this case, we need to get the + // one before it, if any. + // + const ElementEntry* r(0); + ElementState::size_type n(_elementState.size() - 1); + + if (_elementState[n].depth == _depth) + r = &_elementState[n]; + else if (n != 0 && _elementState[n].depth > _depth) + { + n--; + if (_elementState[n].depth == _depth) + r = &_elementState[n]; + } + + return r; +} + + +void XMLStreamParser::popElement() +{ + // Make sure there are no unhandled attributes left. + // + const ElementEntry& e(_elementState.back()); + if (e.attributesUnhandled != 0) + { + // Find the first unhandled attribute and report it. + // + for (AttributeMapType::const_iterator i(e.attributeMap.begin()); i != e.attributeMap.end(); ++i) + { + if (!i->second.handled) + throw XMLStreamParserException(*this, "unexpected attribute '" + i->first.toString() + "'"); + } + poco_assert(false); + } + + _elementState.pop_back(); +} + + +XMLStreamParser::EventType XMLStreamParser::nextImpl(bool peek) +{ + EventType e(nextBody()); + + // Content-specific processing. Note that we handle characters in the + // handleCharacters() Expat handler for two reasons. Firstly, it is faster + // to ignore the whitespaces at the source. Secondly, this allows us + // to distinguish between element and attribute characters. We can + // move this processing to the handler because the characters event + // is never queued. + // + switch (e) + { + case EV_END_ELEMENT: + { + // If this is a peek, then avoid popping the stack just yet. + // This way, the attribute map will still be valid until we + // call next(). + // + if (!peek) + { + if (!_elementState.empty() && _elementState.back().depth == _depth) + popElement(); + + _depth--; + } + break; + } + case EV_START_ELEMENT: + { + if (const ElementEntry* pEntry = getElement()) + { + switch (pEntry->content) + { + case Content::Empty: + throw XMLStreamParserException(*this, "element in empty content"); + case Content::Simple: + throw XMLStreamParserException(*this, "element in simple content"); + default: + break; + } + } + + // If this is a peek, then delay adjusting the depth. + // + if (!peek) + _depth++; + + break; + } + default: + break; + } + + return e; +} + + +XMLStreamParser::EventType XMLStreamParser::nextBody() +{ + // See if we have any start namespace declarations we need to return. + // + if (_startNamespaceIndex < _startNamespace.size()) + { + // Based on the previous event determine what's the next one must be. + // + switch (_currentEvent) + { + case EV_START_NAMESPACE_DECL: + { + if (++_startNamespaceIndex == _startNamespace.size()) + { + _startNamespaceIndex = 0; + _startNamespace.clear(); + _qualifiedName = &_qname; + break; // No more declarations. + } + // Fall through. + } + case EV_START_ELEMENT: + { + _currentEvent = EV_START_NAMESPACE_DECL; + _qualifiedName = &_startNamespace[_startNamespaceIndex]; + return _currentEvent; + } + default: + { + poco_assert(false); + return _currentEvent = EV_EOF; + } + } + } + + // See if we have any attributes we need to return as events. + // + if (_currentAttributeIndex < _attributes.size()) + { + // Based on the previous event determine what's the next one must be. + // + switch (_currentEvent) + { + case EV_START_ATTRIBUTE: + { + _currentEvent = EV_CHARACTERS; + _pvalue = &_attributes[_currentAttributeIndex].value; + return _currentEvent; + } + case EV_CHARACTERS: + { + _currentEvent = EV_END_ATTRIBUTE; // Name is already set. + return _currentEvent; + } + case EV_END_ATTRIBUTE: + { + if (++_currentAttributeIndex == _attributes.size()) + { + _currentAttributeIndex = 0; + _attributes.clear(); + _qualifiedName = &_qname; + _pvalue = &_value; + break; // No more attributes. + } + // Fall through. + } + case EV_START_ELEMENT: + case EV_START_NAMESPACE_DECL: + { + _currentEvent = EV_START_ATTRIBUTE; + _qualifiedName = &_attributes[_currentAttributeIndex].qname; + return _currentEvent; + } + default: + { + poco_assert(false); + return _currentEvent = EV_EOF; + } + } + } + + // See if we have any end namespace declarations we need to return. + // + if (_endNamespaceIndex < _endNamespace.size()) + { + // Based on the previous event determine what's the next one must be. + // + switch (_currentEvent) + { + case EV_END_NAMESPACE_DECL: + { + if (++_endNamespaceIndex == _endNamespace.size()) + { + _endNamespaceIndex = 0; + _endNamespace.clear(); + _qualifiedName = &_qname; + break; // No more declarations. + } + // Fall through. + } + // The end namespace declaration comes before the end element + // which means it can follow pretty much any other event. + // + default: + { + _currentEvent = EV_END_NAMESPACE_DECL; + _qualifiedName = &_endNamespace[_endNamespaceIndex]; + return _currentEvent; + } + } + } + + // Check the queue. + // + if (_queue != EV_EOF) + { + _currentEvent = _queue; + _queue = EV_EOF; + + _line = XML_GetCurrentLineNumber(_parser); + _column = XML_GetCurrentColumnNumber(_parser); + + return _currentEvent; + } + + // Reset the character accumulation flag. + // + _accumulateContent = false; + + XML_ParsingStatus ps; + XML_GetParsingStatus(_parser, &ps); + + switch (ps.parsing) + { + case XML_INITIALIZED: + { + // As if we finished the previous chunk. + break; + } + case XML_PARSING: + { + poco_assert(false); + return _currentEvent = EV_EOF; + } + case XML_FINISHED: + { + return _currentEvent = EV_EOF; + } + case XML_SUSPENDED: + { + switch (XML_ResumeParser(_parser)) + { + case XML_STATUS_SUSPENDED: + { + // If the XMLStreamParser is again in the suspended state, then + // that means we have the next event. + // + return _currentEvent; + } + case XML_STATUS_OK: + { + // Otherwise, we need to get and parse the next chunk of data + // unless this was the last chunk, in which case this is eof. + // + if (ps.finalBuffer) + return _currentEvent = EV_EOF; + + break; + } + case XML_STATUS_ERROR: + handleError(); + } + break; + } + } + + // Get and parse the next chunk of data until we get the next event + // or reach eof. + // + if (!_accumulateContent) + _currentEvent = EV_EOF; + + XML_Status s; + do + { + if (_size != 0) + { + s = XML_Parse(_parser, static_cast<const char*>(_data.buf), static_cast<int>(_size), true); + + if (s == XML_STATUS_ERROR) + handleError(); + + break; + } + else + { + const size_t cap(4096); + + char* b(static_cast<char*>(XML_GetBuffer(_parser, cap))); + if (b == 0) + throw std::bad_alloc(); + + // Temporarily unset the exception failbit. Also clear the fail bit + // when we reset the old state if it was caused by eof. + // + std::istream& is(*_data.is); + { + StreamExceptionController sec(is); + is.read(b, static_cast<std::streamsize>(cap)); + } + + // If the caller hasn't configured the stream to use exceptions, + // then use the parsing exception to report an error. + // + if (is.bad() || (is.fail() && !is.eof())) + throw XMLStreamParserException(*this, "io failure"); + + bool eof(is.eof()); + + s = XML_ParseBuffer(_parser, static_cast<int>(is.gcount()), eof); + + if (s == XML_STATUS_ERROR) + handleError(); + + if (eof) + break; + } + } while (s != XML_STATUS_SUSPENDED); + + return _currentEvent; +} + + +static void splitName(const XML_Char* s, QName& qn) +{ + std::string& ns(qn.namespaceURI()); + std::string& name(qn.localName()); + std::string& prefix(qn.prefix()); + + const char* p(strchr(s, ' ')); + + if (p == 0) + { + ns.clear(); + name = s; + prefix.clear(); + } + else + { + ns.assign(s, 0, p - s); + + s = p + 1; + p = strchr(s, ' '); + + if (p == 0) + { + name = s; + prefix.clear(); + } + else + { + name.assign(s, 0, p - s); + prefix = p + 1; + } + } +} + + +void XMLCALL XMLStreamParser::handleStartElement(void* v, const XML_Char* name, const XML_Char** atts) +{ + XMLStreamParser& p(*static_cast<XMLStreamParser*>(v)); + + XML_ParsingStatus ps; + XML_GetParsingStatus(p._parser, &ps); + + // Expat has a (mis)-feature of a possibily calling handlers even + // after the non-resumable XML_StopParser call. + // + if (ps.parsing == XML_FINISHED) + return; + + // Cannot be a followup event. + // + poco_assert(ps.parsing == XML_PARSING); + + // When accumulating characters in simple content, we expect to + // see more characters or end element. Seeing start element is + // possible but means violation of the content model. + // + if (p._accumulateContent) + { + // It would have been easier to throw the exception directly, + // however, the Expat code is most likely not exception safe. + // + p._line = XML_GetCurrentLineNumber(p._parser); + p._column = XML_GetCurrentColumnNumber(p._parser); + XML_StopParser(p._parser, false); + return; + } + + p._currentEvent = EV_START_ELEMENT; + splitName(name, p._qname); + + p._line = XML_GetCurrentLineNumber(p._parser); + p._column = XML_GetCurrentColumnNumber(p._parser); + + // Handle attributes. + // + if (*atts != 0) + { + bool am((p._feature & RECEIVE_ATTRIBUTE_MAP) != 0); + bool ae((p._feature & RECEIVE_ATTRIBUTES_EVENT) != 0); + + // Provision an entry for this element. + // + ElementEntry* pe(0); + if (am) + { + p._elementState.push_back(ElementEntry(p._depth + 1)); + pe = &p._elementState.back(); + } + + if (am || ae) + { + for (; *atts != 0; atts += 2) + { + if (am) + { + QName qn; + splitName(*atts, qn); + AttributeMapType::value_type value(qn, AttributeValueType()); + value.second.value = *(atts + 1); + value.second.handled = false; + pe->attributeMap.insert(value); + } + else + { + p._attributes.push_back(AttributeType()); + splitName(*atts, p._attributes.back().qname); + p._attributes.back().value = *(atts + 1); + } + } + + if (am) + pe->attributesUnhandled = pe->attributeMap.size(); + } + } + + XML_StopParser(p._parser, true); +} + + +void XMLCALL XMLStreamParser::handleEndElement(void* v, const XML_Char* name) +{ + XMLStreamParser& p(*static_cast<XMLStreamParser*>(v)); + + XML_ParsingStatus ps; + XML_GetParsingStatus(p._parser, &ps); + + // Expat has a (mis)-feature of a possibily calling handlers even + // after the non-resumable XML_StopParser call. + // + if (ps.parsing == XML_FINISHED) + return; + + // This can be a followup event for empty elements (<foo/>). In this + // case the element name is already set. + // + if (ps.parsing != XML_PARSING) + p._queue = EV_END_ELEMENT; + else + { + splitName(name, p._qname); + + // If we are accumulating characters, then queue this event. + // + if (p._accumulateContent) + p._queue = EV_END_ELEMENT; + else + { + p._currentEvent = EV_END_ELEMENT; + + p._line = XML_GetCurrentLineNumber(p._parser); + p._column = XML_GetCurrentColumnNumber(p._parser); + } + + XML_StopParser(p._parser, true); + } +} + + +void XMLCALL XMLStreamParser::handleCharacters(void* v, const XML_Char* s, int n) +{ + XMLStreamParser& p(*static_cast<XMLStreamParser*>(v)); + + XML_ParsingStatus ps; + XML_GetParsingStatus(p._parser, &ps); + + // Expat has a (mis)-feature of a possibily calling handlers even + // after the non-resumable XML_StopParser call. + // + if (ps.parsing == XML_FINISHED) + return; + + Content cont(p.content()); + + // If this is empty or complex content, see if these are whitespaces. + // + switch (cont) + { + case Content::Empty: + case Content::Complex: + { + for (int i(0); i != n; ++i) + { + char c(s[i]); + if (c == 0x20 || c == 0x0A || c == 0x0D || c == 0x09) + continue; + + // It would have been easier to throw the exception directly, + // however, the Expat code is most likely not exception safe. + // + p._line = XML_GetCurrentLineNumber(p._parser); + p._column = XML_GetCurrentColumnNumber(p._parser); + XML_StopParser(p._parser, false); + break; + } + return; + } + default: + break; + } + + // Append the characters if we are accumulating. This can also be a + // followup event for another character event. In this case also + // append the data. + // + if (p._accumulateContent || ps.parsing != XML_PARSING) + { + poco_assert(p._currentEvent == EV_CHARACTERS); + p._value.append(s, n); + } + else + { + p._currentEvent = EV_CHARACTERS; + p._value.assign(s, n); + + p._line = XML_GetCurrentLineNumber(p._parser); + p._column = XML_GetCurrentColumnNumber(p._parser); + + // In simple content we need to accumulate all the characters + // into a single event. To do this we will let the XMLStreamParser run + // until we reach the end of the element. + // + if (cont == Content::Simple) + p._accumulateContent = true; + else + XML_StopParser(p._parser, true); + } +} + + +void XMLCALL XMLStreamParser::handleStartNamespaceDecl(void* v, const XML_Char* prefix, const XML_Char* ns) +{ + XMLStreamParser& p(*static_cast<XMLStreamParser*>(v)); + + XML_ParsingStatus ps; + XML_GetParsingStatus(p._parser, &ps); + + // Expat has a (mis)-feature of a possibily calling handlers even + // after the non-resumable XML_StopParser call. + // + if (ps.parsing == XML_FINISHED) + return; + + p._startNamespace.push_back(QName()); + p._startNamespace.back().prefix() = (prefix != 0 ? prefix : ""); + p._startNamespace.back().namespaceURI() = (ns != 0 ? ns : ""); +} + + +void XMLCALL XMLStreamParser::handleEndNamespaceDecl(void* v, const XML_Char* prefix) +{ + XMLStreamParser& p(*static_cast<XMLStreamParser*>(v)); + + XML_ParsingStatus ps; + XML_GetParsingStatus(p._parser, &ps); + + // Expat has a (mis)-feature of a possibily calling handlers even + // after the non-resumable XML_StopParser call. + // + if (ps.parsing == XML_FINISHED) + return; + + p._endNamespace.push_back(QName()); + p._endNamespace.back().prefix() = (prefix != 0 ? prefix : ""); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/XMLStreamParserException.cpp b/contrib/libs/poco/XML/src/XMLStreamParserException.cpp new file mode 100644 index 0000000000..d7b01690ed --- /dev/null +++ b/contrib/libs/poco/XML/src/XMLStreamParserException.cpp @@ -0,0 +1,88 @@ +// +// XMLStreamParserException.cpp +// +// Library: XML +// Package: XML +// Module: XMLStreamParserException +// +// Copyright (c) 2015, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/XML/XMLStreamParserException.h" +#include "Poco/XML/XMLStreamParser.h" + + +namespace Poco { +namespace XML { + + +XMLStreamParserException::~XMLStreamParserException() noexcept +{ +} + + +XMLStreamParserException::XMLStreamParserException(const std::string& n, Poco::UInt64 l, Poco::UInt64 c, const std::string& d): + _name(n), + _line(l), + _column(c), + _description(d) +{ + init(); +} + + +XMLStreamParserException::XMLStreamParserException(const XMLStreamParser& p, const std::string& d): + _name(p.inputName()), + _line(p.line()), + _column(p.column()), + _description(d) +{ + init(); +} + + +void XMLStreamParserException::init() +{ + std::ostringstream os; + if (!_name.empty()) + os << _name << ':'; + os << _line << ':' << _column << ": error: " << _description; + _what = os.str(); +} + + +const char* XMLStreamParserException::name() const noexcept +{ + return _name.c_str(); +} + + +Poco::UInt64 XMLStreamParserException::line() const +{ + return _line; +} + + +Poco::UInt64 XMLStreamParserException::column() const +{ + return _column; +} + + +const std::string& XMLStreamParserException::description() const +{ + return _description; +} + + +char const* XMLStreamParserException::what() const noexcept +{ + return _what.c_str(); +} + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/XMLString.cpp b/contrib/libs/poco/XML/src/XMLString.cpp new file mode 100644 index 0000000000..732d61f1a5 --- /dev/null +++ b/contrib/libs/poco/XML/src/XMLString.cpp @@ -0,0 +1,64 @@ +// +// XMLString.cpp +// +// Library: XML +// Package: XML +// Module: XMLString +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/XML/XMLString.h" + + +#if defined(XML_UNICODE_WCHAR_T) +#include <stdlib.h> +#endif + + +namespace Poco { +namespace XML { + + +#if defined(XML_UNICODE_WCHAR_T) + + +std::string fromXMLString(const XMLString& str) +{ + std::string result; + result.reserve(str.size()); + + for (XMLString::const_iterator it = str.begin(); it != str.end(); ++it) + { + char c; + wctomb(&c, *it); + result += c; + } + return result; +} + + +XMLString toXMLString(const std::string& str) +{ + XMLString result; + result.reserve(str.size()); + + for (std::string::const_iterator it = str.begin(); it != str.end();) + { + wchar_t c; + int n = mbtowc(&c, &*it, MB_CUR_MAX); + result += c; + it += (n > 0 ? n : 1); + } + return result; +} + + +#endif // XML_UNICODE_WCHAR_T + + +} } // namespace Poco::XML diff --git a/contrib/libs/poco/XML/src/XMLWriter.cpp b/contrib/libs/poco/XML/src/XMLWriter.cpp new file mode 100644 index 0000000000..10833e7b33 --- /dev/null +++ b/contrib/libs/poco/XML/src/XMLWriter.cpp @@ -0,0 +1,1072 @@ +// +// XMLWriter.cpp +// +// Library: XML +// Package: XML +// Module: XMLWriter +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/XML/XMLWriter.h" +#include "Poco/XML/XMLString.h" +#include "Poco/XML/XMLException.h" +#include "Poco/SAX/AttributesImpl.h" +#include "Poco/UTF8Encoding.h" +#include "Poco/UTF16Encoding.h" +#include <sstream> + + +namespace Poco { +namespace XML { + + +const std::string XMLWriter::NEWLINE_DEFAULT; +const std::string XMLWriter::NEWLINE_CR = "\r"; +const std::string XMLWriter::NEWLINE_CRLF = "\r\n"; +const std::string XMLWriter::NEWLINE_LF = "\n"; +const std::string XMLWriter::MARKUP_QUOTENC = """; +const std::string XMLWriter::MARKUP_AMPENC = "&"; +const std::string XMLWriter::MARKUP_LTENC = "<"; +const std::string XMLWriter::MARKUP_GTENC = ">"; +const std::string XMLWriter::MARKUP_TABENC = "	"; +const std::string XMLWriter::MARKUP_CRENC = "
"; +const std::string XMLWriter::MARKUP_LFENC = "
"; +const std::string XMLWriter::MARKUP_LT = "<"; +const std::string XMLWriter::MARKUP_GT = ">"; +const std::string XMLWriter::MARKUP_SLASHGT = "/>"; +const std::string XMLWriter::MARKUP_LTSLASH = "</"; +const std::string XMLWriter::MARKUP_COLON = ":"; +const std::string XMLWriter::MARKUP_EQQUOT = "=\""; +const std::string XMLWriter::MARKUP_QUOT = "\""; +const std::string XMLWriter::MARKUP_SPACE = " "; +const std::string XMLWriter::MARKUP_TAB = "\t"; +const std::string XMLWriter::MARKUP_BEGIN_CDATA = "<![CDATA["; +const std::string XMLWriter::MARKUP_END_CDATA = "]]>"; + + +#if defined(XML_UNICODE_WCHAR_T) + #define NATIVE_ENCODING Poco::UTF16Encoding +#else + #define NATIVE_ENCODING Poco::UTF8Encoding +#endif + + +XMLWriter::XMLWriter(XMLByteOutputStream& str, int options): + _pTextConverter(0), + _pInEncoding(new NATIVE_ENCODING), + _pOutEncoding(new Poco::UTF8Encoding), + _options(options), + _encoding("UTF-8"), + _depth(-1), + _elementCount(0), + _inFragment(false), + _inCDATA(false), + _inDTD(false), + _inInternalDTD(false), + _contentWritten(false), + _unclosedStartTag(false), + _prefix(0), + _nsContextPushed(false), + _indent(MARKUP_TAB) +{ + _pTextConverter = new Poco::OutputStreamConverter(str, *_pInEncoding, *_pOutEncoding); + setNewLine((_options & CANONICAL_XML) ? NEWLINE_LF : NEWLINE_DEFAULT); +} + + +XMLWriter::XMLWriter(XMLByteOutputStream& str, int options, const std::string& encodingName, Poco::TextEncoding& textEncoding): + _pTextConverter(0), + _pInEncoding(new NATIVE_ENCODING), + _pOutEncoding(0), + _options(options), + _encoding(encodingName), + _depth(-1), + _elementCount(0), + _inFragment(false), + _inCDATA(false), + _inDTD(false), + _inInternalDTD(false), + _contentWritten(false), + _unclosedStartTag(false), + _prefix(0), + _nsContextPushed(false), + _indent(MARKUP_TAB) +{ + _pTextConverter = new Poco::OutputStreamConverter(str, *_pInEncoding, textEncoding); + setNewLine((_options & CANONICAL_XML) ? NEWLINE_LF : NEWLINE_DEFAULT); +} + + +XMLWriter::XMLWriter(XMLByteOutputStream& str, int options, const std::string& encodingName, Poco::TextEncoding* pTextEncoding): + _pTextConverter(0), + _pInEncoding(new NATIVE_ENCODING), + _pOutEncoding(0), + _options(options), + _encoding(encodingName), + _depth(-1), + _elementCount(0), + _inFragment(false), + _inCDATA(false), + _inDTD(false), + _inInternalDTD(false), + _contentWritten(false), + _unclosedStartTag(false), + _prefix(0), + _nsContextPushed(false), + _indent(MARKUP_TAB) +{ + if (pTextEncoding) + { + _pTextConverter = new Poco::OutputStreamConverter(str, *_pInEncoding, *pTextEncoding); + } + else + { + _encoding = "UTF-8"; + _pOutEncoding = new Poco::UTF8Encoding; + _pTextConverter = new Poco::OutputStreamConverter(str, *_pInEncoding, *_pOutEncoding); + } + setNewLine((_options & CANONICAL_XML) ? NEWLINE_LF : NEWLINE_DEFAULT); +} + + +XMLWriter::~XMLWriter() +{ + delete _pTextConverter; + delete _pInEncoding; + delete _pOutEncoding; +} + + +void XMLWriter::setDocumentLocator(const Locator* /*loc*/) +{ +} + + +void XMLWriter::setNewLine(const std::string& newLineCharacters) +{ + if (newLineCharacters.empty()) + { +#if defined(_WIN32) + _newLine = NEWLINE_CRLF; +#else + _newLine = NEWLINE_LF; +#endif + } + else _newLine = newLineCharacters; +} + + +const std::string& XMLWriter::getNewLine() const +{ + return _newLine; +} + + +void XMLWriter::setIndent(const std::string& indent) +{ + _indent = indent; +} + + +const std::string& XMLWriter::getIndent() const +{ + return _indent; +} + + +void XMLWriter::startDocument() +{ + if (_depth != -1) + throw XMLException("Cannot start a document in another document"); + + _inFragment = false; + _depth = 0; + _elementCount = 0; + _inDTD = false; + _inInternalDTD = false; + _prefix = 0; + + if (_options & WRITE_XML_DECLARATION) + writeXMLDeclaration(); + + _contentWritten = true; + _namespaces.reset(); + _namespaces.pushContext(); +} + + +void XMLWriter::endDocument() +{ + if (_depth > 0) + throw XMLException("Not well-formed (at least one tag has no matching end tag)"); + if (_elementCount == 0) + throw XMLException("No document element"); + + poco_assert_dbg (!_unclosedStartTag); + + _elementCount = 0; + _depth = -1; +} + + +void XMLWriter::startFragment() +{ + if (_depth != -1) + throw XMLException("Cannot start a fragment in another fragment or document"); + + _inFragment = true; + _depth = 0; + _elementCount = 0; + _prefix = 0; + + _contentWritten = true; + _namespaces.reset(); + _namespaces.pushContext(); +} + + +void XMLWriter::endFragment() +{ + if (_depth > 1) + throw XMLException("Not well-formed (at least one tag has no matching end tag)"); + + _inFragment = false; + _elementCount = 0; + _depth = -1; +} + + +void XMLWriter::startElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname) +{ + const AttributesImpl attributes; + startElement(namespaceURI, localName, qname, attributes); +} + + +void XMLWriter::startElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname, const Attributes& attributes) +{ + if (_depth == 0 && !_inFragment && _elementCount > 1) + throw XMLException("Not well-formed. Second root element found", nameToString(localName, qname)); + + if (_unclosedStartTag) closeStartTag(); + prettyPrint(); + if (_options & CANONICAL_XML) + writeCanonicalStartElement(namespaceURI, localName, qname, attributes); + else + writeStartElement(namespaceURI, localName, qname, attributes); + _elementStack.push_back(Name(qname, namespaceURI, localName)); + _contentWritten = false; + ++_depth; +} + + +void XMLWriter::endElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname) +{ + if (_depth < 1) + throw XMLException("No unclosed tag"); + + if (!_elementStack.back().equalsWeakly(qname, namespaceURI, localName)) + throw XMLException("End tag does not match start tag", nameToString(localName, qname)); + + _elementStack.pop_back(); + --_depth; + if (!_unclosedStartTag) prettyPrint(); + writeEndElement(namespaceURI, localName, qname); + _contentWritten = false; + if (_depth == 0) + writeNewLine(); +} + + +void XMLWriter::emptyElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname) +{ + const AttributesImpl attributes; + emptyElement(namespaceURI, localName, qname, attributes); +} + + +void XMLWriter::emptyElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname, const Attributes& attributes) +{ + if (_depth == 0 && _elementCount > 1) + throw XMLException("Not well-formed. Second root element found."); + + if (_unclosedStartTag) closeStartTag(); + prettyPrint(); + if (_options & CANONICAL_XML) + writeCanonicalStartElement(namespaceURI, localName, qname, attributes); + else + writeStartElement(namespaceURI, localName, qname, attributes); + _contentWritten = false; + writeMarkup("/"); + closeStartTag(); + _namespaces.popContext(); +} + + +void XMLWriter::characters(const XMLChar ch[], int start, int length) +{ + if (length == 0) return; + + if (_unclosedStartTag) closeStartTag(); + _contentWritten = _contentWritten || length > 0; + if (_inCDATA) + { + while (length-- > 0) writeXML(ch[start++]); + } + else + { + while (length-- > 0) + { + XMLChar c = ch[start++]; + switch (c) + { + case '"': writeMarkup(MARKUP_QUOTENC); break; + case '&': writeMarkup(MARKUP_AMPENC); break; + case '<': writeMarkup(MARKUP_LTENC); break; + case '>': writeMarkup(MARKUP_GTENC); break; + default: + if (c >= 0 && c < 32) + { + if (c == '\t' || c == '\r' || c == '\n') + writeXML(c); + else + throw XMLException("Invalid character token."); + } + else writeXML(c); + } + } + } +} + + +void XMLWriter::characters(const XMLString& str) +{ + characters(str.data(), 0, (int) str.length()); +} + + +void XMLWriter::rawCharacters(const XMLString& str) +{ + if (_unclosedStartTag) closeStartTag(); + _contentWritten = _contentWritten || !str.empty(); + writeXML(str); +} + + +void XMLWriter::ignorableWhitespace(const XMLChar ch[], int start, int length) +{ + characters(ch, start, length); +} + + +void XMLWriter::processingInstruction(const XMLString& target, const XMLString& data) +{ + if (_unclosedStartTag) closeStartTag(); + prettyPrint(); + writeMarkup("<?"); + writeXML(target); + if (!data.empty()) + { + writeMarkup(MARKUP_SPACE); + writeXML(data); + } + writeMarkup("?>"); + if (_depth == 0) + writeNewLine(); +} + + +namespace +{ + static const XMLString CDATA = toXMLString("CDATA"); +} + + +void XMLWriter::dataElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname, + const XMLString& data, + const XMLString& attr1, const XMLString& value1, + const XMLString& attr2, const XMLString& value2, + const XMLString& attr3, const XMLString& value3) +{ + AttributesImpl attributes; + if (!attr1.empty()) attributes.addAttribute(XMLString(), XMLString(), attr1, CDATA, value1); + if (!attr2.empty()) attributes.addAttribute(XMLString(), XMLString(), attr2, CDATA, value2); + if (!attr3.empty()) attributes.addAttribute(XMLString(), XMLString(), attr3, CDATA, value3); + if (data.empty()) + { + emptyElement(namespaceURI, localName, qname, attributes); + } + else + { + startElement(namespaceURI, localName, qname, attributes); + characters(data); + endElement(namespaceURI, localName, qname); + } +} + + +void XMLWriter::startPrefixMapping(const XMLString& prefix, const XMLString& namespaceURI) +{ + if (prefix != NamespaceSupport::XML_NAMESPACE_PREFIX) + { + if (!_nsContextPushed) + { + _namespaces.pushContext(); + _nsContextPushed = true; + } + _namespaces.declarePrefix(prefix, namespaceURI); + } +} + + +void XMLWriter::endPrefixMapping(const XMLString& /*prefix*/) +{ + // Note: prefix removed by popContext() at element closing tag +} + + +void XMLWriter::skippedEntity(const XMLString& /*name*/) +{ +} + + +void XMLWriter::startCDATA() +{ + if (_inCDATA) throw XMLException("Cannot nest CDATA sections"); + if (_unclosedStartTag) closeStartTag(); + _inCDATA = true; + writeMarkup(MARKUP_BEGIN_CDATA); +} + + +void XMLWriter::endCDATA() +{ + poco_assert (_inCDATA); + _inCDATA = false; + writeMarkup(MARKUP_END_CDATA); +} + + +void XMLWriter::comment(const XMLChar ch[], int start, int length) +{ + if (_unclosedStartTag) closeStartTag(); + prettyPrint(); + writeMarkup("<!--"); + while (length-- > 0) writeXML(ch[start++]); + writeMarkup("-->"); + _contentWritten = false; +} + + +void XMLWriter::startDTD(const XMLString& name, const XMLString& publicId, const XMLString& systemId) +{ + writeMarkup("<!DOCTYPE "); + writeXML(name); + if (!publicId.empty()) + { + writeMarkup(" PUBLIC \""); + writeXML(publicId); + writeMarkup("\""); + } + if (!systemId.empty()) + { + if (publicId.empty()) + { + writeMarkup(" SYSTEM"); + } + writeMarkup(" \""); + writeXML(systemId); + writeMarkup("\""); + } + _inDTD = true; +} + + +void XMLWriter::endDTD() +{ + poco_assert (_inDTD); + if (_inInternalDTD) + { + writeNewLine(); + writeMarkup("]"); + _inInternalDTD = false; + } + writeMarkup(">"); + writeNewLine(); + _inDTD = false; +} + + +void XMLWriter::startEntity(const XMLString& /*name*/) +{ +} + + +void XMLWriter::endEntity(const XMLString& /*name*/) +{ +} + + +void XMLWriter::notationDecl(const XMLString& name, const XMLString* publicId, const XMLString* systemId) +{ + if (!_inDTD) throw XMLException("Notation declaration not within DTD"); + if (!_inInternalDTD) + { + writeMarkup(" ["); + _inInternalDTD = true; + } + if (_options & PRETTY_PRINT) + { + writeNewLine(); + writeMarkup(_indent); + } + writeMarkup("<!NOTATION "); + writeXML(name); + if (systemId && !systemId->empty()) + { + writeMarkup(" SYSTEM \""); + writeXML(*systemId); + writeMarkup("\""); + } + if (publicId && !publicId->empty()) + { + writeMarkup(" PUBLIC \""); + writeXML(*publicId); + writeMarkup("\""); + } + writeMarkup(">"); +} + + +void XMLWriter::unparsedEntityDecl(const XMLString& name, const XMLString* publicId, const XMLString& systemId, const XMLString& notationName) +{ + if (!_inDTD) throw XMLException("Entity declaration not within DTD"); + if (!_inInternalDTD) + { + writeMarkup(" ["); + _inInternalDTD = true; + } + if (_options & PRETTY_PRINT) + { + writeNewLine(); + writeMarkup(_indent); + } + writeMarkup("<!ENTITY "); + writeXML(name); + if (!systemId.empty()) + { + writeMarkup(" SYSTEM \""); + writeXML(systemId); + writeMarkup("\""); + } + if (publicId && !publicId->empty()) + { + writeMarkup(" PUBLIC \""); + writeXML(*publicId); + writeMarkup("\""); + } + if (!notationName.empty()) + { + writeMarkup(" NDATA "); + writeXML(notationName); + } + writeMarkup(">"); +} + + +void XMLWriter::prettyPrint() const +{ + if ((_options & PRETTY_PRINT) && !_contentWritten) + { + writeNewLine(); + writeIndent(); + } +} + + +void XMLWriter::writeStartElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname, const Attributes& attributes) +{ + if (!_nsContextPushed) + _namespaces.pushContext(); + _nsContextPushed = false; + ++_elementCount; + + declareAttributeNamespaces(attributes); + + writeMarkup(MARKUP_LT); + if (!localName.empty() && (qname.empty() || localName == qname)) + { + XMLString prefix; + if (!namespaceURI.empty() && !_namespaces.isMapped(namespaceURI)) + { + prefix = uniquePrefix(); + _namespaces.declarePrefix(prefix, namespaceURI); + } + else prefix = _namespaces.getPrefix(namespaceURI); + writeName(prefix, localName); + } + else if (namespaceURI.empty() && localName.empty() && !qname.empty()) + { + writeXML(qname); + } + else if (!localName.empty() && !qname.empty()) + { + XMLString local; + XMLString prefix; + Name::split(qname, prefix, local); + if (prefix.empty()) prefix = _namespaces.getPrefix(namespaceURI); + const XMLString& uri = _namespaces.getURI(prefix); + if ((uri.empty() || uri != namespaceURI) && !namespaceURI.empty()) + { + _namespaces.declarePrefix(prefix, namespaceURI); + } + writeName(prefix, localName); + } + else throw XMLException("Tag mismatch", nameToString(localName, qname)); + + AttributeMap attributeMap; + addNamespaceAttributes(attributeMap); + addAttributes(attributeMap, attributes, namespaceURI); + writeAttributes(attributeMap); + _unclosedStartTag = true; +} + + +void XMLWriter::writeCanonicalStartElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname, const Attributes& attributes) +{ + if (!_nsContextPushed) + _namespaces.pushContext(); + _nsContextPushed = false; + ++_elementCount; + + declareNamespaces(namespaceURI, localName, qname, attributes); + + writeMarkup(MARKUP_LT); + if (!localName.empty()) + { + writeName(_namespaces.getPrefix(namespaceURI), localName); + } + else if (namespaceURI.empty() && !qname.empty()) + { + writeXML(qname); + } + else throw XMLException("Tag mismatch", nameToString(localName, qname)); + + CanonicalAttributeMap namespaceAttributeMap; + addNamespaceAttributes(namespaceAttributeMap); + writeAttributes(namespaceAttributeMap); + CanonicalAttributeMap attributeMap; + addAttributes(attributeMap, attributes, namespaceURI); + writeAttributes(attributeMap); + _unclosedStartTag = true; +} + + +void XMLWriter::writeEndElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname) +{ + if (_unclosedStartTag && !(_options & CANONICAL_XML)) + { + writeMarkup(MARKUP_SLASHGT); + _unclosedStartTag = false; + } + else + { + if (_unclosedStartTag) + { + writeMarkup(MARKUP_GT); + _unclosedStartTag = false; + } + writeMarkup(MARKUP_LTSLASH); + if (!localName.empty()) + { + XMLString prefix = _namespaces.getPrefix(namespaceURI); + writeName(prefix, localName); + } + else + { + writeXML(qname); + } + writeMarkup(MARKUP_GT); + } + _namespaces.popContext(); +} + + +void XMLWriter::closeStartTag() +{ + _unclosedStartTag = false; + writeMarkup(MARKUP_GT); +} + + +void XMLWriter::declareNamespaces(const XMLString& namespaceURI, const XMLString& /*localName*/, const XMLString& qname, const Attributes& attributes) +{ + std::map<XMLString, std::set<XMLString> > usedNamespaces; + bool defaultNameSpaceUsed = false; + XMLString defaultNamespaceURI = _namespaces.getURI(XMLString()); + XMLString local; + XMLString prefix; + XMLString elementNamespaceURI = namespaceURI; + Name::split(qname, prefix, local); + if (elementNamespaceURI.empty()) + elementNamespaceURI = _namespaces.getURI(prefix); + if (!elementNamespaceURI.empty()) + { + usedNamespaces[prefix].insert(elementNamespaceURI); + if (!defaultNamespaceURI.empty() && elementNamespaceURI == defaultNamespaceURI) + defaultNameSpaceUsed = true; + } + for (int i = 0; i < attributes.getLength(); i++) + { + XMLString attributeNamespaceURI = attributes.getURI(i); + XMLString attributeLocalName = attributes.getLocalName(i); + XMLString attributeQName = attributes.getQName(i); + + XMLString attributePrefix; + XMLString attributeLocal; + Name::split(attributeQName, attributePrefix, attributeLocal); + if (attributeNamespaceURI.empty()) + attributeNamespaceURI = _namespaces.getURI(prefix); + if (!attributeNamespaceURI.empty()) + { + usedNamespaces[attributePrefix].insert(attributeNamespaceURI); + defaultNameSpaceUsed = defaultNameSpaceUsed || (!defaultNamespaceURI.empty() && attributeNamespaceURI == defaultNamespaceURI); + } + } + for (std::map<XMLString, std::set<XMLString> >::const_iterator it = usedNamespaces.begin(); it != usedNamespaces.end(); ++it) + { + const std::set<XMLString> namespaceURIs = it->second; + for (std::set<XMLString>::const_iterator itURI = namespaceURIs.begin(); itURI != namespaceURIs.end(); ++itURI) + { + XMLString prefix2 = it->first; + if (prefix2.empty()) + prefix2 = _namespaces.getPrefix(*itURI); + if (prefix2.empty() && !_namespaces.isMapped(*itURI)) + { + if (defaultNameSpaceUsed) + { + if (*itURI != defaultNamespaceURI) + prefix2 = uniquePrefix(); + } + else + { + defaultNamespaceURI = *itURI; + defaultNameSpaceUsed = true; + } + + } + const XMLString& uri = _namespaces.getURI(prefix2); + if ((uri.empty() || uri != *itURI) && !itURI->empty()) + { + _namespaces.declarePrefix(prefix2, *itURI); + } + } + } +} + + +void XMLWriter::declareAttributeNamespaces(const Attributes& attributes) +{ + for (int i = 0; i < attributes.getLength(); i++) + { + XMLString namespaceURI = attributes.getURI(i); + XMLString localName = attributes.getLocalName(i); + XMLString qname = attributes.getQName(i); + if (!localName.empty()) + { + XMLString prefix; + XMLString splitLocalName; + Name::split(qname, prefix, splitLocalName); + if (prefix.empty()) prefix = _namespaces.getPrefix(namespaceURI); + if (prefix.empty() && !namespaceURI.empty() && !_namespaces.isMapped(namespaceURI)) + { + prefix = uniquePrefix(); + _namespaces.declarePrefix(prefix, namespaceURI); + } + + const XMLString& uri = _namespaces.getURI(prefix); + if ((uri.empty() || uri != namespaceURI) && !namespaceURI.empty()) + { + _namespaces.declarePrefix(prefix, namespaceURI); + } + } + } +} + + +void XMLWriter::addNamespaceAttributes(AttributeMap& attributeMap) +{ + NamespaceSupport::PrefixSet prefixes; + _namespaces.getDeclaredPrefixes(prefixes); + for (NamespaceSupport::PrefixSet::const_iterator it = prefixes.begin(); it != prefixes.end(); ++it) + { + XMLString prefix = *it; + XMLString uri = _namespaces.getURI(prefix); + XMLString qname = NamespaceSupport::XMLNS_NAMESPACE_PREFIX; + + if (!prefix.empty()) + { + qname.append(toXMLString(MARKUP_COLON)); + qname.append(prefix); + } + attributeMap[qname] = uri; + } +} + + +void XMLWriter::addNamespaceAttributes(CanonicalAttributeMap& attributeMap) +{ + NamespaceSupport::PrefixSet prefixes; + _namespaces.getDeclaredPrefixes(prefixes); + for (NamespaceSupport::PrefixSet::const_iterator it = prefixes.begin(); it != prefixes.end(); ++it) + { + XMLString prefix = *it; + XMLString uri = _namespaces.getURI(prefix); + XMLString qname = NamespaceSupport::XMLNS_NAMESPACE_PREFIX; + + if (!prefix.empty()) + { + qname.append(toXMLString(MARKUP_COLON)); + qname.append(prefix); + } + attributeMap.insert(std::make_pair(qname, std::make_pair(qname, uri))); + } +} + + +void XMLWriter::addAttributes(AttributeMap& attributeMap, const Attributes& attributes, const XMLString& /*elementNamespaceURI*/) +{ + for (int i = 0; i < attributes.getLength(); i++) + { + XMLString namespaceURI = attributes.getURI(i); + XMLString localName = attributes.getLocalName(i); + XMLString qname = attributes.getQName(i); + if (!localName.empty()) + { + XMLString prefix; + if (!namespaceURI.empty()) + prefix = _namespaces.getPrefix(namespaceURI); + if (!prefix.empty()) + { + qname = prefix; + qname.append(toXMLString(MARKUP_COLON)); + } + else qname.clear(); + qname.append(localName); + } + attributeMap[qname] = attributes.getValue(i); + } +} + + +void XMLWriter::addAttributes(CanonicalAttributeMap& attributeMap, const Attributes& attributes, const XMLString& /*elementNamespaceURI*/) +{ + for (int i = 0; i < attributes.getLength(); i++) + { + XMLString namespaceURI = attributes.getURI(i); + XMLString localName = attributes.getLocalName(i); + XMLString qname = attributes.getQName(i); + XMLString fullQName = qname; + if (!localName.empty()) + { + XMLString prefix; + if (!namespaceURI.empty()) + { + prefix = _namespaces.getPrefix(namespaceURI); + fullQName = namespaceURI; + fullQName.append(toXMLString(MARKUP_COLON)); + } + else fullQName.clear(); + if (!prefix.empty()) + { + qname = prefix; + qname.append(toXMLString(MARKUP_COLON)); + } + else qname.clear(); + qname.append(localName); + fullQName.append(localName); + } + attributeMap.insert(std::make_pair(fullQName, std::make_pair(qname, attributes.getValue(i)))); + } +} + + +void XMLWriter::writeAttributes(const AttributeMap& attributeMap) +{ + for (AttributeMap::const_iterator it = attributeMap.begin(); it != attributeMap.end(); ++it) + { + if ((_options & PRETTY_PRINT) && (_options & PRETTY_PRINT_ATTRIBUTES)) + { + writeNewLine(); + writeIndent(_depth + 1); + } + else + { + writeMarkup(MARKUP_SPACE); + } + writeXML(it->first); + writeMarkup(MARKUP_EQQUOT); + for (XMLString::const_iterator itc = it->second.begin(); itc != it->second.end(); ++itc) + { + XMLChar c = *itc; + switch (c) + { + case '"': writeMarkup(MARKUP_QUOTENC); break; + case '&': writeMarkup(MARKUP_AMPENC); break; + case '<': writeMarkup(MARKUP_LTENC); break; + case '>': writeMarkup(MARKUP_GTENC); break; + case '\t': writeMarkup(MARKUP_TABENC); break; + case '\r': writeMarkup(MARKUP_CRENC); break; + case '\n': writeMarkup(MARKUP_LFENC); break; + default: + if (c >= 0 && c < 32) + throw XMLException("Invalid character token."); + else + writeXML(c); + } + } + writeMarkup(MARKUP_QUOT); + } +} + + +void XMLWriter::writeAttributes(const CanonicalAttributeMap& attributeMap) +{ + for (CanonicalAttributeMap::const_iterator it = attributeMap.begin(); it != attributeMap.end(); ++it) + { + if ((_options & PRETTY_PRINT) && (_options & PRETTY_PRINT_ATTRIBUTES)) + { + writeNewLine(); + writeIndent(_depth + 1); + } + else + { + writeMarkup(MARKUP_SPACE); + } + writeXML(it->second.first); + writeMarkup(MARKUP_EQQUOT); + for (XMLString::const_iterator itc = it->second.second.begin(); itc != it->second.second.end(); ++itc) + { + XMLChar c = *itc; + switch (c) + { + case '"': writeMarkup(MARKUP_QUOTENC); break; + case '&': writeMarkup(MARKUP_AMPENC); break; + case '<': writeMarkup(MARKUP_LTENC); break; + case '>': writeMarkup(MARKUP_GTENC); break; + case '\t': writeMarkup(MARKUP_TABENC); break; + case '\r': writeMarkup(MARKUP_CRENC); break; + case '\n': writeMarkup(MARKUP_LFENC); break; + default: + if (c >= 0 && c < 32) + throw XMLException("Invalid character token."); + else + writeXML(c); + } + } + writeMarkup(MARKUP_QUOT); + } +} + + +void XMLWriter::writeMarkup(const std::string& str) const +{ +#if defined(XML_UNICODE_WCHAR_T) + const XMLString xmlString = toXMLString(str); + writeXML(xmlString); +#else + _pTextConverter->write(str.data(), (int) str.size()); +#endif +} + + +void XMLWriter::writeXML(const XMLString& str) const +{ + _pTextConverter->write((const char*) str.data(), (int) str.size()*sizeof(XMLChar)); +} + + +void XMLWriter::writeXML(XMLChar ch) const +{ + _pTextConverter->write((const char*) &ch, sizeof(ch)); +} + + +void XMLWriter::writeName(const XMLString& prefix, const XMLString& localName) +{ + if (prefix.empty()) + { + writeXML(localName); + } + else + { + writeXML(prefix); + writeMarkup(MARKUP_COLON); + writeXML(localName); + } +} + + +void XMLWriter::writeNewLine() const +{ + if (_options & PRETTY_PRINT) + writeMarkup(_newLine); +} + + +void XMLWriter::writeIndent() const +{ + writeIndent(_depth); +} + + +void XMLWriter::writeIndent(int depth) const +{ + for (int i = 0; i < depth; ++i) + writeMarkup(_indent); +} + + +void XMLWriter::writeXMLDeclaration() +{ + writeMarkup("<?xml version=\"1.0\""); + if (!_encoding.empty()) + { + writeMarkup(" encoding=\""); + writeMarkup(_encoding); + writeMarkup("\""); + } + writeMarkup("?>"); + writeNewLine(); +} + + +std::string XMLWriter::nameToString(const XMLString& localName, const XMLString& qname) +{ + if (qname.empty()) + return fromXMLString(localName); + else + return fromXMLString(qname); +} + + +XMLString XMLWriter::uniquePrefix() +{ + std::ostringstream str; + str << "ns" << ++_prefix; + return toXMLString(str.str()); +} + + +bool XMLWriter::isNamespaceMapped(const XMLString& namespc) const +{ + return _namespaces.isMapped(namespc); +} + + +} } // namespace Poco::XML |