summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Parser/ExpatParser.cpp')
-rw-r--r--Swiften/Parser/ExpatParser.cpp57
1 files changed, 39 insertions, 18 deletions
diff --git a/Swiften/Parser/ExpatParser.cpp b/Swiften/Parser/ExpatParser.cpp
index 640d561..6c3845a 100644
--- a/Swiften/Parser/ExpatParser.cpp
+++ b/Swiften/Parser/ExpatParser.cpp
@@ -11,6 +11,8 @@
11#include <memory> 11#include <memory>
12#include <string> 12#include <string>
13 13
14#include <boost/algorithm/string.hpp>
15
14#include <expat.h> 16#include <expat.h>
15 17
16#include <Swiften/Base/String.h> 18#include <Swiften/Base/String.h>
@@ -18,6 +20,33 @@
18 20
19#pragma clang diagnostic ignored "-Wdisabled-macro-expansion" 21#pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
20 22
23namespace {
24struct XmlInfo {
25 std::string prefix;
26 std::string uri;
27 std::string name;
28};
29
30XmlInfo splitExpatInfo(const std::string& s, char sep) {
31 // name
32 // uri|name
33 // uri|name|prefix
34 std::vector<std::string> v;
35 boost::split(v, s, [sep](char c) {return c == sep; });
36 switch (v.size()) {
37 case 1:
38 return{ "", "", std::move(v[0]) };
39 case 2:
40 return{ "", std::move(v[0]), std::move(v[1]) };
41 case 3:
42 return{ std::move(v[2]), std::move(v[0]), std::move(v[1]) };
43 default:
44 return{ "", "", "" };
45 }
46}
47}
48
49
21namespace Swift { 50namespace Swift {
22 51
23static const char NAMESPACE_SEPARATOR = '\x01'; 52static const char NAMESPACE_SEPARATOR = '\x01';
@@ -27,33 +56,24 @@ struct ExpatParser::Private {
27}; 56};
28 57
29static void handleStartElement(void* parser, const XML_Char* name, const XML_Char** attributes) { 58static void handleStartElement(void* parser, const XML_Char* name, const XML_Char** attributes) {
30 std::pair<std::string,std::string> nsTagPair = String::getSplittedAtFirst(name, NAMESPACE_SEPARATOR); 59 auto elemInfo = splitExpatInfo(name, NAMESPACE_SEPARATOR);
31 if (nsTagPair.second == "") { 60
32 nsTagPair.second = nsTagPair.first;
33 nsTagPair.first = "";
34 }
35 AttributeMap attributeValues; 61 AttributeMap attributeValues;
36 const XML_Char** currentAttribute = attributes; 62 const XML_Char** currentAttribute = attributes;
37 while (*currentAttribute) { 63 while (*currentAttribute) {
38 std::pair<std::string,std::string> nsAttributePair = String::getSplittedAtFirst(*currentAttribute, NAMESPACE_SEPARATOR); 64 auto attribInfo = splitExpatInfo(*currentAttribute, NAMESPACE_SEPARATOR);
39 if (nsAttributePair.second == "") { 65 attributeValues.addAttribute(attribInfo.name, attribInfo.uri, attribInfo.prefix, std::string(*(currentAttribute+1)));
40 nsAttributePair.second = nsAttributePair.first;
41 nsAttributePair.first = "";
42 }
43 attributeValues.addAttribute(nsAttributePair.second, nsAttributePair.first, std::string(*(currentAttribute+1)));
44 currentAttribute += 2; 66 currentAttribute += 2;
45 } 67 }
46 68
47 static_cast<XMLParser*>(parser)->getClient()->handleStartElement(nsTagPair.second, nsTagPair.first, attributeValues); 69 auto* client = static_cast<XMLParser*>(parser)->getClient();
70 client->handleStartElementPrefix(elemInfo.prefix, elemInfo.uri, elemInfo.name, elemInfo.name, elemInfo.uri, attributeValues);
71 client->handleStartElement(elemInfo.name, elemInfo.uri, attributeValues);
48} 72}
49 73
50static void handleEndElement(void* parser, const XML_Char* name) { 74static void handleEndElement(void* parser, const XML_Char* name) {
51 std::pair<std::string,std::string> nsTagPair = String::getSplittedAtFirst(name, NAMESPACE_SEPARATOR); 75 auto elemInfo = splitExpatInfo(name, NAMESPACE_SEPARATOR);
52 if (nsTagPair.second == "") { 76 static_cast<XMLParser*>(parser)->getClient()->handleEndElement(elemInfo.name, elemInfo.uri);
53 nsTagPair.second = nsTagPair.first;
54 nsTagPair.first = "";
55 }
56 static_cast<XMLParser*>(parser)->getClient()->handleEndElement(nsTagPair.second, nsTagPair.first);
57} 77}
58 78
59static void handleCharacterData(void* parser, const XML_Char* data, int len) { 79static void handleCharacterData(void* parser, const XML_Char* data, int len) {
@@ -88,6 +108,7 @@ static void handleDoctypeDeclaration(void* parser, const XML_Char* /*doctypeName
88 108
89ExpatParser::ExpatParser(XMLParserClient* client, bool allowComments) : XMLParser(client, allowComments), p(new Private()) { 109ExpatParser::ExpatParser(XMLParserClient* client, bool allowComments) : XMLParser(client, allowComments), p(new Private()) {
90 p->parser_ = XML_ParserCreateNS("UTF-8", NAMESPACE_SEPARATOR); 110 p->parser_ = XML_ParserCreateNS("UTF-8", NAMESPACE_SEPARATOR);
111 XML_SetReturnNSTriplet(p->parser_, true);
91 XML_SetUserData(p->parser_, this); 112 XML_SetUserData(p->parser_, this);
92 XML_SetElementHandler(p->parser_, handleStartElement, handleEndElement); 113 XML_SetElementHandler(p->parser_, handleStartElement, handleEndElement);
93 XML_SetCharacterDataHandler(p->parser_, handleCharacterData); 114 XML_SetCharacterDataHandler(p->parser_, handleCharacterData);