content.cpp 5.61 KB
Newer Older
1 2
/*
 * content.cpp
3
 * Copyright (C) 2010-2018 Belledonne Communications SARL
4
 *
Ghislain MARY's avatar
Ghislain MARY committed
5 6 7 8
 * 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.
9 10 11 12 13 14 15
 *
 * 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
Ghislain MARY's avatar
Ghislain MARY committed
16 17
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 19
 */

Ronan's avatar
Ronan committed
20 21
// TODO: Remove me later.
#include "linphone/core.h"
22

23 24
#include "linphone/utils/algorithm.h"
#include "linphone/utils/utils.h"
25

26
#include "content-p.h"
Ronan's avatar
Ronan committed
27
#include "content-type.h"
28 29 30

// =============================================================================

Ronan's avatar
Ronan committed
31 32
using namespace std;

33 34 35 36
LINPHONE_BEGIN_NAMESPACE

// -----------------------------------------------------------------------------

37
Content::Content () : ClonableObject(*new ContentPrivate) {}
Ronan's avatar
Ronan committed
38

39
Content::Content (const Content &other) : ClonableObject(*new ContentPrivate), AppDataContainer(other) {
40
	L_D();
41 42
	d->body = other.getBody();
	d->contentType = other.getContentType();
43 44
	d->contentDisposition = other.getContentDisposition();;
	d->headers = other.getHeaders();
Ronan's avatar
Ronan committed
45 46
}

47
Content::Content (Content &&other) : ClonableObject(*new ContentPrivate), AppDataContainer(move(other)) {
48
	L_D();
49 50 51 52 53
	ContentPrivate *dOther = other.getPrivate();
	d->body = move(dOther->body);
	d->contentType = move(dOther->contentType);
	d->contentDisposition = move(dOther->contentDisposition);
	d->headers = move(dOther->headers);
54 55
}

56
Content::Content (ContentPrivate &p) : ClonableObject(p) {}
Ronan's avatar
Ronan committed
57

58 59
Content::~Content () {
	L_D();
60 61 62 63
	/*
	 * Fills the body with zeros before releasing since it may contain
	 * private data like cipher keys or decoded messages.
	 */
64 65 66
	d->body.assign(d->body.size(), 0);
}

67
Content &Content::operator= (const Content &other) {
68
	L_D();
69
	if (this != &other) {
70
		AppDataContainer::operator=(other);
71 72 73
		d->body = other.getBody();
		d->contentType = other.getContentType();
		d->contentDisposition = other.getContentDisposition();
74
		d->headers = other.getHeaders();
75 76
	}
	return *this;
Ronan's avatar
Ronan committed
77 78
}

79
Content &Content::operator= (Content &&other) {
80
	L_D();
81
	AppDataContainer::operator=(move(other));
82 83 84 85 86
	ContentPrivate *dOther = other.getPrivate();
	d->body = move(dOther->body);
	d->contentType = move(dOther->contentType);
	d->contentDisposition = move(dOther->contentDisposition);
	d->headers = move(dOther->headers);
87
	return *this;
Ronan's avatar
Ronan committed
88 89
}

90
bool Content::operator== (const Content &other) const {
91
	L_D();
92 93
	return d->contentType == other.getContentType() &&
		d->body == other.getBody() &&
94 95
		d->contentDisposition == other.getContentDisposition() &&
		d->headers == other.getHeaders();
96 97
}

98
const ContentType &Content::getContentType () const {
99
	L_D();
100
	return d->contentType;
Ronan's avatar
Ronan committed
101 102
}

103
void Content::setContentType (const ContentType &contentType) {
104
	L_D();
105
	d->contentType = contentType;
Ronan's avatar
Ronan committed
106 107
}

108
void Content::setContentType (const string &contentType) {
109
	L_D();
110 111 112 113
	d->contentType = ContentType(contentType);
}

const string &Content::getContentDisposition () const {
114
	L_D();
115 116 117 118
	return d->contentDisposition;
}

void Content::setContentDisposition (const string &contentDisposition) {
119
	L_D();
120 121 122
	d->contentDisposition = contentDisposition;
}

Ronan's avatar
Ronan committed
123
const vector<char> &Content::getBody () const {
124
	L_D();
125
	return d->body;
Ronan's avatar
Ronan committed
126 127
}

128
string Content::getBodyAsString () const {
129 130 131 132 133
	L_D();
	return Utils::utf8ToLocale(string(d->body.begin(), d->body.end()));
}

string Content::getBodyAsUtf8String () const {
134
	L_D();
135 136 137
	return string(d->body.begin(), d->body.end());
}

Ronan's avatar
Ronan committed
138
void Content::setBody (const vector<char> &body) {
139
	L_D();
140
	d->body = body;
Ronan's avatar
Ronan committed
141 142
}

143
void Content::setBody (vector<char> &&body) {
144
	L_D();
145
	d->body = move(body);
146 147
}

Ronan's avatar
Ronan committed
148
void Content::setBody (const string &body) {
149
	L_D();
150 151
	string toUtf8 = Utils::localeToUtf8(body);
	d->body = vector<char>(toUtf8.cbegin(), toUtf8.cend());
Ronan's avatar
Ronan committed
152 153
}

154
void Content::setBody (const void *buffer, size_t size) {
155
	L_D();
156 157
	const char *start = static_cast<const char *>(buffer);
	d->body = vector<char>(start, start + size);
Ronan's avatar
Ronan committed
158 159
}

160 161 162 163 164
void Content::setBodyFromUtf8 (const string &body) {
	L_D();
	d->body = vector<char>(body.cbegin(), body.cend());
}

165
size_t Content::getSize () const {
166
	L_D();
167
	return d->body.size();
Ronan's avatar
Ronan committed
168
}
169

170 171 172 173
bool Content::isEmpty () const {
	return getSize() == 0;
}

Ronan's avatar
Ronan committed
174
bool Content::isValid () const {
175
	L_D();
176
	return d->contentType.isValid() || (d->contentType.isEmpty() && d->body.empty());
177 178
}

179 180 181 182
bool Content::isFile () const {
	return false;
}

183 184 185 186 187 188
void Content::addHeader (const string &headerName, const string &headerValue) {
	L_D();
	removeHeader(headerName);
	d->headers.push_back(make_pair(headerName, headerValue));
}

189
const list<pair<string, string>> &Content::getHeaders () const {
190 191 192 193 194 195 196 197 198 199 200
	L_D();
	return d->headers;
}

void Content::removeHeader (const string &headerName) {
	L_D();
	auto it = findHeader(headerName);
	if (it != d->headers.cend())
		d->headers.remove(*it);
}

201
list<pair<string, string>>::const_iterator Content::findHeader (const string &headerName) const {
202
	L_D();
203
	return findIf(d->headers, [&headerName](const pair<string, string> &pair) {
204 205 206 207
		return pair.first == headerName;
	});
}

Ronan's avatar
Ronan committed
208 209
LinphoneContent *Content::toLinphoneContent () const {
	LinphoneContent *content = linphone_core_create_content(nullptr);
210 211 212 213 214
	linphone_content_set_type(content, getContentType().getType().c_str());
	linphone_content_set_subtype(content, getContentType().getSubType().c_str());
	return content;
}

215
LINPHONE_END_NAMESPACE