Merge remote-tracking branch 'origin/master' into dev_conference_info

This commit is contained in:
Benjamin Reis 2017-08-16 17:10:11 +02:00
commit c33a2c3028
30 changed files with 782 additions and 467 deletions

View file

@ -125,6 +125,7 @@ else()
endif()
find_package(XML2 REQUIRED)
find_package(LibXsd REQUIRED)
find_package(Soci REQUIRED)
find_package(Zlib)
if(ENABLE_TUNNEL)
if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)

View file

@ -159,6 +159,7 @@ set(LIBS
${XML2_LIBRARIES}
${BELR_LIBRARIES}
${LIBXSD_LIBRARIES}
${SOCI_LIBRARY}
)
if(WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
list(APPEND LIBS "Ws2_32")

View file

@ -3515,22 +3515,24 @@ extern "C" jint Java_org_linphone_core_PayloadTypeImpl_getRate(JNIEnv* env,jobj
/* Linphone Player */
struct LinphonePlayerData {
LinphonePlayerData(JNIEnv *env, jobject listener, jobject window) :
mListener(env->NewGlobalRef(listener)),
mWindow(env->NewGlobalRef(window))
mListener(listener ? env->NewGlobalRef(listener) : NULL), mListenerClass(NULL),
mWindow(window ? env->NewGlobalRef(window) : NULL)
{
mListenerClass = (jclass)env->NewGlobalRef(env->GetObjectClass(listener));
mEndOfFileMethodID = env->GetMethodID(mListenerClass, "endOfFile", "(Lorg/linphone/core/LinphonePlayer;)V");
if(mEndOfFileMethodID == NULL) {
ms_error("Could not get endOfFile method ID");
env->ExceptionClear();
if (mListener){
mListenerClass = (jclass)env->NewGlobalRef(env->GetObjectClass(listener));
mEndOfFileMethodID = env->GetMethodID(mListenerClass, "endOfFile", "(Lorg/linphone/core/LinphonePlayer;)V");
if(mEndOfFileMethodID == NULL) {
ms_error("Could not get endOfFile method ID");
env->ExceptionClear();
}
}
}
~LinphonePlayerData() {
JNIEnv *env;
jvm->AttachCurrentThread(&env, NULL);
env->DeleteGlobalRef(mListener);
env->DeleteGlobalRef(mListenerClass);
if (mListener) env->DeleteGlobalRef(mListener);
if (mListenerClass) env->DeleteGlobalRef(mListenerClass);
if (mWindow) env->DeleteGlobalRef(mWindow);
}
@ -3546,8 +3548,10 @@ struct LinphonePlayerData {
static void _eof_callback(LinphonePlayer *player) {
JNIEnv *env;
LinphonePlayerData *player_data = (LinphonePlayerData *)linphone_player_get_user_data(player);
jvm->AttachCurrentThread(&env, NULL);
env->CallVoidMethod(player_data->mListener, player_data->mEndOfFileMethodID, player_data->mJLinphonePlayer);
if (player_data->mListener){
jvm->AttachCurrentThread(&env, NULL);
env->CallVoidMethod(player_data->mListener, player_data->mEndOfFileMethodID, player_data->mJLinphonePlayer);
}
}
extern "C" void Java_org_linphone_core_LinphonePlayerImpl_init(JNIEnv *env, jobject jPlayer, jlong ptr) {
@ -3804,7 +3808,7 @@ extern "C" jfloat Java_org_linphone_core_LinphoneCallImpl_getAverageQuality( JNI
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getPlayer(JNIEnv *env, jobject thiz, jlong callPtr) {
LinphonePlayer *player = linphone_call_get_player((LinphoneCall *)callPtr);
LinphonePlayerData *data = new LinphonePlayerData(env, thiz, NULL);
LinphonePlayerData *data = new LinphonePlayerData(env, NULL, NULL);
linphone_player_set_user_data(player, data);
return (jlong)linphone_player_ref(player);
}
@ -7609,7 +7613,7 @@ JNIEXPORT void JNICALL Java_org_linphone_core_ErrorInfoImpl_unref(JNIEnv *env, j
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_createLocalPlayer(JNIEnv *env, jobject jobj, jlong ptr, jobject window) {
LinphonePlayer *player = linphone_core_create_local_player((LinphoneCore *)ptr, NULL, "MSAndroidDisplay", (void *)window);
LinphonePlayerData *data = new LinphonePlayerData(env, jobj, window);
LinphonePlayerData *data = new LinphonePlayerData(env, NULL, window);
linphone_player_set_user_data(player, data);
if(player == NULL) {
ms_error("Fails to create a player");

View file

@ -32,8 +32,11 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
cpim/message/cpim-message.h
cpim/parser/cpim-grammar.h
cpim/parser/cpim-parser.h
object/object.h
logger/logger.h
object/clonable-object.h
object/clonable-object-p.h
object/object-p.h
object/object.h
object/singleton.h
utils/general.h
utils/utils.h
@ -50,6 +53,8 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
cpim/message/cpim-message.cpp
cpim/parser/cpim-grammar.cpp
cpim/parser/cpim-parser.cpp
logger/logger.cpp
object/clonable-object.cpp
object/object.cpp
utils/utils.cpp
xml/conference-info.cpp
@ -59,8 +64,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
ADD_XSD_WRAPPERS(xml/xml "XML XSD - xml.xsd")
ADD_XSD_WRAPPERS(xml/conference-info "Conference info XSD - conference-info.xsd")
set(LINPHONE_CXX_OBJECTS_DEFINITIONS "-DLIBLINPHONE_EXPORTS")
set(LINPHONE_CXX_OBJECTS_INCLUDE_DIRS ${BELR_INCLUDE_DIRS} ${LIBXSD_INCLUDE_DIRS})
set(LINPHONE_CXX_OBJECTS_INCLUDE_DIRS ${BELR_INCLUDE_DIRS} ${SOCI_INCLUDE_DIRS} ${SOCI_MYSQL_INCLUDES} ${LIBXSD_INCLUDE_DIRS})
set(LINPHONE_PRIVATE_HEADER_FILES)
foreach(header ${LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES})

View file

@ -21,11 +21,11 @@
#include "cpim-core-headers.h"
// =============================================================================
using namespace std;
using namespace LinphonePrivate;
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
Cpim::CoreHeader::CoreHeader () : Header(*new HeaderPrivate) {}
@ -56,7 +56,7 @@ MAKE_CORE_HEADER_IMPL(Require);
// -----------------------------------------------------------------------------
void Cpim::CoreHeader::force (const std::string &value) {
void Cpim::CoreHeader::force (const string &value) {
Header::setValue(value);
}
@ -103,3 +103,5 @@ void Cpim::SubjectHeader::force (const string &value, const string &language) {
CoreHeader::force(value);
d->language = language;
}
LINPHONE_END_NAMESPACE

View file

@ -23,6 +23,8 @@
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
#define MAKE_CORE_HEADER(CLASS_PREFIX, NAME) \
class LINPHONE_PUBLIC CLASS_PREFIX ## Header : public CoreHeader { \
public: \
@ -35,77 +37,77 @@
L_DISABLE_COPY(CLASS_PREFIX ## Header); \
};
namespace LinphonePrivate {
namespace Cpim {
class HeaderNode;
namespace Cpim {
class HeaderNode;
// -------------------------------------------------------------------------
// Generic core header.
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// Generic core header.
// -------------------------------------------------------------------------
class LINPHONE_PUBLIC CoreHeader : public Header {
friend class HeaderNode;
class LINPHONE_PUBLIC CoreHeader : public Header {
friend class HeaderNode;
public:
CoreHeader ();
public:
CoreHeader ();
virtual ~CoreHeader () = 0;
virtual ~CoreHeader () = 0;
bool isValid () const override;
bool isValid () const override;
protected:
explicit CoreHeader (HeaderPrivate &p);
protected:
explicit CoreHeader (HeaderPrivate &p);
void force (const std::string &value);
void force (const std::string &value);
private:
L_DISABLE_COPY(CoreHeader);
};
private:
L_DISABLE_COPY(CoreHeader);
};
// -------------------------------------------------------------------------
// Core headers.
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// 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");
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.
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// Specific Subject declaration.
// -------------------------------------------------------------------------
class SubjectHeaderPrivate;
class SubjectHeaderPrivate;
class LINPHONE_PUBLIC SubjectHeader : public CoreHeader {
friend class HeaderNode;
class LINPHONE_PUBLIC SubjectHeader : public CoreHeader {
friend class HeaderNode;
public:
SubjectHeader ();
public:
SubjectHeader ();
inline std::string getName () const override {
return "Subject";
}
inline std::string getName () const override {
return "Subject";
}
bool setValue (const std::string &value) override;
bool setValue (const std::string &value) override;
std::string getLanguage () const;
bool setLanguage (const std::string &language);
std::string getLanguage () const;
bool setLanguage (const std::string &language);
std::string asString () const override;
std::string asString () const override;
protected:
void force (const std::string &value, const std::string &language);
protected:
void force (const std::string &value, const std::string &language);
private:
L_DECLARE_PRIVATE(SubjectHeader);
L_DISABLE_COPY(SubjectHeader);
};
}
private:
L_DECLARE_PRIVATE(SubjectHeader);
L_DISABLE_COPY(SubjectHeader);
};
}
#undef MAKE_CORE_HEADER
LINPHONE_END_NAMESPACE
#endif // ifndef _CPIM_CORE_HEADERS_H_

View file

@ -24,11 +24,11 @@
#include "cpim-generic-header.h"
// =============================================================================
using namespace std;
using namespace LinphonePrivate;
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class Cpim::GenericHeaderPrivate : public HeaderPrivate {
public:
@ -117,3 +117,5 @@ void Cpim::GenericHeader::force (const string &name, const string &value, const
d->parameters->push_back(make_pair(parameter.substr(0, equalIndex), parameter.substr(equalIndex + 1)));
}
}
LINPHONE_END_NAMESPACE

View file

@ -26,40 +26,42 @@
// =============================================================================
namespace LinphonePrivate {
namespace Cpim {
class GenericHeaderPrivate;
class HeaderNode;
LINPHONE_BEGIN_NAMESPACE
class LINPHONE_PUBLIC GenericHeader : public Header {
friend class HeaderNode;
namespace Cpim {
class GenericHeaderPrivate;
class HeaderNode;
public:
GenericHeader ();
class LINPHONE_PUBLIC GenericHeader : public Header {
friend class HeaderNode;
std::string getName () const override;
bool setName (const std::string &name);
public:
GenericHeader ();
bool setValue (const std::string &value) override;
std::string getName () const override;
bool setName (const std::string &name);
typedef std::shared_ptr<const std::list<std::pair<std::string, std::string> > > ParameterList;
bool setValue (const std::string &value) override;
ParameterList getParameters () const;
bool addParameter (const std::string &key, const std::string &value);
void removeParameter (const std::string &key, const std::string &value);
typedef std::shared_ptr<const std::list<std::pair<std::string, std::string> > > ParameterList;
bool isValid () const override;
ParameterList getParameters () const;
bool addParameter (const std::string &key, const std::string &value);
void removeParameter (const std::string &key, const std::string &value);
std::string asString () const override;
bool isValid () const override;
protected:
void force (const std::string &name, const std::string &value, const std::string &parameters);
std::string asString () const override;
private:
L_DECLARE_PRIVATE(GenericHeader);
L_DISABLE_COPY(GenericHeader);
};
}
protected:
void force (const std::string &name, const std::string &value, const std::string &parameters);
private:
L_DECLARE_PRIVATE(GenericHeader);
L_DISABLE_COPY(GenericHeader);
};
}
LINPHONE_END_NAMESPACE
#endif // ifndef _CPIM_GENERIC_HEADER_H_

View file

@ -24,18 +24,20 @@
// =============================================================================
namespace LinphonePrivate {
namespace Cpim {
class HeaderPrivate : public ObjectPrivate {
public:
virtual ~HeaderPrivate () = default;
LINPHONE_BEGIN_NAMESPACE
private:
std::string value;
namespace Cpim {
class HeaderPrivate : public ObjectPrivate {
public:
virtual ~HeaderPrivate () = default;
L_DECLARE_PUBLIC(Header);
};
}
private:
std::string value;
L_DECLARE_PUBLIC(Header);
};
}
LINPHONE_END_NAMESPACE
#endif // ifndef _CPIM_HEADER_P_H_

View file

@ -20,11 +20,11 @@
#include "cpim-header.h"
// =============================================================================
using namespace std;
using namespace LinphonePrivate;
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
Cpim::Header::Header (HeaderPrivate &p) : Object(p) {}
@ -43,3 +43,5 @@ string Cpim::Header::asString () const {
L_D(const Header);
return getName() + ": " + d->value + "\r\n";
}
LINPHONE_END_NAMESPACE

View file

@ -25,31 +25,33 @@
// =============================================================================
namespace LinphonePrivate {
namespace Cpim {
class HeaderPrivate;
LINPHONE_BEGIN_NAMESPACE
class LINPHONE_PUBLIC Header : public Object {
public:
virtual ~Header () = default;
namespace Cpim {
class HeaderPrivate;
virtual std::string getName () const = 0;
class LINPHONE_PUBLIC Header : public Object {
public:
virtual ~Header () = default;
std::string getValue () const;
virtual bool setValue (const std::string &value);
virtual std::string getName () const = 0;
virtual bool isValid () const = 0;
std::string getValue () const;
virtual bool setValue (const std::string &value);
virtual std::string asString () const;
virtual bool isValid () const = 0;
protected:
explicit Header (HeaderPrivate &p);
virtual std::string asString () const;
private:
L_DECLARE_PRIVATE(Header);
L_DISABLE_COPY(Header);
};
}
protected:
explicit Header (HeaderPrivate &p);
private:
L_DECLARE_PRIVATE(Header);
L_DISABLE_COPY(Header);
};
}
LINPHONE_END_NAMESPACE
#endif // ifndef _CPIM_HEADER_H_

View file

@ -24,11 +24,11 @@
#include "cpim-message.h"
// =============================================================================
using namespace std;
using namespace LinphonePrivate;
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class Cpim::MessagePrivate : public ObjectPrivate {
public:
@ -139,3 +139,5 @@ string Cpim::Message::asString () const {
shared_ptr<const Cpim::Message> Cpim::Message::createFromString (const string &str) {
return Parser::getInstance()->parseMessage(str);
}
LINPHONE_END_NAMESPACE

View file

@ -24,38 +24,40 @@
// =============================================================================
namespace LinphonePrivate {
namespace Cpim {
class MessagePrivate;
LINPHONE_BEGIN_NAMESPACE
class LINPHONE_PUBLIC Message : public Object {
public:
Message ();
namespace Cpim {
class MessagePrivate;
typedef std::shared_ptr<std::list<std::shared_ptr<const Cpim::Header> > > HeaderList;
class LINPHONE_PUBLIC Message : public Object {
public:
Message ();
HeaderList getCpimHeaders () const;
bool addCpimHeader (const Header &cpimHeader);
void removeCpimHeader (const Header &cpimHeader);
typedef std::shared_ptr<std::list<std::shared_ptr<const Cpim::Header> > > HeaderList;
HeaderList getMessageHeaders () const;
bool addMessageHeader (const Header &messageHeader);
void removeMessageHeader (const Header &messageHeader);
HeaderList getCpimHeaders () const;
bool addCpimHeader (const Header &cpimHeader);
void removeCpimHeader (const Header &cpimHeader);
std::string getContent () const;
bool setContent (const std::string &content);
HeaderList getMessageHeaders () const;
bool addMessageHeader (const Header &messageHeader);
void removeMessageHeader (const Header &messageHeader);
bool isValid () const;
std::string getContent () const;
bool setContent (const std::string &content);
std::string asString () const;
bool isValid () const;
static std::shared_ptr<const Message> createFromString (const std::string &str);
std::string asString () const;
private:
L_DECLARE_PRIVATE(Message);
L_DISABLE_COPY(Message);
};
}
static std::shared_ptr<const Message> createFromString (const std::string &str);
private:
L_DECLARE_PRIVATE(Message);
L_DISABLE_COPY(Message);
};
}
LINPHONE_END_NAMESPACE
#endif // ifndef _CPIM_MESSAGE_H_

View file

@ -20,8 +20,9 @@
// =============================================================================
namespace LinphonePrivate {
static const char *grammar =
LINPHONE_BEGIN_NAMESPACE
static const char *grammar =
// See: https://tools.ietf.org/html/rfc3862
R"==GRAMMAR==(
Message = Headers CRLF Headers CRLF
@ -200,8 +201,9 @@ full-time = partial-time time-offset
date-time = full-date "T" full-time
)==GRAMMAR==";
}
const char *LinphonePrivate::Cpim::getGrammar () {
const char *Cpim::getGrammar () {
return grammar;
}
LINPHONE_END_NAMESPACE

View file

@ -19,12 +19,16 @@
#ifndef _CPIM_GRAMMAR_H_
#define _CPIM_GRAMMAR_H_
#include "utils/general.h"
// =============================================================================
namespace LinphonePrivate {
namespace Cpim {
const char *getGrammar ();
}
LINPHONE_BEGIN_NAMESPACE
namespace Cpim {
const char *getGrammar ();
}
LINPHONE_END_NAMESPACE
#endif // ifndef _CPIM_GRAMMAR_H_

View file

@ -21,188 +21,186 @@
#include <belr/abnf.h>
#include <belr/grammarbuilder.h>
#include "linphone/core.h"
#include "cpim-grammar.h"
#include "logger/logger.h"
#include "object/object-p.h"
#include "utils/utils.h"
#include "cpim-parser.h"
using namespace std;
using namespace LinphonePrivate;
// =============================================================================
namespace LinphonePrivate {
namespace Cpim {
class Node {
public:
virtual ~Node () = default;
};
using namespace std;
class HeaderNode : public Node {
public:
HeaderNode () = default;
LINPHONE_BEGIN_NAMESPACE
explicit HeaderNode (const Header &header) {
mName = header.getName();
mValue = header.getValue();
namespace Cpim {
class Node {
public:
virtual ~Node () = default;
};
// Generic header.
const GenericHeader *genericHeader = dynamic_cast<const GenericHeader *>(&header);
if (genericHeader) {
for (const auto &parameter : *genericHeader->getParameters())
mParameters += ";" + parameter.first + "=" + parameter.second;
return;
}
class HeaderNode : public Node {
public:
HeaderNode () = default;
// Subject header.
const SubjectHeader *subjectHeader = dynamic_cast<const SubjectHeader *>(&header);
if (subjectHeader) {
const string language = subjectHeader->getLanguage();
if (!language.empty())
mParameters = ";lang=" + language;
}
explicit HeaderNode (const Header &header) {
mName = header.getName();
mValue = header.getValue();
// Generic header.
const GenericHeader *genericHeader = dynamic_cast<const GenericHeader *>(&header);
if (genericHeader) {
for (const auto &parameter : *genericHeader->getParameters())
mParameters += ";" + parameter.first + "=" + parameter.second;
return;
}
string getName () const {
return mName;
// Subject header.
const SubjectHeader *subjectHeader = dynamic_cast<const SubjectHeader *>(&header);
if (subjectHeader) {
const string language = subjectHeader->getLanguage();
if (!language.empty())
mParameters = ";lang=" + language;
}
}
void setName (const string &name) {
mName = name;
}
string getName () const {
return mName;
}
string getParameters () const {
return mParameters;
}
void setName (const string &name) {
mName = name;
}
void setParameters (const string &parameters) {
mParameters = parameters;
}
string getParameters () const {
return mParameters;
}
string getValue () const {
return mValue;
}
void setParameters (const string &parameters) {
mParameters = parameters;
}
void setValue (const string &value) {
mValue = value;
}
string getValue () const {
return mValue;
}
shared_ptr<Header> createHeader (bool force) const;
void setValue (const string &value) {
mValue = value;
}
private:
template<typename T>
shared_ptr<Header> createCoreHeader (bool force) const {
shared_ptr<T> header = make_shared<T>();
if (force)
header->force(mValue);
else if (!header->setValue(mValue)) {
ms_fatal("Unable to set value on core header: `%s` => `%s`.", mName.c_str(), mValue.c_str());
return nullptr;
}
return header;
}
string mValue;
string mName;
string mParameters;
};
template<>
shared_ptr<Header> HeaderNode::createCoreHeader<SubjectHeader>(bool force) const {
shared_ptr<SubjectHeader> header = make_shared<SubjectHeader>();
const string language = mParameters.length() >= 6 ? mParameters.substr(6) : "";
shared_ptr<Header> createHeader (bool force) const;
private:
template<typename T>
shared_ptr<Header> createCoreHeader (bool force) const {
shared_ptr<T> header = make_shared<T>();
if (force)
header->force(mValue, language);
else if (!header->setValue(mValue) || (!language.empty() && !header->setLanguage(language))) {
ms_fatal("Unable to set value on subject header: `%s` => `%s`, `%s`.", mName.c_str(), mValue.c_str(), language.c_str());
header->force(mValue);
else if (!header->setValue(mValue)) {
lWarning() << "Unable to set value on core header: `" << mName << "` => `" << mValue << "`.";
return nullptr;
}
return header;
}
shared_ptr<Header> HeaderNode::createHeader (bool force = false) const {
static const unordered_map<string, shared_ptr<Header>(HeaderNode::*)(bool)const> reservedHandlers = {
{ "From", &HeaderNode::createCoreHeader<FromHeader> },
{ "To", &HeaderNode::createCoreHeader<ToHeader> },
{ "cc", &HeaderNode::createCoreHeader<CcHeader> },
{ "DateTime", &HeaderNode::createCoreHeader<DateTimeHeader> },
{ "Subject", &HeaderNode::createCoreHeader<SubjectHeader> },
{ "NS", &HeaderNode::createCoreHeader<NsHeader> },
{ "Require", &HeaderNode::createCoreHeader<RequireHeader> }
};
string mValue;
string mName;
string mParameters;
};
// Core Header.
const auto it = reservedHandlers.find(mName);
if (it != reservedHandlers.cend())
return (this->*it->second)(force);
template<>
shared_ptr<Header> HeaderNode::createCoreHeader<SubjectHeader>(bool force) const {
shared_ptr<SubjectHeader> header = make_shared<SubjectHeader>();
const string language = mParameters.length() >= 6 ? mParameters.substr(6) : "";
// Generic Header
shared_ptr<GenericHeader> genericHeader = make_shared<GenericHeader>();
genericHeader->force(mName, mValue, mParameters);
return genericHeader;
if (force)
header->force(mValue, language);
else if (!header->setValue(mValue) || (!language.empty() && !header->setLanguage(language))) {
lWarning() << "Unable to set value on subject header: `" <<
mName << "` => `" << mValue << "`, `" << language << "`.";
return nullptr;
}
// -------------------------------------------------------------------------
class ListHeaderNode :
public Node,
public list<shared_ptr<HeaderNode> > {};
// -------------------------------------------------------------------------
class MessageNode : public Node {
public:
void addHeaders (const shared_ptr<ListHeaderNode> &headers) {
mHeaders->push_back(headers);
}
// Warning: Call this function one time!
shared_ptr<Message> createMessage () const {
size_t size = mHeaders->size();
if (size != 2) {
ms_fatal("Bad headers lists size.");
return nullptr;
}
const shared_ptr<Message> message = make_shared<Message>();
const shared_ptr<ListHeaderNode> cpimHeaders = mHeaders->front();
if (find_if(cpimHeaders->cbegin(), cpimHeaders->cend(),
[](const shared_ptr<const HeaderNode> &headerNode) {
return Utils::iequals(headerNode->getName(), "content-type") && headerNode->getValue() == "Message/CPIM";
}) == cpimHeaders->cend()) {
ms_fatal("No MIME `Content-Type` found!");
return nullptr;
}
// Add MIME headers.
for (const auto &headerNode : *cpimHeaders) {
const shared_ptr<const Header> header = headerNode->createHeader();
if (!header || !message->addCpimHeader(*header))
return nullptr;
}
// Add message headers.
for (const auto &headerNode : *mHeaders->back()) {
const shared_ptr<const Header> header = headerNode->createHeader();
if (!header || !message->addMessageHeader(*header))
return nullptr;
}
return message;
}
private:
shared_ptr<list<shared_ptr<ListHeaderNode> > > mHeaders = make_shared<list<shared_ptr<ListHeaderNode> > >();
};
return header;
}
shared_ptr<Header> HeaderNode::createHeader (bool force = false) const {
static const unordered_map<string, shared_ptr<Header>(HeaderNode::*)(bool)const> reservedHandlers = {
{ "From", &HeaderNode::createCoreHeader<FromHeader> },
{ "To", &HeaderNode::createCoreHeader<ToHeader> },
{ "cc", &HeaderNode::createCoreHeader<CcHeader> },
{ "DateTime", &HeaderNode::createCoreHeader<DateTimeHeader> },
{ "Subject", &HeaderNode::createCoreHeader<SubjectHeader> },
{ "NS", &HeaderNode::createCoreHeader<NsHeader> },
{ "Require", &HeaderNode::createCoreHeader<RequireHeader> }
};
// Core Header.
const auto it = reservedHandlers.find(mName);
if (it != reservedHandlers.cend())
return (this->*it->second)(force);
// Generic Header
shared_ptr<GenericHeader> genericHeader = make_shared<GenericHeader>();
genericHeader->force(mName, mValue, mParameters);
return genericHeader;
}
// -------------------------------------------------------------------------
class ListHeaderNode :
public Node,
public list<shared_ptr<HeaderNode> > {};
// -------------------------------------------------------------------------
class MessageNode : public Node {
public:
void addHeaders (const shared_ptr<ListHeaderNode> &headers) {
mHeaders->push_back(headers);
}
// Warning: Call this function one time!
shared_ptr<Message> createMessage () const {
size_t size = mHeaders->size();
if (size != 2) {
lWarning() << "Bad headers lists size.";
return nullptr;
}
const shared_ptr<Message> message = make_shared<Message>();
const shared_ptr<ListHeaderNode> cpimHeaders = mHeaders->front();
if (find_if(cpimHeaders->cbegin(), cpimHeaders->cend(),
[](const shared_ptr<const HeaderNode> &headerNode) {
return Utils::iequals(headerNode->getName(), "content-type") && headerNode->getValue() == "Message/CPIM";
}) == cpimHeaders->cend()) {
lWarning() << "No MIME `Content-Type` found!";
return nullptr;
}
// Add MIME headers.
for (const auto &headerNode : *cpimHeaders) {
const shared_ptr<const Header> header = headerNode->createHeader();
if (!header || !message->addCpimHeader(*header))
return nullptr;
}
// Add message headers.
for (const auto &headerNode : *mHeaders->back()) {
const shared_ptr<const Header> header = headerNode->createHeader();
if (!header || !message->addMessageHeader(*header))
return nullptr;
}
return message;
}
private:
shared_ptr<list<shared_ptr<ListHeaderNode> > > mHeaders = make_shared<list<shared_ptr<ListHeaderNode> > >();
};
}
// -----------------------------------------------------------------------------
@ -219,7 +217,7 @@ Cpim::Parser::Parser () : Singleton(*new ParserPrivate) {
d->grammar = builder.createFromAbnf(getGrammar(), make_shared<belr::CoreRules>());
if (!d->grammar)
ms_fatal("Unable to build CPIM grammar.");
lFatal() << "Unable to build CPIM grammar.";
}
// -----------------------------------------------------------------------------
@ -255,13 +253,13 @@ shared_ptr<Cpim::Message> Cpim::Parser::parseMessage (const string &input) {
size_t parsedSize;
shared_ptr<Node> node = parser.parseInput("Message", input, &parsedSize);
if (!node) {
ms_fatal("Unable to parse message.");
lWarning() << "Unable to parse message.";
return nullptr;
}
shared_ptr<MessageNode> messageNode = dynamic_pointer_cast<MessageNode>(node);
if (!messageNode) {
ms_fatal("Unable to cast belr result to message node.");
lWarning() << "Unable to cast belr result to message node.";
return nullptr;
}
@ -294,17 +292,17 @@ inline bool headerIsValid (const shared_ptr<belr::Grammar> &grammar, const strin
bool Cpim::Parser::headerNameIsValid (const string &headerName) const {
L_D(const Parser);
return ::headerIsValid(d->grammar, headerName + ": value\r\n");
return headerIsValid(d->grammar, headerName + ": value\r\n");
}
bool Cpim::Parser::headerValueIsValid (const string &headerValue) const {
L_D(const Parser);
return ::headerIsValid(d->grammar, "key: " + headerValue + "\r\n");
return headerIsValid(d->grammar, "key: " + headerValue + "\r\n");
}
bool Cpim::Parser::headerParameterIsValid (const std::string &headerParameter) const {
bool Cpim::Parser::headerParameterIsValid (const string &headerParameter) const {
L_D(const Parser);
return ::headerIsValid(d->grammar, "key:;" + headerParameter + " value\r\n");
return headerIsValid(d->grammar, "key:;" + headerParameter + " value\r\n");
}
// -----------------------------------------------------------------------------
@ -332,19 +330,19 @@ inline bool coreHeaderIsValid (
template<>
bool Cpim::Parser::coreHeaderIsValid<Cpim::FromHeader>(const string &headerValue) const {
L_D(const Parser);
return ::coreHeaderIsValid(d->grammar, "From", headerValue);
return LINPHONE_NAMESPACE::coreHeaderIsValid(d->grammar, "From", headerValue);
}
template<>
bool Cpim::Parser::coreHeaderIsValid<Cpim::ToHeader>(const string &headerValue) const {
L_D(const Parser);
return ::coreHeaderIsValid(d->grammar, "To", headerValue);
return LINPHONE_NAMESPACE::coreHeaderIsValid(d->grammar, "To", headerValue);
}
template<>
bool Cpim::Parser::coreHeaderIsValid<Cpim::CcHeader>(const string &headerValue) const {
L_D(const Parser);
return ::coreHeaderIsValid(d->grammar, "cc", headerValue);
return LINPHONE_NAMESPACE::coreHeaderIsValid(d->grammar, "cc", headerValue);
}
template<>
@ -352,7 +350,7 @@ bool Cpim::Parser::coreHeaderIsValid<Cpim::DateTimeHeader>(const string &headerV
static const int daysInMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
L_D(const Parser);
if (!::coreHeaderIsValid(d->grammar, "DateTime", headerValue))
if (!LINPHONE_NAMESPACE::coreHeaderIsValid(d->grammar, "DateTime", headerValue))
return false;
// Check date.
@ -391,24 +389,26 @@ bool Cpim::Parser::coreHeaderIsValid<Cpim::DateTimeHeader>(const string &headerV
template<>
bool Cpim::Parser::coreHeaderIsValid<Cpim::SubjectHeader>(const string &headerValue) const {
L_D(const Parser);
return ::coreHeaderIsValid(d->grammar, "Subject", headerValue);
return LINPHONE_NAMESPACE::coreHeaderIsValid(d->grammar, "Subject", headerValue);
}
template<>
bool Cpim::Parser::coreHeaderIsValid<Cpim::NsHeader>(const string &headerValue) const {
L_D(const Parser);
return ::coreHeaderIsValid(d->grammar, "NS", headerValue);
return LINPHONE_NAMESPACE::coreHeaderIsValid(d->grammar, "NS", headerValue);
}
template<>
bool Cpim::Parser::coreHeaderIsValid<Cpim::RequireHeader>(const string &headerValue) const {
L_D(const Parser);
return ::coreHeaderIsValid(d->grammar, "Require", headerValue);
return LINPHONE_NAMESPACE::coreHeaderIsValid(d->grammar, "Require", headerValue);
}
// -----------------------------------------------------------------------------
bool Cpim::Parser::subjectHeaderLanguageIsValid (const string &language) const {
L_D(const Parser);
return ::coreHeaderIsValid(d->grammar, "Subject", "SubjectValue", ";lang=" + language);
return LINPHONE_NAMESPACE::coreHeaderIsValid(d->grammar, "Subject", "SubjectValue", ";lang=" + language);
}
LINPHONE_END_NAMESPACE

View file

@ -24,59 +24,61 @@
// =============================================================================
namespace LinphonePrivate {
namespace Cpim {
class ParserPrivate;
LINPHONE_BEGIN_NAMESPACE
class Parser : public Singleton<Parser> {
friend class Singleton<Parser>;
namespace Cpim {
class ParserPrivate;
public:
std::shared_ptr<Message> parseMessage (const std::string &input);
class Parser : public Singleton<Parser> {
friend class Singleton<Parser>;
std::shared_ptr<Header> cloneHeader (const Header &header);
public:
std::shared_ptr<Message> parseMessage (const std::string &input);
bool headerNameIsValid (const std::string &headerName) const;
bool headerValueIsValid (const std::string &headerValue) const;
bool headerParameterIsValid (const std::string &headerParameter) const;
std::shared_ptr<Header> cloneHeader (const Header &header);
template<typename>
bool coreHeaderIsValid (const std::string &headerValue) const {
return false;
}
bool headerNameIsValid (const std::string &headerName) const;
bool headerValueIsValid (const std::string &headerValue) const;
bool headerParameterIsValid (const std::string &headerParameter) const;
bool subjectHeaderLanguageIsValid (const std::string &language) const;
template<typename>
bool coreHeaderIsValid (const std::string &headerValue) const {
return false;
}
private:
Parser ();
bool subjectHeaderLanguageIsValid (const std::string &language) const;
L_DECLARE_PRIVATE(Parser);
L_DISABLE_COPY(Parser);
};
private:
Parser ();
// -------------------------------------------------------------------------
L_DECLARE_PRIVATE(Parser);
L_DISABLE_COPY(Parser);
};
template<>
bool Parser::coreHeaderIsValid<FromHeader>(const std::string &headerValue) const;
// ---------------------------------------------------------------------------
template<>
bool Parser::coreHeaderIsValid<ToHeader>(const std::string &headerValue) const;
template<>
bool Parser::coreHeaderIsValid<FromHeader>(const std::string &headerValue) const;
template<>
bool Parser::coreHeaderIsValid<CcHeader>(const std::string &headerValue) const;
template<>
bool Parser::coreHeaderIsValid<ToHeader>(const std::string &headerValue) const;
template<>
bool Parser::coreHeaderIsValid<DateTimeHeader>(const std::string &headerValue) const;
template<>
bool Parser::coreHeaderIsValid<CcHeader>(const std::string &headerValue) const;
template<>
bool Parser::coreHeaderIsValid<SubjectHeader>(const std::string &headerValue) const;
template<>
bool Parser::coreHeaderIsValid<DateTimeHeader>(const std::string &headerValue) const;
template<>
bool Parser::coreHeaderIsValid<NsHeader>(const std::string &headerValue) const;
template<>
bool Parser::coreHeaderIsValid<SubjectHeader>(const std::string &headerValue) const;
template<>
bool Parser::coreHeaderIsValid<RequireHeader>(const std::string &headerValue) const;
}
template<>
bool Parser::coreHeaderIsValid<NsHeader>(const std::string &headerValue) const;
template<>
bool Parser::coreHeaderIsValid<RequireHeader>(const std::string &headerValue) const;
}
LINPHONE_END_NAMESPACE
#endif // ifndef _CPIM_PARSER_H_

74
src/logger/logger.cpp Normal file
View file

@ -0,0 +1,74 @@
/*
* logger.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 "linphone/core.h"
#include "object/object-p.h"
#include "logger.h"
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
class LoggerPrivate : public ObjectPrivate {
public:
Logger::Level level;
ostringstream os;
};
// -----------------------------------------------------------------------------
Logger::Logger (Level level) : Object(*new LoggerPrivate) {
L_D(Logger);
d->level = level;
}
Logger::~Logger () {
L_D(Logger);
d->os << endl;
const string str = d->os.str();
switch (d->level) {
case Debug:
ms_debug("%s", str.c_str());
break;
case Info:
ms_message("%s", str.c_str());
break;
case Warning:
ms_warning("%s", str.c_str());
break;
case Error:
ms_error("%s", str.c_str());
break;
case Fatal:
ms_fatal("%s", str.c_str());
break;
}
}
ostringstream &Logger::getOutput () {
L_D(Logger);
return d->os;
}
LINPHONE_END_NAMESPACE

60
src/logger/logger.h Normal file
View file

@ -0,0 +1,60 @@
/*
* logger.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 _LOGGER_H_
#define _LOGGER_H_
#include <sstream>
#include "object/object.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class LoggerPrivate;
class LINPHONE_PUBLIC Logger : public Object {
public:
enum Level {
Debug,
Info,
Warning,
Error,
Fatal
};
Logger (Level level);
~Logger ();
std::ostringstream &getOutput ();
private:
L_DECLARE_PRIVATE(Logger);
L_DISABLE_COPY(Logger);
};
LINPHONE_END_NAMESPACE
#define lDebug() LINPHONE_NAMESPACE::Logger(Logger::Debug).getOutput()
#define lInfo() LINPHONE_NAMESPACE::Logger(Logger::Info).getOutput()
#define lWarning() LINPHONE_NAMESPACE::Logger(Logger::Warning).getOutput()
#define lError() LINPHONE_NAMESPACE::Logger(Logger::Error).getOutput()
#define lFatal() LINPHONE_NAMESPACE::Logger(Logger::Fatal).getOutput()
#endif // ifndef _LOGGER_H_

View file

@ -0,0 +1,43 @@
/*
* clonable-object-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 _CLONABLE_OBJECT_P_H_
#define _CLONABLE_OBJECT_P_H_
#include "utils/general.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class ClonableObject;
class ClonableObjectPrivate {
public:
virtual ~ClonableObjectPrivate () = default;
protected:
ClonableObject *mPublic = nullptr;
private:
L_DECLARE_PUBLIC(ClonableObject);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _CLONABLE_OBJECT_P_H_

View file

@ -0,0 +1,35 @@
/*
* clonable-object.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 "clonable-object-p.h"
#include "clonable-object.h"
LINPHONE_BEGIN_NAMESPACE
// =============================================================================
ClonableObject::~ClonableObject () {
delete mPrivate;
}
ClonableObject::ClonableObject (ClonableObjectPrivate &p) : mPrivate(&p) {
mPrivate->mPublic = this;
}
LINPHONE_END_NAMESPACE

View file

@ -0,0 +1,45 @@
/*
* clonable-object.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 _CLONABLE_OBJECT_H_
#define _CLONABLE_OBJECT_H_
#include "utils/general.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class ClonableObjectPrivate;
class LINPHONE_PUBLIC ClonableObject {
public:
virtual ~ClonableObject ();
protected:
explicit ClonableObject (ClonableObjectPrivate &p);
ClonableObjectPrivate *mPrivate = nullptr;
private:
L_DECLARE_PRIVATE(ClonableObject);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _CLONABLE_OBJECT_H_

View file

@ -23,19 +23,21 @@
// =============================================================================
namespace LinphonePrivate {
class Object;
LINPHONE_BEGIN_NAMESPACE
class ObjectPrivate {
public:
virtual ~ObjectPrivate () = default;
class Object;
protected:
Object *mPublic = nullptr;
class ObjectPrivate {
public:
virtual ~ObjectPrivate () = default;
private:
L_DECLARE_PUBLIC(Object);
};
}
protected:
Object *mPublic = nullptr;
private:
L_DECLARE_PUBLIC(Object);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _OBJECT_P_H_

View file

@ -20,10 +20,10 @@
#include "object.h"
using namespace LinphonePrivate;
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
Object::~Object () {
delete mPrivate;
}
@ -31,3 +31,5 @@ Object::~Object () {
Object::Object (ObjectPrivate &p) : mPrivate(&p) {
mPrivate->mPublic = this;
}
LINPHONE_END_NAMESPACE

View file

@ -23,22 +23,24 @@
// =============================================================================
namespace LinphonePrivate {
class ObjectPrivate;
LINPHONE_BEGIN_NAMESPACE
class LINPHONE_PUBLIC Object {
public:
virtual ~Object ();
class ObjectPrivate;
protected:
explicit Object (ObjectPrivate &p);
class LINPHONE_PUBLIC Object {
public:
virtual ~Object ();
ObjectPrivate *mPrivate = nullptr;
protected:
explicit Object (ObjectPrivate &p);
private:
L_DECLARE_PRIVATE(Object);
L_DISABLE_COPY(Object);
};
}
ObjectPrivate *mPrivate = nullptr;
private:
L_DECLARE_PRIVATE(Object);
L_DISABLE_COPY(Object);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _OBJECT_H_

View file

@ -23,37 +23,25 @@
// =============================================================================
namespace LinphonePrivate {
template<class T>
class Singleton : public Object {
public:
virtual ~Singleton () = default;
LINPHONE_BEGIN_NAMESPACE
static T *getInstance () {
if (!mInstance) {
mInstance = new T();
static SingletonDeleter deleter;
}
return mInstance;
}
template<class T>
class Singleton : public Object {
public:
virtual ~Singleton () = default;
protected:
explicit Singleton (ObjectPrivate &p) : Object(p) {}
static T *getInstance () {
static T instance;
return &instance;
}
private:
struct SingletonDeleter {
~SingletonDeleter () {
delete mInstance;
}
};
protected:
explicit Singleton (ObjectPrivate &p) : Object(p) {}
static T *mInstance;
private:
L_DISABLE_COPY(Singleton);
};
L_DISABLE_COPY(Singleton);
};
template<class T>
T *Singleton<T>::mInstance = nullptr;
}
LINPHONE_END_NAMESPACE
#endif // ifndef _SINGLETON_H_

View file

@ -39,6 +39,12 @@
// -----------------------------------------------------------------------------
#define LINPHONE_NAMESPACE LinphonePrivate
#define LINPHONE_BEGIN_NAMESPACE namespace LINPHONE_NAMESPACE {
#define LINPHONE_END_NAMESPACE }
// -----------------------------------------------------------------------------
#define L_DECLARE_PRIVATE(CLASS) \
inline CLASS ## Private * getPrivate() { \
return reinterpret_cast<CLASS ## Private *>(mPrivate); \

View file

@ -20,11 +20,11 @@
#include "utils.h"
// =============================================================================
using namespace std;
using namespace LinphonePrivate;
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
bool Utils::iequals (const string &a, const string &b) {
size_t size = a.size();
@ -59,3 +59,5 @@ int Utils::stoi (const string &str, size_t *idx, int base) {
return v;
}
LINPHONE_END_NAMESPACE

View file

@ -22,20 +22,24 @@
#include <string>
#include <vector>
#include "general.h"
// =============================================================================
namespace LinphonePrivate {
namespace Utils {
bool iequals (const std::string &a, const std::string &b);
LINPHONE_BEGIN_NAMESPACE
std::vector<std::string> split (const std::string &str, const std::string &delimiter);
namespace Utils {
bool iequals (const std::string &a, const std::string &b);
inline std::vector<std::string> split (const std::string &str, char delimiter) {
return split(str, std::string(1, delimiter));
}
std::vector<std::string> split (const std::string &str, const std::string &delimiter);
int stoi (const std::string &str, size_t *idx = 0, int base = 10);
inline std::vector<std::string> split (const std::string &str, char delimiter) {
return split(str, std::string(1, delimiter));
}
int stoi (const std::string &str, size_t *idx = 0, int base = 10);
}
LINPHONE_END_NAMESPACE
#endif // ifndef _UTILS_H_

View file

@ -30,7 +30,7 @@ namespace Linphone
/// <summary>
/// Only contains the LIB_NAME value that represents the library in which all DllImport are made
/// </summary>
public class LinphoneWrapper
public class LinphoneWrapper
{
#if __IOS__
public const string LIB_NAME = "linphone.framework/linphone";
@ -40,8 +40,10 @@ namespace Linphone
#if WINDOWS_UWP
public const string BELLE_SIP_LIB_NAME = "bellesip";
public const string BCTOOLBOX_LIB_NAME = "bctoolbox";
#else
public const string BELLE_SIP_LIB_NAME = "linphone";
public const string BCTOOLBOX_LIB_NAME = "linphone";
#endif
#if ANDROID
@ -86,7 +88,7 @@ namespace Linphone
protected LinphoneException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
}
#endif
[StructLayout(LayoutKind.Sequential)]
/// <summary>
/// Parent class for a Linphone public objects
@ -94,56 +96,58 @@ namespace Linphone
public class LinphoneObject
{
internal IntPtr nativePtr;
internal GCHandle handle;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void OnLinphoneObjectDataDestroyed(IntPtr data);
[DllImport(LinphoneWrapper.BELLE_SIP_LIB_NAME)]
#if WINDOWS_UWP
static extern int belle_sip_object_data_set(IntPtr ptr, string name, IntPtr data, IntPtr cb);
#else
static extern int belle_sip_object_data_set(IntPtr ptr, string name, IntPtr data, OnLinphoneObjectDataDestroyed cb);
#endif
[DllImport(LinphoneWrapper.BELLE_SIP_LIB_NAME)]
static extern IntPtr belle_sip_object_data_get(IntPtr ptr, string name);
[DllImport(LinphoneWrapper.BELLE_SIP_LIB_NAME)]
static extern IntPtr belle_sip_object_ref(IntPtr ptr);
[DllImport(LinphoneWrapper.BELLE_SIP_LIB_NAME)]
static extern void belle_sip_object_unref(IntPtr ptr);
[DllImport(LinphoneWrapper.BELLE_SIP_LIB_NAME)]
static extern void belle_sip_object_data_remove(IntPtr ptr, string data);
[DllImport(LinphoneWrapper.BCTOOLBOX_LIB_NAME)]
static extern IntPtr bctbx_list_next(IntPtr ptr);
[DllImport(LinphoneWrapper.BELLE_SIP_LIB_NAME)]
[DllImport(LinphoneWrapper.BCTOOLBOX_LIB_NAME)]
static extern IntPtr bctbx_list_get_data(IntPtr ptr);
[DllImport(LinphoneWrapper.BELLE_SIP_LIB_NAME)]
[DllImport(LinphoneWrapper.BCTOOLBOX_LIB_NAME)]
static extern IntPtr bctbx_list_append(IntPtr elem, string data);
[DllImport(LinphoneWrapper.BELLE_SIP_LIB_NAME)]
[DllImport(LinphoneWrapper.BCTOOLBOX_LIB_NAME)]
static extern IntPtr bctbx_list_append(IntPtr elem, IntPtr data);
#if __IOS__
[MonoPInvokeCallback(typeof(OnLinphoneObjectDataDestroyed))]
#endif
private static void onDataDestroyed(IntPtr data)
{
if (data != IntPtr.Zero)
{
//Console.WriteLine("Freeing C# handle");
GCHandle handle = GCHandle.FromIntPtr(data);
handle.Free();
}
}
~LinphoneObject()
{
//Console.WriteLine("Destroying " + this.ToString());
if (nativePtr != IntPtr.Zero) {
//Console.WriteLine("Unreffing " + this.ToString());
belle_sip_object_data_remove(nativePtr, "cs_obj");
belle_sip_object_unref(nativePtr);
handle.Free();
}
}
internal static T fromNativePtr<T>(IntPtr ptr, bool takeRef=true) where T : LinphoneObject, new()
{
if (ptr == IntPtr.Zero) return null;
@ -177,14 +181,15 @@ namespace Linphone
//Console.WriteLine("Reffing " + obj.ToString());
}
obj.nativePtr = ptr;
GCHandle handle = GCHandle.Alloc(obj, GCHandleType.WeakTrackResurrection);
objPtr = GCHandle.ToIntPtr(handle);
belle_sip_object_data_set(ptr, "cs_obj", objPtr, onDataDestroyed);
obj.handle = GCHandle.Alloc(obj, GCHandleType.WeakTrackResurrection);
objPtr = GCHandle.ToIntPtr(obj.handle);
belle_sip_object_data_set(ptr, "cs_obj", objPtr, IntPtr.Zero);
return obj;
}
return null;
}
internal static IEnumerable<string> MarshalStringArray(IntPtr arrayPtr)
{
if (arrayPtr != IntPtr.Zero)
@ -199,7 +204,7 @@ namespace Linphone
}
}
}
internal static IEnumerable<T> MarshalBctbxList<T>(IntPtr listPtr) where T : LinphoneObject, new()
{
if (listPtr != IntPtr.Zero)
@ -239,7 +244,7 @@ namespace Linphone
return bctbx_list;
}
}
#if ANDROID
/// <summary>
/// Methods that are only found in Android version of Linphone libraries and related to JNI
@ -251,7 +256,7 @@ namespace Linphone
[DllImport(LinphoneWrapper.LIB_NAME)]
static extern void setMediastreamerAndroidContext(IntPtr jnienv, IntPtr context);
/// <summary>
/// Sets the JVM and JNI pointers in Linphone, required to be able to make JAVA upcalls.
/// Calling this method is mandatory and must be done as soon as possible !
@ -264,7 +269,7 @@ namespace Linphone
}
#endif
#endregion
#region Enums
{{#enums}}
{{#enum}}
@ -284,11 +289,11 @@ namespace Linphone
{{name}} = {{value}},
{{/values}}
}
{{/enum}}
{{/enums}}
#endregion
#region Listeners
{{#interfaces}}
{{#interface}}
@ -298,14 +303,19 @@ namespace Linphone
{{#methods}}
[DllImport(LinphoneWrapper.LIB_NAME)]
{{#cb_setter}}
#if WINDOWS_UWP
static extern void {{name}}(IntPtr thiz, IntPtr cb);
#else
static extern void {{name}}(IntPtr thiz, {{name_private}} cb);
#endif
{{/cb_setter}}
{{#delegate}}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void {{name_private}}({{params_private}});
public delegate void {{name_public}}({{params_public}});
private {{name_private}} {{var_private}};
private {{name_public}} {{var_public}};
#if __IOS__
@ -328,17 +338,23 @@ namespace Linphone
set
{
{{var_public}} = value;
#if WINDOWS_UWP
{{var_private}} = {{cb_name}};
IntPtr cb = Marshal.GetFunctionPointerForDelegate({{var_private}});
{{c_name_setter}}(nativePtr, cb);
#else
{{c_name_setter}}(nativePtr, {{cb_name}});
#endif
}
}
{{/delegate}}
{{/delegate}}
{{/methods}}
}
{{/interface}}
{{/interfaces}}
#endregion
#region Classes
{{#classes}}
{{#_class}}
@ -353,21 +369,21 @@ namespace Linphone
{{#isLinphoneFactory}}
[DllImport(LinphoneWrapper.LIB_NAME)]
static extern IntPtr linphone_factory_create_core_cbs(IntPtr factory);
public CoreListener CreateCoreListener()
{
IntPtr coreCbsPtr = linphone_factory_create_core_cbs(nativePtr);
return fromNativePtr<CoreListener>(coreCbsPtr, false);
}
{{/isLinphoneFactory}}
{{#dllImports}}
{{/isLinphoneFactory}}
{{#dllImports}}
[DllImport(LinphoneWrapper.LIB_NAME)]
{{{prototype}}}
{{#has_second_prototype}}
[DllImport(LinphoneWrapper.LIB_NAME)]
{{second_prototype}}
{{/has_second_prototype}}
{{#has_property}}
{{#doc}}
{{#lines}}
@ -384,7 +400,7 @@ namespace Linphone
return Marshal.PtrToStringAnsi(stringPtr);
{{/is_string}}
{{#is_bool}}
return {{getter_c_name}}({{getter_nativePtr}}) == 0;
return {{getter_c_name}}({{getter_nativePtr}}) == 1;
{{/is_bool}}
{{#is_class}}
IntPtr ptr = {{getter_c_name}}({{getter_nativePtr}});
@ -478,7 +494,7 @@ namespace Linphone
{{/has_impl}}
{{/dllImports}}
}
{{/_class}}
{{/_class}}
{{/classes}}
#endregion
}
}