diff options
| author | Joanna Hulboj <joanna.hulboj@isode.com> | 2019-09-19 19:48:44 (GMT) |
|---|---|---|
| committer | Joanna Hulboj <joanna.hulboj@isode.com> | 2019-09-24 10:08:15 (GMT) |
| commit | 23e2766dab6d4a3f6158eca7649cd36b644634d3 (patch) | |
| tree | 1faa4b741b03704e7a70918196310a4453e699a7 /Swiften/Parser/LibXMLParser.cpp | |
| parent | e58cf7d5d7d3bab330bccf6a098dd476fbf4dc86 (diff) | |
| download | swift-23e2766dab6d4a3f6158eca7649cd36b644634d3.zip swift-23e2766dab6d4a3f6158eca7649cd36b644634d3.tar.bz2 | |
Process attribute and element prefixes
XML (Expat/LibXML) parsing modified to process prefix information.
Prefixes for attributes stored within attributes.
Prefixes for elements passed in additional callback
(only if prefix present).
Test-information:
Unit tests pass on Windows 10 and Ubuntu 18.04.1 LTS.
Change-Id: Ib6b5087feed758c31895f426df6a3c7ea975f248
Diffstat (limited to 'Swiften/Parser/LibXMLParser.cpp')
| -rw-r--r-- | Swiften/Parser/LibXMLParser.cpp | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/Swiften/Parser/LibXMLParser.cpp b/Swiften/Parser/LibXMLParser.cpp index 4e02059..71515a7 100644 --- a/Swiften/Parser/LibXMLParser.cpp +++ b/Swiften/Parser/LibXMLParser.cpp | |||
| @@ -17,6 +17,12 @@ | |||
| 17 | #include <Swiften/Base/Log.h> | 17 | #include <Swiften/Base/Log.h> |
| 18 | #include <Swiften/Parser/XMLParserClient.h> | 18 | #include <Swiften/Parser/XMLParserClient.h> |
| 19 | 19 | ||
| 20 | namespace { | ||
| 21 | std::string asString(const unsigned char* s) { | ||
| 22 | return s ? std::string(reinterpret_cast<const char*>(s)) : std::string(); | ||
| 23 | } | ||
| 24 | } | ||
| 25 | |||
| 20 | namespace Swift { | 26 | namespace Swift { |
| 21 | 27 | ||
| 22 | struct LibXMLParser::Private { | 28 | struct LibXMLParser::Private { |
| @@ -24,34 +30,39 @@ struct LibXMLParser::Private { | |||
| 24 | xmlParserCtxtPtr context_; | 30 | xmlParserCtxtPtr context_; |
| 25 | }; | 31 | }; |
| 26 | 32 | ||
| 27 | 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) { | 33 | static void handleStartElement(void* parser, const xmlChar* name, const xmlChar* prefix, const xmlChar* xmlns, int nbNamespaces, const xmlChar** namespaces, int nbAttributes, int nbDefaulted, const xmlChar ** attributes) { |
| 28 | AttributeMap attributeValues; | 34 | AttributeMap attributeValues; |
| 29 | if (nbDefaulted != 0) { | 35 | if (nbDefaulted != 0) { |
| 30 | // Just because i don't understand what this means yet :-) | 36 | // Just because i don't understand what this means yet :-) |
| 31 | SWIFT_LOG(error) << "Unexpected nbDefaulted on XML element" << std::endl; | 37 | SWIFT_LOG(error) << "Unexpected nbDefaulted on XML element" << std::endl; |
| 32 | } | 38 | } |
| 33 | for (int i = 0; i < nbAttributes*5; i += 5) { | 39 | for (int i = 0; i < nbAttributes*5; i += 5) { |
| 34 | std::string attributeNS = ""; | 40 | std::string attributeName = asString(attributes[i]); |
| 35 | if (attributes[i+2]) { | 41 | std::string attributePrefix = asString(attributes[i+1]); |
| 36 | attributeNS = std::string(reinterpret_cast<const char*>(attributes[i+2])); | 42 | std::string attributeNS = asString(attributes[i+2]); |
| 37 | } | ||
| 38 | assert(attributes[i+4] >= attributes[i+3]); | 43 | assert(attributes[i+4] >= attributes[i+3]); |
| 39 | attributeValues.addAttribute( | 44 | attributeValues.addAttribute( |
| 40 | std::string(reinterpret_cast<const char*>(attributes[i])), | 45 | attributeName, |
| 41 | attributeNS, | 46 | attributeNS, |
| 47 | attributePrefix, | ||
| 42 | std::string(reinterpret_cast<const char*>(attributes[i+3]), | 48 | std::string(reinterpret_cast<const char*>(attributes[i+3]), |
| 43 | static_cast<size_t>(attributes[i+4]-attributes[i+3]))); | 49 | static_cast<size_t>(attributes[i+4]-attributes[i+3]))); |
| 44 | } | 50 | } |
| 51 | auto* client = static_cast<XMLParser*>(parser)->getClient(); | ||
| 45 | for (auto i = 0; i < nbNamespaces * 2; i += 2) { | 52 | for (auto i = 0; i < nbNamespaces * 2; i += 2) { |
| 46 | const auto prefix = namespaces[i] ? std::string(reinterpret_cast<const char*>(namespaces[i])) : ""; | 53 | const auto prefix = asString(namespaces[i]); |
| 47 | const auto uri = std::string(reinterpret_cast<const char*>(namespaces[i + 1])); | 54 | const auto uri = asString(namespaces[i + 1]); |
| 48 | static_cast<XMLParser*>(parser)->getClient()->handleNamespaceDeclaration(prefix, uri); | 55 | client->handleNamespaceDeclaration(prefix, uri); |
| 49 | } | 56 | } |
| 50 | static_cast<XMLParser*>(parser)->getClient()->handleStartElement(reinterpret_cast<const char*>(name), (xmlns ? reinterpret_cast<const char*>(xmlns) : std::string()), attributeValues); | 57 | auto nameStr = asString(name); |
| 58 | auto xmlsnsStr = asString(xmlns); | ||
| 59 | auto prefixStr = asString(prefix); | ||
| 60 | client->handleStartElementPrefix(prefixStr, xmlsnsStr, nameStr, nameStr, xmlsnsStr, attributeValues); | ||
| 61 | client->handleStartElement(nameStr, xmlsnsStr, attributeValues); | ||
| 51 | } | 62 | } |
| 52 | 63 | ||
| 53 | static void handleEndElement(void *parser, const xmlChar* name, const xmlChar*, const xmlChar* xmlns) { | 64 | static void handleEndElement(void *parser, const xmlChar* name, const xmlChar*, const xmlChar* xmlns) { |
| 54 | static_cast<XMLParser*>(parser)->getClient()->handleEndElement(reinterpret_cast<const char*>(name), (xmlns ? reinterpret_cast<const char*>(xmlns) : std::string())); | 65 | static_cast<XMLParser*>(parser)->getClient()->handleEndElement(asString(name), asString(xmlns)); |
| 55 | } | 66 | } |
| 56 | 67 | ||
| 57 | static void handleCharacterData(void* parser, const xmlChar* data, int len) { | 68 | static void handleCharacterData(void* parser, const xmlChar* data, int len) { |
Swift