diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2acdde1ab..924e17009 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -101,7 +101,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 @@ -229,7 +231,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 67859c75e..5bb264db6 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; }; // ----------------------------------------------------------------------------- @@ -55,7 +53,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('/'); @@ -87,7 +85,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)) @@ -98,7 +96,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)) @@ -110,7 +108,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)) @@ -124,6 +122,7 @@ ContentType &ContentType::operator= (const ContentType &other) { if (this != &other) { setType(other.getType()); setSubType(other.getSubType()); + cleanParameters(); addParameters(other.getParameters()); } @@ -168,56 +167,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 ad7b051cc..d77c15e82 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..0c8017e60 --- /dev/null +++ b/src/content/header/header.cpp @@ -0,0 +1,93 @@ +/* + * 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) { + +} + +void Header::cleanParameters() { + L_D(); + d->parameters.clear(); +} + +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..822839516 --- /dev/null +++ b/src/content/header/header.h @@ -0,0 +1,55 @@ +/* + * 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: + void cleanParameters(); + 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_ 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 b16e306bd..c94dc9a2e 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); } @@ -82,7 +82,20 @@ 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 || 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); linphone_core_manager_destroy(pauline);