summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2010-09-05 11:01:20 (GMT)
committerRemko Tronçon <git@el-tramo.be>2010-09-05 11:01:20 (GMT)
commit0630c01cf274a9de6b67856b8c00b1503b39353e (patch)
treed304c6510063ddd7ba5eb934e92f93f7222e3b41
parent840dc1e190cfdfdc9ec88f9f2db3a507221c96bc (diff)
downloadswift-0630c01cf274a9de6b67856b8c00b1503b39353e.zip
swift-0630c01cf274a9de6b67856b8c00b1503b39353e.tar.bz2
Don't lose unknown roster content.
Resolves: #555
-rw-r--r--Swiften/Elements/RosterItemPayload.h6
-rw-r--r--Swiften/Parser/PayloadParsers/RosterParser.cpp32
-rw-r--r--Swiften/Parser/PayloadParsers/RosterParser.h3
-rw-r--r--Swiften/Parser/PayloadParsers/UnitTest/RosterParserTest.cpp25
-rw-r--r--Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp6
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp28
6 files changed, 95 insertions, 5 deletions
diff --git a/Swiften/Elements/RosterItemPayload.h b/Swiften/Elements/RosterItemPayload.h
index 9120e12..84b2887 100644
--- a/Swiften/Elements/RosterItemPayload.h
+++ b/Swiften/Elements/RosterItemPayload.h
@@ -37,12 +37,18 @@ namespace Swift {
void setSubscriptionRequested() { ask_ = true; }
bool getSubscriptionRequested() const { return ask_; }
+ const String& getUnknownContent() const { return unknownContent_; }
+ void addUnknownContent(const String& c) {
+ unknownContent_ += c;
+ }
+
private:
JID jid_;
String name_;
Subscription subscription_;
std::vector<String> groups_;
bool ask_;
+ String unknownContent_;
};
}
diff --git a/Swiften/Parser/PayloadParsers/RosterParser.cpp b/Swiften/Parser/PayloadParsers/RosterParser.cpp
index b35c035..c3a35b6 100644
--- a/Swiften/Parser/PayloadParsers/RosterParser.cpp
+++ b/Swiften/Parser/PayloadParsers/RosterParser.cpp
@@ -5,13 +5,14 @@
*/
#include "Swiften/Parser/PayloadParsers/RosterParser.h"
+#include "Swiften/Parser/SerializingParser.h"
namespace Swift {
-RosterParser::RosterParser() : level_(TopLevel) {
+RosterParser::RosterParser() : level_(TopLevel), unknownContentParser_(0) {
}
-void RosterParser::handleStartElement(const String& element, const String&, const AttributeMap& attributes) {
+void RosterParser::handleStartElement(const String& element, const String& ns, const AttributeMap& attributes) {
if (level_ == PayloadLevel) {
if (element == "item") {
inItem_ = true;
@@ -46,11 +47,19 @@ void RosterParser::handleStartElement(const String& element, const String&, cons
if (element == "group") {
currentText_ = "";
}
+ else {
+ assert(!unknownContentParser_);
+ unknownContentParser_ = new SerializingParser();
+ unknownContentParser_->handleStartElement(element, ns, attributes);
+ }
+ }
+ else if (unknownContentParser_) {
+ unknownContentParser_->handleStartElement(element, ns, attributes);
}
++level_;
}
-void RosterParser::handleEndElement(const String& element, const String&) {
+void RosterParser::handleEndElement(const String& element, const String& ns) {
--level_;
if (level_ == PayloadLevel) {
if (inItem_) {
@@ -59,14 +68,27 @@ void RosterParser::handleEndElement(const String& element, const String&) {
}
}
else if (level_ == ItemLevel) {
- if (element == "group") {
+ if (unknownContentParser_) {
+ unknownContentParser_->handleEndElement(element, ns);
+ currentItem_.addUnknownContent(unknownContentParser_->getResult());
+ unknownContentParser_ = NULL;
+ }
+ else if (element == "group") {
currentItem_.addGroup(currentText_);
}
}
+ else if (unknownContentParser_) {
+ unknownContentParser_->handleEndElement(element, ns);
+ }
}
void RosterParser::handleCharacterData(const String& data) {
- currentText_ += data;
+ if (unknownContentParser_) {
+ unknownContentParser_->handleCharacterData(data);
+ }
+ else {
+ currentText_ += data;
+ }
}
}
diff --git a/Swiften/Parser/PayloadParsers/RosterParser.h b/Swiften/Parser/PayloadParsers/RosterParser.h
index a039ff4..4a28618 100644
--- a/Swiften/Parser/PayloadParsers/RosterParser.h
+++ b/Swiften/Parser/PayloadParsers/RosterParser.h
@@ -11,6 +11,8 @@
#include "Swiften/Parser/GenericPayloadParser.h"
namespace Swift {
+ class SerializingParser;
+
class RosterParser : public GenericPayloadParser<RosterPayload> {
public:
RosterParser();
@@ -29,6 +31,7 @@ namespace Swift {
bool inItem_;
RosterItemPayload currentItem_;
String currentText_;
+ SerializingParser* unknownContentParser_;
};
}
diff --git a/Swiften/Parser/PayloadParsers/UnitTest/RosterParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/RosterParserTest.cpp
index e085d58..aea9dc4 100644
--- a/Swiften/Parser/PayloadParsers/UnitTest/RosterParserTest.cpp
+++ b/Swiften/Parser/PayloadParsers/UnitTest/RosterParserTest.cpp
@@ -16,6 +16,7 @@ class RosterParserTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(RosterParserTest);
CPPUNIT_TEST(testParse);
+ CPPUNIT_TEST(testParse_ItemWithUnknownContent);
CPPUNIT_TEST_SUITE_END();
public:
@@ -51,6 +52,30 @@ class RosterParserTest : public CppUnit::TestFixture
CPPUNIT_ASSERT(!items[1].getSubscriptionRequested());
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), items[1].getGroups().size());
}
+
+ void testParse_ItemWithUnknownContent() {
+ PayloadsParserTester parser;
+ parser.parse(
+ "<query xmlns='jabber:iq:roster'>"
+ " <item jid='foo@bar.com' name='Foo @ Bar' subscription='from' ask='subscribe'>"
+ " <group>Group 1</group>"
+ " <foo xmlns=\"http://example.com\"><bar>Baz</bar></foo>"
+ " <group>Group 2</group>"
+ " <baz><fum>foo</fum></baz>"
+ " </item>"
+ "</query>");
+
+ RosterPayload* payload = dynamic_cast<RosterPayload*>(parser.getPayload().get());
+ const RosterPayload::RosterItemPayloads& items = payload->getItems();
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), items.size());
+ CPPUNIT_ASSERT_EQUAL(String("Group 1"), items[0].getGroups()[0]);
+ CPPUNIT_ASSERT_EQUAL(String("Group 2"), items[0].getGroups()[1]);
+ CPPUNIT_ASSERT_EQUAL(String(
+ "<foo xmlns=\"http://example.com\"><bar xmlns=\"http://example.com\">Baz</bar></foo>"
+ "<baz xmlns=\"jabber:iq:roster\"><fum xmlns=\"jabber:iq:roster\">foo</fum></baz>"
+ ), items[0].getUnknownContent());
+ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(RosterParserTest);
diff --git a/Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp b/Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp
index fc3c03a..b56f404 100644
--- a/Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp
+++ b/Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp
@@ -10,6 +10,7 @@
#include "Swiften/Base/foreach.h"
#include "Swiften/Serializer/XML/XMLTextNode.h"
+#include "Swiften/Serializer/XML/XMLRawTextNode.h"
#include "Swiften/Serializer/XML/XMLElement.h"
namespace Swift {
@@ -42,6 +43,11 @@ String RosterSerializer::serializePayload(boost::shared_ptr<RosterPayload> roste
itemElement->addNode(groupElement);
}
+ if (!item.getUnknownContent().isEmpty()) {
+ itemElement->addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(item.getUnknownContent())));
+ }
+
+
queryElement.addNode(itemElement);
}
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp
index fdf93a9..bf30db8 100644
--- a/Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp
@@ -15,6 +15,7 @@ class RosterSerializerTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(RosterSerializerTest);
CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST(testSerialize_ItemWithUnknownContent);
CPPUNIT_TEST_SUITE_END();
public:
@@ -49,6 +50,33 @@ class RosterSerializerTest : public CppUnit::TestFixture
CPPUNIT_ASSERT_EQUAL(expectedResult, testling.serialize(roster));
}
+
+ void testSerialize_ItemWithUnknownContent() {
+ RosterSerializer testling;
+ boost::shared_ptr<RosterPayload> roster(new RosterPayload());
+
+ RosterItemPayload item;
+ item.setJID(JID("baz@blo.com"));
+ item.setName("Baz");
+ item.addGroup("Group 1");
+ item.addGroup("Group 2");
+ item.addUnknownContent(String(
+ "<foo xmlns=\"http://example.com\"><bar xmlns=\"http://example.com\">Baz</bar></foo>"
+ "<baz xmlns=\"jabber:iq:roster\"><fum xmlns=\"jabber:iq:roster\">foo</fum></baz>"));
+ roster->addItem(item);
+
+ String expectedResult =
+ "<query xmlns=\"jabber:iq:roster\">"
+ "<item jid=\"baz@blo.com\" name=\"Baz\" subscription=\"none\">"
+ "<group>Group 1</group>"
+ "<group>Group 2</group>"
+ "<foo xmlns=\"http://example.com\"><bar xmlns=\"http://example.com\">Baz</bar></foo>"
+ "<baz xmlns=\"jabber:iq:roster\"><fum xmlns=\"jabber:iq:roster\">foo</fum></baz>"
+ "</item>"
+ "</query>";
+
+ CPPUNIT_ASSERT_EQUAL(expectedResult, testling.serialize(roster));
+ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(RosterSerializerTest);