diff options
-rw-r--r-- | Sluift/ElementConvertors/DOMElementConvertor.cpp | 2 | ||||
-rw-r--r-- | Swift/Controllers/Settings/XMLSettingsProvider.cpp | 3 | ||||
-rw-r--r-- | Swiften/Client/ClientXMLTracer.cpp | 29 | ||||
-rw-r--r-- | Swiften/Client/ClientXMLTracer.h | 11 | ||||
-rw-r--r-- | Swiften/Client/UnitTest/XMLBeautifierTest.cpp | 66 | ||||
-rw-r--r-- | Swiften/Client/XMLBeautifier.cpp | 94 | ||||
-rw-r--r-- | Swiften/Client/XMLBeautifier.h | 24 | ||||
-rw-r--r-- | Swiften/Parser/BOSHBodyExtractor.cpp | 2 | ||||
-rw-r--r-- | Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h | 6 | ||||
-rw-r--r-- | Swiften/Parser/PlatformXMLParserFactory.cpp | 6 | ||||
-rw-r--r-- | Swiften/Parser/PlatformXMLParserFactory.h | 2 | ||||
-rw-r--r-- | Swiften/Parser/UnitTest/ParserTester.h | 9 | ||||
-rw-r--r-- | Swiften/Parser/XMLParserFactory.h | 4 | ||||
-rw-r--r-- | Swiften/Parser/XMPPParser.cpp | 1 | ||||
-rw-r--r-- | Swiften/Parser/XMPPParser.h | 2 | ||||
-rw-r--r-- | Swiften/SConscript | 1 |
16 files changed, 174 insertions, 88 deletions
diff --git a/Sluift/ElementConvertors/DOMElementConvertor.cpp b/Sluift/ElementConvertors/DOMElementConvertor.cpp index b957686..72474bb 100644 --- a/Sluift/ElementConvertors/DOMElementConvertor.cpp +++ b/Sluift/ElementConvertors/DOMElementConvertor.cpp @@ -158,44 +158,44 @@ namespace { DOMElementConvertor::DOMElementConvertor() { } DOMElementConvertor::~DOMElementConvertor() { } std::shared_ptr<Element> DOMElementConvertor::convertFromLua(lua_State* L, int index, const std::string& type) { if (!lua_istable(L, index) || type != "dom") { return std::shared_ptr<Payload>(); } return std::make_shared<RawXMLPayload>(serializeElement(L).c_str()); } boost::optional<std::string> DOMElementConvertor::convertToLua( lua_State* L, std::shared_ptr<Element> element) { // Serialize payload to XML std::shared_ptr<Payload> payload = std::dynamic_pointer_cast<Payload>(element); if (!payload) { return boost::optional<std::string>(); } PayloadSerializer* serializer = serializers.getPayloadSerializer(payload); assert(serializer); std::string serializedPayload = serializer->serialize(payload); lua_newtable(L); // Parse the payload again ParserClient parserClient(L); - std::shared_ptr<XMLParser> parser(parsers.createXMLParser(&parserClient)); + std::shared_ptr<XMLParser> parser(std::move(parsers.createXMLParser(&parserClient))); bool result = parser->parse(serializedPayload); assert(result); // There can only be one element, so stripping the list lua_pushnil(L); lua_next(L, -2); Lua::registerTableToString(L, -1); lua_replace(L, -3); lua_settop(L, -2); return std::string("dom"); } diff --git a/Swift/Controllers/Settings/XMLSettingsProvider.cpp b/Swift/Controllers/Settings/XMLSettingsProvider.cpp index 4dfb8bd..2573af0 100644 --- a/Swift/Controllers/Settings/XMLSettingsProvider.cpp +++ b/Swift/Controllers/Settings/XMLSettingsProvider.cpp @@ -1,58 +1,57 @@ /* * Copyright (c) 2012-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swift/Controllers/Settings/XMLSettingsProvider.h> #include <boost/algorithm/string.hpp> #include <boost/lexical_cast.hpp> #include <Swiften/Base/Log.h> #include <Swiften/Parser/PlatformXMLParserFactory.h> #include <Swiften/Parser/XMLParser.h> namespace Swift { XMLSettingsProvider::XMLSettingsProvider(const std::string& xmlConfig) : level_(0) { if (!xmlConfig.empty()) { PlatformXMLParserFactory factory; - XMLParser* parser = factory.createXMLParser(this); + auto parser = factory.createXMLParser(this); if (parser->parse(xmlConfig)) { SWIFT_LOG(debug) << "Found and parsed system config" << std::endl; } else { SWIFT_LOG(debug) << "Found invalid system config" << std::endl; } - delete parser; } else { SWIFT_LOG(debug) << "No system config found" << std::endl; } } XMLSettingsProvider::~XMLSettingsProvider() { } bool XMLSettingsProvider::hasSetting(const std::string& key) { return (values_.find(key) != values_.end()); } std::string XMLSettingsProvider::getSetting(const Setting<std::string>& setting) { if (values_.find(setting.getKey()) != values_.end()) { std::string value = values_[setting.getKey()]; return value; } return setting.getDefaultValue(); } void XMLSettingsProvider::storeSetting(const Setting<std::string>& /*settingPath*/, const std::string& /*settingValue*/) { assert(false); } bool XMLSettingsProvider::getSetting(const Setting<bool>& setting) { if (values_.find(setting.getKey()) != values_.end()) { std::string value = values_[setting.getKey()]; diff --git a/Swiften/Client/ClientXMLTracer.cpp b/Swiften/Client/ClientXMLTracer.cpp index 4852aa1..e205f41 100644 --- a/Swiften/Client/ClientXMLTracer.cpp +++ b/Swiften/Client/ClientXMLTracer.cpp @@ -1,56 +1,61 @@ /* * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/Client/ClientXMLTracer.h> #include <iostream> #include <boost/bind.hpp> #include <Swiften/Base/Platform.h> namespace Swift { -ClientXMLTracer::ClientXMLTracer(CoreClient* client, bool bosh) : bosh(bosh) { +ClientXMLTracer::ClientXMLTracer(CoreClient* client, bool bosh) : bosh_(bosh) { #ifdef SWIFTEN_PLATFORM_WIN32 - beautifier = new XMLBeautifier(true, false); + beautifier_ = std::unique_ptr<XMLBeautifier>(new XMLBeautifier(true, false)); #else - beautifier = new XMLBeautifier(true, true); + beautifier_ = std::unique_ptr<XMLBeautifier>(new XMLBeautifier(true, true)); #endif - onDataReadConnection = client->onDataRead.connect(boost::bind(&ClientXMLTracer::printData, this, '<', _1)); - onDataWrittenConnection = client->onDataWritten.connect(boost::bind(&ClientXMLTracer::printData, this, '>', _1)); -} - -ClientXMLTracer::~ClientXMLTracer() { - delete beautifier; + onDataReadConnection_ = client->onDataRead.connect(boost::bind(&ClientXMLTracer::printData, this, '<', _1)); + onDataWrittenConnection_ = client->onDataWritten.connect(boost::bind(&ClientXMLTracer::printData, this, '>', _1)); } void ClientXMLTracer::printData(char direction, const SafeByteArray& data) { - printLine(direction); - if (bosh) { + if (bosh_) { + printLine(direction); std::string line = byteArrayToString(ByteArray(data.begin(), data.end())); // Disabled because it swallows bits of XML (namespaces, if I recall) // size_t endOfHTTP = line.find("\r\n\r\n"); // if (false && endOfHTTP != std::string::npos) { // std::cerr << line.substr(0, endOfHTTP) << std::endl << beautifier->beautify(line.substr(endOfHTTP)) << std::endl; // } // else { std::cerr << line << std::endl; // } } else { - std::cerr << beautifier->beautify(byteArrayToString(ByteArray(data.begin(), data.end()))) << std::endl; + const auto& str = beautifier_->beautify(byteArrayToString(ByteArray(data.begin(), data.end()))); + + if (beautifier_->wasReset()) { + printLine(direction); + } + std::cerr << str; + if (beautifier_->getLevel() <= 1) { + std::cerr << std::endl; + } + } } void ClientXMLTracer::printLine(char c) { for (unsigned int i = 0; i < 80; ++i) { std::cerr << c; } std::cerr << std::endl; } } diff --git a/Swiften/Client/ClientXMLTracer.h b/Swiften/Client/ClientXMLTracer.h index ad28fe2..d3aeb0c 100644 --- a/Swiften/Client/ClientXMLTracer.h +++ b/Swiften/Client/ClientXMLTracer.h @@ -1,30 +1,31 @@ /* * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once +#include <memory> + #include <Swiften/Base/API.h> #include <Swiften/Base/SafeByteArray.h> #include <Swiften/Client/CoreClient.h> #include <Swiften/Client/XMLBeautifier.h> namespace Swift { class SWIFTEN_API ClientXMLTracer { public: ClientXMLTracer(CoreClient* client, bool bosh = false); - ~ClientXMLTracer(); private: void printData(char direction, const SafeByteArray& data); void printLine(char c); private: - XMLBeautifier *beautifier; - bool bosh; - boost::signals2::scoped_connection onDataReadConnection; - boost::signals2::scoped_connection onDataWrittenConnection; + std::unique_ptr<XMLBeautifier> beautifier_; + bool bosh_; + boost::signals2::scoped_connection onDataReadConnection_; + boost::signals2::scoped_connection onDataWrittenConnection_; }; } diff --git a/Swiften/Client/UnitTest/XMLBeautifierTest.cpp b/Swiften/Client/UnitTest/XMLBeautifierTest.cpp new file mode 100644 index 0000000..0188634 --- /dev/null +++ b/Swiften/Client/UnitTest/XMLBeautifierTest.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2010-2017 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include "gtest/gtest.h" +#include <Swiften/Client/XMLBeautifier.h> +#include <iostream> + +using namespace Swift; + +namespace { + const static std::string FULL_FORMATTED_OUTPUT("<list>\n <el>aqq</el>\n <el>bzz</el>\n</list>"); +} + +TEST(XMLBeautifierTest, testBeautify) { + auto beautifier = std::unique_ptr<XMLBeautifier>(new XMLBeautifier(true, false)); + + ASSERT_EQ(FULL_FORMATTED_OUTPUT, beautifier->beautify("<list><el>aqq</el><el>bzz</el></list>")); + ASSERT_TRUE(beautifier->wasReset()); + ASSERT_EQ(0, beautifier->getLevel()); + ASSERT_EQ(FULL_FORMATTED_OUTPUT, beautifier->beautify("<list><el>aqq</el><el>bzz</el></list>")); + ASSERT_TRUE(beautifier->wasReset()); + ASSERT_EQ(0, beautifier->getLevel()); +} + +TEST(XMLBeautifierTest, testBeautifyMultipleChunks) { + auto beautifier = std::unique_ptr<XMLBeautifier>(new XMLBeautifier(true, false)); + + auto result = beautifier->beautify("<list><el>aqq</el>"); + ASSERT_TRUE(beautifier->wasReset()); + ASSERT_EQ(1, beautifier->getLevel()); + + result += beautifier->beautify("<el>bzz</el></list>"); + ASSERT_FALSE(beautifier->wasReset()); + ASSERT_EQ(0, beautifier->getLevel()); + + ASSERT_EQ(FULL_FORMATTED_OUTPUT, result); +} + +TEST(XMLBeautifierTest, testBeautifyMultipleChunksMiddleElement) { + auto beautifier = std::unique_ptr<XMLBeautifier>(new XMLBeautifier(true, false)); + + auto result = beautifier->beautify("<l"); + ASSERT_TRUE(beautifier->wasReset()); + ASSERT_EQ(0, beautifier->getLevel()); + + result += beautifier->beautify("ist><el>aqq</el><el>bzz</el></list>"); + ASSERT_FALSE(beautifier->wasReset()); + ASSERT_EQ(0, beautifier->getLevel()); + + ASSERT_EQ(FULL_FORMATTED_OUTPUT, result); +} + +TEST(XMLBeautifierTest, testBeautifyInvalidMultipleChunks) { + auto beautifier = std::unique_ptr<XMLBeautifier>(new XMLBeautifier(true, false)); + + ASSERT_EQ(std::string("<list>\n <el>aqq"), beautifier->beautify("<list><el>aqq<")); + ASSERT_TRUE(beautifier->wasReset()); + ASSERT_EQ(2, beautifier->getLevel()); + + ASSERT_EQ(FULL_FORMATTED_OUTPUT, beautifier->beautify("<list><el>aqq</el><el>bzz</el></list>")); + ASSERT_TRUE(beautifier->wasReset()); + ASSERT_EQ(0, beautifier->getLevel()); +} diff --git a/Swiften/Client/XMLBeautifier.cpp b/Swiften/Client/XMLBeautifier.cpp index e2cd58e..97a228f 100644 --- a/Swiften/Client/XMLBeautifier.cpp +++ b/Swiften/Client/XMLBeautifier.cpp @@ -1,132 +1,150 @@ /* * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* * Copyright (c) 2014-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/Client/XMLBeautifier.h> #include <sstream> #include <stack> +#include <iostream> #include <Swiften/Base/Log.h> #include <Swiften/Parser/PlatformXMLParserFactory.h> namespace Swift { -XMLBeautifier::XMLBeautifier(bool indention, bool coloring) : doIndention(indention), doColoring(coloring), intLevel(0), parser(nullptr), lastWasStepDown(false) { - factory = new PlatformXMLParserFactory(); +XMLBeautifier::XMLBeautifier(bool indention, bool coloring) : doIndention_(indention), doColoring_(coloring), factory_(new PlatformXMLParserFactory()) { } -XMLBeautifier::~XMLBeautifier() { - delete factory; -} std::string XMLBeautifier::beautify(const std::string &text) { - parser = factory->createXMLParser(this); - intLevel = 0; - buffer.str(std::string()); - parser->parse(text); - delete parser; - return buffer.str(); + wasReset_ = false; + if (!parser_) { + reset(); + } + buffer_.str(std::string()); + if (!parser_->parse(text)) { + reset(); + parser_->parse(text); + } + return buffer_.str(); +} + +bool XMLBeautifier::wasReset() const { + return wasReset_; +} + +int XMLBeautifier::getLevel() const { + return intLevel_; } void XMLBeautifier::indent() { - for (int i = 0; i < intLevel; ++i) { - buffer << " "; + for (int i = 0; i < intLevel_; ++i) { + buffer_ << " "; } } +void XMLBeautifier::reset() { + parser_ = factory_->createXMLParser(this); + intLevel_ = 0; + lastWasStepDown_ = false; + std::stack<std::string>().swap(parentNSs_); + buffer_.str(std::string()); + wasReset_ = true; +} + // all bold but reset // static const char colorBlue[] = "\x1b[01;34m"; static const char colorCyan[] = "\x1b[01;36m"; static const char colorGreen[] = "\x1b[01;32m"; // static const char colorMagenta[] = "\x1b[01;35m"; static const char colorRed[] = "\x1b[01;31m"; static const char colorReset[] = "\x1b[0m"; static const char colorYellow[] = "\x1b[01;33m"; std::string XMLBeautifier::styleTag(const std::string& text) const { std::string result; result += colorYellow; result += text; result += colorReset; return result; } std::string XMLBeautifier::styleNamespace(const std::string& text) const { std::string result; result += colorRed; result += text; result += colorReset; return result; } std::string XMLBeautifier::styleAttribute(const std::string& text) const { std::string result; result += colorGreen; result += text; result += colorReset; return result; } std::string XMLBeautifier::styleValue(const std::string& text) const { std::string result; result += colorCyan; result += text; result += colorReset; return result; } void XMLBeautifier::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { - if (doIndention) { - if (intLevel) buffer << std::endl; + if (doIndention_) { + if (intLevel_) buffer_ << std::endl; } indent(); - buffer << "<" << (doColoring ? styleTag(element) : element); - if (!ns.empty() && (!parentNSs.empty() && parentNSs.top() != ns)) { - buffer << " "; - buffer << (doColoring ? styleAttribute("xmlns") : "xmlns"); - buffer << "="; - buffer << "\"" << (doColoring ? styleNamespace(ns) : ns) << "\""; + buffer_ << "<" << (doColoring_ ? styleTag(element) : element); + if (!ns.empty() && (!parentNSs_.empty() && parentNSs_.top() != ns)) { + buffer_ << " "; + buffer_ << (doColoring_ ? styleAttribute("xmlns") : "xmlns"); + buffer_ << "="; + buffer_ << "\"" << (doColoring_ ? styleNamespace(ns) : ns) << "\""; } if (!attributes.getEntries().empty()) { for (const auto& entry : attributes.getEntries()) { - buffer << " "; - buffer << (doColoring ? styleAttribute(entry.getAttribute().getName()) : entry.getAttribute().getName()); - buffer << "="; - buffer << "\"" << (doColoring ? styleValue(entry.getValue()) : entry.getValue()) << "\""; + buffer_ << " "; + buffer_ << (doColoring_ ? styleAttribute(entry.getAttribute().getName()) : entry.getAttribute().getName()); + buffer_ << "="; + buffer_ << "\"" << (doColoring_ ? styleValue(entry.getValue()) : entry.getValue()) << "\""; } } - buffer << ">"; - ++intLevel; - lastWasStepDown = false; - parentNSs.push(ns); + buffer_ << ">"; + ++intLevel_; + lastWasStepDown_ = false; + parentNSs_.push(ns); } void XMLBeautifier::handleEndElement(const std::string& element, const std::string& /* ns */) { - --intLevel; - parentNSs.pop(); - if (/*hadCDATA.top() ||*/ lastWasStepDown) { - if (doIndention) { - buffer << std::endl; + --intLevel_; + parentNSs_.pop(); + if (/*hadCDATA.top() ||*/ lastWasStepDown_) { + if (doIndention_) { + buffer_ << std::endl; } indent(); } - buffer << "</" << (doColoring ? styleTag(element) : element) << ">"; - lastWasStepDown = true; + buffer_ << "</" << (doColoring_ ? styleTag(element) : element) << ">"; + lastWasStepDown_ = true; } void XMLBeautifier::handleCharacterData(const std::string& data) { - buffer << data; - lastWasStepDown = false; + buffer_ << data; + lastWasStepDown_ = false; } } diff --git a/Swiften/Client/XMLBeautifier.h b/Swiften/Client/XMLBeautifier.h index 8da935a..7458211 100644 --- a/Swiften/Client/XMLBeautifier.h +++ b/Swiften/Client/XMLBeautifier.h @@ -1,62 +1,66 @@ /* * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* * Copyright (c) 2014-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once +#include <memory> #include <sstream> #include <stack> #include <string> #include <boost/signals2.hpp> #include <Swiften/Base/API.h> #include <Swiften/Parser/XMLParser.h> #include <Swiften/Parser/XMLParserClient.h> #include <Swiften/Parser/XMLParserFactory.h> namespace Swift { class SWIFTEN_API XMLBeautifier : public XMLParserClient { public: + XMLBeautifier(bool indention, bool coloring); - virtual ~XMLBeautifier(); std::string beautify(const std::string&); + bool wasReset() const; + int getLevel() const; private: void handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes); void handleEndElement(const std::string& element, const std::string& ns); void handleCharacterData(const std::string& data); private: void indent(); + void reset(); private: std::string styleTag(const std::string& text) const; std::string styleNamespace(const std::string& text) const; std::string styleAttribute(const std::string& text) const; std::string styleValue(const std::string& text) const; private: - bool doIndention; - bool doColoring; + const bool doIndention_; + const bool doColoring_; - int intLevel; - std::string inputBuffer; - std::stringstream buffer; - XMLParserFactory* factory; - XMLParser* parser; + std::unique_ptr<XMLParserFactory> factory_; + std::unique_ptr<XMLParser> parser_; - bool lastWasStepDown; - std::stack<std::string> parentNSs; + bool wasReset_ = true; + int intLevel_ = 0; + bool lastWasStepDown_ = false; + std::stringstream buffer_; + std::stack<std::string> parentNSs_; }; } diff --git a/Swiften/Parser/BOSHBodyExtractor.cpp b/Swiften/Parser/BOSHBodyExtractor.cpp index c45d338..803f16a 100644 --- a/Swiften/Parser/BOSHBodyExtractor.cpp +++ b/Swiften/Parser/BOSHBodyExtractor.cpp @@ -99,42 +99,42 @@ BOSHBodyExtractor::BOSHBodyExtractor(XMLParserFactory* parserFactory, const Byte ByteArray::const_reverse_iterator j = data.rbegin(); if (!endElementSeen) { while (isWhitespace(*j) && j < data.rend()) { ++j; } if (j == data.rend() || *j != '>') { return; } ++j; while (j < data.rend() && isWhitespace(*j)) { ++j; } if (std::distance(j, data.rend()) < 6 || *(j+5) != '<' || *(j+4) != '/' || *(j+3) != 'b' || *(j+2) != 'o' || *(j+1) != 'd' || *j != 'y') { return; } j += 6; } body = BOSHBody(); if (!endElementSeen) { body->content = std::string( reinterpret_cast<const char*>(vecptr(data) + std::distance(data.begin(), i)), boost::numeric_cast<size_t>(std::distance(i, j.base()))); } // Parse the body element BOSHBodyParserClient parserClient(this); - std::shared_ptr<XMLParser> parser(parserFactory->createXMLParser(&parserClient)); + std::shared_ptr<XMLParser> parser(std::move(parserFactory->createXMLParser(&parserClient))); if (!parser->parse(std::string( reinterpret_cast<const char*>(vecptr(data)), boost::numeric_cast<size_t>(std::distance(data.begin(), i))))) { /* TODO: This needs to be only validating the BOSH <body> element, so that XMPP parsing errors are caught at the correct higher layer */ body = boost::optional<BOSHBody>(); return; } } } diff --git a/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h b/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h index 2c1ff8e..dcdbffa 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h +++ b/Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h @@ -1,68 +1,64 @@ /* * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <cassert> #include <Swiften/Elements/Payload.h> #include <Swiften/Parser/PayloadParser.h> #include <Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h> #include <Swiften/Parser/PlatformXMLParserFactory.h> #include <Swiften/Parser/XMLParser.h> #include <Swiften/Parser/XMLParserClient.h> namespace Swift { class PayloadsParserTester : public XMLParserClient { public: PayloadsParserTester() : level(0) { xmlParser = PlatformXMLParserFactory().createXMLParser(this); } - ~PayloadsParserTester() { - delete xmlParser; - } - bool parse(const std::string& data) { return xmlParser->parse(data); } virtual void handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { if (level == 0) { assert(!payloadParser.get()); PayloadParserFactory* payloadParserFactory = factories.getPayloadParserFactory(element, ns, attributes); assert(payloadParserFactory); payloadParser.reset(payloadParserFactory->createPayloadParser()); } payloadParser->handleStartElement(element, ns, attributes); level++; } virtual void handleEndElement(const std::string& element, const std::string& ns) { level--; payloadParser->handleEndElement(element, ns); } virtual void handleCharacterData(const std::string& data) { payloadParser->handleCharacterData(data); } std::shared_ptr<Payload> getPayload() const { return payloadParser->getPayload(); } template<typename T> std::shared_ptr<T> getPayload() const { return std::dynamic_pointer_cast<T>(payloadParser->getPayload()); } private: - XMLParser* xmlParser; + std::unique_ptr<XMLParser> xmlParser; FullPayloadParserFactoryCollection factories; std::shared_ptr<PayloadParser> payloadParser; int level; }; } diff --git a/Swiften/Parser/PlatformXMLParserFactory.cpp b/Swiften/Parser/PlatformXMLParserFactory.cpp index 87f70d1..97e1c9e 100644 --- a/Swiften/Parser/PlatformXMLParserFactory.cpp +++ b/Swiften/Parser/PlatformXMLParserFactory.cpp @@ -1,31 +1,31 @@ /* * Copyright (c) 2010 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/Parser/PlatformXMLParserFactory.h> #include <cassert> #ifdef HAVE_LIBXML #include <Swiften/Parser/LibXMLParser.h> #else #include <Swiften/Parser/ExpatParser.h> #endif namespace Swift { PlatformXMLParserFactory::PlatformXMLParserFactory() { } -XMLParser* PlatformXMLParserFactory::createXMLParser(XMLParserClient* client) { +std::unique_ptr<XMLParser> PlatformXMLParserFactory::createXMLParser(XMLParserClient* client) { #ifdef HAVE_LIBXML - return new LibXMLParser(client); + return std::unique_ptr<XMLParser>(new LibXMLParser(client)); #else - return new ExpatParser(client); + return std::unique_ptr<XMLParser>(new ExpatParser(client)); #endif } } diff --git a/Swiften/Parser/PlatformXMLParserFactory.h b/Swiften/Parser/PlatformXMLParserFactory.h index 82b8573..fa3ca19 100644 --- a/Swiften/Parser/PlatformXMLParserFactory.h +++ b/Swiften/Parser/PlatformXMLParserFactory.h @@ -1,19 +1,19 @@ /* * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <Swiften/Base/API.h> #include <Swiften/Parser/XMLParserFactory.h> namespace Swift { class SWIFTEN_API PlatformXMLParserFactory : public XMLParserFactory { public: PlatformXMLParserFactory(); - virtual XMLParser* createXMLParser(XMLParserClient*); + virtual std::unique_ptr<XMLParser> createXMLParser(XMLParserClient*); }; } diff --git a/Swiften/Parser/UnitTest/ParserTester.h b/Swiften/Parser/UnitTest/ParserTester.h index a98eb51..aa01d40 100644 --- a/Swiften/Parser/UnitTest/ParserTester.h +++ b/Swiften/Parser/UnitTest/ParserTester.h @@ -1,47 +1,42 @@ /* * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <Swiften/Parser/PlatformXMLParserFactory.h> #include <Swiften/Parser/XMLParser.h> #include <Swiften/Parser/XMLParserClient.h> namespace Swift { class XMLParser; template<typename ParserType> class ParserTester : public XMLParserClient { public: - ParserTester(ParserType* parser) : parser_(parser) { - xmlParser_ = PlatformXMLParserFactory().createXMLParser(this); - } - - ~ParserTester() { - delete xmlParser_; + ParserTester(ParserType* parser) : xmlParser_(PlatformXMLParserFactory().createXMLParser(this)), parser_(parser) { } bool parse(const std::string& data) { return xmlParser_->parse(data); } virtual void handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { parser_->handleStartElement(element, ns, attributes); } virtual void handleEndElement(const std::string& element, const std::string& ns) { parser_->handleEndElement(element, ns); } virtual void handleCharacterData(const std::string& data) { parser_->handleCharacterData(data); } private: - XMLParser* xmlParser_; + std::unique_ptr<XMLParser> xmlParser_; ParserType* parser_; }; } diff --git a/Swiften/Parser/XMLParserFactory.h b/Swiften/Parser/XMLParserFactory.h index 091f45b..595512b 100644 --- a/Swiften/Parser/XMLParserFactory.h +++ b/Swiften/Parser/XMLParserFactory.h @@ -1,21 +1,23 @@ /* * Copyright (c) 2010 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once +#include <memory> + #include <Swiften/Base/API.h> namespace Swift { class XMLParser; class XMLParserClient; class SWIFTEN_API XMLParserFactory { public: virtual ~XMLParserFactory(); - virtual XMLParser* createXMLParser(XMLParserClient*) = 0; + virtual std::unique_ptr<XMLParser> createXMLParser(XMLParserClient*) = 0; }; } diff --git a/Swiften/Parser/XMPPParser.cpp b/Swiften/Parser/XMPPParser.cpp index 2b45a12..d2a5a98 100644 --- a/Swiften/Parser/XMPPParser.cpp +++ b/Swiften/Parser/XMPPParser.cpp @@ -33,61 +33,60 @@ #include <Swiften/Parser/StreamManagementEnabledParser.h> #include <Swiften/Parser/StreamManagementFailedParser.h> #include <Swiften/Parser/StreamResumeParser.h> #include <Swiften/Parser/StreamResumedParser.h> #include <Swiften/Parser/TLSProceedParser.h> #include <Swiften/Parser/UnknownElementParser.h> #include <Swiften/Parser/XMLParser.h> #include <Swiften/Parser/XMLParserFactory.h> #include <Swiften/Parser/XMPPParserClient.h> // TODO: Whenever an error occurs in the handlers, stop the parser by returing // a bool value, and stopping the XML parser namespace Swift { XMPPParser::XMPPParser( XMPPParserClient* client, PayloadParserFactoryCollection* payloadParserFactories, XMLParserFactory* xmlParserFactory) : xmlParser_(nullptr), client_(client), payloadParserFactories_(payloadParserFactories), level_(0), currentElementParser_(nullptr), parseErrorOccurred_(false) { xmlParser_ = xmlParserFactory->createXMLParser(this); } XMPPParser::~XMPPParser() { delete currentElementParser_; - delete xmlParser_; } bool XMPPParser::parse(const std::string& data) { bool xmlParseResult = xmlParser_->parse(data); return xmlParseResult && !parseErrorOccurred_; } void XMPPParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { if (!parseErrorOccurred_) { if (level_ == TopLevel) { if (element == "stream" && ns == "http://etherx.jabber.org/streams") { ProtocolHeader header; header.setFrom(attributes.getAttribute("from")); header.setTo(attributes.getAttribute("to")); header.setID(attributes.getAttribute("id")); header.setVersion(attributes.getAttribute("version")); client_->handleStreamStart(header); } else { parseErrorOccurred_ = true; } } else { if (level_ == StreamLevel) { assert(!currentElementParser_); currentElementParser_ = createElementParser(element, ns); } currentElementParser_->handleStartElement(element, ns, attributes); } } diff --git a/Swiften/Parser/XMPPParser.h b/Swiften/Parser/XMPPParser.h index 09fae38..6595b94 100644 --- a/Swiften/Parser/XMPPParser.h +++ b/Swiften/Parser/XMPPParser.h @@ -15,43 +15,43 @@ #include <Swiften/Parser/XMLParserClient.h> namespace Swift { class XMLParser; class XMPPParserClient; class XMLParserFactory; class ElementParser; class PayloadParserFactoryCollection; class SWIFTEN_API XMPPParser : public XMLParserClient, boost::noncopyable { public: XMPPParser( XMPPParserClient* parserClient, PayloadParserFactoryCollection* payloadParserFactories, XMLParserFactory* xmlParserFactory); virtual ~XMPPParser(); bool parse(const std::string&); private: virtual void handleStartElement( const std::string& element, const std::string& ns, const AttributeMap& attributes); virtual void handleEndElement(const std::string& element, const std::string& ns); virtual void handleCharacterData(const std::string& data); ElementParser* createElementParser(const std::string& element, const std::string& xmlns); private: - XMLParser* xmlParser_; + std::unique_ptr<XMLParser> xmlParser_; XMPPParserClient* client_; PayloadParserFactoryCollection* payloadParserFactories_; enum Level { TopLevel = 0, StreamLevel = 1, ElementLevel = 2 }; int level_; ElementParser* currentElementParser_; bool parseErrorOccurred_; }; } diff --git a/Swiften/SConscript b/Swiften/SConscript index 2182132..c77d80f 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -355,60 +355,61 @@ if env["SCONS_STAGE"] == "build" : res_env.Depends(res, "Version.h") sources += res swiften_lib = myenv.SwiftenLibrary(swiften_env["SWIFTEN_LIBRARY_FILE"], sources + swiften_env["SWIFTEN_OBJECTS"]) def symlink(env, target, source) : if os.path.exists(str(target[0])) : os.unlink(str(target[0])) os.symlink(source[0].get_contents(), str(target[0])) for alias in myenv["SWIFTEN_LIBRARY_ALIASES"] : myenv.Command(myenv.File(alias), [myenv.Value(swiften_lib[0].name), swiften_lib[0]], symlink) env.Append(UNITTEST_SOURCES = [ File("Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp"), File("Avatars/UnitTest/VCardAvatarManagerTest.cpp"), File("Avatars/UnitTest/CombinedAvatarProviderTest.cpp"), File("Avatars/UnitTest/AvatarManagerImplTest.cpp"), File("Base/UnitTest/IDGeneratorTest.cpp"), File("Base/UnitTest/LRUCacheTest.cpp"), File("Base/UnitTest/SimpleIDGeneratorTest.cpp"), File("Base/UnitTest/StringTest.cpp"), File("Base/UnitTest/DateTimeTest.cpp"), File("Base/UnitTest/ByteArrayTest.cpp"), File("Base/UnitTest/URLTest.cpp"), File("Base/UnitTest/PathTest.cpp"), File("Chat/UnitTest/ChatStateNotifierTest.cpp"), # File("Chat/UnitTest/ChatStateTrackerTest.cpp"), File("Client/UnitTest/ClientSessionTest.cpp"), File("Client/UnitTest/NickResolverTest.cpp"), File("Client/UnitTest/ClientBlockListManagerTest.cpp"), File("Client/UnitTest/BlockListImplTest.cpp"), + File("Client/UnitTest/XMLBeautifierTest.cpp"), File("Compress/UnitTest/ZLibCompressorTest.cpp"), File("Compress/UnitTest/ZLibDecompressorTest.cpp"), File("Component/UnitTest/ComponentHandshakeGeneratorTest.cpp"), File("Component/UnitTest/ComponentConnectorTest.cpp"), File("Component/UnitTest/ComponentSessionTest.cpp"), File("Disco/UnitTest/CapsInfoGeneratorTest.cpp"), File("Disco/UnitTest/CapsManagerTest.cpp"), File("Disco/UnitTest/DiscoInfoResponderTest.cpp"), File("Disco/UnitTest/EntityCapsManagerTest.cpp"), File("Disco/UnitTest/FeatureOracleTest.cpp"), File("Disco/UnitTest/JIDDiscoInfoResponderTest.cpp"), File("Elements/UnitTest/IQTest.cpp"), File("Elements/UnitTest/StanzaTest.cpp"), File("Elements/UnitTest/FormTest.cpp"), File("EventLoop/UnitTest/EventLoopTest.cpp"), File("EventLoop/UnitTest/SimpleEventLoopTest.cpp"), # File("History/UnitTest/SQLiteHistoryManagerTest.cpp"), File("JID/UnitTest/JIDTest.cpp"), File("LinkLocal/UnitTest/LinkLocalConnectorTest.cpp"), File("LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp"), File("LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp"), File("LinkLocal/UnitTest/LinkLocalServiceTest.cpp"), File("MUC/UnitTest/MUCTest.cpp"), File("MUC/UnitTest/MockMUC.cpp"), File("Network/UnitTest/HostAddressTest.cpp"), File("Network/UnitTest/ConnectorTest.cpp"), File("Network/UnitTest/ChainedConnectorTest.cpp"), File("Network/UnitTest/DomainNameServiceQueryTest.cpp"), File("Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp"), File("Network/UnitTest/BOSHConnectionTest.cpp"), |