Use Header class instead of pair<string, string> in Content + improved tester

This commit is contained in:
Sylvain Berfini 2018-03-27 11:48:40 +02:00
parent 2081f71c78
commit 813ab614eb
13 changed files with 140 additions and 33 deletions

View file

@ -446,3 +446,7 @@ const char * sal_body_handler_get_header(const SalBodyHandler *body_handler, con
}
return NULL;
}
const belle_sip_list_t* sal_body_handler_get_headers(const SalBodyHandler *body_handler) {
return belle_sip_body_handler_get_headers(BELLE_SIP_BODY_HANDLER(body_handler));
}

View file

@ -25,6 +25,7 @@
#include "content/content.h"
#include "content/content-type.h"
#include "content/header/header-param.h"
#include "content/header/header.h"
#include "content/content-manager.h"
#include "content/file-content.h"
#include "content/file-transfer-content.h"
@ -259,6 +260,13 @@ static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler *
belle_sip_free(body);
}
belle_sip_list_t *headers = (belle_sip_list_t *)sal_body_handler_get_headers(body_handler);
while (headers) {
belle_sip_header_t *cHeader = BELLE_SIP_HEADER(headers->data);
LinphonePrivate::Header header = LinphonePrivate::Header(belle_sip_header_get_name(cHeader), belle_sip_header_get_unparsed_value(cHeader));
L_GET_CPP_PTR_FROM_C_OBJECT(content)->addHeader(header);
headers = headers->next;
}
if (sal_body_handler_get_encoding(body_handler)) linphone_content_set_encoding(content, sal_body_handler_get_encoding(body_handler));
}
@ -307,12 +315,7 @@ SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) {
}
for (const auto &header : L_GET_CPP_PTR_FROM_C_OBJECT(content)->getHeaders()) {
belle_sip_header_t *additionalHeader = BELLE_SIP_HEADER(
belle_sip_header_create(
header.first.c_str(),
header.second.c_str()
)
);
belle_sip_header_t *additionalHeader = belle_sip_header_parse(header.asString().c_str());
belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(body_handler), additionalHeader);
}

View file

@ -650,6 +650,7 @@ SalBodyHandler * sal_body_handler_get_part(const SalBodyHandler *body_handler, i
const belle_sip_list_t * sal_body_handler_get_parts(const SalBodyHandler *body_handler);
SalBodyHandler * sal_body_handler_find_part_by_header(const SalBodyHandler *body_handler, const char *header_name, const char *header_value);
const char * sal_body_handler_get_header(const SalBodyHandler *body_handler, const char *header_name);
const belle_sip_list_t* sal_body_handler_get_headers(const SalBodyHandler *body_handler);
/*this function parses a document with key=value pairs separated by new lines, and extracts the value for a given key*/
int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size);

View file

