diff options
19 files changed, 406 insertions, 93 deletions
diff --git a/Swiften/Elements/JingleFileTransferDescription.h b/Swiften/Elements/JingleFileTransferDescription.h index 04f3f1f..bdd5aae 100644 --- a/Swiften/Elements/JingleFileTransferDescription.h +++ b/Swiften/Elements/JingleFileTransferDescription.h @@ -10,32 +10,32 @@ #include <vector> #include <Swiften/Elements/JingleDescription.h> -#include <Swiften/Elements/StreamInitiationFileInfo.h> +#include <Swiften/Elements/JingleFileTransferFileInfo.h> namespace Swift { class JingleFileTransferDescription : public JingleDescription { public: typedef boost::shared_ptr<JingleFileTransferDescription> ref; - void addOffer(const StreamInitiationFileInfo& offer) { + void addOffer(const JingleFileTransferFileInfo& offer) { offers.push_back(offer); } - const std::vector<StreamInitiationFileInfo>& getOffers() const { + const std::vector<JingleFileTransferFileInfo>& getOffers() const { return offers; } - void addRequest(const StreamInitiationFileInfo& request) { + void addRequest(const JingleFileTransferFileInfo& request) { reqeusts.push_back(request); } - const std::vector<StreamInitiationFileInfo>& getRequests() const { + const std::vector<JingleFileTransferFileInfo>& getRequests() const { return reqeusts; } private: - std::vector<StreamInitiationFileInfo> offers; - std::vector<StreamInitiationFileInfo> reqeusts; + std::vector<JingleFileTransferFileInfo> offers; + std::vector<JingleFileTransferFileInfo> reqeusts; }; } diff --git a/Swiften/Elements/JingleFileTransferFileInfo.h b/Swiften/Elements/JingleFileTransferFileInfo.h new file mode 100644 index 0000000..a174df0 --- /dev/null +++ b/Swiften/Elements/JingleFileTransferFileInfo.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/Payload.h> +#include <boost/shared_ptr.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> +#include <Swiften/Elements/StreamInitiationFileInfo.h> + +#include <string> + +namespace Swift { + +class JingleFileTransferFileInfo : public Payload { +public: + typedef boost::shared_ptr<JingleFileTransferFileInfo> ref; + +public: + JingleFileTransferFileInfo(const std::string& name = "", const std::string& description = "", int size = 0, + const std::string& hash = "", const boost::posix_time::ptime &date = boost::posix_time::ptime(), const std::string& algo="md5") : + name(name), description(description), size(size), hash(hash), date(date), algo(algo), supportsRangeRequests(false), rangeOffset(0) {} + JingleFileTransferFileInfo(const StreamInitiationFileInfo& siFileInfo) { + this->name = siFileInfo.getName(); + this->description = siFileInfo.getDescription(); + this->size = siFileInfo.getSize(); + this->hash = siFileInfo.getHash(); + this->date = siFileInfo.getDate(); + this->algo = siFileInfo.getAlgo(); + this->supportsRangeRequests = siFileInfo.getSupportsRangeRequests(); + this->rangeOffset = siFileInfo.getRangeOffset(); + } + + void setName(const std::string& name) { + this->name = name;; + } + + const std::string& getName() const { + return this->name; + } + + void setDescription(const std::string& description) { + this->description = description; + } + + const std::string& getDescription() const { + return this->description; + } + + void setSize(const boost::uintmax_t size) { + this->size = size; + } + + boost::uintmax_t getSize() const { + return this->size; + } + + void setHash(const std::string& hash) { + this->hash = hash; + } + + const std::string& getHash() const { + return this->hash; + } + + void setDate(const boost::posix_time::ptime& date) { + this->date = date; + } + + const boost::posix_time::ptime& getDate() const { + return this->date; + } + + void setAlgo(const std::string& algo) { + this->algo = algo; + } + + const std::string& getAlgo() const { + return this->algo; + } + + void setSupportsRangeRequests(const bool supportsIt) { + supportsRangeRequests = supportsIt; + } + + bool getSupportsRangeRequests() const { + return supportsRangeRequests; + } + + void setRangeOffset(const int offset) { + supportsRangeRequests = offset >= 0 ? true : false; + rangeOffset = offset; + } + + boost::uintmax_t getRangeOffset() const { + return rangeOffset; + } + +private: + std::string name; + std::string description; + boost::uintmax_t size; + std::string hash; + boost::posix_time::ptime date; + std::string algo; + bool supportsRangeRequests; + boost::uintmax_t rangeOffset; +}; + +} diff --git a/Swiften/Elements/JingleFileTransferReceived.h b/Swiften/Elements/JingleFileTransferReceived.h index 75c95d9..0a65088 100644 --- a/Swiften/Elements/JingleFileTransferReceived.h +++ b/Swiften/Elements/JingleFileTransferReceived.h @@ -9,7 +9,7 @@ #include <boost/shared_ptr.hpp> #include <vector> -#include <Swiften/Elements/StreamInitiationFileInfo.h> +#include <Swiften/Elements/JingleFileTransferFileInfo.h> #include <Swiften/Elements/Payload.h> namespace Swift { @@ -18,15 +18,15 @@ class JingleFileTransferReceived : public Payload { public: typedef boost::shared_ptr<JingleFileTransferReceived> ref; - void setFileInfo(const StreamInitiationFileInfo& fileInfo) { + void setFileInfo(const JingleFileTransferFileInfo& fileInfo) { this->fileInfo = fileInfo; } - const StreamInitiationFileInfo& getFileInfo() const { + const JingleFileTransferFileInfo& getFileInfo() const { return this->fileInfo; } private: - StreamInitiationFileInfo fileInfo; + JingleFileTransferFileInfo fileInfo; }; diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp index 808ff58..dd7cde4 100644 --- a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp +++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp @@ -64,7 +64,7 @@ IncomingJingleFileTransfer::IncomingJingleFileTransfer( description = initialContent->getDescription<JingleFileTransferDescription>(); assert(description); assert(description->getOffers().size() == 1); - StreamInitiationFileInfo fileInfo = description->getOffers().front(); + JingleFileTransferFileInfo fileInfo = description->getOffers().front(); fileSizeInBytes = fileInfo.getSize(); filename = fileInfo.getName(); hash = fileInfo.getHash(); diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.h b/Swiften/FileTransfer/OutgoingJingleFileTransfer.h index e18b5c3..2dbc89c 100644 --- a/Swiften/FileTransfer/OutgoingJingleFileTransfer.h +++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.h @@ -11,6 +11,7 @@ #include <Swiften/Base/API.h> #include <Swiften/Elements/JingleContentPayload.h> #include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/Elements/JingleFileTransferFileInfo.h> #include <Swiften/Elements/StreamInitiationFileInfo.h> #include <Swiften/Elements/S5BProxyRequest.h> #include <Swiften/Elements/ErrorPayload.h> @@ -93,7 +94,7 @@ private: JID fromJID; JID toJID; boost::shared_ptr<ReadBytestream> readStream; - StreamInitiationFileInfo fileInfo; + JingleFileTransferFileInfo fileInfo; IncrementalBytestreamHashCalculator *hashCalculator; boost::shared_ptr<IBBSendSession> ibbSession; diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp index a40e8f6..0a0fc39 100644 --- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp +++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp @@ -59,6 +59,7 @@ #include <Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.h> #include <Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParserFactory.h> #include <Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h> +#include <Swiften/Parser/PayloadParsers/JingleFileTransferFileInfoParser.h> #include <Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h> #include <Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.h> #include <Swiften/Parser/PayloadParsers/S5BProxyRequestParser.h> @@ -122,6 +123,7 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() { factories_.push_back(boost::make_shared<GenericPayloadParserFactory<JingleS5BTransportMethodPayloadParser> >("transport", "urn:xmpp:jingle:transports:s5b:1")); factories_.push_back(boost::make_shared<JingleFileTransferDescriptionParserFactory>(this)); factories_.push_back(boost::make_shared<GenericPayloadParserFactory<StreamInitiationFileInfoParser> >("file", "http://jabber.org/protocol/si/profile/file-transfer")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<JingleFileTransferFileInfoParser> >("file", "urn:xmpp:jingle:apps:file-transfer:3")); factories_.push_back(boost::make_shared<GenericPayloadParserFactory<JingleFileTransferReceivedParser> >("received", "urn:xmpp:jingle:apps:file-transfer:3")); factories_.push_back(boost::make_shared<GenericPayloadParserFactory<JingleFileTransferHashParser> >("checksum")); factories_.push_back(boost::make_shared<GenericPayloadParserFactory<S5BProxyRequestParser> >("query", "http://jabber.org/protocol/bytestreams")); diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.cpp b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.cpp index b394115..fa6c6ae 100644 --- a/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.cpp +++ b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.cpp @@ -54,7 +54,7 @@ void JingleFileTransferDescriptionParser::handleEndElement(const std::string& el } if (level == 2) { - boost::shared_ptr<StreamInitiationFileInfo> info = boost::dynamic_pointer_cast<StreamInitiationFileInfo>(currentPayloadParser->getPayload()); + boost::shared_ptr<JingleFileTransferFileInfo> info = boost::dynamic_pointer_cast<JingleFileTransferFileInfo>(currentPayloadParser->getPayload()); if (info) { if (currentElement == OfferElement) { getPayloadInternal()->addOffer(*info); diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferFileInfoParser.cpp b/Swiften/Parser/PayloadParsers/JingleFileTransferFileInfoParser.cpp new file mode 100644 index 0000000..769fc84 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleFileTransferFileInfoParser.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "JingleFileTransferFileInfoParser.h" + +#include <boost/optional.hpp> +#include <boost/lexical_cast.hpp> + +#include <Swiften/Base/DateTime.h> +#include <Swiften/Base/Log.h> + +#include <cstdio> + +namespace Swift { + +JingleFileTransferFileInfoParser::JingleFileTransferFileInfoParser() : level(0) { + +} + +void JingleFileTransferFileInfoParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) { + if (level == 0) { + + } else if (level == 1) { + if (element == "date" || element == "desc" || element == "name" || element == "size") { + cdataBuffer.clear(); + } else if (element == "hash") { + cdataBuffer.clear(); + getPayloadInternal()->setAlgo(attributes.getAttributeValue("algo").get_value_or("md5")); + } else { + if (element == "range") { + int offset = 0; + try { + offset = boost::lexical_cast<boost::uintmax_t>(attributes.getAttributeValue("offset").get_value_or("0")); + } catch (boost::bad_lexical_cast &) { + offset = 0; + } + if (offset == 0) { + getPayloadInternal()->setSupportsRangeRequests(true); + } else { + getPayloadInternal()->setRangeOffset(offset); + } + } + } + } + ++level; +} + +void JingleFileTransferFileInfoParser::handleEndElement(const std::string& element, const std::string&) { + --level; + if (element == "date") { + getPayloadInternal()->setDate(stringToDateTime(cdataBuffer)); + } else if (element == "desc") { + getPayloadInternal()->setDescription(cdataBuffer); + } else if (element == "name") { + getPayloadInternal()->setName(cdataBuffer); + } else if (element == "size") { + try { + getPayloadInternal()->setSize(boost::lexical_cast<boost::uintmax_t>(cdataBuffer)); + } catch (boost::bad_lexical_cast &) { + getPayloadInternal()->setSize(0); + } + } else if (element == "hash") { + getPayloadInternal()->setHash(cdataBuffer); + } +} + +void JingleFileTransferFileInfoParser::handleCharacterData(const std::string& data) { + cdataBuffer += data; +} + +} diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferFileInfoParser.h b/Swiften/Parser/PayloadParsers/JingleFileTransferFileInfoParser.h new file mode 100644 index 0000000..5b44f9a --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleFileTransferFileInfoParser.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/JingleFileTransferFileInfo.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + +class JingleFileTransferFileInfoParser : public GenericPayloadParser<JingleFileTransferFileInfo> { + public: + JingleFileTransferFileInfoParser(); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + + private: + int level; + std::string cdataBuffer; +}; + +} diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.cpp b/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.cpp index ae56981..afe1da1 100644 --- a/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.cpp +++ b/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.cpp @@ -7,8 +7,7 @@ #include <Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h> #include <boost/shared_ptr.hpp> -#include <Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h> -#include <Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h> +#include <Swiften/Parser/PayloadParsers/JingleFileTransferFileInfoParser.h> #include <Swiften/Parser/GenericPayloadParserFactory.h> #include <Swiften/Parser/PayloadParserFactory.h> @@ -19,7 +18,7 @@ JingleFileTransferReceivedParser::JingleFileTransferReceivedParser() : level(0) void JingleFileTransferReceivedParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { if (level == 1 && element == "file") { - PayloadParserFactory* payloadParserFactory = new GenericPayloadParserFactory<StreamInitiationFileInfoParser>("file", "http://jabber.org/protocol/si/profile/file-transfer"); + PayloadParserFactory* payloadParserFactory = new GenericPayloadParserFactory<JingleFileTransferFileInfoParser>("file"); if (payloadParserFactory) { currentPayloadParser.reset(payloadParserFactory->createPayloadParser()); } @@ -32,18 +31,22 @@ void JingleFileTransferReceivedParser::handleStartElement(const std::string& ele ++level; } -void JingleFileTransferReceivedParser::handleEndElement(const std::string& element, const std::string& ) { +void JingleFileTransferReceivedParser::handleEndElement(const std::string& element, const std::string& ns) { --level; if (element == "file") { - boost::shared_ptr<StreamInitiationFileInfo> fileInfo = boost::dynamic_pointer_cast<StreamInitiationFileInfo>(currentPayloadParser->getPayload()); + boost::shared_ptr<JingleFileTransferFileInfo> fileInfo = boost::dynamic_pointer_cast<JingleFileTransferFileInfo>(currentPayloadParser->getPayload()); if (fileInfo) { getPayloadInternal()->setFileInfo(*fileInfo); } + } else { + currentPayloadParser->handleEndElement(element, ns); } } -void JingleFileTransferReceivedParser::handleCharacterData(const std::string& ) { - +void JingleFileTransferReceivedParser::handleCharacterData(const std::string &data) { + if (currentPayloadParser && level >= 1) { + currentPayloadParser->handleCharacterData(data); + } } } diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h b/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h index 824b06d..d5ed138 100644 --- a/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h +++ b/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h @@ -16,7 +16,7 @@ public: JingleFileTransferReceivedParser(); virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); - virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleEndElement(const std::string& element, const std::string& ns); virtual void handleCharacterData(const std::string& data); private: @@ -24,4 +24,4 @@ private: int level; }; -}
\ No newline at end of file +} diff --git a/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp index 8719a5d..95423c1 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp @@ -35,9 +35,9 @@ class JingleParserTest : public CppUnit::TestFixture { CPPUNIT_TEST(testParse_Xep0234_Example3); CPPUNIT_TEST(testParse_Xep0234_Example5); CPPUNIT_TEST(testParse_Xep0234_Example8); - CPPUNIT_TEST(testParse_Xep0234_Example10); - CPPUNIT_TEST(testParse_Xep0234_Example11); CPPUNIT_TEST(testParse_Xep0234_Example12); + CPPUNIT_TEST(testParse_Xep0234_Example13); + CPPUNIT_TEST(testParse_Xep0234_Example14); CPPUNIT_TEST(testParse_Xep0260_Example1); CPPUNIT_TEST(testParse_Xep0260_Example3); @@ -229,13 +229,13 @@ class JingleParserTest : public CppUnit::TestFixture { " <content creator='initiator' name='a-file-offer'>\n" " <description xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n" " <offer>\n" - " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" - " date='1969-07-21T02:56:15Z'\n" - " hash='552da749930852c69ae5d2141d3766b1'\n" - " name='test.txt'\n" - " size='1022'>\n" + " <file>\n" + " <date>1969-07-21T02:56:15Z</date>\n" " <desc>This is a test. If this were a real file...</desc>\n" + "............<name>test.txt</name>\n" " <range/>\n" + " <size>1022</size>\n" + " <hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>\n" " </file>\n" " </offer>\n" " </description>\n" @@ -271,7 +271,7 @@ class JingleParserTest : public CppUnit::TestFixture { JingleFileTransferDescription::ref description = contents[0]->getDescription<JingleFileTransferDescription>(); - std::vector<StreamInitiationFileInfo> offers = description->getOffers(); + std::vector<JingleFileTransferFileInfo> offers = description->getOffers(); CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), offers.size()); CPPUNIT_ASSERT_EQUAL(std::string("test.txt"), offers[0].getName()); CPPUNIT_ASSERT_EQUAL(std::string("552da749930852c69ae5d2141d3766b1"), offers[0].getHash()); @@ -279,7 +279,7 @@ class JingleParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(std::string("This is a test. If this were a real file..."), offers[0].getDescription()); CPPUNIT_ASSERT_EQUAL(true, offers[0].getSupportsRangeRequests()); CPPUNIT_ASSERT(stringToDateTime("1969-07-21T02:56:15Z") == offers[0].getDate()); - CPPUNIT_ASSERT_EQUAL(std::string("md5"), offers[0].getAlgo()); + CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), offers[0].getAlgo()); } // http://xmpp.org/extensions/xep-0234.html#example-3 @@ -293,14 +293,14 @@ class JingleParserTest : public CppUnit::TestFixture { " <content creator='initiator' name='a-file-offer'>\n" " <description xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n" " <offer>\n" - " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" - " name='test.txt'\n" - " size='1022'\n" - " hash='552da749930852c69ae5d2141d3766b1'\n" - " date='1969-07-21T02:56:15Z'>\n" - " <desc>This is a test. If this were a real file...</desc>\n" - " <range/>\n" - " </file>\n" + " <file>\n" + " <date>1969-07-21T02:56:15Z</date>\n" + " <desc>This is a test. If this were a real file...</desc>\n" + "............<name>test.txt</name>\n" + " <range/>\n" + " <size>1022</size>\n" + " <hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>\n" + " </file>\n" " </offer>\n" " </description>\n" " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n" @@ -341,7 +341,7 @@ class JingleParserTest : public CppUnit::TestFixture { JingleFileTransferDescription::ref description = contents[0]->getDescription<JingleFileTransferDescription>(); - std::vector<StreamInitiationFileInfo> offers = description->getOffers(); + std::vector<JingleFileTransferFileInfo> offers = description->getOffers(); CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), offers.size()); CPPUNIT_ASSERT_EQUAL(std::string("test.txt"), offers[0].getName()); CPPUNIT_ASSERT_EQUAL(std::string("552da749930852c69ae5d2141d3766b1"), offers[0].getHash()); @@ -349,7 +349,7 @@ class JingleParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(std::string("This is a test. If this were a real file..."), offers[0].getDescription()); CPPUNIT_ASSERT_EQUAL(true, offers[0].getSupportsRangeRequests()); CPPUNIT_ASSERT(stringToDateTime("1969-07-21T02:56:15Z") == offers[0].getDate()); - CPPUNIT_ASSERT_EQUAL(std::string("md5"), offers[0].getAlgo()); + CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), offers[0].getAlgo()); } // http://xmpp.org/extensions/xep-0234.html#example-5 @@ -395,9 +395,7 @@ class JingleParserTest : public CppUnit::TestFixture { " sid='a73sjjvkla37jfea'>\n" " <checksum xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n" " <file>\n" - " <hashes xmlns='urn:xmpp:hashes:0'>\n" - " <hash algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>\n" - " </hashes>\n" + " <hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>\n" " </file>\n" " </checksum>\n" "</jingle>\n" @@ -414,8 +412,8 @@ class JingleParserTest : public CppUnit::TestFixture { } - // http://xmpp.org/extensions/xep-0234.html#example-10 - void testParse_Xep0234_Example10() { + // http://xmpp.org/extensions/xep-0234.html#example-12 + void testParse_Xep0234_Example12() { PayloadsParserTester parser; CPPUNIT_ASSERT(parser.parse( "<jingle xmlns='urn:xmpp:jingle:1'\n" @@ -425,9 +423,9 @@ class JingleParserTest : public CppUnit::TestFixture { " <content creator='initiator' name='a-file-request'>\n" " <description xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n" " <request>\n" - " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" - " hash='552da749930852c69ae5d2141d3766b1'>\n" + " <file>\n" " <range offset='270336'/>\n" + " <hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>\n" " </file>\n" " </request>\n" " </description>\n" @@ -466,14 +464,14 @@ class JingleParserTest : public CppUnit::TestFixture { JingleContentPayload::ref content = jingle->getPayload<JingleContentPayload>(); CPPUNIT_ASSERT(content); - StreamInitiationFileInfo file = content->getDescription<JingleFileTransferDescription>()->getRequests()[0]; + JingleFileTransferFileInfo file = content->getDescription<JingleFileTransferDescription>()->getRequests()[0]; CPPUNIT_ASSERT_EQUAL(std::string("552da749930852c69ae5d2141d3766b1"), file.getHash()); CPPUNIT_ASSERT_EQUAL(static_cast<boost::uintmax_t>(270336), file.getRangeOffset()); CPPUNIT_ASSERT_EQUAL(true, file.getSupportsRangeRequests()); } - // http://xmpp.org/extensions/xep-0234.html#example-11 - void testParse_Xep0234_Example11() { + // http://xmpp.org/extensions/xep-0234.html#example-13 + void testParse_Xep0234_Example13() { PayloadsParserTester parser; CPPUNIT_ASSERT(parser.parse( "<jingle xmlns='urn:xmpp:jingle:1'\n" @@ -483,21 +481,24 @@ class JingleParserTest : public CppUnit::TestFixture { " <content creator='initiator' name='a-file-offer'>\n" " <description xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n" " <offer>\n" - " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" - " date='2011-06-01T15:58:15Z'\n" - " hash='a749930852c69ae5d2141d3766b1552d'\n" - " name='somefile.txt'\n" - " size='1234'/>\n" - " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" - " date='2011-06-01T15:58:15Z'\n" - " hash='930852c69ae5d2141d3766b1552da749'\n" - " name='anotherfile.txt'\n" - " size='2345'/>\n" - " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" - " date='2011-06-01T15:58:15Z'\n" - " hash='52c69ae5d2141d3766b1552da7499308'\n" - " name='yetanotherfile.txt'\n" - " size='3456'/>\n" + " <file>\n" + " <date>2011-06-01T15:58:15Z</date>\n" + " <name>somefile.txt</name>\n" + " <size>1234</size>\n" + " <hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>a749930852c69ae5d2141d3766b1552d</hash>\n" + " </file>\n" + " <file>\n" + " <date>2011-06-01T15:58:15Z</date>\n" + " <name>somefile.txt</name>\n" + " <size>2345</size>\n" + " <hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>a749930852c69ae5d2141d3766b1552d</hash>\n" + " </file>\n" + " <file>\n" + " <date>2011-06-01T15:58:15Z</date>\n" + " <name>yetanotherfile.txt</name>\n" + " <size>3456</size>\n" + " <hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>52c69ae5d2141d3766b1552da7499308</hash>\n" + " </file>\n" " </offer>\n" " </description>\n" " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n" @@ -531,12 +532,12 @@ class JingleParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(JingleContentPayload::InitiatorCreator, content->getCreator()); CPPUNIT_ASSERT_EQUAL(std::string("a-file-offer"), content->getName()); - std::vector<StreamInitiationFileInfo> offers = content->getDescription<JingleFileTransferDescription>()->getOffers(); + std::vector<JingleFileTransferFileInfo> offers = content->getDescription<JingleFileTransferDescription>()->getOffers(); CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), offers.size()); } - // http://xmpp.org/extensions/xep-0234.html#example-12 - void testParse_Xep0234_Example12() { + // http://xmpp.org/extensions/xep-0234.html#example-14 + void testParse_Xep0234_Example14() { PayloadsParserTester parser; CPPUNIT_ASSERT(parser.parse( "<jingle xmlns='urn:xmpp:jingle:1'\n" @@ -544,8 +545,9 @@ class JingleParserTest : public CppUnit::TestFixture { " initiator='romeo@montague.lit/orchard'\n" " sid='a73sjjvkla37jfea'>\n" " <received xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n" - " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n" - " hash='a749930852c69ae5d2141d3766b1552d'/>\n" + " <file>\n" + " <hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>a749930852c69ae5d2141d3766b1552d</hash>\n" + "....</file>" " </received>\n" "</jingle>\n" )); diff --git a/Swiften/Parser/SConscript b/Swiften/Parser/SConscript index 64e9eb9..ce3b1b7 100644 --- a/Swiften/Parser/SConscript +++ b/Swiften/Parser/SConscript @@ -38,6 +38,7 @@ sources = [ "PayloadParsers/JingleFileTransferDescriptionParser.cpp", "PayloadParsers/JingleFileTransferReceivedParser.cpp", "PayloadParsers/JingleFileTransferHashParser.cpp", + "PayloadParsers/JingleFileTransferFileInfoParser.cpp", "PayloadParsers/StreamInitiationFileInfoParser.cpp", "PayloadParsers/CommandParser.cpp", "PayloadParsers/InBandRegistrationPayloadParser.cpp", diff --git a/Swiften/SConscript b/Swiften/SConscript index db18cc3..b7a2af7 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -200,6 +200,7 @@ if env["SCONS_STAGE"] == "build" : "Serializer/PayloadSerializers/JingleFileTransferReceivedSerializer.cpp", "Serializer/PayloadSerializers/JingleIBBTransportPayloadSerializer.cpp", "Serializer/PayloadSerializers/JingleS5BTransportPayloadSerializer.cpp", + "Serializer/PayloadSerializers/JingleFileTransferFileInfoSerializer.cpp", "Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.cpp", "Serializer/PayloadSerializers/DeliveryReceiptSerializer.cpp", "Serializer/PayloadSerializers/DeliveryReceiptRequestSerializer.cpp", diff --git a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp index b4822cd..8946360 100644 --- a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp +++ b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp @@ -53,6 +53,7 @@ #include <Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h> #include <Swiften/Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/JingleFileTransferFileInfoSerializer.h> #include <Swiften/Serializer/PayloadSerializers/JingleContentPayloadSerializer.h> #include <Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.h> #include <Swiften/Serializer/PayloadSerializers/JingleFileTransferHashSerializer.h> @@ -112,6 +113,7 @@ FullPayloadSerializerCollection::FullPayloadSerializerCollection() { serializers_.push_back(new WhiteboardSerializer()); serializers_.push_back(new StreamInitiationFileInfoSerializer()); + serializers_.push_back(new JingleFileTransferFileInfoSerializer()); serializers_.push_back(new JingleContentPayloadSerializer()); serializers_.push_back(new JingleFileTransferDescriptionSerializer()); serializers_.push_back(new JingleFileTransferHashSerializer()); diff --git a/Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.cpp b/Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.cpp index 16337ff..1162a32 100644 --- a/Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/JingleFileTransferDescriptionSerializer.cpp @@ -14,7 +14,7 @@ #include <Swiften/Serializer/XML/XMLElement.h> #include <Swiften/Serializer/XML/XMLRawTextNode.h> -#include <Swiften/Serializer/PayloadSerializers/StreamInitiationFileInfoSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/JingleFileTransferFileInfoSerializer.h> namespace Swift { @@ -23,19 +23,19 @@ JingleFileTransferDescriptionSerializer::JingleFileTransferDescriptionSerializer std::string JingleFileTransferDescriptionSerializer::serializePayload(boost::shared_ptr<JingleFileTransferDescription> payload) const { XMLElement description("description", "urn:xmpp:jingle:apps:file-transfer:3"); - StreamInitiationFileInfoSerializer fileInfoSerializer; + JingleFileTransferFileInfoSerializer fileInfoSerializer; if (!payload->getOffers().empty()) { boost::shared_ptr<XMLElement> offers = boost::make_shared<XMLElement>("offer"); - foreach(const StreamInitiationFileInfo &fileInfo, payload->getOffers()) { - boost::shared_ptr<XMLRawTextNode> fileInfoXML = boost::make_shared<XMLRawTextNode>(fileInfoSerializer.serialize(boost::make_shared<StreamInitiationFileInfo>(fileInfo))); + foreach(const JingleFileTransferFileInfo &fileInfo, payload->getOffers()) { + boost::shared_ptr<XMLRawTextNode> fileInfoXML = boost::make_shared<XMLRawTextNode>(fileInfoSerializer.serialize(boost::make_shared<JingleFileTransferFileInfo>(fileInfo))); offers->addNode(fileInfoXML); } description.addNode(offers); } if (!payload->getRequests().empty()) { boost::shared_ptr<XMLElement> requests = boost::make_shared<XMLElement>("request"); - foreach(const StreamInitiationFileInfo &fileInfo, payload->getRequests()) { - boost::shared_ptr<XMLRawTextNode> fileInfoXML = boost::make_shared<XMLRawTextNode>(fileInfoSerializer.serialize(boost::make_shared<StreamInitiationFileInfo>(fileInfo))); + foreach(const JingleFileTransferFileInfo &fileInfo, payload->getRequests()) { + boost::shared_ptr<XMLRawTextNode> fileInfoXML = boost::make_shared<XMLRawTextNode>(fileInfoSerializer.serialize(boost::make_shared<JingleFileTransferFileInfo>(fileInfo))); requests->addNode(fileInfoXML); } description.addNode(requests); diff --git a/Swiften/Serializer/PayloadSerializers/JingleFileTransferFileInfoSerializer.cpp b/Swiften/Serializer/PayloadSerializers/JingleFileTransferFileInfoSerializer.cpp new file mode 100644 index 0000000..a13a40a --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleFileTransferFileInfoSerializer.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Serializer/PayloadSerializers/JingleFileTransferFileInfoSerializer.h> + +#include <boost/shared_ptr.hpp> +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/lexical_cast.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/DateTime.h> +#include <Swiften/Serializer/XML/XMLElement.h> +#include <Swiften/Serializer/XML/XMLRawTextNode.h> +#include <Swiften/Serializer/XML/XMLTextNode.h> + + + +namespace Swift { + +JingleFileTransferFileInfoSerializer::JingleFileTransferFileInfoSerializer() { +} + +std::string JingleFileTransferFileInfoSerializer::serializePayload(boost::shared_ptr<JingleFileTransferFileInfo> fileInfo) const { + XMLElement fileElement("file"); + + if (fileInfo->getDate() != stringToDateTime("")) { + boost::shared_ptr<XMLElement> date = boost::make_shared<XMLElement>("date", "", dateTimeToString(fileInfo->getDate())); + fileElement.addNode(date); + } + if (!fileInfo->getDescription().empty()) { + boost::shared_ptr<XMLElement> desc = boost::make_shared<XMLElement>("desc", "", fileInfo->getDescription()); + fileElement.addNode(desc); + } + if (!fileInfo->getName().empty()) { + boost::shared_ptr<XMLElement> name = boost::make_shared<XMLElement>("name", "", fileInfo->getName()); + fileElement.addNode(name); + } + if (fileInfo->getSupportsRangeRequests()) { + boost::shared_ptr<XMLElement> range = boost::make_shared<XMLElement>("range"); + if (fileInfo->getRangeOffset() != 0) { + range->setAttribute("offset", boost::lexical_cast<std::string>(fileInfo->getRangeOffset())); + } + fileElement.addNode(range); + } + if (fileInfo->getSize() != 0) { + boost::shared_ptr<XMLElement> size = boost::make_shared<XMLElement>("size", "", boost::lexical_cast<std::string>(fileInfo->getSize())); + fileElement.addNode(size); + } + if (!fileInfo->getHash().empty()) { + boost::shared_ptr<XMLElement> hash = boost::make_shared<XMLElement>("hash", "urn:xmpp:hashes:1", fileInfo->getHash()); + if (!fileInfo->getAlgo().empty()) { + hash->setAttribute("algo", fileInfo->getAlgo()); + } + fileElement.addNode(hash); + } + + return fileElement.serialize(); +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/JingleFileTransferFileInfoSerializer.h b/Swiften/Serializer/PayloadSerializers/JingleFileTransferFileInfoSerializer.h new file mode 100644 index 0000000..6f468d7 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/JingleFileTransferFileInfoSerializer.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Base/API.h> +#include <Swiften/Serializer/GenericPayloadSerializer.h> +#include <Swiften/Elements/JingleFileTransferFileInfo.h> + +#include <Swiften/Serializer/XML/XMLElement.h> + +namespace Swift { + class PayloadSerializerCollection; + + class SWIFTEN_API JingleFileTransferFileInfoSerializer : public GenericPayloadSerializer<JingleFileTransferFileInfo> { + public: + JingleFileTransferFileInfoSerializer(); + + virtual std::string serializePayload(boost::shared_ptr<JingleFileTransferFileInfo>) const; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp index e3ec8fc..10aa7e9 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp @@ -181,14 +181,13 @@ class JingleSerializersTest : public CppUnit::TestFixture { void testSerialize_Xep0234_Example1() { std::string expected = "<description xmlns=\"urn:xmpp:jingle:apps:file-transfer:3\">" "<offer>" - "<file" - " date=\"1969-07-21T02:56:15Z\"" - " hash=\"552da749930852c69ae5d2141d3766b1\"" - " name=\"test.txt\"" - " size=\"1022\"" - " xmlns=\"http://jabber.org/protocol/si/profile/file-transfer\">" + "<file>" + "<date>1969-07-21T02:56:15Z</date>" "<desc>This is a test. If this were a real file...</desc>" + "<name>test.txt</name>" "<range/>" + "<size>1022</size>" + "<hash algo=\"sha-1\" xmlns=\"urn:xmpp:hashes:1\">552da749930852c69ae5d2141d3766b1</hash>" "</file>" "</offer>" "</description>"; @@ -197,6 +196,7 @@ class JingleSerializersTest : public CppUnit::TestFixture { fileInfo.setDate(stringToDateTime("1969-07-21T02:56:15Z")); fileInfo.setHash("552da749930852c69ae5d2141d3766b1"); + fileInfo.setAlgo("sha-1"); fileInfo.setSize(1022); fileInfo.setName("test.txt"); fileInfo.setDescription("This is a test. If this were a real file..."); @@ -217,14 +217,13 @@ class JingleSerializersTest : public CppUnit::TestFixture { "<content creator=\"initiator\" name=\"a-file-offer\">" "<description xmlns=\"urn:xmpp:jingle:apps:file-transfer:3\">" "<offer>" - "<file" - " date=\"1969-07-21T02:56:15Z\"" - " hash=\"552da749930852c69ae5d2141d3766b1\"" - " name=\"test.txt\"" - " size=\"1022\"" - " xmlns=\"http://jabber.org/protocol/si/profile/file-transfer\">" + "<file>" + "<date>1969-07-21T02:56:15Z</date>" "<desc>This is a test. If this were a real file...</desc>" + "<name>test.txt</name>" "<range/>" + "<size>1022</size>" + "<hash algo=\"sha-1\" xmlns=\"urn:xmpp:hashes:1\">552da749930852c69ae5d2141d3766b1</hash>" "</file>" "</offer>" "</description>" @@ -266,6 +265,7 @@ class JingleSerializersTest : public CppUnit::TestFixture { StreamInitiationFileInfo fileInfo; fileInfo.setName("test.txt"); fileInfo.setSize(1022); + fileInfo.setAlgo("sha-1"); fileInfo.setHash("552da749930852c69ae5d2141d3766b1"); fileInfo.setDate(stringToDateTime("1969-07-21T02:56:15Z")); fileInfo.setDescription("This is a test. If this were a real file..."); @@ -350,10 +350,9 @@ class JingleSerializersTest : public CppUnit::TestFixture { "<description" " xmlns=\"urn:xmpp:jingle:apps:file-transfer:3\">" "<request>" - "<file" - " hash=\"552da749930852c69ae5d2141d3766b1\"" - " xmlns=\"http://jabber.org/protocol/si/profile/file-transfer\">" + "<file>" "<range offset=\"270336\"/>" + "<hash algo=\"sha-1\" xmlns=\"urn:xmpp:hashes:1\">552da749930852c69ae5d2141d3766b1</hash>" "</file>" "</request>" "</description>" @@ -393,6 +392,7 @@ class JingleSerializersTest : public CppUnit::TestFixture { StreamInitiationFileInfo fileInfo; fileInfo.setHash("552da749930852c69ae5d2141d3766b1"); + fileInfo.setAlgo("sha-1"); fileInfo.setRangeOffset(270336); JingleFileTransferDescription::ref desc = boost::make_shared<JingleFileTransferDescription>(); |