From d150c2677a9e172d47ca660af6c7c61ace499f5f Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 10 Aug 2017 15:20:03 +0200 Subject: [PATCH 1/9] fix crash in linphoneplayer end of file --- coreapi/linphonecore_jni.cc | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 08108902b..5f730ca0c 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -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"); From 30cd76587184e9b1e64b0de7117a4d4b00351254 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Thu, 10 Aug 2017 15:33:45 +0200 Subject: [PATCH 2/9] feat(core): provide a cpp logger --- src/CMakeLists.txt | 4 +- src/cpim/parser/cpim-parser.cpp | 18 ++++---- src/logger/logger.cpp | 74 +++++++++++++++++++++++++++++++++ src/logger/logger.h | 58 ++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 10 deletions(-) create mode 100644 src/logger/logger.cpp create mode 100644 src/logger/logger.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f02e12816..823db4682 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,8 +29,9 @@ 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/object-p.h + object/object.h object/singleton.h utils/general.h utils/utils.h @@ -43,6 +44,7 @@ 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/object.cpp utils/utils.cpp ) diff --git a/src/cpim/parser/cpim-parser.cpp b/src/cpim/parser/cpim-parser.cpp index 8c637fcb4..e29371f7f 100644 --- a/src/cpim/parser/cpim-parser.cpp +++ b/src/cpim/parser/cpim-parser.cpp @@ -21,9 +21,8 @@ #include #include -#include "linphone/core.h" - #include "cpim-grammar.h" +#include "logger/logger.h" #include "object/object-p.h" #include "utils/utils.h" @@ -100,7 +99,7 @@ namespace LinphonePrivate { 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()); + lWarning() << "Unable to set value on core header: `" << mName << "` => `" << mValue << "`."; return nullptr; } @@ -120,7 +119,8 @@ namespace LinphonePrivate { 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()); + lWarning() << "Unable to set value on subject header: `" << + mName << "` => `" << mValue << "`, `" << language << "`."; return nullptr; } @@ -167,7 +167,7 @@ namespace LinphonePrivate { shared_ptr createMessage () const { size_t size = mHeaders->size(); if (size != 2) { - ms_fatal("Bad headers lists size."); + lWarning() << "Bad headers lists size."; return nullptr; } @@ -178,7 +178,7 @@ namespace LinphonePrivate { [](const shared_ptr &headerNode) { return Utils::iequals(headerNode->getName(), "content-type") && headerNode->getValue() == "Message/CPIM"; }) == cpimHeaders->cend()) { - ms_fatal("No MIME `Content-Type` found!"); + lWarning() << "No MIME `Content-Type` found!"; return nullptr; } @@ -219,7 +219,7 @@ Cpim::Parser::Parser () : Singleton(*new ParserPrivate) { d->grammar = builder.createFromAbnf(getGrammar(), make_shared()); if (!d->grammar) - ms_fatal("Unable to build CPIM grammar."); + lFatal() << "Unable to build CPIM grammar."; } // ----------------------------------------------------------------------------- @@ -255,13 +255,13 @@ shared_ptr Cpim::Parser::parseMessage (const string &input) { size_t parsedSize; shared_ptr node = parser.parseInput("Message", input, &parsedSize); if (!node) { - ms_fatal("Unable to parse message."); + lWarning() << "Unable to parse message."; return nullptr; } shared_ptr messageNode = dynamic_pointer_cast(node); if (!messageNode) { - ms_fatal("Unable to cast belr result to message node."); + lWarning() << "Unable to cast belr result to message node."; return nullptr; } diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp new file mode 100644 index 000000000..ae70a6201 --- /dev/null +++ b/src/logger/logger.cpp @@ -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 . + */ + +#include "linphone/core.h" + +#include "object/object-p.h" + +#include "logger.h" + +using namespace std; + +using namespace LinphonePrivate; + +// ============================================================================= + +namespace LinphonePrivate { + 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; +} diff --git a/src/logger/logger.h b/src/logger/logger.h new file mode 100644 index 000000000..2c435fb78 --- /dev/null +++ b/src/logger/logger.h @@ -0,0 +1,58 @@ +/* + * 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 . + */ + +#ifndef _LOGGER_H_ +#define _LOGGER_H_ + +#include + +#include "object/object.h" + +// ============================================================================= + +namespace LinphonePrivate { + 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); + }; +} + +#define lDebug() LinphonePrivate::Logger(Logger::Debug).getOutput() +#define lInfo() LinphonePrivate::Logger(Logger::Info).getOutput() +#define lWarning() LinphonePrivate::Logger(Logger::Warning).getOutput() +#define lError() LinphonePrivate::Logger(Logger::Error).getOutput() +#define lFatal() LinphonePrivate::Logger(Logger::Fatal).getOutput() + +#endif // ifndef _LOGGER_H_ From 8891799efcd32a7d711386ecd510d9a52e8cbf5c Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Fri, 11 Aug 2017 10:46:37 +0200 Subject: [PATCH 3/9] Fix wrapper for UWP --- wrappers/csharp/wrapper_impl.mustache | 65 ++++++++++++++++----------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/wrappers/csharp/wrapper_impl.mustache b/wrappers/csharp/wrapper_impl.mustache index 924be6fda..d9488b22f 100644 --- a/wrappers/csharp/wrapper_impl.mustache +++ b/wrappers/csharp/wrapper_impl.mustache @@ -30,7 +30,7 @@ namespace Linphone /// /// Only contains the LIB_NAME value that represents the library in which all DllImport are made /// - public class LinphoneWrapper + public class LinphoneWrapper { #if __IOS__ public const string LIB_NAME = "linphone.framework/linphone"; @@ -86,7 +86,7 @@ namespace Linphone protected LinphoneException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } } #endif - + [StructLayout(LayoutKind.Sequential)] /// /// Parent class for a Linphone public objects @@ -94,7 +94,7 @@ namespace Linphone public class LinphoneObject { internal IntPtr nativePtr; - + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void OnLinphoneObjectDataDestroyed(IntPtr data); @@ -103,16 +103,16 @@ namespace Linphone [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 IntPtr bctbx_list_next(IntPtr ptr); - + [DllImport(LinphoneWrapper.BELLE_SIP_LIB_NAME)] static extern IntPtr bctbx_list_get_data(IntPtr ptr); @@ -134,7 +134,7 @@ namespace Linphone handle.Free(); } } - + ~LinphoneObject() { //Console.WriteLine("Destroying " + this.ToString()); @@ -143,7 +143,7 @@ namespace Linphone belle_sip_object_unref(nativePtr); } } - + internal static T fromNativePtr(IntPtr ptr, bool takeRef=true) where T : LinphoneObject, new() { if (ptr == IntPtr.Zero) return null; @@ -184,7 +184,7 @@ namespace Linphone } return null; } - + internal static IEnumerable MarshalStringArray(IntPtr arrayPtr) { if (arrayPtr != IntPtr.Zero) @@ -199,7 +199,7 @@ namespace Linphone } } } - + internal static IEnumerable MarshalBctbxList(IntPtr listPtr) where T : LinphoneObject, new() { if (listPtr != IntPtr.Zero) @@ -239,7 +239,7 @@ namespace Linphone return bctbx_list; } } - + #if ANDROID /// /// Methods that are only found in Android version of Linphone libraries and related to JNI @@ -251,7 +251,7 @@ namespace Linphone [DllImport(LinphoneWrapper.LIB_NAME)] static extern void setMediastreamerAndroidContext(IntPtr jnienv, IntPtr context); - + /// /// 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 +264,7 @@ namespace Linphone } #endif #endregion - + #region Enums {{#enums}} {{#enum}} @@ -284,11 +284,11 @@ namespace Linphone {{name}} = {{value}}, {{/values}} } - + {{/enum}} {{/enums}} #endregion - + #region Listeners {{#interfaces}} {{#interface}} @@ -298,14 +298,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 +333,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 +364,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(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}} @@ -478,7 +489,7 @@ namespace Linphone {{/has_impl}} {{/dllImports}} } - {{/_class}} + {{/_class}} {{/classes}} #endregion -} \ No newline at end of file +} From 87ab5a9465bfa8e36bdfd7b49935d9f9f71ee66b Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Fri, 11 Aug 2017 11:15:41 +0200 Subject: [PATCH 4/9] feat(src): use now a LINPHONE_{BEGIN,END}_NAMESPACE macro --- src/cpim/header/cpim-core-headers.cpp | 10 +- src/cpim/header/cpim-core-headers.h | 100 ++++---- src/cpim/header/cpim-generic-header.cpp | 8 +- src/cpim/header/cpim-generic-header.h | 50 ++-- src/cpim/header/cpim-header-p.h | 22 +- src/cpim/header/cpim-header.cpp | 8 +- src/cpim/header/cpim-header.h | 38 +-- src/cpim/message/cpim-message.cpp | 8 +- src/cpim/message/cpim-message.h | 48 ++-- src/cpim/parser/cpim-grammar.cpp | 10 +- src/cpim/parser/cpim-grammar.h | 12 +- src/cpim/parser/cpim-parser.cpp | 316 ++++++++++++------------ src/cpim/parser/cpim-parser.h | 76 +++--- src/logger/logger.cpp | 22 +- src/logger/logger.h | 52 ++-- src/object/object-p.h | 24 +- src/object/object.cpp | 6 +- src/object/object.h | 28 ++- src/object/singleton.h | 54 ++-- src/utils/general.h | 6 + src/utils/utils.cpp | 8 +- src/utils/utils.h | 20 +- 22 files changed, 487 insertions(+), 439 deletions(-) diff --git a/src/cpim/header/cpim-core-headers.cpp b/src/cpim/header/cpim-core-headers.cpp index d49ba6ee0..6270b810a 100644 --- a/src/cpim/header/cpim-core-headers.cpp +++ b/src/cpim/header/cpim-core-headers.cpp @@ -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 diff --git a/src/cpim/header/cpim-core-headers.h b/src/cpim/header/cpim-core-headers.h index 3ff1deecd..15519e5b5 100644 --- a/src/cpim/header/cpim-core-headers.h +++ b/src/cpim/header/cpim-core-headers.h @@ -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_ diff --git a/src/cpim/header/cpim-generic-header.cpp b/src/cpim/header/cpim-generic-header.cpp index 6c043c55d..040a17e7f 100644 --- a/src/cpim/header/cpim-generic-header.cpp +++ b/src/cpim/header/cpim-generic-header.cpp @@ -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 diff --git a/src/cpim/header/cpim-generic-header.h b/src/cpim/header/cpim-generic-header.h index 94ced0e44..259e60046 100644 --- a/src/cpim/header/cpim-generic-header.h +++ b/src/cpim/header/cpim-generic-header.h @@ -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 > > 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 > > 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 ¶meters); + 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 ¶meters); + + private: + L_DECLARE_PRIVATE(GenericHeader); + L_DISABLE_COPY(GenericHeader); + }; } +LINPHONE_END_NAMESPACE + #endif // ifndef _CPIM_GENERIC_HEADER_H_ diff --git a/src/cpim/header/cpim-header-p.h b/src/cpim/header/cpim-header-p.h index 446e98647..af1606b12 100644 --- a/src/cpim/header/cpim-header-p.h +++ b/src/cpim/header/cpim-header-p.h @@ -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_ diff --git a/src/cpim/header/cpim-header.cpp b/src/cpim/header/cpim-header.cpp index 694b9ffd1..0db1585a6 100644 --- a/src/cpim/header/cpim-header.cpp +++ b/src/cpim/header/cpim-header.cpp @@ -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 diff --git a/src/cpim/header/cpim-header.h b/src/cpim/header/cpim-header.h index 1839d3afa..8fadea125 100644 --- a/src/cpim/header/cpim-header.h +++ b/src/cpim/header/cpim-header.h @@ -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_ diff --git a/src/cpim/message/cpim-message.cpp b/src/cpim/message/cpim-message.cpp index 7eab6fea0..d005efc40 100644 --- a/src/cpim/message/cpim-message.cpp +++ b/src/cpim/message/cpim-message.cpp @@ -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 Cpim::Message::createFromString (const string &str) { return Parser::getInstance()->parseMessage(str); } + +LINPHONE_END_NAMESPACE diff --git a/src/cpim/message/cpim-message.h b/src/cpim/message/cpim-message.h index fe8d0d03f..6905cb364 100644 --- a/src/cpim/message/cpim-message.h +++ b/src/cpim/message/cpim-message.h @@ -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 > > 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 > > 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 createFromString (const std::string &str); + std::string asString () const; - private: - L_DECLARE_PRIVATE(Message); - L_DISABLE_COPY(Message); - }; - } + static std::shared_ptr createFromString (const std::string &str); + + private: + L_DECLARE_PRIVATE(Message); + L_DISABLE_COPY(Message); + }; } +LINPHONE_END_NAMESPACE + #endif // ifndef _CPIM_MESSAGE_H_ diff --git a/src/cpim/parser/cpim-grammar.cpp b/src/cpim/parser/cpim-grammar.cpp index 91eab3d30..94bd86d16 100644 --- a/src/cpim/parser/cpim-grammar.cpp +++ b/src/cpim/parser/cpim-grammar.cpp @@ -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 diff --git a/src/cpim/parser/cpim-grammar.h b/src/cpim/parser/cpim-grammar.h index 45887a661..d75cbd008 100644 --- a/src/cpim/parser/cpim-grammar.h +++ b/src/cpim/parser/cpim-grammar.h @@ -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_ diff --git a/src/cpim/parser/cpim-parser.cpp b/src/cpim/parser/cpim-parser.cpp index e29371f7f..c57a15ab2 100644 --- a/src/cpim/parser/cpim-parser.cpp +++ b/src/cpim/parser/cpim-parser.cpp @@ -28,181 +28,179 @@ #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(&header); - if (genericHeader) { - for (const auto ¶meter : *genericHeader->getParameters()) - mParameters += ";" + parameter.first + "=" + parameter.second; - return; - } + class HeaderNode : public Node { + public: + HeaderNode () = default; - // Subject header. - const SubjectHeader *subjectHeader = dynamic_cast(&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(&header); + if (genericHeader) { + for (const auto ¶meter : *genericHeader->getParameters()) + mParameters += ";" + parameter.first + "=" + parameter.second; + return; } - string getName () const { - return mName; + // Subject header. + const SubjectHeader *subjectHeader = dynamic_cast(&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 ¶meters) { - mParameters = parameters; - } + string getParameters () const { + return mParameters; + } - string getValue () const { - return mValue; - } + void setParameters (const string ¶meters) { + mParameters = parameters; + } - void setValue (const string &value) { - mValue = value; - } + string getValue () const { + return mValue; + } - shared_ptr
createHeader (bool force) const; + void setValue (const string &value) { + mValue = value; + } - private: - template - shared_ptr
createCoreHeader (bool force) const { - shared_ptr header = make_shared(); - if (force) - header->force(mValue); - else if (!header->setValue(mValue)) { - lWarning() << "Unable to set value on core header: `" << mName << "` => `" << mValue << "`."; - return nullptr; - } - - return header; - } - - string mValue; - string mName; - string mParameters; - }; - - template<> - shared_ptr
HeaderNode::createCoreHeader(bool force) const { - shared_ptr header = make_shared(); - const string language = mParameters.length() >= 6 ? mParameters.substr(6) : ""; + shared_ptr
createHeader (bool force) const; + private: + template + shared_ptr
createCoreHeader (bool force) const { + shared_ptr header = make_shared(); 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 << "`."; + header->force(mValue); + else if (!header->setValue(mValue)) { + lWarning() << "Unable to set value on core header: `" << mName << "` => `" << mValue << "`."; return nullptr; } return header; } - shared_ptr
HeaderNode::createHeader (bool force = false) const { - static const unordered_map(HeaderNode::*)(bool)const> reservedHandlers = { - { "From", &HeaderNode::createCoreHeader }, - { "To", &HeaderNode::createCoreHeader }, - { "cc", &HeaderNode::createCoreHeader }, - { "DateTime", &HeaderNode::createCoreHeader }, - { "Subject", &HeaderNode::createCoreHeader }, - { "NS", &HeaderNode::createCoreHeader }, - { "Require", &HeaderNode::createCoreHeader } - }; + 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
HeaderNode::createCoreHeader(bool force) const { + shared_ptr header = make_shared(); + const string language = mParameters.length() >= 6 ? mParameters.substr(6) : ""; - // Generic Header - shared_ptr genericHeader = make_shared(); - 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 > {}; - - // ------------------------------------------------------------------------- - - class MessageNode : public Node { - public: - void addHeaders (const shared_ptr &headers) { - mHeaders->push_back(headers); - } - - // Warning: Call this function one time! - shared_ptr createMessage () const { - size_t size = mHeaders->size(); - if (size != 2) { - lWarning() << "Bad headers lists size."; - return nullptr; - } - - const shared_ptr message = make_shared(); - const shared_ptr cpimHeaders = mHeaders->front(); - - if (find_if(cpimHeaders->cbegin(), cpimHeaders->cend(), - [](const shared_ptr &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 header = headerNode->createHeader(); - if (!header || !message->addCpimHeader(*header)) - return nullptr; - } - - // Add message headers. - for (const auto &headerNode : *mHeaders->back()) { - const shared_ptr header = headerNode->createHeader(); - if (!header || !message->addMessageHeader(*header)) - return nullptr; - } - - return message; - } - - private: - shared_ptr > > mHeaders = make_shared > >(); - }; + return header; } + + shared_ptr
HeaderNode::createHeader (bool force = false) const { + static const unordered_map(HeaderNode::*)(bool)const> reservedHandlers = { + { "From", &HeaderNode::createCoreHeader }, + { "To", &HeaderNode::createCoreHeader }, + { "cc", &HeaderNode::createCoreHeader }, + { "DateTime", &HeaderNode::createCoreHeader }, + { "Subject", &HeaderNode::createCoreHeader }, + { "NS", &HeaderNode::createCoreHeader }, + { "Require", &HeaderNode::createCoreHeader } + }; + + // Core Header. + const auto it = reservedHandlers.find(mName); + if (it != reservedHandlers.cend()) + return (this->*it->second)(force); + + // Generic Header + shared_ptr genericHeader = make_shared(); + genericHeader->force(mName, mValue, mParameters); + return genericHeader; + } + + // ------------------------------------------------------------------------- + + class ListHeaderNode : + public Node, + public list > {}; + + // ------------------------------------------------------------------------- + + class MessageNode : public Node { + public: + void addHeaders (const shared_ptr &headers) { + mHeaders->push_back(headers); + } + + // Warning: Call this function one time! + shared_ptr createMessage () const { + size_t size = mHeaders->size(); + if (size != 2) { + lWarning() << "Bad headers lists size."; + return nullptr; + } + + const shared_ptr message = make_shared(); + const shared_ptr cpimHeaders = mHeaders->front(); + + if (find_if(cpimHeaders->cbegin(), cpimHeaders->cend(), + [](const shared_ptr &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 header = headerNode->createHeader(); + if (!header || !message->addCpimHeader(*header)) + return nullptr; + } + + // Add message headers. + for (const auto &headerNode : *mHeaders->back()) { + const shared_ptr header = headerNode->createHeader(); + if (!header || !message->addMessageHeader(*header)) + return nullptr; + } + + return message; + } + + private: + shared_ptr > > mHeaders = make_shared > >(); + }; } // ----------------------------------------------------------------------------- @@ -294,17 +292,17 @@ inline bool headerIsValid (const shared_ptr &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(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(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(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(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(const string &headerV template<> bool Cpim::Parser::coreHeaderIsValid(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(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(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 diff --git a/src/cpim/parser/cpim-parser.h b/src/cpim/parser/cpim-parser.h index 397e9e3b7..fc7c42d8d 100644 --- a/src/cpim/parser/cpim-parser.h +++ b/src/cpim/parser/cpim-parser.h @@ -24,59 +24,61 @@ // ============================================================================= -namespace LinphonePrivate { - namespace Cpim { - class ParserPrivate; +LINPHONE_BEGIN_NAMESPACE - class Parser : public Singleton { - friend class Singleton; +namespace Cpim { + class ParserPrivate; - public: - std::shared_ptr parseMessage (const std::string &input); + class Parser : public Singleton { + friend class Singleton; - std::shared_ptr
cloneHeader (const Header &header); + public: + std::shared_ptr 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
cloneHeader (const Header &header); - template - 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 + 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(const std::string &headerValue) const; + // --------------------------------------------------------------------------- - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; + template<> + bool Parser::coreHeaderIsValid(const std::string &headerValue) const; - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; + template<> + bool Parser::coreHeaderIsValid(const std::string &headerValue) const; - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; + template<> + bool Parser::coreHeaderIsValid(const std::string &headerValue) const; - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; + template<> + bool Parser::coreHeaderIsValid(const std::string &headerValue) const; - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; + template<> + bool Parser::coreHeaderIsValid(const std::string &headerValue) const; - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; - } + template<> + bool Parser::coreHeaderIsValid(const std::string &headerValue) const; + + template<> + bool Parser::coreHeaderIsValid(const std::string &headerValue) const; } +LINPHONE_END_NAMESPACE + #endif // ifndef _CPIM_PARSER_H_ diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp index ae70a6201..340cf4a4f 100644 --- a/src/logger/logger.cpp +++ b/src/logger/logger.cpp @@ -22,19 +22,17 @@ #include "logger.h" -using namespace std; - -using namespace LinphonePrivate; - // ============================================================================= -namespace LinphonePrivate { - class LoggerPrivate : public ObjectPrivate { - public: - Logger::Level level; - ostringstream os; - }; -} +using namespace std; + +LINPHONE_BEGIN_NAMESPACE + +class LoggerPrivate : public ObjectPrivate { +public: + Logger::Level level; + ostringstream os; +}; // ----------------------------------------------------------------------------- @@ -72,3 +70,5 @@ ostringstream &Logger::getOutput () { L_D(Logger); return d->os; } + +LINPHONE_END_NAMESPACE diff --git a/src/logger/logger.h b/src/logger/logger.h index 2c435fb78..c3c209c1e 100644 --- a/src/logger/logger.h +++ b/src/logger/logger.h @@ -25,34 +25,36 @@ // ============================================================================= -namespace LinphonePrivate { - class LoggerPrivate; +LINPHONE_BEGIN_NAMESPACE - class LINPHONE_PUBLIC Logger : public Object { - public: - enum Level { - Debug, - Info, - Warning, - Error, - Fatal - }; +class LoggerPrivate; - Logger (Level level); - ~Logger (); - - std::ostringstream &getOutput (); - - private: - L_DECLARE_PRIVATE(Logger); - L_DISABLE_COPY(Logger); +class LINPHONE_PUBLIC Logger : public Object { +public: + enum Level { + Debug, + Info, + Warning, + Error, + Fatal }; -} -#define lDebug() LinphonePrivate::Logger(Logger::Debug).getOutput() -#define lInfo() LinphonePrivate::Logger(Logger::Info).getOutput() -#define lWarning() LinphonePrivate::Logger(Logger::Warning).getOutput() -#define lError() LinphonePrivate::Logger(Logger::Error).getOutput() -#define lFatal() LinphonePrivate::Logger(Logger::Fatal).getOutput() + 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_ diff --git a/src/object/object-p.h b/src/object/object-p.h index f08a6b968..83d7612fc 100644 --- a/src/object/object-p.h +++ b/src/object/object-p.h @@ -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_ diff --git a/src/object/object.cpp b/src/object/object.cpp index a4c0a5a34..191337235 100644 --- a/src/object/object.cpp +++ b/src/object/object.cpp @@ -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 diff --git a/src/object/object.h b/src/object/object.h index 5756bcc8e..54ed08d28 100644 --- a/src/object/object.h +++ b/src/object/object.h @@ -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_ diff --git a/src/object/singleton.h b/src/object/singleton.h index 16e16d471..2a97c6609 100644 --- a/src/object/singleton.h +++ b/src/object/singleton.h @@ -23,37 +23,39 @@ // ============================================================================= -namespace LinphonePrivate { - template - 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 Singleton : public Object { +public: + virtual ~Singleton () = default; + + static T *getInstance () { + if (!mInstance) { + mInstance = new T(); + static SingletonDeleter deleter; } + return mInstance; + } - protected: - explicit Singleton (ObjectPrivate &p) : Object(p) {} +protected: + explicit Singleton (ObjectPrivate &p) : Object(p) {} - private: - struct SingletonDeleter { - ~SingletonDeleter () { - delete mInstance; - } - }; - - static T *mInstance; - - L_DISABLE_COPY(Singleton); +private: + struct SingletonDeleter { + ~SingletonDeleter () { + delete mInstance; + } }; - template - T *Singleton::mInstance = nullptr; -} + static T *mInstance; + + L_DISABLE_COPY(Singleton); +}; + +template +T *Singleton::mInstance = nullptr; + +LINPHONE_END_NAMESPACE #endif // ifndef _SINGLETON_H_ diff --git a/src/utils/general.h b/src/utils/general.h index e0a8ed7f6..17a911eb6 100644 --- a/src/utils/general.h +++ b/src/utils/general.h @@ -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(mPrivate); \ diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index 3fa701d60..55e8d2026 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -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 diff --git a/src/utils/utils.h b/src/utils/utils.h index d061b9e35..3e5ca768d 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -22,20 +22,24 @@ #include #include +#include "general.h" + // ============================================================================= -namespace LinphonePrivate { - namespace Utils { - bool iequals (const std::string &a, const std::string &b); +LINPHONE_BEGIN_NAMESPACE - std::vector split (const std::string &str, const std::string &delimiter); +namespace Utils { + bool iequals (const std::string &a, const std::string &b); - inline std::vector split (const std::string &str, char delimiter) { - return split(str, std::string(1, delimiter)); - } + std::vector 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 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_ From 21e6a2b67913afb456a98c61f865b5f6a4d7b23d Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Fri, 11 Aug 2017 16:22:57 +0200 Subject: [PATCH 5/9] Fix crash on bellesip object destroy in UWP Wrapper --- wrappers/csharp/wrapper_impl.mustache | 35 +++++++++++++++------------ 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/wrappers/csharp/wrapper_impl.mustache b/wrappers/csharp/wrapper_impl.mustache index d9488b22f..016b45381 100644 --- a/wrappers/csharp/wrapper_impl.mustache +++ b/wrappers/csharp/wrapper_impl.mustache @@ -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 @@ -95,11 +97,17 @@ namespace Linphone { 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); @@ -111,36 +119,32 @@ namespace Linphone 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(); } } @@ -177,9 +181,10 @@ 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; From 041797aed1421b00bbd3289c66e8594fb6a32be9 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Fri, 11 Aug 2017 10:29:29 +0200 Subject: [PATCH 6/9] Add ClonableObject base class. --- src/CMakeLists.txt | 3 +++ src/object/clonable-object-p.h | 43 ++++++++++++++++++++++++++++++++ src/object/clonable-object.cpp | 35 ++++++++++++++++++++++++++ src/object/clonable-object.h | 45 ++++++++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+) create mode 100644 src/object/clonable-object-p.h create mode 100644 src/object/clonable-object.cpp create mode 100644 src/object/clonable-object.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 823db4682..c30476f70 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,6 +30,8 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES cpim/parser/cpim-grammar.h cpim/parser/cpim-parser.h logger/logger.h + object/clonable-object.h + object/clonable-object-p.h object/object-p.h object/object.h object/singleton.h @@ -45,6 +47,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES cpim/parser/cpim-grammar.cpp cpim/parser/cpim-parser.cpp logger/logger.cpp + object/clonable-object.cpp object/object.cpp utils/utils.cpp ) diff --git a/src/object/clonable-object-p.h b/src/object/clonable-object-p.h new file mode 100644 index 000000000..94c3b4491 --- /dev/null +++ b/src/object/clonable-object-p.h @@ -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 . + */ + +#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_ diff --git a/src/object/clonable-object.cpp b/src/object/clonable-object.cpp new file mode 100644 index 000000000..5b21b09b3 --- /dev/null +++ b/src/object/clonable-object.cpp @@ -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 . + */ + +#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 diff --git a/src/object/clonable-object.h b/src/object/clonable-object.h new file mode 100644 index 000000000..bda4392e1 --- /dev/null +++ b/src/object/clonable-object.h @@ -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 . + */ + +#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_ From e4415e9b16aea8b93f37ced117d16b402e9401c5 Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Mon, 14 Aug 2017 14:29:21 +0200 Subject: [PATCH 7/9] Fix getter on cs wrapper --- wrappers/csharp/wrapper_impl.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/csharp/wrapper_impl.mustache b/wrappers/csharp/wrapper_impl.mustache index 016b45381..f99438889 100644 --- a/wrappers/csharp/wrapper_impl.mustache +++ b/wrappers/csharp/wrapper_impl.mustache @@ -400,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}}); From 075bf87798041d00f95762aad443120089be270a Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Wed, 16 Aug 2017 09:38:22 +0200 Subject: [PATCH 8/9] fix(Singleton): better code --- src/object/singleton.h | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/object/singleton.h b/src/object/singleton.h index 2a97c6609..667f71f9b 100644 --- a/src/object/singleton.h +++ b/src/object/singleton.h @@ -31,31 +31,17 @@ public: virtual ~Singleton () = default; static T *getInstance () { - if (!mInstance) { - mInstance = new T(); - static SingletonDeleter deleter; - } - return mInstance; + static T instance; + return &instance; } protected: explicit Singleton (ObjectPrivate &p) : Object(p) {} private: - struct SingletonDeleter { - ~SingletonDeleter () { - delete mInstance; - } - }; - - static T *mInstance; - L_DISABLE_COPY(Singleton); }; -template -T *Singleton::mInstance = nullptr; - LINPHONE_END_NAMESPACE #endif // ifndef _SINGLETON_H_ From 154e3adce73e956a2c5afb056c1ef0bd15f9bd56 Mon Sep 17 00:00:00 2001 From: Benjamin Reis Date: Wed, 16 Aug 2017 15:51:05 +0200 Subject: [PATCH 9/9] add soci dependency --- CMakeLists.txt | 1 + coreapi/CMakeLists.txt | 1 + src/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 17b86bbaa..681df3806 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,7 @@ else() find_package(Belr REQUIRED) endif() find_package(XML2 REQUIRED) +find_package(Soci REQUIRED) find_package(Zlib) if(ENABLE_TUNNEL) if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index 64284cfb7..c2d02a538 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -158,6 +158,7 @@ set(LIBS ${ORTP_LIBRARIES} ${XML2_LIBRARIES} ${BELR_LIBRARIES} + ${SOCI_LIBRARY} ) if(WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") list(APPEND LIBS "Ws2_32") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c30476f70..8c3ec397f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -53,7 +53,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES ) set(LINPHONE_CXX_OBJECTS_DEFINITIONS "-DLIBLINPHONE_EXPORTS") -set(LINPHONE_CXX_OBJECTS_INCLUDE_DIRS ${BELR_INCLUDE_DIRS}) +set(LINPHONE_CXX_OBJECTS_INCLUDE_DIRS ${BELR_INCLUDE_DIRS} ${SOCI_INCLUDE_DIRS} ${SOCI_MYSQL_INCLUDES}) set(LINPHONE_PRIVATE_HEADER_FILES) foreach(header ${LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES})