summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Sluift/ElementConvertors/DOMElementConvertor.cpp2
-rw-r--r--Swift/Controllers/Settings/XMLSettingsProvider.cpp3
-rw-r--r--Swiften/Client/ClientXMLTracer.cpp29
-rw-r--r--Swiften/Client/ClientXMLTracer.h11
-rw-r--r--Swiften/Client/UnitTest/XMLBeautifierTest.cpp66
-rw-r--r--Swiften/Client/XMLBeautifier.cpp94
-rw-r--r--Swiften/Client/XMLBeautifier.h24
-rw-r--r--Swiften/Parser/BOSHBodyExtractor.cpp2
-rw-r--r--Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h6
-rw-r--r--Swiften/Parser/PlatformXMLParserFactory.cpp6
-rw-r--r--Swiften/Parser/PlatformXMLParserFactory.h2
-rw-r--r--Swiften/Parser/UnitTest/ParserTester.h9
-rw-r--r--Swiften/Parser/XMLParserFactory.h4
-rw-r--r--Swiften/Parser/XMPPParser.cpp1
-rw-r--r--Swiften/Parser/XMPPParser.h2
-rw-r--r--Swiften/SConscript1
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"),