Commit 2bb18938 authored by Ghislain MARY's avatar Ghislain MARY
Browse files

Merge branch 'dev_cpim_improvements' into dev_refactor_cpp

parents 728574a5 96e0a6a2
No preview for this file type
......@@ -17,6 +17,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <iomanip>
#include <sstream>
#include "linphone/utils/utils.h"
#include "logger/logger.h"
#include "chat/cpim/parser/cpim-parser.h"
#include "cpim-header-p.h"
......@@ -28,50 +35,278 @@ using namespace std;
LINPHONE_BEGIN_NAMESPACE
Cpim::CoreHeader::CoreHeader () : Header(*new HeaderPrivate) {}
class Cpim::ContactHeaderPrivate : public HeaderPrivate {
public:
string uri;
string formalName;
};
Cpim::ContactHeader::ContactHeader () : Header(*new ContactHeaderPrivate) {}
Cpim::ContactHeader::ContactHeader (const string &uri, const string &formalName) : ContactHeader() {
setUri(uri);
setFormalName(formalName);
}
string Cpim::ContactHeader::getUri () const {
L_D();
return d->uri;
}
void Cpim::ContactHeader::setUri (const string &uri) {
L_D();
d->uri = uri;
}
string Cpim::ContactHeader::getFormalName () const {
L_D();
return d->formalName;
}
Cpim::CoreHeader::CoreHeader (HeaderPrivate &p) : Header(p) {}
void Cpim::ContactHeader::setFormalName (const string &formalName) {
L_D();
if (formalName.front() == '\"' && formalName.back() == '\"')
d->formalName = formalName.substr(1, formalName.size() - 2);
else if (formalName.back() == ' ')
d->formalName = formalName.substr(0, formalName.size() - 1);
else
d->formalName = formalName;
}
Cpim::CoreHeader::~CoreHeader () {}
string Cpim::ContactHeader::getValue () const {
L_D();
string result;
if (!d->formalName.empty())
result += "\"" + d->formalName + "\"";
result += "<" + d->uri + ">";
return result;
}
bool Cpim::CoreHeader::isValid () const {
return !getValue().empty();
string Cpim::ContactHeader::asString () const {
return getName() + ": " + getValue() + "\r\n";
}
// -----------------------------------------------------------------------------
#define MAKE_CORE_HEADER_IMPL(CLASS_PREFIX) \
bool Cpim::CLASS_PREFIX ## Header::setValue(const string &value) { \
return Parser::getInstance()->coreHeaderIsValid<CLASS_PREFIX ## Header>(value) && Header::setValue(value); \
class Cpim::DateTimeHeaderPrivate : public HeaderPrivate {
public:
tm dateTime;
tm dateTimeOffset;
string signOffset;
};
Cpim::DateTimeHeader::DateTimeHeader () : Header(*new DateTimeHeaderPrivate) {}
Cpim::DateTimeHeader::DateTimeHeader (time_t time) : DateTimeHeader() {
setTime(time);
}
Cpim::DateTimeHeader::DateTimeHeader (const tm &time, const tm &timeOffset, const string &signOffset) : DateTimeHeader() {
setTime(time, timeOffset, signOffset);
}
time_t Cpim::DateTimeHeader::getTime () const {
L_D();
tm result = d->dateTime;
result.tm_year -= 1900;
result.tm_isdst = 0;
if (d->signOffset == "+") {
result.tm_hour += d->dateTimeOffset.tm_hour;
result.tm_min += d->dateTimeOffset.tm_min;
while (result.tm_min > 59) {
result.tm_hour++;
result.tm_min -= 60;
}
}
else if (d->signOffset == "-") {
result.tm_hour -= d->dateTimeOffset.tm_hour;
result.tm_hour -= d->dateTimeOffset.tm_min;
while (result.tm_min < 0) {
result.tm_hour--;
result.tm_min += 60;
}
}
MAKE_CORE_HEADER_IMPL(From);
MAKE_CORE_HEADER_IMPL(To);
MAKE_CORE_HEADER_IMPL(Cc);
MAKE_CORE_HEADER_IMPL(DateTime);
return Utils::getTmAsTimeT(result);
}
void Cpim::DateTimeHeader::setTime (const time_t time) {
L_D();
d->signOffset = "Z";
d->dateTime = Utils::getTimeTAsTm(time);
d->dateTime.tm_year += 1900;
}
void Cpim::DateTimeHeader::setTime (const tm &time, const tm &timeOffset, const string &signOffset) {
L_D();
d->dateTime = time;
d->dateTimeOffset = timeOffset;
d->signOffset = signOffset;
}
string Cpim::DateTimeHeader::getValue () const {
L_D();
MAKE_CORE_HEADER_IMPL(Ns);
MAKE_CORE_HEADER_IMPL(Require);
stringstream ss;
ss << setfill('0') << setw(4) << d->dateTime.tm_year << "-"
<< setfill('0') << setw(2) << d->dateTime.tm_mon + 1 << "-"
<< setfill('0') << setw(2) << d->dateTime.tm_mday << "T"
<< setfill('0') << setw(2) << d->dateTime.tm_hour << ":"
<< setfill('0') << setw(2) << d->dateTime.tm_min << ":"
<< setfill('0') << setw(2) << d->dateTime.tm_sec;
#undef MAKE_CORE_HEADER_IMPL
ss << d->signOffset;
if (d->signOffset != "Z")
ss << setfill('0') << setw(2) << d->dateTimeOffset.tm_hour << ":"
<< setfill('0') << setw(2) << d->dateTimeOffset.tm_min;
return ss.str();
}
string Cpim::DateTimeHeader::asString () const {
return getName() + ": " + getValue() + "\r\n";
}
struct tm Cpim::DateTimeHeader::getTimeStruct () const {
L_D();
return d->dateTime;
}
struct tm Cpim::DateTimeHeader::getTimeOffset () const {
L_D();
return d->dateTimeOffset;
}
string Cpim::DateTimeHeader::getSignOffset () const {
L_D();
return d->signOffset;
}
// -----------------------------------------------------------------------------
void Cpim::CoreHeader::force (const string &value) {
Header::setValue(value);
class Cpim::NsHeaderPrivate : public HeaderPrivate {
public:
string uri;
string prefixName;
};
Cpim::NsHeader::NsHeader () : Header(*new NsHeaderPrivate) {}
Cpim::NsHeader::NsHeader (const string &uri, const string &prefixName) : NsHeader() {
setUri(uri);
setPrefixName(prefixName);
}
string Cpim::NsHeader::getUri () const {
L_D();
return d->uri;
}
void Cpim::NsHeader::setUri (const string &uri) {
L_D();
d->uri = uri;
}
string Cpim::NsHeader::getPrefixName () const {
L_D();
return d->prefixName;
}
void Cpim::NsHeader::setPrefixName (const string &prefixName) {
L_D();
d->prefixName = prefixName;
}
string Cpim::NsHeader::getValue () const {
L_D();
string ns;
if (!d->prefixName.empty())
ns = d->prefixName + " ";
return ns + "<" + d->uri + ">";
}
string Cpim::NsHeader::asString () const {
return getName() + ": " + getValue() + "\r\n";
}
// -----------------------------------------------------------------------------
class Cpim::RequireHeaderPrivate : public HeaderPrivate {
public:
list<string> headerNames;
};
Cpim::RequireHeader::RequireHeader () : Header(*new RequireHeaderPrivate) {}
Cpim::RequireHeader::RequireHeader (const string &headerNames) : RequireHeader() {
for (const string &header : Utils::split(headerNames, ",")) {
addHeaderName(header);
}
}
Cpim::RequireHeader::RequireHeader (const list<string> &headerNames) : RequireHeader() {
L_D();
d->headerNames = headerNames;
}
list<string> Cpim::RequireHeader::getHeaderNames () const {
L_D();
return d->headerNames;
}
void Cpim::RequireHeader::addHeaderName (const string &headerName) {
L_D();
d->headerNames.push_back(headerName);
}
string Cpim::RequireHeader::getValue () const {
L_D();
string requires;
for (const string &header : d->headerNames) {
if (header != d->headerNames.front())
requires += ",";
requires += header;
}
return requires;
}
string Cpim::RequireHeader::asString () const {
return getName() + ": " + getValue() + "\r\n";
}
// -----------------------------------------------------------------------------
class Cpim::SubjectHeaderPrivate : public HeaderPrivate {
public:
string subject;
string language;
};
Cpim::SubjectHeader::SubjectHeader () : CoreHeader(*new SubjectHeaderPrivate) {}
Cpim::SubjectHeader::SubjectHeader () : Header(*new SubjectHeaderPrivate) {}
Cpim::SubjectHeader::SubjectHeader (const string &subject, const string &language) : SubjectHeader() {
setSubject(subject);
setLanguage(language);
}
string Cpim::SubjectHeader::getSubject () const {
L_D();
return d->subject;
}
bool Cpim::SubjectHeader::setValue (const string &value) {
return Parser::getInstance()->coreHeaderIsValid<SubjectHeader>(value) && Header::setValue(value);
void Cpim::SubjectHeader::setSubject (const string &subject) {
L_D();
d->subject = subject;
}
string Cpim::SubjectHeader::getLanguage () const {
......@@ -79,30 +314,23 @@ string Cpim::SubjectHeader::getLanguage () const {
return d->language;
}
bool Cpim::SubjectHeader::setLanguage (const string &language) {
if (!language.empty() && !Parser::getInstance()->subjectHeaderLanguageIsValid(language))
return false;
void Cpim::SubjectHeader::setLanguage (const string &language) {
L_D();
d->language = language;
return true;
}
string Cpim::SubjectHeader::asString () const {
string Cpim::SubjectHeader::getValue () const {
L_D();
string languageParam;
if (!d->language.empty())
languageParam = ";lang=" + d->language;
return getName() + ":" + languageParam + " " + getValue() + "\r\n";
return languageParam + " " + d->subject;
}
void Cpim::SubjectHeader::force (const string &value, const string &language) {
L_D();
CoreHeader::force(value);
d->language = language;
string Cpim::SubjectHeader::asString () const {
return getName() + ":" + getValue() + "\r\n";
}
LINPHONE_END_NAMESPACE
......@@ -20,60 +20,160 @@
#ifndef _L_CPIM_CORE_HEADERS_H_
#define _L_CPIM_CORE_HEADERS_H_
#include <ctime>
#include <list>
#include "cpim-header.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
#define MAKE_CORE_HEADER(CLASS_PREFIX, NAME) \
class LINPHONE_PUBLIC CLASS_PREFIX ## Header : public CoreHeader { \
#define MAKE_CONTACT_HEADER(CLASS_PREFIX, NAME) \
class LINPHONE_PUBLIC CLASS_PREFIX ## Header : public ContactHeader { \
public: \
CLASS_PREFIX ## Header() = default; \
inline std::string getName() const override { \
CLASS_PREFIX ## Header () = default; \
CLASS_PREFIX ## Header (const std::string &uri, const std::string &formalName = "") : ContactHeader (uri, formalName) {} \
inline std::string getName () const override { \
return NAME; \
} \
bool setValue(const std::string &value) override; \
private: \
L_DISABLE_COPY(CLASS_PREFIX ## Header); \
};
namespace Cpim {
class HeaderNode;
class DateTimeHeaderNode;
// -------------------------------------------------------------------------
// Specific Contact headers declaration.
// -------------------------------------------------------------------------
class ContactHeaderPrivate;
class LINPHONE_PUBLIC ContactHeader : public Header {
public:
ContactHeader ();
ContactHeader (const std::string &uri, const std::string &formalName = "");
std::string getUri () const;
void setUri (const std::string &uri);
std::string getFormalName () const;
void setFormalName (const std::string &formalName);
std::string getValue () const override;
std::string asString () const override;
private:
L_DECLARE_PRIVATE(ContactHeader);
L_DISABLE_COPY(ContactHeader);
};
// -------------------------------------------------------------------------
MAKE_CONTACT_HEADER(From, "From");
MAKE_CONTACT_HEADER(To, "To");
MAKE_CONTACT_HEADER(Cc, "cc");
// -------------------------------------------------------------------------
// Specific DateTime declaration.
// -------------------------------------------------------------------------
class DateTimeHeaderPrivate;
class LINPHONE_PUBLIC DateTimeHeader : public Header {
friend class DateTimeHeaderNode;
public:
DateTimeHeader ();
DateTimeHeader (time_t time);
DateTimeHeader (const tm &time, const tm &timeOffset, const std::string &signOffset);
inline std::string getName () const override {
return "DateTime";
}
time_t getTime () const;
void setTime (const time_t time);
void setTime (const tm &time, const tm &timeOffset, const std::string &signOffset);
std::string getValue () const override;
std::string asString () const override;
private:
tm getTimeStruct () const;
tm getTimeOffset () const;
std::string getSignOffset () const;
L_DECLARE_PRIVATE(DateTimeHeader);
L_DISABLE_COPY(DateTimeHeader);
};
// -------------------------------------------------------------------------
// Generic core header.
// Specific Ns declaration.
// -------------------------------------------------------------------------
class LINPHONE_PUBLIC CoreHeader : public Header {
friend class HeaderNode;
class NsHeaderPrivate;
class LINPHONE_PUBLIC NsHeader : public Header {
public:
CoreHeader ();
NsHeader ();
NsHeader (const std::string &uri, const std::string &prefixName = "");
inline std::string getName () const override {
return "NS";
}
virtual ~CoreHeader () = 0;
std::string getPrefixName () const;
void setPrefixName (const std::string &prefixName);
bool isValid () const override;
std::string getUri () const;
void setUri (const std::string &uri);
protected:
explicit CoreHeader (HeaderPrivate &p);
std::string getValue () const override;
void force (const std::string &value);
std::string asString () const override;
private:
L_DISABLE_COPY(CoreHeader);
L_DECLARE_PRIVATE(NsHeader);
L_DISABLE_COPY(NsHeader);
};
// -------------------------------------------------------------------------
// Core headers.
// Specific Require declaration.
// -------------------------------------------------------------------------
MAKE_CORE_HEADER(From, "From");
MAKE_CORE_HEADER(To, "To");
MAKE_CORE_HEADER(Cc, "cc");
MAKE_CORE_HEADER(DateTime, "DateTime");
MAKE_CORE_HEADER(Ns, "NS");
MAKE_CORE_HEADER(Require, "Require");
class RequireHeaderPrivate;
class LINPHONE_PUBLIC RequireHeader : public Header {
public:
RequireHeader ();
RequireHeader (const std::string &headerNames);
RequireHeader (const std::list<std::string> &headerNames);
inline std::string getName () const override {
return "Require";
}
std::list<std::string> getHeaderNames () const;
void addHeaderName (const std::string &headerName);
std::string getValue () const override;
std::string asString () const override;
private:
L_DECLARE_PRIVATE(RequireHeader);
L_DISABLE_COPY(RequireHeader);
};
// -------------------------------------------------------------------------
// Specific Subject declaration.
......@@ -81,25 +181,25 @@ namespace Cpim {
class SubjectHeaderPrivate;
class LINPHONE_PUBLIC SubjectHeader : public CoreHeader {
friend class HeaderNode;
class LINPHONE_PUBLIC SubjectHeader : public Header {
public:
SubjectHeader ();
SubjectHeader (const std::string &subject, const std::string &language = "");
inline std::string getName () const override {
return "Subject";
}
bool setValue (const std::string &value) override;
std::string getSubject () const;
void setSubject (const std::string &subject);
std::string getLanguage () const;
bool setLanguage (const std::string &language);
void setLanguage (const std::string &language);
std::string asString () const override;
std::string getValue () const override;
protected:
void force (const std::string &value, const std::string &language);
std::string asString () const override;
private:
L_DECLARE_PRIVATE(SubjectHeader);
......@@ -107,7 +207,7 @@ namespace Cpim {
};
}
#undef MAKE_CORE_HEADER
#undef MAKE_CONTACT_HEADER
LINPHONE_END_NAMESPACE
......
......@@ -34,38 +34,50 @@ LINPHONE_BEGIN_NAMESPACE
class Cpim::GenericHeaderPrivate : public HeaderPrivate {
public:
GenericHeaderPrivate () : parameters(make_shared<list<pair<string, string> > >()) {}
GenericHeaderPrivate () : parameters(make_shared<list<pair<string, string>>>()) {}
string name;
shared_ptr<list<pair<string, string> > > parameters;
string value;
shared_ptr<list<pair<string, string>>> parameters;
};
Cpim::GenericHeader::GenericHeader () : Header(*new GenericHeaderPrivate) {}
Cpim::GenericHeader::GenericHeader (string name, string value, string parameters) : GenericHeader() {
setName(name);
setValue(value);
for (const auto &parameter : Utils::split(parameters, ';')) {
size_t equalIndex = parameter.find('=');
if (equalIndex != string::npos)
addParameter(parameter.substr(0, equalIndex), parameter.substr(equalIndex + 1));