diff options
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); | 
 Swift
 Swift