From fa9b881e10e7cab8495909818cc61519d24d6117 Mon Sep 17 00:00:00 2001 From: dknn Date: Sat, 2 Jun 2012 17:31:42 +0200 Subject: Payload, serializer and parser for the "payload-type" XML node diff --git a/Swiften/Elements/RTPPayloadType.h b/Swiften/Elements/RTPPayloadType.h new file mode 100644 index 0000000..e61f921 --- /dev/null +++ b/Swiften/Elements/RTPPayloadType.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include +#include +#include + +#include +#include + +namespace Swift { + +class RTPPayloadType : public Payload { +public: + typedef boost::shared_ptr ref; + typedef std::map ParameterMap; + +public: + RTPPayloadType(boost::uint8_t id = 0, const std::string& name = "", boost::uint32_t clockrate = 0, + boost::uint8_t channels = 1, boost::uint32_t ptime = 0, boost::uint32_t maxptime = 0) : + m_id(id), m_name(name), m_clockrate(clockrate), m_channels(channels), m_ptime(ptime), m_maxptime(maxptime) {} + + void setChannels(boost::uint32_t channels) { m_channels = channels; } + boost::uint32_t getChannels() const { return m_channels; } + + void setClockrate(boost::uint32_t clockrate) { m_clockrate = clockrate; } + boost::uint32_t getClockrate() const { return m_clockrate; } + + void setID(boost::uint8_t id) { m_id = id; } + boost::uint8_t getID() const { return m_id; } + + void setMaxptime(boost::uint32_t maxptime) { m_maxptime = maxptime; } + boost::uint32_t getMaxptime() const { return m_maxptime; } + + void setName(const std::string& name) { m_name = name; } + const std::string& getName() const { return m_name; } + + void setPTime(boost::uint32_t ptime) { m_ptime = ptime; } + boost::uint32_t getPTime() const { return m_ptime; } + + bool addParameter(const std::string& name, const std::string& value) { + return parameters.insert(std::make_pair(name, value)).second; + } + + const ParameterMap& getParameters() const { return parameters; } + +private: + boost::uint8_t m_id; + std::string m_name; + boost::uint32_t m_clockrate; + boost::uint8_t m_channels; + boost::uint32_t m_ptime; + boost::uint32_t m_maxptime; + ParameterMap parameters; +}; + +} diff --git a/Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.cpp b/Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.cpp new file mode 100644 index 0000000..bddf96a --- /dev/null +++ b/Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "RTPPayloadTypeParser.h" + +#include +#include + +//#include +//#include + +namespace Swift { + +RTPPayloadTypeParser::RTPPayloadTypeParser() : level(0) { + +} + +void RTPPayloadTypeParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) { + if (level == 0) { + // channel + try { + getPayloadInternal()->setChannels(boost::lexical_cast(attributes.getAttributeValue("channels").get_value_or("1"))); + } catch (boost::bad_lexical_cast &) { + getPayloadInternal()->setChannels(1); + } + // clockrate + try { + getPayloadInternal()->setClockrate(boost::lexical_cast(attributes.getAttributeValue("clockrate").get_value_or("0"))); + } catch (boost::bad_lexical_cast &) { + getPayloadInternal()->setClockrate(0); + } + // ID + try { + getPayloadInternal()->setID(boost::lexical_cast(attributes.getAttributeValue("id").get_value_or("0"))); + } catch (boost::bad_lexical_cast &) { + getPayloadInternal()->setID(0); + } + // maxptime + try { + getPayloadInternal()->setMaxptime(boost::lexical_cast(attributes.getAttributeValue("maxptime").get_value_or("0"))); + } catch (boost::bad_lexical_cast &) { + getPayloadInternal()->setMaxptime(0); + } + // name + getPayloadInternal()->setName(attributes.getAttributeValue("name").get_value_or("")); + // ptime + try { + getPayloadInternal()->setPTime(boost::lexical_cast(attributes.getAttributeValue("ptime").get_value_or("0"))); + } catch (boost::bad_lexical_cast &) { + getPayloadInternal()->setPTime(0); + } + } else if (level == 1) { + getPayloadInternal()->addParameter(attributes.getAttributeValue("name").get_value_or(""), + attributes.getAttributeValue("value").get_value_or("")); + } + ++level; +} + +void RTPPayloadTypeParser::handleEndElement(const std::string& element, const std::string&) { + --level; +} + +} diff --git a/Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.h b/Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.h new file mode 100644 index 0000000..360053f --- /dev/null +++ b/Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include +#include + +namespace Swift { + +class RTPPayloadTypeParser : public GenericPayloadParser { + public: + RTPPayloadTypeParser(); + + 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&) {}; + + private: + int level; +}; + +} diff --git a/Swiften/SConscript b/Swiften/SConscript index db18cc3..53ce39f 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -204,6 +204,7 @@ if env["SCONS_STAGE"] == "build" : "Serializer/PayloadSerializers/DeliveryReceiptSerializer.cpp", "Serializer/PayloadSerializers/DeliveryReceiptRequestSerializer.cpp", "Serializer/PayloadSerializers/WhiteboardSerializer.cpp", + "Serializer/PayloadSerializers/RTPPayloadTypeSerializer.cpp", "Serializer/PresenceSerializer.cpp", "Serializer/StanzaSerializer.cpp", "Serializer/StreamErrorSerializer.cpp", diff --git a/Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.cpp b/Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.cpp new file mode 100644 index 0000000..db21146 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include + +#include +#include +#include + +#include + + + +namespace Swift { + +RTPPayloadTypeSerializer::RTPPayloadTypeSerializer() { +} + +std::string RTPPayloadTypeSerializer::serializePayload(boost::shared_ptr payloadType) const { + XMLElement payloadTypeElement("payload-type"); + + if (payloadType->getChannels() != 1) { + payloadTypeElement.setAttribute("channels", boost::lexical_cast(payloadType->getChannels())); + } + if (payloadType->getClockrate() != 0) { + payloadTypeElement.setAttribute("clockrate", boost::lexical_cast(payloadType->getClockrate())); + } + payloadTypeElement.setAttribute("id", boost::lexical_cast(static_cast(payloadType->getID()))); + if (payloadType->getMaxptime() != 0) { + payloadTypeElement.setAttribute("maxptime", boost::lexical_cast(payloadType->getMaxptime())); + } + if (!payloadType->getName().empty()) { + payloadTypeElement.setAttribute("name", payloadType->getName()); + } + if (payloadType->getPTime() != 0) { + payloadTypeElement.setAttribute("ptime", boost::lexical_cast( payloadType->getPTime())); + } + + const RTPPayloadType::ParameterMap ¶meters = payloadType->getParameters(); + RTPPayloadType::ParameterMap::const_iterator it; + for (it = parameters.begin(); it != parameters.end(); ++it) { + boost::shared_ptr parameterElement = boost::make_shared("parameter"); + parameterElement->setAttribute("name", it->first); + parameterElement->setAttribute("value", it->second); + payloadTypeElement.addNode(parameterElement); + } + + return payloadTypeElement.serialize(); +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.h b/Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.h new file mode 100644 index 0000000..dda40ea --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/RTPPayloadTypeSerializer.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include +#include + +#include + +namespace Swift { + class PayloadSerializerCollection; // NEEDED ? + + class RTPPayloadTypeSerializer : public GenericPayloadSerializer { + public: + RTPPayloadTypeSerializer(); + + virtual std::string serializePayload(boost::shared_ptr) const; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp index e3ec8fc..a1526fc 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/JingleSerializersTest.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,12 +22,14 @@ #include #include #include +#include #include using namespace Swift; class JingleSerializersTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(JingleSerializersTest); + CPPUNIT_TEST(testSerialize_StreamInitiationFileInfo); CPPUNIT_TEST(testSerialize_StreamInitiationFileInfoRange); @@ -43,6 +46,9 @@ class JingleSerializersTest : public CppUnit::TestFixture { CPPUNIT_TEST(testSerialize_Xep0260_Example1); + CPPUNIT_TEST(testSerialize_RTPPayloadType_Simple); + CPPUNIT_TEST(testSerialize_RTPPayloadType_WithSub); + CPPUNIT_TEST_SUITE_END(); boost::shared_ptr createTestling() { @@ -504,6 +510,39 @@ class JingleSerializersTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(expected, createTestling()->serialize(payload)); } + void testSerialize_RTPPayloadType_Simple() { + std::string expected = ""; + + RTPPayloadType::ref payloadType = boost::make_shared(96); + payloadType->setName("speex"); + payloadType->setClockrate(16000); + + boost::shared_ptr serializer = boost::make_shared(); + CPPUNIT_ASSERT_EQUAL(expected, serializer->serializePayload(payloadType)); + } + + void testSerialize_RTPPayloadType_WithSub() { + std::string expected = "" + "" + "" + "" + "" + "" + ""; + + RTPPayloadType::ref payloadType = boost::make_shared(98); + payloadType->setName("theora"); + payloadType->setClockrate(90000); + payloadType->addParameter("height", "600"); + payloadType->addParameter("width", "800"); + payloadType->addParameter("delivery-method", "inline"); + payloadType->addParameter("configuration", "somebase16string"); + payloadType->addParameter("sampling", "YCbCr-4:2:2"); + + boost::shared_ptr serializer = boost::make_shared(); + CPPUNIT_ASSERT_EQUAL(expected, serializer->serializePayload(payloadType)); + } + private: FullPayloadSerializerCollection collection; }; -- cgit v0.10.2-6-g49f6