Commit 6e0a7ae3 authored by Mickaël Turnel's avatar Mickaël Turnel Committed by Ghislain MARY
Browse files

Add specific headers

parent 728574a5
......@@ -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,348 @@ 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;
}
bool Cpim::ContactHeader::setUri (const string &uri) {
if (uri.empty())
return false;
L_D();
d->uri = uri;
return true;
}
string Cpim::ContactHeader::getFormalName () const {
L_D();
return d->formalName;
}
bool Cpim::ContactHeader::setFormalName (const string &formalName) {
if (formalName.empty())
return false;
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;
return true;
}
string Cpim::ContactHeader::getValue () const {
L_D();
return "\"" + d->formalName + "\"" + "<" + d->uri + ">";
}
string Cpim::ContactHeader::asString () const {
return getName() + ": " + getValue() + "\r\n";
}
// -----------------------------------------------------------------------------
class Cpim::MessageIdHeaderPrivate : public HeaderPrivate {
public:
string token;
};
Cpim::MessageIdHeader::MessageIdHeader () : Header(*new MessageIdHeaderPrivate) {}
Cpim::MessageIdHeader::MessageIdHeader (const string &token) : MessageIdHeader() {
L_D();
d->token = token;
}
string Cpim::MessageIdHeader::getToken () const {
L_D();
return d->token;
}
Cpim::CoreHeader::CoreHeader (HeaderPrivate &p) : Header(p) {}
bool Cpim::MessageIdHeader::setToken (string token) {
if (token.empty())
return false;
Cpim::CoreHeader::~CoreHeader () {}
L_D();
d->token = token;
bool Cpim::CoreHeader::isValid () const {
return !getValue().empty();
return true;
}
string Cpim::MessageIdHeader::getValue () const {
return getToken();
}
string Cpim::MessageIdHeader::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 timeT;
tm timeTOffset;
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->timeT;
result.tm_year -= 1900;
result.tm_isdst = 0;
if (d->signOffset == "+") {
result.tm_hour += d->timeTOffset.tm_hour;
result.tm_min += d->timeTOffset.tm_min;
while (result.tm_min > 59) {
result.tm_hour++;
result.tm_min -= 60;
}
}
else if (d->signOffset == "-") {
result.tm_hour -= d->timeTOffset.tm_hour;
result.tm_hour -= d->timeTOffset.tm_min;
while (result.tm_min < 0) {
result.tm_hour--;
result.tm_min += 60;
}
}
return Utils::getTmAsTimeT(result);
}
bool Cpim::DateTimeHeader::setTime (const time_t time) {
L_D();
d->signOffset = "Z";
d->timeT = Utils::getTimeTAsTm(time);
d->timeT.tm_year += 1900;
return true;
}
bool Cpim::DateTimeHeader::setTime (const tm &time, const tm &timeOffset, const string &signOffset) {
L_D();
d->timeT = time;
d->timeTOffset = timeOffset;
d->signOffset = signOffset;
return true;
}
string Cpim::DateTimeHeader::getValue () const {
L_D();
stringstream ss;
ss << setfill('0') << setw(4) << d->timeT.tm_year << "-"
<< setfill('0') << setw(2) << d->timeT.tm_mon << "-"
<< setfill('0') << setw(2) << d->timeT.tm_mday << "T"
<< setfill('0') << setw(2) << d->timeT.tm_hour << ":"
<< setfill('0') << setw(2) << d->timeT.tm_min << ":"
<< setfill('0') << setw(2) << d->timeT.tm_sec;
ss << d->signOffset;
if (d->signOffset != "Z")
ss << setfill('0') << setw(2) << d->timeTOffset.tm_hour << ":"
<< setfill('0') << setw(2) << d->timeTOffset.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->timeT;
}
struct tm Cpim::DateTimeHeader::getTimeOffset () const {
L_D();
return d->timeTOffset;
}
string Cpim::DateTimeHeader::getSignOffset () const {
L_D();
return d->signOffset;
}
// -----------------------------------------------------------------------------
class Cpim::NsHeaderPrivate : public HeaderPrivate {
public:
string uri;
string prefixName;
};
MAKE_CORE_HEADER_IMPL(From);
MAKE_CORE_HEADER_IMPL(To);
MAKE_CORE_HEADER_IMPL(Cc);
MAKE_CORE_HEADER_IMPL(DateTime);
Cpim::NsHeader::NsHeader () : Header(*new NsHeaderPrivate) {}
MAKE_CORE_HEADER_IMPL(Ns);
MAKE_CORE_HEADER_IMPL(Require);
Cpim::NsHeader::NsHeader (const string &uri, const string &prefixName) : NsHeader() {
L_D();
d->uri = uri;
d->prefixName = prefixName;
}
string Cpim::NsHeader::getUri () const {
L_D();
return d->uri;
}
bool Cpim::NsHeader::setUri (const string &uri) {
if (uri.empty())
return false;
#undef MAKE_CORE_HEADER_IMPL
L_D();
d->uri = uri;
return true;
}
string Cpim::NsHeader::getPrefixName () const {
L_D();
return d->prefixName;
}
bool Cpim::NsHeader::setPrefixName (const string &prefixName) {
if (prefixName.empty())
return false;
L_D();
d->prefixName = prefixName;
return true;
}
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";
}
// -----------------------------------------------------------------------------
void Cpim::CoreHeader::force (const string &value) {
Header::setValue(value);
class Cpim::RequireHeaderPrivate : public HeaderPrivate {
public:
list<string> headerNames;
};
Cpim::RequireHeader::RequireHeader () : Header(*new RequireHeaderPrivate) {}
Cpim::RequireHeader::RequireHeader (const string &headerNames) : RequireHeader() {
L_D();
for (const string &header : Utils::split(headerNames, ",")) {
d->headerNames.push_back(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;
}
bool Cpim::RequireHeader::addHeaderName (const string &headerName) {
if (headerName.empty())
return false;
L_D();
d->headerNames.push_back(headerName);
return true;
}
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) {}
bool Cpim::SubjectHeader::setValue (const string &value) {
return Parser::getInstance()->coreHeaderIsValid<SubjectHeader>(value) && Header::setValue(value);
Cpim::SubjectHeader::SubjectHeader (const string &subject, const string &language) : SubjectHeader() {
L_D();
d->subject = subject;
d->language = language;
}
string Cpim::SubjectHeader::getSubject () const {
L_D();
return d->subject;
}
bool Cpim::SubjectHeader::setSubject (const string &subject) {
if (subject.empty())
return false;
L_D();
d->subject = subject;
return true;
}
string Cpim::SubjectHeader::getLanguage () const {
......@@ -80,7 +385,7 @@ string Cpim::SubjectHeader::getLanguage () const {
}
bool Cpim::SubjectHeader::setLanguage (const string &language) {
if (!language.empty() && !Parser::getInstance()->subjectHeaderLanguageIsValid(language))
if (!language.empty())
return false;
L_D();
......@@ -89,20 +394,18 @@ bool Cpim::SubjectHeader::setLanguage (const string &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,188 @@
#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;
bool setUri (const std::string &uri);
std::string getFormalName () const;
bool 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 MessageId declaration.
// -------------------------------------------------------------------------
class MessageIdHeaderPrivate;
class LINPHONE_PUBLIC MessageIdHeader : public Header {
public:
MessageIdHeader ();
MessageIdHeader (const std::string &token);
inline std::string getName() const override {
return "Message-ID";
}
std::string getToken () const;
bool setToken (std::string token);
std::string getValue () const override;
std::string asString () const override;
private:
L_DECLARE_PRIVATE(MessageIdHeader);
L_DISABLE_COPY(MessageIdHeader);
};
// -------------------------------------------------------------------------
// 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;
bool setTime (const time_t time);
bool 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 = "");
virtual ~CoreHeader () = 0;
inline std::string getName () const override {
return "NS";
}
bool isValid () const override;
std::string getPrefixName () const;
bool setPrefixName (const std::string &prefixName);
protected:
explicit CoreHeader (HeaderPrivate &p);
std::string getUri () const;
bool setUri (const std::string &uri);
void force (const std::string &value);
std::string getValue () const override;
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);