diff options
author | Remko Tronçon <git@el-tramo.be> | 2010-09-05 11:01:20 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2010-09-05 11:01:20 (GMT) |
commit | 0630c01cf274a9de6b67856b8c00b1503b39353e (patch) | |
tree | d304c6510063ddd7ba5eb934e92f93f7222e3b41 /Swiften/Parser | |
parent | 840dc1e190cfdfdc9ec88f9f2db3a507221c96bc (diff) | |
download | swift-0630c01cf274a9de6b67856b8c00b1503b39353e.zip swift-0630c01cf274a9de6b67856b8c00b1503b39353e.tar.bz2 |
Don't lose unknown roster content.
Resolves: #555
Diffstat (limited to 'Swiften/Parser')
-rw-r--r-- | Swiften/Parser/PayloadParsers/RosterParser.cpp | 32 | ||||
-rw-r--r-- | Swiften/Parser/PayloadParsers/RosterParser.h | 3 | ||||
-rw-r--r-- | Swiften/Parser/PayloadParsers/UnitTest/RosterParserTest.cpp | 25 |
3 files changed, 55 insertions, 5 deletions
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); |