From 49b93c6f9a70fc52ce0bba389e63ff74dcd46cd6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 23 Mar 2018 15:20:48 +0100 Subject: [PATCH 1/3] Created Header class as parent of ContentType --- src/CMakeLists.txt | 7 +- src/c-wrapper/api/c-content.cpp | 2 +- src/chat/chat-message/chat-message.cpp | 2 +- src/content/content-type.cpp | 66 ++--------------- src/content/content-type.h | 14 +--- src/content/header/header-p.h | 41 +++++++++++ src/content/{ => header}/header-param.cpp | 0 src/content/{ => header}/header-param.h | 0 src/content/header/header.cpp | 88 +++++++++++++++++++++++ src/content/header/header.h | 54 ++++++++++++++ 10 files changed, 199 insertions(+), 75 deletions(-) create mode 100644 src/content/header/header-p.h rename src/content/{ => header}/header-param.cpp (100%) rename src/content/{ => header}/header-param.h (100%) create mode 100644 src/content/header/header.cpp create mode 100644 src/content/header/header.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 66d42b91e..b7c47abf8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -99,7 +99,9 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES content/content.h content/file-content.h content/file-transfer-content.h - content/header-param.h + content/header/header.h + content/header/header-p.h + content/header/header-param.h core/core-accessor.h core/core-listener.h core/core-p.h @@ -224,7 +226,8 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES content/content.cpp content/file-content.cpp content/file-transfer-content.cpp - content/header-param.cpp + content/header/header.cpp + content/header/header-param.cpp core/core-accessor.cpp core/core-call.cpp core/core-chat-room.cpp diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index 6d6bdde34..2b68cbbde 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -24,7 +24,7 @@ #include "content/content.h" #include "content/content-type.h" -#include "content/header-param.h" +#include "content/header/header-param.h" #include "content/content-manager.h" #include "content/file-content.h" #include "content/file-transfer-content.h" diff --git a/src/chat/chat-message/chat-message.cpp b/src/chat/chat-message/chat-message.cpp index ff2a595e7..407a9e734 100644 --- a/src/chat/chat-message/chat-message.cpp +++ b/src/chat/chat-message/chat-message.cpp @@ -36,7 +36,7 @@ #include "chat/modifier/file-transfer-chat-message-modifier.h" #include "chat/modifier/multipart-chat-message-modifier.h" #include "content/file-content.h" -#include "content/header-param.h" +#include "content/header/header-param.h" #include "content/content.h" #include "core/core.h" #include "core/core-p.h" diff --git a/src/content/content-type.cpp b/src/content/content-type.cpp index 4af2f2195..be3b7da00 100644 --- a/src/content/content-type.cpp +++ b/src/content/content-type.cpp @@ -18,11 +18,10 @@ */ #include "linphone/utils/utils.h" -#include "linphone/utils/algorithm.h" #include "content-type.h" -#include "header-param.h" -#include "object/clonable-object-p.h" +#include "header/header-p.h" +#include "header/header-param.h" // ============================================================================= @@ -32,11 +31,10 @@ LINPHONE_BEGIN_NAMESPACE // ----------------------------------------------------------------------------- -class ContentTypePrivate : public ClonableObjectPrivate { +class ContentTypePrivate : public HeaderPrivate { public: string type; string subType; - std::list parameters; }; // ----------------------------------------------------------------------------- @@ -54,7 +52,7 @@ const ContentType ContentType::Sdp("application/sdp"); // ----------------------------------------------------------------------------- -ContentType::ContentType (const string &contentType) : ClonableObject(*new ContentTypePrivate) { +ContentType::ContentType (const string &contentType) : Header(*new ContentTypePrivate) { L_D(); size_t pos = contentType.find('/'); @@ -86,7 +84,7 @@ ContentType::ContentType (const string &contentType) : ClonableObject(*new Conte } } -ContentType::ContentType (const string &type, const string &subType) : ClonableObject(*new ContentTypePrivate) { +ContentType::ContentType (const string &type, const string &subType) : Header(*new ContentTypePrivate) { L_D(); if (setType(type) && !setSubType(subType)) @@ -97,7 +95,7 @@ ContentType::ContentType ( const string &type, const string &subType, const HeaderParam ¶meter -) : ClonableObject(*new ContentTypePrivate) { +) : Header(*new ContentTypePrivate) { L_D(); if (setType(type) && !setSubType(subType)) @@ -109,7 +107,7 @@ ContentType::ContentType ( const string &type, const string &subType, const std::list ¶meters -) : ClonableObject(*new ContentTypePrivate) { +) : Header(*new ContentTypePrivate) { L_D(); if (setType(type) && !setSubType(subType)) @@ -167,56 +165,6 @@ bool ContentType::setSubType (const string &subType) { return false; } -const std::list &ContentType::getParameters () const { - L_D(); - - return d->parameters; -} - -void ContentType::addParameter (const std::string ¶mName, const std::string ¶mValue) { - addParameter(HeaderParam(paramName, paramValue)); -} - -void ContentType::addParameter (const HeaderParam ¶m) { - L_D(); - removeParameter(param); - d->parameters.push_back(param); -} - -void ContentType::addParameters(const std::list ¶ms) { - for (auto it = std::begin(params); it!=std::end(params); ++it) { - HeaderParam param = *it; - addParameter(param.getName(), param.getValue()); - } -} - -void ContentType::removeParameter (const std::string ¶mName) { - L_D(); - auto it = findParameter(paramName); - if (it != d->parameters.cend()) - d->parameters.remove(*it); -} - -void ContentType::removeParameter (const HeaderParam ¶m) { - removeParameter(param.getName()); -} - -std::list::const_iterator ContentType::findParameter (const std::string ¶mName) const { - L_D(); - return findIf(d->parameters, [¶mName](const HeaderParam ¶m) { - return param.getName() == paramName; - }); -} - -const HeaderParam &ContentType::getParameter (const std::string ¶mName) const { - L_D(); - std::list::const_iterator it = findParameter(paramName); - if (it != d->parameters.cend()) { - return *it; - } - return Utils::getEmptyConstRefObject(); -} - bool ContentType::isEmpty () const { L_D(); return d->type.empty() && d->subType.empty(); diff --git a/src/content/content-type.h b/src/content/content-type.h index 3b155e4cd..2ed267065 100644 --- a/src/content/content-type.h +++ b/src/content/content-type.h @@ -20,9 +20,8 @@ #ifndef _L_CONTENT_TYPE_H_ #define _L_CONTENT_TYPE_H_ -#include - #include "object/clonable-object.h" +#include "header/header.h" // ============================================================================= @@ -31,7 +30,7 @@ LINPHONE_BEGIN_NAMESPACE class ContentTypePrivate; class HeaderParam; -class LINPHONE_PUBLIC ContentType : public ClonableObject { +class LINPHONE_PUBLIC ContentType : public Header { public: explicit ContentType (const std::string &contentType = ""); ContentType (const std::string &type, const std::string &subType); @@ -59,15 +58,6 @@ public: const std::string &getSubType () const; bool setSubType (const std::string &subType); - const std::list &getParameters () const; - void addParameter (const std::string ¶mName, const std::string ¶mValue); - void addParameter (const HeaderParam ¶m); - void addParameters(const std::list ¶ms); - void removeParameter (const std::string ¶mName); - void removeParameter (const HeaderParam ¶m); - std::list::const_iterator findParameter (const std::string ¶mName) const; - const HeaderParam &getParameter (const std::string ¶mName) const; - std::string asString () const; bool isMultipart() const; diff --git a/src/content/header/header-p.h b/src/content/header/header-p.h new file mode 100644 index 000000000..3af1e3688 --- /dev/null +++ b/src/content/header/header-p.h @@ -0,0 +1,41 @@ +/* + * header-p.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_HEADER_P_H_ +#define _L_HEADER_P_H_ + +#include + +#include "object/clonable-object-p.h" + +#include "header.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class HeaderPrivate : public ClonableObjectPrivate { +private: + std::list parameters; + L_DECLARE_PUBLIC(Header); +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _L_HEADER_P_H_ \ No newline at end of file diff --git a/src/content/header-param.cpp b/src/content/header/header-param.cpp similarity index 100% rename from src/content/header-param.cpp rename to src/content/header/header-param.cpp diff --git a/src/content/header-param.h b/src/content/header/header-param.h similarity index 100% rename from src/content/header-param.h rename to src/content/header/header-param.h diff --git a/src/content/header/header.cpp b/src/content/header/header.cpp new file mode 100644 index 000000000..a621a2e8b --- /dev/null +++ b/src/content/header/header.cpp @@ -0,0 +1,88 @@ +/* + * header.cpp + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "linphone/utils/utils.h" +#include "linphone/utils/algorithm.h" + +#include "header-p.h" +#include "header-param.h" + +// ============================================================================= + +using namespace std; + +LINPHONE_BEGIN_NAMESPACE + +// ----------------------------------------------------------------------------- + +Header::Header(HeaderPrivate &p) : ClonableObject(p) { + +} + +const std::list &Header::getParameters () const { + L_D(); + + return d->parameters; +} + +void Header::addParameter (const std::string ¶mName, const std::string ¶mValue) { + addParameter(HeaderParam(paramName, paramValue)); +} + +void Header::addParameter (const HeaderParam ¶m) { + L_D(); + removeParameter(param); + d->parameters.push_back(param); +} + +void Header::addParameters(const std::list ¶ms) { + for (auto it = std::begin(params); it!=std::end(params); ++it) { + HeaderParam param = *it; + addParameter(param.getName(), param.getValue()); + } +} + +void Header::removeParameter (const std::string ¶mName) { + L_D(); + auto it = findParameter(paramName); + if (it != d->parameters.cend()) + d->parameters.remove(*it); +} + +void Header::removeParameter (const HeaderParam ¶m) { + removeParameter(param.getName()); +} + +std::list::const_iterator Header::findParameter (const std::string ¶mName) const { + L_D(); + return findIf(d->parameters, [¶mName](const HeaderParam ¶m) { + return param.getName() == paramName; + }); +} + +const HeaderParam &Header::getParameter (const std::string ¶mName) const { + L_D(); + std::list::const_iterator it = findParameter(paramName); + if (it != d->parameters.cend()) { + return *it; + } + return Utils::getEmptyConstRefObject(); +} + +LINPHONE_END_NAMESPACE \ No newline at end of file diff --git a/src/content/header/header.h b/src/content/header/header.h new file mode 100644 index 000000000..9fb3dab47 --- /dev/null +++ b/src/content/header/header.h @@ -0,0 +1,54 @@ +/* + * header.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_HEADER_H_ +#define _L_HEADER_H_ + +#include + +#include "object/clonable-object.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class HeaderPrivate; +class HeaderParam; + +class LINPHONE_PUBLIC Header : public ClonableObject { +public: + const std::list &getParameters () const; + void addParameter (const std::string ¶mName, const std::string ¶mValue); + void addParameter (const HeaderParam ¶m); + void addParameters(const std::list ¶ms); + void removeParameter (const std::string ¶mName); + void removeParameter (const HeaderParam ¶m); + std::list::const_iterator findParameter (const std::string ¶mName) const; + const HeaderParam &getParameter (const std::string ¶mName) const; + +protected: + explicit Header (HeaderPrivate &p); + +private: + L_DECLARE_PRIVATE(Header); +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _L_HEADER_H_ From c0a7c027a6c54fd79b73ae0fda288f643fc38aef Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 23 Mar 2018 17:56:09 +0100 Subject: [PATCH 2/3] Improved multipart tester --- tester/multipart-tester.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tester/multipart-tester.cpp b/tester/multipart-tester.cpp index b16e306bd..d3b9f21b5 100644 --- a/tester/multipart-tester.cpp +++ b/tester/multipart-tester.cpp @@ -58,7 +58,7 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool } else { Content *content = new Content(); content->setContentType(ContentType::PlainText); - content->setBody("Hello Part 1"); + content->setBody("Hello part 1"); marieMessage->addContent(content); } @@ -73,7 +73,7 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool } else { Content *content = new Content(); content->setContentType(ContentType::PlainText); - content->setBody("Hello Part 2"); + content->setBody("Hello part 2"); marieMessage->addContent(content); } @@ -83,6 +83,9 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageReceived,1)); BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(pauline->stat.last_received_chat_message), "multipart/mixed"); + if (!first_file_transfer) { + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), "Hello part 1"); + } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); From 8f2be0252a03c9fc8361d3221e94f6c5325163dd Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 26 Mar 2018 10:57:08 +0200 Subject: [PATCH 3/3] Fixed 2 issues related to content type parameters : one in = operator, one in the Sal --- src/content/content-type.cpp | 1 + src/content/header/header.cpp | 5 +++++ src/content/header/header.h | 1 + src/sal/op.cpp | 8 +++++++- tester/multipart-tester.cpp | 16 +++++++++++++--- 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/content/content-type.cpp b/src/content/content-type.cpp index be3b7da00..e34241a40 100644 --- a/src/content/content-type.cpp +++ b/src/content/content-type.cpp @@ -121,6 +121,7 @@ ContentType &ContentType::operator= (const ContentType &other) { if (this != &other) { setType(other.getType()); setSubType(other.getSubType()); + cleanParameters(); addParameters(other.getParameters()); } diff --git a/src/content/header/header.cpp b/src/content/header/header.cpp index a621a2e8b..0c8017e60 100644 --- a/src/content/header/header.cpp +++ b/src/content/header/header.cpp @@ -35,6 +35,11 @@ Header::Header(HeaderPrivate &p) : ClonableObject(p) { } +void Header::cleanParameters() { + L_D(); + d->parameters.clear(); +} + const std::list &Header::getParameters () const { L_D(); diff --git a/src/content/header/header.h b/src/content/header/header.h index 9fb3dab47..822839516 100644 --- a/src/content/header/header.h +++ b/src/content/header/header.h @@ -33,6 +33,7 @@ class HeaderParam; class LINPHONE_PUBLIC Header : public ClonableObject { public: + void cleanParameters(); const std::list &getParameters () const; void addParameter (const std::string ¶mName, const std::string ¶mValue); void addParameter (const HeaderParam ¶m); diff --git a/src/sal/op.cpp b/src/sal/op.cpp index e5e211f3b..497a7a99b 100644 --- a/src/sal/op.cpp +++ b/src/sal/op.cpp @@ -1029,12 +1029,18 @@ void SalOp::process_incoming_message(const belle_sip_request_event_t *event) { /* if we just deciphered a message, use the deciphered part(which can be a rcs xml body pointing to the file to retreive from server)*/ salmsg.text=(!external_body)?belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)):NULL; salmsg.url=NULL; - salmsg.content_type = ms_strdup_printf("%s/%s", belle_sip_header_content_type_get_type(content_type), belle_sip_header_content_type_get_subtype(content_type)); + + char buffer[1024]; + size_t offset = 0; + belle_sip_parameters_marshal(BELLE_SIP_PARAMETERS(content_type), buffer, 1024, &offset); + buffer[offset] = '\0'; + salmsg.content_type = ms_strdup_printf("%s/%s%s", belle_sip_header_content_type_get_type(content_type), belle_sip_header_content_type_get_subtype(content_type), buffer); if (external_body && belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")) { size_t url_length=strlen(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")); salmsg.url = ms_strdup(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")+1); /* skip first "*/ ((char*)salmsg.url)[url_length-2]='\0'; /*remove trailing "*/ } + salmsg.message_id=message_id; salmsg.time=date ? belle_sip_header_date_get_time(date) : time(NULL); this->root->callbacks.message_received(this,&salmsg); diff --git a/tester/multipart-tester.cpp b/tester/multipart-tester.cpp index d3b9f21b5..c94dc9a2e 100644 --- a/tester/multipart-tester.cpp +++ b/tester/multipart-tester.cpp @@ -82,9 +82,19 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageReceived,1)); BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(pauline->stat.last_received_chat_message), "multipart/mixed"); - if (!first_file_transfer) { - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), "Hello part 1"); + + if (first_file_transfer || second_file_transfer) { + LinphoneContent *content = linphone_chat_message_get_file_transfer_information(pauline->stat.last_received_chat_message); + BC_ASSERT_PTR_NOT_NULL(content); + linphone_content_unref(content); + } + if (!first_file_transfer || !second_file_transfer) { + const char *content = linphone_chat_message_get_text_content(pauline->stat.last_received_chat_message); + BC_ASSERT_PTR_NOT_NULL(content); + if (!first_file_transfer) + BC_ASSERT_STRING_EQUAL(content, "Hello part 1"); + else if (!second_file_transfer) + BC_ASSERT_STRING_EQUAL(content, "Hello part 2"); } linphone_core_manager_destroy(marie);