Commit 44de032c authored by Ronan's avatar Ronan

feat(core): add a Cpim parser

parent 0af15815
......@@ -115,11 +115,13 @@ if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
include("${EP_ortp_CONFIG_DIR}/ORTPConfig.cmake")
set(BcToolbox_FIND_COMPONENTS tester)
include("${EP_bctoolbox_CONFIG_DIR}/BcToolboxConfig.cmake")
include("${EP_belr_CONFIG_DIR}/BelrConfig.cmake")
else()
find_package(BelleSIP REQUIRED)
find_package(Mediastreamer2 REQUIRED)
find_package(ORTP REQUIRED)
find_package(BcToolbox 0.0.3 REQUIRED OPTIONAL_COMPONENTS tester)
find_package(Belr REQUIRED)
endif()
find_package(XML2 REQUIRED)
find_package(Zlib)
......@@ -208,6 +210,7 @@ set(LINPHONE_INCLUDE_DIRS
${BELLESIP_INCLUDE_DIRS}
${MEDIASTREAMER2_INCLUDE_DIRS}
${BCTOOLBOX_CORE_INCLUDE_DIRS}
${BELR_INCLUDE_DIRS}
)
if (BZRTP_FOUND)
list(APPEND LINPHONE_INCLUDE_DIRS ${BZRTP_INCLUDE_DIRS})
......@@ -243,7 +246,7 @@ if(MSVC)
endif()
add_definitions("-DLINPHONE_EXPORTS")
set(LINPHONE_CPPFLAGS ${BELCARD_CPPFLAGS} ${BELLESIP_CPPFLAGS} ${MEDIASTREAMER2_CPPFLAGS} ${BCTOOLBOX_CPPFLAGS})
set(LINPHONE_CPPFLAGS ${BELCARD_CPPFLAGS} ${BELLESIP_CPPFLAGS} ${MEDIASTREAMER2_CPPFLAGS} ${BCTOOLBOX_CPPFLAGS} ${BELR_CPPFLAGS})
if(ENABLE_STATIC)
list(APPEND LINPHONE_CPPFLAGS "-DLINPHONE_STATIC")
endif()
......
......@@ -35,9 +35,18 @@ endif()
set(LINPHONE_PRIVATE_HEADER_FILES
../src/cpim/cpim.h
../src/cpim/header/cpim-core-headers.h
../src/cpim/header/cpim-generic-header.h
../src/cpim/header/cpim-header-p.h
../src/cpim/header/cpim-header.h
../src/cpim/message/cpim-message.h
../src/cpim/parser/cpim-grammar.h
../src/cpim/parser/cpim-parser.h
../src/object/object.h
../src/object/singleton.h
../src/utils/general.h
../src/utils/utils.h
bellesip_sal/sal_impl.h
carddav.h
conference_private.h
......@@ -122,7 +131,16 @@ set(LINPHONE_SOURCE_FILES_C
xmlrpc.c
vtables.c
)
set(LINPHONE_SOURCE_FILES_CXX conference.cc)
set(LINPHONE_SOURCE_FILES_CXX
../src/cpim/header/cpim-core-headers.cpp
../src/cpim/header/cpim-generic-header.cpp
../src/cpim/header/cpim-header.cpp
../src/cpim/message/cpim-message.cpp
../src/cpim/parser/cpim-grammar.cpp
../src/cpim/parser/cpim-parser.cpp
../src/utils/utils.cpp
conference.cc
)
if(ANDROID)
list(APPEND LINPHONE_SOURCE_FILES_CXX linphonecore_jni.cc)
set_source_files_properties(linphonecore_jni.cc PROPERTIES COMPILE_DEFINITIONS "USE_JAVAH")
......@@ -158,6 +176,7 @@ set(LIBS
${MEDIASTREAMER2_LIBRARIES}
${ORTP_LIBRARIES}
${XML2_LIBRARIES}
${BELR_LIBRARIES}
)
if(WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
list(APPEND LIBS "Ws2_32")
......
/*
* cpim.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CPIM_H_
#define _CPIM_H_
#include "message/cpim-message.h"
// =============================================================================
#endif // ifndef _CPIM_H_
/*
* cpim-core-headers.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cpim-header-p.h"
#include "cpim/parser/cpim-parser.h"
#include "cpim-core-headers.h"
using namespace std;
using namespace LinphonePrivate;
// =============================================================================
Cpim::CoreHeader::CoreHeader () : Header(*new HeaderPrivate) {}
Cpim::CoreHeader::CoreHeader (HeaderPrivate &p) : Header(p) {}
Cpim::CoreHeader::~CoreHeader () {}
bool Cpim::CoreHeader::isValid () const {
return !getValue().empty();
}
// -----------------------------------------------------------------------------
#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); \
}
MAKE_CORE_HEADER_IMPL(From);
MAKE_CORE_HEADER_IMPL(To);
MAKE_CORE_HEADER_IMPL(Cc);
MAKE_CORE_HEADER_IMPL(DateTime);
MAKE_CORE_HEADER_IMPL(Ns);
MAKE_CORE_HEADER_IMPL(Require);
#undef MAKE_CORE_HEADER_IMPL
// -----------------------------------------------------------------------------
void Cpim::CoreHeader::force (const std::string &value) {
Header::setValue(value);
}
// -----------------------------------------------------------------------------
class Cpim::SubjectHeaderPrivate : public HeaderPrivate {
public:
string language;
};
Cpim::SubjectHeader::SubjectHeader () : CoreHeader(*new SubjectHeaderPrivate) {}
bool Cpim::SubjectHeader::setValue (const string &value) {
return Parser::getInstance()->coreHeaderIsValid<SubjectHeader>(value) && Header::setValue(value);
}
string Cpim::SubjectHeader::getLanguage () const {
L_D(const SubjectHeader);
return d->language;
}
bool Cpim::SubjectHeader::setLanguage (const string &language) {
if (!language.empty() && !Parser::getInstance()->subjectHeaderLanguageIsValid(language))
return false;
L_D(SubjectHeader);
d->language = language;
return true;
}
string Cpim::SubjectHeader::asString () const {
L_D(const SubjectHeader);
string languageParam;
if (!d->language.empty())
languageParam = ";lang=" + d->language;
return getName() + ":" + languageParam + " " + getValue() + "\r\n";
}
void Cpim::SubjectHeader::force (const string &value, const string &language) {
L_D(SubjectHeader);
CoreHeader::force(value);
d->language = language;
}
/*
* cpim-core-headers.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CPIM_CORE_HEADERS_H_
#define _CPIM_CORE_HEADERS_H_
#include "cpim-header.h"
// =============================================================================
#define MAKE_CORE_HEADER(CLASS_PREFIX, NAME) \
class CLASS_PREFIX ## Header : public CoreHeader { \
public: \
CLASS_PREFIX ## Header() = default; \
inline std::string getName() const override { \
return NAME; \
} \
bool setValue(const std::string &value) override; \
private: \
L_DISABLE_COPY(CLASS_PREFIX ## Header); \
};
namespace LinphonePrivate {
namespace Cpim {
class HeaderNode;
// -------------------------------------------------------------------------
// Generic core header.
// -------------------------------------------------------------------------
class CoreHeader : public Header {
friend class HeaderNode;
public:
CoreHeader ();
virtual ~CoreHeader () = 0;
bool isValid () const override;
protected:
explicit CoreHeader (HeaderPrivate &p);
void force (const std::string &value);
private:
L_DISABLE_COPY(CoreHeader);
};
// -------------------------------------------------------------------------
// Core headers.
// -------------------------------------------------------------------------
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");
// -------------------------------------------------------------------------
// Specific Subject declaration.
// -------------------------------------------------------------------------
class SubjectHeaderPrivate;
class SubjectHeader : public CoreHeader {
friend class HeaderNode;
public:
SubjectHeader ();
inline std::string getName () const override {
return "Subject";
}
bool setValue (const std::string &value) override;
std::string getLanguage () const;
bool setLanguage (const std::string &language);
std::string asString () const override;
protected:
void force (const std::string &value, const std::string &language);
private:
L_DECLARE_PRIVATE(SubjectHeader);
L_DISABLE_COPY(SubjectHeader);
};
}
}
#undef MAKE_CORE_HEADER
#endif // ifndef _CPIM_CORE_HEADERS_H_
/*
* cpim-generic-header.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <set>
#include "cpim-header-p.h"
#include "cpim/parser/cpim-parser.h"
#include "utils/utils.h"
#include "cpim-generic-header.h"
using namespace std;
using namespace LinphonePrivate;
// =============================================================================
class Cpim::GenericHeaderPrivate : public HeaderPrivate {
public:
string name;
shared_ptr<list<pair<string, string> > > parameters = make_shared<list<pair<string, string> > >();
};
Cpim::GenericHeader::GenericHeader () : Header(*new GenericHeaderPrivate) {}
string Cpim::GenericHeader::getName () const {
L_D(const GenericHeader);
return d->name;
}
bool Cpim::GenericHeader::setName (const string &name) {
L_D(GenericHeader);
static const set<string> reserved = {
"From", "To", "cc", "DateTime", "Subject", "NS", "Require"
};
if (
reserved.find(name) != reserved.end() ||
!Parser::getInstance()->headerNameIsValid(name)
)
return false;
d->name = name;
return true;
}
bool Cpim::GenericHeader::setValue (const string &value) {
return Parser::getInstance()->headerValueIsValid(value) && Header::setValue(value);
}
Cpim::GenericHeader::ParameterList Cpim::GenericHeader::getParameters () const {
L_D(const GenericHeader);
return d->parameters;
}
bool Cpim::GenericHeader::addParameter (const string &key, const string &value) {
L_D(GenericHeader);
if (!Parser::getInstance()->headerParameterIsValid(key + "=" + value))
return false;
d->parameters->push_back(make_pair(key, value));
return true;
}
void Cpim::GenericHeader::removeParameter (const string &key, const string &value) {
L_D(GenericHeader);
d->parameters->remove(make_pair(key, value));
}
bool Cpim::GenericHeader::isValid () const {
L_D(const GenericHeader);
return !d->name.empty() && !getValue().empty();
}
string Cpim::GenericHeader::asString () const {
L_D(const GenericHeader);
string parameters;
for (const auto &parameter : *d->parameters)
parameters += ";" + parameter.first + "=" + parameter.second;
return d->name + ":" + parameters + " " + getValue() + "\r\n";
}
// -----------------------------------------------------------------------------
void Cpim::GenericHeader::force (const string &name, const string &value, const string &parameters) {
L_D(GenericHeader);
// Set name/value.
d->name = name;
Header::setValue(value);
// Parse and build parameters list.
for (const auto &parameter : Utils::split(parameters, ';')) {
size_t equalIndex = parameter.find('=');
if (equalIndex != string::npos)
d->parameters->push_back(make_pair(parameter.substr(0, equalIndex), parameter.substr(equalIndex + 1)));
}
}
/*
* cpim-generic-header.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CPIM_GENERIC_HEADER_H_
#define _CPIM_GENERIC_HEADER_H_
#include <list>
#include <memory>
#include "cpim-header.h"
// =============================================================================
namespace LinphonePrivate {
namespace Cpim {
class GenericHeaderPrivate;
class HeaderNode;
class GenericHeader : public Header {
friend class HeaderNode;
public:
GenericHeader ();
std::string getName () const override;
bool setName (const std::string &name);
bool setValue (const std::string &value) override;
typedef std::shared_ptr<const std::list<std::pair<std::string, std::string> > > ParameterList;
ParameterList getParameters () const;
bool addParameter (const std::string &key, const std::string &value);
void removeParameter (const std::string &key, const std::string &value);
bool isValid () const override;
std::string asString () const override;
protected:
void force (const std::string &name, const std::string &value, const std::string &parameters);
private:
L_DECLARE_PRIVATE(GenericHeader);
L_DISABLE_COPY(GenericHeader);
};
}
}
#endif // ifndef _CPIM_GENERIC_HEADER_H_
/*
* cpim-header-p.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CPIM_HEADER_P_H_
#define _CPIM_HEADER_P_H_
#include "cpim-header.h"
// =============================================================================
namespace LinphonePrivate {
namespace Cpim {
class HeaderPrivate : public ObjectPrivate {
public:
virtual ~HeaderPrivate () = default;
private:
std::string value;
L_DECLARE_PUBLIC(Header);
};
}
}
#endif // ifndef _CPIM_HEADER_P_H_
/*
* cpim-header.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cpim-header-p.h"
#include "cpim-header.h"
using namespace std;
using namespace LinphonePrivate;
// =============================================================================
Cpim::Header::Header (HeaderPrivate &p) : Object(p) {}
string Cpim::Header::getValue () const {
L_D(const Header);
return d->value;
}
bool Cpim::Header::setValue (const string &value) {
L_D(Header);
d->value = value;
return true;
}
string Cpim::Header::asString () const {
L_D(const Header);
return getName() + ": " + d->value + "\r\n";
}
/*
* cpim-header.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CPIM_HEADER_H_
#define _CPIM_HEADER_H_
#include <string>
#include "object/object.h"
// =============================================================================
namespace LinphonePrivate {
namespace Cpim {
class HeaderPrivate;
class Header : public Object {
public:
virtual ~Header () = default;
virtual std::string getName () const = 0;
std::string getValue () const;
virtual bool setValue (const std::string &value);
virtual bool isValid () const = 0;
virtual std::string asString () const;
protected:
explicit Header (HeaderPrivate &p);
private:
L_DECLARE_PRIVATE(Header);
L_DISABLE_COPY(Header);
};
}
}
#endif // ifndef _CPIM_HEADER_H_
/*
* cpim-message.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include "cpim/parser/cpim-parser.h"
#include "utils/utils.h"
#include "cpim-message.h"
using namespace std;
using namespace LinphonePrivate;
// =============================================================================
class Cpim::MessagePrivate : public ObjectPrivate {
public:
typedef list<shared_ptr<const Header> > PrivHeaderList;
shared_ptr<PrivHeaderList> cpimHeaders = make_shared<PrivHeaderList>();
shared_ptr<PrivHeaderList> messageHeaders = make_shared<PrivHeaderList>();
string content;
};
Cpim::Message::Message () : Object(*new MessagePrivate) {}
// -----------------------------------------------------------------------------
Cpim::Message::HeaderList Cpim::Message::getCpimHeaders () const {
L_D(const Message);
return d->cpimHeaders;
}
bool Cpim::Message::addCpimHeader (const Header &cpimHeader) {
L_D(Message);
if (!cpimHeader.isValid())
return false;
d->cpimHeaders->push_back(Parser::getInstance()->cloneHeader(cpimHeader));
return true;
}
void Cpim::Message::removeCpimHeader (const Header &cpimHeader) {
L_D(Message);
d->cpimHeaders->remove_if([&cpimHeader](const shared_ptr<const Header> &header) {
return cpimHeader.getName() == header->getName() && cpimHeader.getValue() == header->getValue();
});
}
// -----------------------------------------------------------------------------
Cpim::Message::HeaderList Cpim::Message::getMessageHeaders () const {
L_D(const Message);
return d->messageHeaders;
}
bool Cpim::Message::addMessageHeader (const Header &messageHeader) {
L_D(Message);
if (!messageHeader.isValid())
return false;
d->messageHeaders->push_back(Parser::getInstance()->cloneHeader(messageHeader));
return true;
}
void Cpim::Message::removeMessageHeader (const Header &messageHeader) {
L_D(Message);
d->messageHeaders->remove_if([&messageHeader](const shared_ptr<const Header> &header) {
return messageHeader.getName() == header->getName() && messageHeader.getValue() == header->getValue();