summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdwin Mons <edwin.mons@isode.com>2019-07-22 08:54:55 (GMT)
committerEdwin Mons <edwin.mons@isode.com>2019-07-22 10:13:33 (GMT)
commitf6fb85ba98fdd6601c4b8323c51c8367ccc4b52e (patch)
tree16f37c7ad860a527aac7e29e4b9d7e61bf1b635f
parentf4b6bfbf4c1573e9914185e2ef170f47838ea11a (diff)
downloadswift-f6fb85ba98fdd6601c4b8323c51c8367ccc4b52e.zip
swift-f6fb85ba98fdd6601c4b8323c51c8367ccc4b52e.tar.bz2
Signal namespace declarations to ParserClients
Prior to calling handleStartElement, the ParserClient handleNamespaceDeclaration will fire for each namespace declared on the element. Test-Information: Unit tests pass on Debian 9 for both expat and libxml2 Change-Id: Ic42e83aee83edfbb2aa5c971997808eb6e133223
-rw-r--r--Swiften/Parser/ExpatParser.cpp5
-rw-r--r--Swiften/Parser/LibXMLParser.cpp7
-rw-r--r--Swiften/Parser/UnitTest/XMLParserTest.cpp35
-rw-r--r--Swiften/Parser/XMLParserClient.cpp5
-rw-r--r--Swiften/Parser/XMLParserClient.h10
5 files changed, 52 insertions, 10 deletions
diff --git a/Swiften/Parser/ExpatParser.cpp b/Swiften/Parser/ExpatParser.cpp
index e4e66f2..a50949b 100644
--- a/Swiften/Parser/ExpatParser.cpp
+++ b/Swiften/Parser/ExpatParser.cpp
@@ -66,2 +66,6 @@ static void handleXMLDeclaration(void*, const XML_Char*, const XML_Char*, int) {
+static void handleNamespaceDeclaration(void* parser, const XML_Char* prefix, const XML_Char* uri) {
+ static_cast<XMLParser*>(parser)->getClient()->handleNamespaceDeclaration(std::string(prefix ? prefix : ""), std::string(uri ? uri : ""));
+}
+
static void handleEntityDeclaration(void* parser, const XML_Char*, int, const XML_Char*, int, const XML_Char*, const XML_Char*, const XML_Char*, const XML_Char*) {
@@ -78,2 +82,3 @@ ExpatParser::ExpatParser(XMLParserClient* client) : XMLParser(client), p(new Pri
XML_SetEntityDeclHandler(p->parser_, handleEntityDeclaration);
+ XML_SetNamespaceDeclHandler(p->parser_, handleNamespaceDeclaration, nullptr);
}
diff --git a/Swiften/Parser/LibXMLParser.cpp b/Swiften/Parser/LibXMLParser.cpp
index c9f3a07..192f44b 100644
--- a/Swiften/Parser/LibXMLParser.cpp
+++ b/Swiften/Parser/LibXMLParser.cpp
@@ -26,3 +26,3 @@ struct LibXMLParser::Private {
-static void handleStartElement(void* parser, const xmlChar* name, const xmlChar*, const xmlChar* xmlns, int, const xmlChar**, int nbAttributes, int nbDefaulted, const xmlChar ** attributes) {
+static void handleStartElement(void* parser, const xmlChar* name, const xmlChar*, const xmlChar* xmlns, int nbNamespaces, const xmlChar** namespaces, int nbAttributes, int nbDefaulted, const xmlChar ** attributes) {
AttributeMap attributeValues;
@@ -44,2 +44,7 @@ static void handleStartElement(void* parser, const xmlChar* name, const xmlChar*
}
+ for (auto i = 0; i < nbNamespaces * 2; i += 2) {
+ const auto prefix = namespaces[i] ? std::string(reinterpret_cast<const char*>(namespaces[i])) : "";
+ const auto uri = std::string(reinterpret_cast<const char*>(namespaces[i + 1]));
+ static_cast<XMLParser*>(parser)->getClient()->handleNamespaceDeclaration(prefix, uri);
+ }
static_cast<XMLParser*>(parser)->getClient()->handleStartElement(reinterpret_cast<const char*>(name), (xmlns ? reinterpret_cast<const char*>(xmlns) : std::string()), attributeValues);
diff --git a/Swiften/Parser/UnitTest/XMLParserTest.cpp b/Swiften/Parser/UnitTest/XMLParserTest.cpp
index 9e9012b..c026b4b 100644
--- a/Swiften/Parser/UnitTest/XMLParserTest.cpp
+++ b/Swiften/Parser/UnitTest/XMLParserTest.cpp
@@ -8,2 +8,3 @@
#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <unordered_map>
#include <vector>
@@ -63,2 +64,5 @@ class XMLParserTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(std::string("jabber:iq:version"), client_.events[1].ns);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[1].namespaces.size());
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[1].namespaces.count(""));
+ CPPUNIT_ASSERT_EQUAL(std::string("jabber:iq:version"), client_.events[1].namespaces[""]);
@@ -87,2 +91,4 @@ class XMLParserTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(std::string("jabber:iq:version"), client_.events[0].ns);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[0].namespaces.size());
+ CPPUNIT_ASSERT_EQUAL(std::string("jabber:iq:version"), client_.events[0].namespaces[""]);
@@ -91,2 +97,3 @@ class XMLParserTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(std::string("jabber:iq:version"), client_.events[1].ns);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), client_.events[1].namespaces.size());
@@ -163,2 +170,4 @@ class XMLParserTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(std::string("bla"), client_.events[0].ns);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[0].namespaces.size());
+ CPPUNIT_ASSERT_EQUAL(std::string("bla"), client_.events[0].namespaces["p"]);
@@ -264,2 +273,5 @@ class XMLParserTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(std::string("http://swift.im/f"), client_.events[0].attributes.getEntries()[0].getAttribute().getNamespace());
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), client_.events[0].namespaces.size());
+ CPPUNIT_ASSERT_EQUAL(std::string("http://swift.im"), client_.events[0].namespaces[""]);
+ CPPUNIT_ASSERT_EQUAL(std::string("http://swift.im/f"), client_.events[0].namespaces["f"]);
}
@@ -303,2 +315,3 @@ class XMLParserTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(std::string(""), client_.events[0].ns);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), client_.events[0].namespaces.size());
@@ -330,3 +343,4 @@ class XMLParserTest : public CppUnit::TestFixture {
public:
- enum Type { StartElement, EndElement, CharacterData };
+ using NamespaceMap = std::unordered_map<std::string /* prefix */, std::string /* uri */>;
+ enum Type { StartElement, EndElement, CharacterData, NamespaceDefined };
struct Event {
@@ -336,4 +350,5 @@ class XMLParserTest : public CppUnit::TestFixture {
const std::string& ns,
- const AttributeMap& attributes)
- : type(type), data(data), ns(ns), attributes(attributes) {}
+ const AttributeMap& attributes,
+ NamespaceMap namespaces = {})
+ : type(type), data(data), ns(ns), attributes(attributes), namespaces(std::move(namespaces)) {}
Event(Type type, const std::string& data, const std::string& ns = std::string())
@@ -345,2 +360,3 @@ class XMLParserTest : public CppUnit::TestFixture {
AttributeMap attributes;
+ NamespaceMap namespaces;
};
@@ -349,7 +365,7 @@ class XMLParserTest : public CppUnit::TestFixture {
- virtual void handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) {
- events.push_back(Event(StartElement, element, ns, attributes));
+ void handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) override {
+ events.push_back(Event(StartElement, element, ns, attributes, std::move(namespaces_)));
}
- virtual void handleEndElement(const std::string& element, const std::string& ns) {
+ void handleEndElement(const std::string& element, const std::string& ns) override {
events.push_back(Event(EndElement, element, ns));
@@ -357,3 +373,3 @@ class XMLParserTest : public CppUnit::TestFixture {
- virtual void handleCharacterData(const std::string& data) {
+ void handleCharacterData(const std::string& data) override {
events.push_back(Event(CharacterData, data));
@@ -361,3 +377,8 @@ class XMLParserTest : public CppUnit::TestFixture {
+ void handleNamespaceDeclaration(const std::string& prefix, const std::string& uri) override {
+ namespaces_[prefix] = uri;
+ }
std::vector<Event> events;
+ private:
+ NamespaceMap namespaces_;
} client_;
diff --git a/Swiften/Parser/XMLParserClient.cpp b/Swiften/Parser/XMLParserClient.cpp
index 6dc6db6..40be4e8 100644
--- a/Swiften/Parser/XMLParserClient.cpp
+++ b/Swiften/Parser/XMLParserClient.cpp
@@ -1,3 +1,3 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2019 Isode Limited.
* All rights reserved.
@@ -13,2 +13,5 @@ XMLParserClient::~XMLParserClient() {
+void XMLParserClient::handleNamespaceDeclaration(const std::string&, const std::string&) {
+}
+
}
diff --git a/Swiften/Parser/XMLParserClient.h b/Swiften/Parser/XMLParserClient.h
index e4346f6..0682320 100644
--- a/Swiften/Parser/XMLParserClient.h
+++ b/Swiften/Parser/XMLParserClient.h
@@ -1,3 +1,3 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2019 Isode Limited.
* All rights reserved.
@@ -19,2 +19,10 @@ namespace Swift {
virtual void handleCharacterData(const std::string& data) = 0;
+
+ /**
+ * Signal that a namespace prefix has been declared
+ * This callback might be called multiple times for a single element,
+ * and will trigger before the corresponding \ref handleStartElement
+ * is called.
+ */
+ virtual void handleNamespaceDeclaration(const std::string& prefix, const std::string& uri);
};