@ -22,6 +22,7 @@
#include "chat/chat-message/chat-message.h"
#include "content/content-type.h"
#include "content/header/header.h"
#include "content/content-manager.h"
#include "content/file-transfer-content.h"
@ -55,8 +56,8 @@ ChatMessageModifier::Result MultipartChatMessageModifier::decode (const shared_p
content->setContentType(c.getContentType());
content->setContentDisposition(c.getContentDisposition());
content->setContentEncoding(c.getContentEncoding());
for (const pair<string, string> &pair : c.getHeaders()) {
content->addHeader(pair.first, pair.second);
for (const Header &header : c.getHeaders()) {
content->addHeader(header);
}
content->setBodyFromUtf8(c.getBodyAsUtf8String());
} else {

View file

@ -29,14 +29,14 @@
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
namespace {
constexpr const char MultipartBoundary[] = "---------------------------14737809831466499882746641449";
}
using namespace std;
LINPHONE_BEGIN_NAMESPACE
// -----------------------------------------------------------------------------
list<Content> ContentManager::multipartToContentList (const Content &content) {

View file

@ -29,13 +29,15 @@
LINPHONE_BEGIN_NAMESPACE
class Header;
class ContentPrivate : public ClonableObjectPrivate {
private:
std::vector<char> body;
ContentType contentType;
ContentDisposition contentDisposition;
std::string contentEncoding;
std::list<std::pair<std::string, std::string>> headers;
std::list<Header> headers;
L_DECLARE_PUBLIC(Content);
};

View file

@ -179,8 +179,7 @@ string ContentType::asString () const {
L_D();
if (isValid()) {
string asString = d->type + "/" + d->subType;
for (auto it = std::begin(getParameters()); it!=std::end(getParameters()); ++it) {
HeaderParam param = *it;
for (const auto &param : getParameters()) {
asString += param.asString();
}
return asString;

View file

@ -25,6 +25,7 @@
#include "content-p.h"
#include "content-type.h"
#include "header/header.h"
// =============================================================================
@ -197,10 +198,17 @@ bool Content::isFileTransfer () const {
void Content::addHeader (const string &headerName, const string &headerValue) {
L_D();
removeHeader(headerName);
d->headers.push_back(make_pair(headerName, headerValue));
Header header = Header(headerName, headerValue);
d->headers.push_back(header);
}
const list<pair<string, string>> &Content::getHeaders () const {
void Content::addHeader (const Header &header) {
L_D();
removeHeader(header.getName());
d->headers.push_back(header);
}
const list<Header> &Content::getHeaders () const {
L_D();
return d->headers;
}
@ -212,10 +220,10 @@ void Content::removeHeader (const string &headerName) {
d->headers.remove(*it);
}
list<pair<string, string>>::const_iterator Content::findHeader (const string &headerName) const {
list<Header>::const_iterator Content::findHeader (const string &headerName) const {
L_D();
return findIf(d->headers, [&headerName](const pair<string, string> &pair) {
return pair.first == headerName;
return findIf(d->headers, [&headerName](const Header &header) {
return header.getName() == headerName;
});
}

View file

@ -35,6 +35,7 @@ LINPHONE_BEGIN_NAMESPACE
class ContentDisposition;
class ContentType;
class ContentPrivate;
class Header;
class LINPHONE_PUBLIC Content : public ClonableObject, public AppDataContainer {
public:
@ -76,10 +77,11 @@ public:
virtual bool isFile () const;
virtual bool isFileTransfer () const;
const std::list<std::pair<std::string, std::string>> &getHeaders () const;
const std::list<Header> &getHeaders () const;
void addHeader (const std::string &headerName, const std::string &headerValue);
void addHeader (const Header &header);
void removeHeader (const std::string &headerName);
std::list<std::pair<std::string, std::string>>::const_iterator findHeader (const std::string &headerName) const;
std::list<Header>::const_iterator findHeader (const std::string &headerName) const;
protected:
explicit Content (ContentPrivate &p);

View file

@ -32,6 +32,8 @@ LINPHONE_BEGIN_NAMESPACE
class HeaderPrivate : public ClonableObjectPrivate {
private:
std::string name;
std::string value;
std::list<HeaderParam> parameters;
L_DECLARE_PUBLIC(Header);
};

View file

@ -35,14 +35,64 @@ Header::Header(HeaderPrivate &p) : ClonableObject(p) {
}
void Header::cleanParameters() {
Header::Header (const string &name, const string &value) : ClonableObject(*new HeaderPrivate) {
setName(name);
setValue(value);
}
Header::Header (const string &name, const string &value, const list<HeaderParam> &params) : Header(name, value) {
addParameters(params);
}
Header::Header (const Header &other) : Header(other.getName(), other.getValue(), other.getParameters()) {}
Header &Header::operator= (const Header &other) {
if (this != &other) {
setName(other.getName());
setValue(other.getValue());
cleanParameters();
addParameters(other.getParameters());
}
return *this;
}
bool Header::operator== (const Header &other) const {
return getName() == other.getName() &&
getValue() == other.getValue();
}
bool Header::operator!= (const Header &other) const {
return !(*this == other);
}
void Header::setName (const string &name) {
L_D();
d->name = name;
}
string Header::getName () const {
L_D();
return d->name;
}
void Header::setValue (const string &value) {
L_D();
d->value = value;
}
string Header::getValue () const {
L_D();
return d->value;
}
void Header::cleanParameters () {
L_D();
d->parameters.clear();
}
const std::list<HeaderParam> &Header::getParameters () const {
L_D();
return d->parameters;
}
@ -90,4 +140,12 @@ const HeaderParam &Header::getParameter (const std::string &paramName) const {
return Utils::getEmptyConstRefObject<HeaderParam>();
}
string Header::asString () const {
string asString = getName() + ":" + getValue();
for (const auto &param : getParameters()) {
asString += param.asString();
}
return asString;
}
LINPHONE_END_NAMESPACE

View file

@ -33,7 +33,22 @@ class HeaderParam;
class LINPHONE_PUBLIC Header : public ClonableObject {
public:
void cleanParameters();
Header (const std::string &name, const std::string &value);
Header (const std::string &name, const std::string &value, const std::list<HeaderParam> &params);
Header (const Header &other);
Header &operator= (const Header &other);
bool operator== (const Header &other) const;
bool operator!= (const Header &other) const;
void setName (const std::string &name);
std::string getName () const;
void setValue (const std::string &value);
std::string getValue () const;
void cleanParameters ();
const std::list<HeaderParam> &getParameters () const;
void addParameter (const std::string &paramName, const std::string &paramValue);
void addParameter (const HeaderParam &param);
@ -43,6 +58,8 @@ public:
std::list<HeaderParam>::const_iterator findParameter (const std::string &paramName) const;
const HeaderParam &getParameter (const std::string &paramName) const;
std::string asString () const;
protected:
explicit Header (HeaderPrivate &p);

View file

@ -61,6 +61,7 @@ static const char* source_multipart = \
" </p1:person>" \
"</presence>" \
"-----------------------------14737809831466499882746641449\r\n" \
"Content-Encoding: b64\r\n" \
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+XXXXXXXXXX@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
@ -78,6 +79,7 @@ static const char* source_multipart = \
" </p1:person>" \
"</presence>" \
"-----------------------------14737809831466499882746641449\r\n" \
"Content-Id: toto;param1=value1;param2;param3=value3\r\n" \
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+ZZZZZZZZZZ@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
@ -98,8 +100,8 @@ static const char* source_multipart = \
static const char* generated_multipart = \
"-----------------------------14737809831466499882746641449\r\n" \
"Content-Type: application/rlmi+xml;charset=\"UTF-8\"\r\n\r\n" \
"Content-Length:582" \
"Content-Type: application/rlmi+xml;charset=\"UTF-8\"\r\n" \
"Content-Length:582\r\n\r\n" \
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
"<list xmlns=\"urn:ietf:params:xml:ns:rlmi\" fullState=\"false\" uri=\"sip:rls@sip.linphone.org\" version=\"1\">" \
" <resource uri=\"sip:+YYYYYYYYYY@sip.linphone.org;user=phone\">" \
@ -113,8 +115,8 @@ static const char* generated_multipart = \
" </resource>" \
"</list>" \
"-----------------------------14737809831466499882746641449\r\n" \
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \
"Content-Length:561" \
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n" \
"Content-Length:561\r\n\r\n" \
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+YYYYYYYYYY@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
" <tuple id=\"qmht-9\">" \
@ -131,8 +133,9 @@ static const char* generated_multipart = \
" </p1:person>" \
"</presence>" \
"-----------------------------14737809831466499882746641449\r\n" \
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \
"Content-Length:561" \
"Content-Encoding:b64\r\n" \
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n" \
"Content-Length:561\r\n\r\n" \
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+XXXXXXXXXX@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
" <tuple id=\"szohvt\">" \
@ -149,8 +152,9 @@ static const char* generated_multipart = \
" </p1:person>" \
"</presence>" \
"-----------------------------14737809831466499882746641449\r\n" \
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \
"Content-Length:546" \
"Content-Id:toto;param1=value1;param2;param3=value3\r\n" \
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n" \
"Content-Length:546\r\n\r\n" \
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+ZZZZZZZZZZ@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
" <tuple id=\"oc3e08\">" \
@ -326,8 +330,14 @@ void list_to_multipart () {
content2.setContentType(contentType);
Content content3;
content3.setBody(part3);
content3.addHeader("Content-Encoding", "b64");
content3.setContentType(contentType);
Content content4;
Header header = Header("Content-Id", "toto");
header.addParameter("param1", "value1");
header.addParameter("param2", "");
header.addParameter("param3", "value3");
content4.addHeader(header);
content4.setBody(part4);
content4.setContentType(contentType);
list<Content *> contents = {&content1, &content2, &content3, &content4};