From 3a0bcc675a2ad5ef205297cfb3a79a943cb339c6 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Fri, 16 Mar 2018 16:55:51 +0100 Subject: [PATCH] Some more improvements to Content-Type and Content-Disposition handling. --- include/linphone/utils/utils.h | 2 ++ src/content/content-disposition.cpp | 31 ++++++++++++++++++++++++----- src/content/content-disposition.h | 4 ++++ src/content/content-type.cpp | 8 ++++---- src/utils/utils.cpp | 6 ++++++ 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/include/linphone/utils/utils.h b/include/linphone/utils/utils.h index 7200ec935..e13c89889 100644 --- a/include/linphone/utils/utils.h +++ b/include/linphone/utils/utils.h @@ -107,6 +107,8 @@ namespace Utils { return str ? str : ""; } + LINPHONE_PUBLIC std::string trim (const std::string &str); + template LINPHONE_PUBLIC const T &getEmptyConstRefObject () { static const T object; diff --git a/src/content/content-disposition.cpp b/src/content/content-disposition.cpp index f8dc53ce4..ccaf7da15 100644 --- a/src/content/content-disposition.cpp +++ b/src/content/content-disposition.cpp @@ -33,33 +33,40 @@ LINPHONE_BEGIN_NAMESPACE class ContentDispositionPrivate : public ClonableObjectPrivate { public: string disposition; + string parameter; }; // ----------------------------------------------------------------------------- const ContentDisposition ContentDisposition::RecipientList("recipient-list"); +const ContentDisposition ContentDisposition::RecipientListHistory("recipient-list-history; handling=optional"); // ----------------------------------------------------------------------------- ContentDisposition::ContentDisposition (const string &disposition) : ClonableObject(*new ContentDispositionPrivate) { L_D(); - d->disposition = disposition; + size_t posParam = disposition.find(";"); + d->disposition = Utils::trim(disposition.substr(0, posParam)); + if (posParam != string::npos) + setParameter(Utils::trim(disposition.substr(posParam + 1))); } ContentDisposition::ContentDisposition (const ContentDisposition &other) - : ContentDisposition(other.getPrivate()->disposition) {} + : ContentDisposition(other.asString()) {} ContentDisposition &ContentDisposition::operator= (const ContentDisposition &other) { L_D(); if (this != &other) { d->disposition = other.getPrivate()->disposition; + setParameter(other.getParameter()); } return *this; } bool ContentDisposition::operator== (const ContentDisposition &other) const { L_D(); - return d->disposition == other.getPrivate()->disposition; + return d->disposition == other.getPrivate()->disposition + && getParameter() == other.getParameter(); } bool ContentDisposition::operator!= (const ContentDisposition &other) const { @@ -76,10 +83,24 @@ bool ContentDisposition::isValid () const { return !d->disposition.empty(); } +const string &ContentDisposition::getParameter () const { + L_D(); + return d->parameter; +} + +void ContentDisposition::setParameter (const string ¶meter) { + L_D(); + d->parameter = parameter; +} + string ContentDisposition::asString () const { L_D(); - if (isValid()) - return d->disposition; + if (isValid()) { + string asString = d->disposition; + if (!d->parameter.empty()) + asString += ";" + d->parameter; + return asString; + } return ""; } diff --git a/src/content/content-disposition.h b/src/content/content-disposition.h index c9668d379..6f2fcc9ca 100644 --- a/src/content/content-disposition.h +++ b/src/content/content-disposition.h @@ -46,9 +46,13 @@ public: bool isEmpty () const; bool isValid () const; + const std::string &getParameter () const; + void setParameter (const std::string ¶meter); + std::string asString () const; static const ContentDisposition RecipientList; + static const ContentDisposition RecipientListHistory; private: L_DECLARE_PRIVATE(ContentDisposition); diff --git a/src/content/content-type.cpp b/src/content/content-type.cpp index 97a0ad488..78c356af6 100644 --- a/src/content/content-type.cpp +++ b/src/content/content-type.cpp @@ -56,20 +56,20 @@ ContentType::ContentType (const string &contentType) : ClonableObject(*new Conte L_D(); size_t pos = contentType.find('/'); - size_t posParam = contentType.find("; "); + size_t posParam = contentType.find(";"); size_t end = contentType.length(); if (pos == string::npos) return; - if (setType(contentType.substr(0, pos))) { + if (setType(Utils::trim(contentType.substr(0, pos)))) { if (posParam != string::npos) end = posParam; - if (!setSubType(contentType.substr(pos + 1, end - (pos + 1)))) + if (!setSubType(Utils::trim(contentType.substr(pos + 1, end - (pos + 1))))) d->type.clear(); } if (posParam != string::npos) - setParameter(contentType.substr(posParam + 2)); // We remove the blankspace after the ;. + setParameter(Utils::trim(contentType.substr(posParam + 1))); } ContentType::ContentType (const string &type, const string &subType) : ClonableObject(*new ContentTypePrivate) { diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index c9d1b8442..eb5ba94d2 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -175,6 +175,12 @@ char *Utils::utf8ToChar (uint32_t ic) { return result; } +string Utils::trim (const string &str) { + auto itFront = find_if_not(str.begin(), str.end(), [] (int c) { return isspace(c); }); + auto itBack = find_if_not(str.rbegin(), str.rend(), [] (int c) { return isspace(c); }).base(); + return (itBack <= itFront ? string() : string(itFront, itBack)); +} + // ----------------------------------------------------------------------------- tm Utils::getTimeTAsTm (time_t time) {