diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index fadfd6224..6a2f3dcbf 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2259,7 +2259,7 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig lc->sal->set_callbacks(&linphone_sal_callbacks); new(&lc->cppCore) std::shared_ptr(); - lc->cppCore = ObjectFactory::create(lc); + lc->cppCore = Core::create(lc); #ifdef TUNNEL_ENABLED lc->tunnel=linphone_core_tunnel_new(lc); @@ -7237,7 +7237,7 @@ void linphone_core_set_conference_factory_uri(LinphoneCore *lc, const char *uri) } const char * linphone_core_get_conference_factory_uri(const LinphoneCore *lc) { - return lp_config_get_string(linphone_core_get_config(lc), "misc", "conference_factory_uri", "sip:"); + return lp_config_get_string(linphone_core_get_config(lc), "misc", "conference_factory_uri", nullptr); } void linphone_core_enable_conference_server (LinphoneCore *lc, bool_t enable) { @@ -7249,7 +7249,11 @@ bool_t linphone_core_conference_server_enabled (const LinphoneCore *lc) { } bool_t _linphone_core_is_conference_creation (const LinphoneCore *lc, const LinphoneAddress *addr) { - LinphoneAddress *factoryAddr = linphone_address_new(linphone_core_get_conference_factory_uri(lc)); + const char *uri = linphone_core_get_conference_factory_uri(lc); + if (!uri) + return FALSE; + + LinphoneAddress *factoryAddr = linphone_address_new(uri); if (!factoryAddr) return FALSE; bool_t result = linphone_address_weak_equal(factoryAddr, addr); diff --git a/src/address/address.cpp b/src/address/address.cpp index 1be60feb0..257fe7e1b 100644 --- a/src/address/address.cpp +++ b/src/address/address.cpp @@ -83,12 +83,20 @@ bool Address::isValid () const { const string &Address::getScheme () const { L_D(); + + if (!d->internalAddress) + return Utils::getEmptyConstRefObject(); + d->cache.scheme = L_C_TO_STRING(sal_address_get_scheme(d->internalAddress)); return d->cache.scheme; } const string &Address::getDisplayName () const { L_D(); + + if (!d->internalAddress) + return Utils::getEmptyConstRefObject(); + d->cache.displayName = L_C_TO_STRING(sal_address_get_display_name(d->internalAddress)); return d->cache.displayName; } @@ -105,6 +113,10 @@ bool Address::setDisplayName (const string &displayName) { const string &Address::getUsername () const { L_D(); + + if (!d->internalAddress) + return Utils::getEmptyConstRefObject(); + d->cache.username = L_C_TO_STRING(sal_address_get_username(d->internalAddress)); return d->cache.username; } @@ -121,6 +133,10 @@ bool Address::setUsername (const string &username) { const string &Address::getDomain () const { L_D(); + + if (!d->internalAddress) + return Utils::getEmptyConstRefObject(); + d->cache.domain = L_C_TO_STRING(sal_address_get_domain(d->internalAddress)); return d->cache.domain; } @@ -187,6 +203,10 @@ bool Address::isSip () const { const string &Address::getMethodParam () const { L_D(); + + if (!d->internalAddress) + return Utils::getEmptyConstRefObject(); + d->cache.methodParam = L_C_TO_STRING(sal_address_get_method_param(d->internalAddress)); return d->cache.methodParam; } @@ -203,6 +223,10 @@ bool Address::setMethodParam (const string &methodParam) { const string &Address::getPassword () const { L_D(); + + if (!d->internalAddress) + return Utils::getEmptyConstRefObject(); + d->cache.password = L_C_TO_STRING(sal_address_get_password(d->internalAddress)); return d->cache.password; } @@ -260,10 +284,12 @@ bool Address::weakEqual (const Address &address) const { const string &Address::getHeaderValue (const string &headerName) const { L_D(); - const char *value = sal_address_get_header(d->internalAddress, L_STRING_TO_C(headerName)); - if (value) { - d->cache.headers[headerName] = value; - return d->cache.headers[headerName]; + if (d->internalAddress) { + const char *value = sal_address_get_header(d->internalAddress, L_STRING_TO_C(headerName)); + if (value) { + d->cache.headers[headerName] = value; + return d->cache.headers[headerName]; + } } return Utils::getEmptyConstRefObject(); @@ -281,16 +307,18 @@ bool Address::setHeader (const string &headerName, const string &headerValue) { bool Address::hasParam (const string ¶mName) const { L_D(); - return !!sal_address_has_param(d->internalAddress, L_STRING_TO_C(paramName)); + return d->internalAddress && !!sal_address_has_param(d->internalAddress, L_STRING_TO_C(paramName)); } const string &Address::getParamValue (const string ¶mName) const { L_D(); - const char *value = sal_address_get_param(d->internalAddress, L_STRING_TO_C(paramName)); - if (value) { - d->cache.params[paramName] = value; - return d->cache.params[paramName]; + if (d->internalAddress) { + const char *value = sal_address_get_param(d->internalAddress, L_STRING_TO_C(paramName)); + if (value) { + d->cache.params[paramName] = value; + return d->cache.params[paramName]; + } } return Utils::getEmptyConstRefObject(); @@ -318,16 +346,18 @@ bool Address::setParams (const string ¶ms) { bool Address::hasUriParam (const string &uriParamName) const { L_D(); - return !!sal_address_has_uri_param(d->internalAddress, L_STRING_TO_C(uriParamName)); + return d->internalAddress && !!sal_address_has_uri_param(d->internalAddress, L_STRING_TO_C(uriParamName)); } const string &Address::getUriParamValue (const string &uriParamName) const { L_D(); - const char *value = sal_address_get_uri_param(d->internalAddress, L_STRING_TO_C(uriParamName)); - if (value) { - d->cache.uriParams[uriParamName] = value; - return d->cache.uriParams[uriParamName]; + if (d->internalAddress) { + const char *value = sal_address_get_uri_param(d->internalAddress, L_STRING_TO_C(uriParamName)); + if (value) { + d->cache.uriParams[uriParamName] = value; + return d->cache.uriParams[uriParamName]; + } } return Utils::getEmptyConstRefObject(); diff --git a/src/c-wrapper/api/c-call.cpp b/src/c-wrapper/api/c-call.cpp index 3f1d13002..dc86b5a1c 100644 --- a/src/c-wrapper/api/c-call.cpp +++ b/src/c-wrapper/api/c-call.cpp @@ -1148,7 +1148,7 @@ void linphone_call_set_user_data (LinphoneCall *call, void *ud) { LinphoneCall *linphone_call_new_outgoing (LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg) { LinphoneCall *call = L_INIT(Call); - L_SET_CPP_PTR_FROM_C_OBJECT(call, LinphonePrivate::ObjectFactory::create(call, lc, LinphoneCallOutgoing, + L_SET_CPP_PTR_FROM_C_OBJECT(call, make_shared(call, lc, LinphoneCallOutgoing, *L_GET_CPP_PTR_FROM_C_OBJECT(from), *L_GET_CPP_PTR_FROM_C_OBJECT(to), cfg, nullptr, L_GET_CPP_PTR_FROM_C_OBJECT(params))); call->currentParamsCache = linphone_call_params_new_for_wrapper(); @@ -1160,7 +1160,7 @@ LinphoneCall *linphone_call_new_outgoing (LinphoneCore *lc, const LinphoneAddres LinphoneCall *linphone_call_new_incoming (LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, LinphonePrivate::SalCallOp *op) { LinphoneCall *call = L_INIT(Call); - L_SET_CPP_PTR_FROM_C_OBJECT(call, LinphonePrivate::ObjectFactory::create(call, lc, LinphoneCallIncoming, + L_SET_CPP_PTR_FROM_C_OBJECT(call, make_shared(call, lc, LinphoneCallIncoming, *L_GET_CPP_PTR_FROM_C_OBJECT(from), *L_GET_CPP_PTR_FROM_C_OBJECT(to), nullptr, op, nullptr)); call->currentParamsCache = linphone_call_params_new_for_wrapper(); diff --git a/src/c-wrapper/api/c-chat-room.cpp b/src/c-wrapper/api/c-chat-room.cpp index 6292f863c..d0f25a116 100644 --- a/src/c-wrapper/api/c-chat-room.cpp +++ b/src/c-wrapper/api/c-chat-room.cpp @@ -348,7 +348,7 @@ LinphoneChatRoom *_linphone_client_group_chat_room_new (LinphoneCore *core, cons from = linphone_core_get_primary_contact(core); LinphonePrivate::Address me(from); LinphoneChatRoom *cr = L_INIT(ChatRoom); - L_SET_CPP_PTR_FROM_C_OBJECT(cr, LinphonePrivate::ObjectFactory::create( + L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared( core->cppCore, me, L_C_TO_STRING(uri), L_C_TO_STRING(subject)) ); L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Instantiated); @@ -357,7 +357,7 @@ LinphoneChatRoom *_linphone_client_group_chat_room_new (LinphoneCore *core, cons LinphoneChatRoom *_linphone_server_group_chat_room_new (LinphoneCore *core, LinphonePrivate::SalCallOp *op) { LinphoneChatRoom *cr = L_INIT(ChatRoom); - L_SET_CPP_PTR_FROM_C_OBJECT(cr, LinphonePrivate::ObjectFactory::create( + L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared( core->cppCore, op )); diff --git a/src/chat/chat-message/chat-message.h b/src/chat/chat-message/chat-message.h index cb2742fc6..00c41df82 100644 --- a/src/chat/chat-message/chat-message.h +++ b/src/chat/chat-message/chat-message.h @@ -41,6 +41,7 @@ class LINPHONE_PUBLIC ChatMessage : public Object, public CoreAccessor { friend class ChatRoom; friend class ChatRoomPrivate; friend class CpimChatMessageModifier; + friend class MainDbPrivate; friend class RealTimeTextChatRoomPrivate; friend class ServerGroupChatRoomPrivate; diff --git a/src/chat/chat-room/basic-chat-room.cpp b/src/chat/chat-room/basic-chat-room.cpp index bb602f9c6..4d9d9e470 100644 --- a/src/chat/chat-room/basic-chat-room.cpp +++ b/src/chat/chat-room/basic-chat-room.cpp @@ -71,7 +71,7 @@ int BasicChatRoom::getNbParticipants () const { list> BasicChatRoom::getParticipants () const { L_D(); list> l; - l.push_back(ObjectFactory::create(d->peerAddress)); + l.push_back(make_shared(d->peerAddress)); return l; } diff --git a/src/chat/chat-room/chat-room.cpp b/src/chat/chat-room/chat-room.cpp index 96401619d..03bd1950f 100644 --- a/src/chat/chat-room/chat-room.cpp +++ b/src/chat/chat-room/chat-room.cpp @@ -480,7 +480,7 @@ shared_ptr ChatRoom::createMessage (const string &message) { shared_ptr ChatRoom::createMessage () { L_D(); - shared_ptr chatMessage = ObjectFactory::create(getSharedFromThis()); + shared_ptr chatMessage = make_shared(getSharedFromThis()); chatMessage->setToAddress(d->peerAddress); chatMessage->setFromAddress(Address(linphone_core_get_identity(getCore()->getCCore()))); chatMessage->getPrivate()->setTime(ms_time(0)); diff --git a/src/chat/chat-room/client-group-chat-room.cpp b/src/chat/chat-room/client-group-chat-room.cpp index 7b0e25656..e50b13e35 100644 --- a/src/chat/chat-room/client-group-chat-room.cpp +++ b/src/chat/chat-room/client-group-chat-room.cpp @@ -72,7 +72,7 @@ ClientGroupChatRoom::ClientGroupChatRoom ( const std::string &subject ) : ChatRoom(*new ClientGroupChatRoomPrivate, core, me), RemoteConference(core->getCCore(), me, nullptr) { L_D_T(RemoteConference, dConference); - dConference->focus = ObjectFactory::create(Address(uri)); + dConference->focus = make_shared(Address(uri)); RemoteConference::setSubject(subject); } @@ -275,7 +275,7 @@ void ClientGroupChatRoom::onParticipantAdded (time_t tm, const Address &addr) { return; } - participant = ObjectFactory::create(addr); + participant = make_shared(addr); dConference->participants.push_back(participant); LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this); LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr); diff --git a/src/chat/chat-room/real-time-text-chat-room.cpp b/src/chat/chat-room/real-time-text-chat-room.cpp index 6c0dce359..2242cdd3c 100644 --- a/src/chat/chat-room/real-time-text-chat-room.cpp +++ b/src/chat/chat-room/real-time-text-chat-room.cpp @@ -171,7 +171,7 @@ int RealTimeTextChatRoom::getNbParticipants () const { list> RealTimeTextChatRoom::getParticipants () const { L_D(); list> l; - l.push_back(ObjectFactory::create(d->peerAddress)); + l.push_back(make_shared(d->peerAddress)); return l; } diff --git a/src/conference/conference.cpp b/src/conference/conference.cpp index 0d97d880f..c0ac545ab 100644 --- a/src/conference/conference.cpp +++ b/src/conference/conference.cpp @@ -34,7 +34,7 @@ Conference::Conference (ConferencePrivate &p, LinphoneCore *core, const Address d->mPublic = this; d->core = core; d->callListener = listener; - d->me = ObjectFactory::create(myAddress); + d->me = make_shared(myAddress); } Conference::~Conference () { diff --git a/src/conference/local-conference.cpp b/src/conference/local-conference.cpp index 872e6da9e..11e41e4e8 100644 --- a/src/conference/local-conference.cpp +++ b/src/conference/local-conference.cpp @@ -41,7 +41,7 @@ void LocalConference::addParticipant (const Address &addr, const CallSessionPara shared_ptr participant = findParticipant(addr); if (participant) return; - participant = ObjectFactory::create(addr); + participant = make_shared(addr); d->participants.push_back(participant); if (!d->activeParticipant) d->activeParticipant = participant; diff --git a/src/conference/participant.cpp b/src/conference/participant.cpp index f4ef38269..ecafa17fd 100644 --- a/src/conference/participant.cpp +++ b/src/conference/participant.cpp @@ -36,9 +36,9 @@ shared_ptr ParticipantPrivate::createSession ( const Conference &conference, const CallSessionParams *params, bool hasMedia, CallSessionListener *listener ) { if (hasMedia && (!params || dynamic_cast(params))) { - session = ObjectFactory::create(conference, params, listener); + session = make_shared(conference, params, listener); } else { - session = ObjectFactory::create(conference, params, listener); + session = make_shared(conference, params, listener); } return session; } diff --git a/src/conference/remote-conference.cpp b/src/conference/remote-conference.cpp index 3b317a10e..d746a495f 100644 --- a/src/conference/remote-conference.cpp +++ b/src/conference/remote-conference.cpp @@ -46,7 +46,7 @@ void RemoteConference::addParticipant (const Address &addr, const CallSessionPar shared_ptr participant = findParticipant(addr); if (participant) return; - participant = ObjectFactory::create(addr); + participant = make_shared(addr); participant->getPrivate()->createSession(*this, params, hasMedia, this); d->participants.push_back(participant); if (!d->activeParticipant) diff --git a/src/core/core-accessor.cpp b/src/core/core-accessor.cpp index 676847cfa..bbd1fe784 100644 --- a/src/core/core-accessor.cpp +++ b/src/core/core-accessor.cpp @@ -35,23 +35,30 @@ public: // ----------------------------------------------------------------------------- CoreAccessor::CoreAccessor (const shared_ptr &core) { - L_D(); - d->core = core; + L_ASSERT(core); + mPrivate = new CoreAccessorPrivate(); + mPrivate->core = core; } CoreAccessor::CoreAccessor (const shared_ptr &&core) { - L_D(); - d->core = move(core); + L_ASSERT(core); + mPrivate = new CoreAccessorPrivate(); + mPrivate->core = move(core); } -CoreAccessor::~CoreAccessor () {} +CoreAccessor::~CoreAccessor () { + delete mPrivate; +} shared_ptr CoreAccessor::getCore () const { L_D(); shared_ptr core = d->core.lock(); - if (!core) + if (!core) { lWarning() << "Unable to get valid core instance."; + throw std::bad_weak_ptr(); + } + return core; } diff --git a/src/core/core-accessor.h b/src/core/core-accessor.h index 0608b1983..cb5ff623b 100644 --- a/src/core/core-accessor.h +++ b/src/core/core-accessor.h @@ -31,13 +31,15 @@ LINPHONE_BEGIN_NAMESPACE class Core; class CoreAccessorPrivate; -class CoreAccessor { +// Decorator to get a valid core instance. +LINPHONE_PUBLIC class CoreAccessor { public: CoreAccessor (const std::shared_ptr &core); CoreAccessor (const std::shared_ptr &&core); virtual ~CoreAccessor () = 0; + // Returns a valid core instance. Or throw one std::bad_weak_ptr exception if core is destroyed. std::shared_ptr getCore () const; private: diff --git a/src/core/core-chat-room.cpp b/src/core/core-chat-room.cpp index 63fd95a85..c5d1484d3 100644 --- a/src/core/core-chat-room.cpp +++ b/src/core/core-chat-room.cpp @@ -39,6 +39,9 @@ LINPHONE_BEGIN_NAMESPACE // ----------------------------------------------------------------------------- static inline Address getCleanedPeerAddress (const Address &peerAddress) { + if (!peerAddress.isValid()) + return Address(); + Address cleanedAddress = peerAddress; cleanedAddress.clean(); cleanedAddress.setPort(0); @@ -50,8 +53,12 @@ static inline string resolveWorkaroundClientGroupChatRoomAddress ( const CorePrivate &corePrivate, const Address &peerAddress ) { + const char *uri = linphone_core_get_conference_factory_uri(corePrivate.cCore); + if (!uri) + return ""; + Address workaroundAddress = peerAddress; - workaroundAddress.setDomain(Address(linphone_core_get_conference_factory_uri(corePrivate.cCore)).getDomain()); + workaroundAddress.setDomain(Address(uri).getDomain()); return workaroundAddress.asStringUriOnly(); } @@ -63,9 +70,9 @@ shared_ptr CorePrivate::createChatRoom (const Address &peerAddress, bo shared_ptr chatRoom; if (isRtt) - chatRoom = ObjectFactory::create(q->getSharedFromThis(), peerAddress); + chatRoom = make_shared(q->getSharedFromThis(), peerAddress); else - chatRoom = ObjectFactory::create(q->getSharedFromThis(), peerAddress); + chatRoom = make_shared(q->getSharedFromThis(), peerAddress); ChatRoomPrivate *dChatRoom = chatRoom->getPrivate(); insertChatRoom(chatRoom); diff --git a/src/core/core.cpp b/src/core/core.cpp index a554ab223..bd47d7ef0 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -32,20 +32,26 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -Core::Core (LinphoneCore *cCore) : Object(*new CorePrivate) { - L_D(); +Core::Core () : Object(*new CorePrivate) {} + +shared_ptr Core::create (LinphoneCore *cCore) { + // Do not use `make_shared` => Private constructor. + shared_ptr core = shared_ptr(new Core); + + CorePrivate * const d = core->getPrivate(); + d->cCore = cCore; - d->mainDb.reset(new MainDb(this)); + d->mainDb.reset(new MainDb(core->getSharedFromThis())); AbstractDb::Backend backend; - string uri = L_C_TO_STRING(lp_config_get_string(linphone_core_get_config(d->cCore), "server", "db_uri", NULL)); + string uri = L_C_TO_STRING(lp_config_get_string(linphone_core_get_config(d->cCore), "storage", "backend", nullptr)); if (!uri.empty()) - backend = strcmp(lp_config_get_string(linphone_core_get_config(d->cCore), "server", "db_backend", NULL), "mysql") == 0 + backend = strcmp(lp_config_get_string(linphone_core_get_config(d->cCore), "storage", "uri", nullptr), "mysql") == 0 ? MainDb::Mysql : MainDb::Sqlite3; else { backend = AbstractDb::Sqlite3; - uri = getDataPath() + LINPHONE_DB; + uri = core->getDataPath() + LINPHONE_DB; } lInfo() << "Opening " LINPHONE_DB " at: " << uri; @@ -54,6 +60,8 @@ Core::Core (LinphoneCore *cCore) : Object(*new CorePrivate) { for (auto &chatRoom : d->mainDb->getChatRooms()) d->insertChatRoom(chatRoom); + + return core; } LinphoneCore *Core::getCCore () const { diff --git a/src/core/core.h b/src/core/core.h index 80f94a04c..0eb899f9a 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -42,7 +42,8 @@ class LINPHONE_PUBLIC Core : public Object { public: L_OVERRIDE_SHARED_FROM_THIS(Core); - Core (LinphoneCore *cCore); + // Return a new Core instance. Entry point of Linphone. + static std::shared_ptr create (LinphoneCore *cCore); // --------------------------------------------------------------------------- // C-Core. @@ -71,6 +72,8 @@ public: static void deleteChatRoom (const std::shared_ptr &chatRoom); private: + Core (); + L_DECLARE_PRIVATE(Core); L_DISABLE_COPY(Core); }; diff --git a/src/db/main-db-p.h b/src/db/main-db-p.h index b7133a055..9a2715a67 100644 --- a/src/db/main-db-p.h +++ b/src/db/main-db-p.h @@ -29,11 +29,8 @@ LINPHONE_BEGIN_NAMESPACE class Content; -struct MessageEventReferences; class MainDbPrivate : public AbstractDbPrivate { -public: - private: // --------------------------------------------------------------------------- // Low level API. @@ -108,8 +105,6 @@ private: long long insertConferenceParticipantDeviceEvent (const std::shared_ptr &eventLog); long long insertConferenceSubjectEvent (const std::shared_ptr &eventLog); - Core *core = nullptr; - L_DECLARE_PUBLIC(MainDb); }; diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index ee45b2af5..40f2be4f0 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -26,6 +26,7 @@ #include "linphone/utils/utils.h" +#include "chat/chat-message/chat-message-p.h" #include "chat/chat-room/chat-room.h" #include "conference/participant.h" #include "content/content-type.h" @@ -45,10 +46,7 @@ LINPHONE_BEGIN_NAMESPACE // ----------------------------------------------------------------------------- -MainDb::MainDb (Core *core) : AbstractDb(*new MainDbPrivate) { - L_D(); - d->core = core; -} +MainDb::MainDb (const shared_ptr &core) : CoreAccessor(core), AbstractDb(*new MainDbPrivate) {} #ifdef SOCI_ENABLED @@ -286,18 +284,49 @@ MainDb::MainDb (Core *core) : AbstractDb(*new MainDbPrivate) { time_t date, const string &peerAddress ) const { + L_Q(); + + shared_ptr core = q->getCore(); + L_ASSERT(core); + + // TODO: Avoid address creation. + shared_ptr chatRoom = core->findChatRoom(Address(peerAddress)); + if (!chatRoom) + return nullptr; + + string localSipAddress; + string remoteSipAddress; + string imdnMessageId; + int state; + int direction; + int isSecured; + soci::session *session = dbSession.getBackendSession(); - *session << "SELECT event_id, type, date, local_sip_address.value, " - "remote_sip_address.value, imdn_message_id, state, direction, is_secured" + *session << "SELECT local_sip_address.value, remote_sip_address.value, imdn_message_id, state, direction, is_secured" " FROM event, conference_chat_message_event, sip_address AS local_sip_address," " sip_address AS remote_sip_address" " WHERE event_id = event.id" " AND local_sip_address_id = local_sip_address.id" " AND remote_sip_address_id = remote_sip_address.id" - " AND remote_sip_address.value = :peerAddress", soci::use(peerAddress); + " AND remote_sip_address.value = :peerAddress", soci::into(localSipAddress), soci::into(remoteSipAddress), + soci::into(imdnMessageId), soci::into(state), soci::into(direction), soci::into(isSecured), + soci::use(peerAddress); // TODO: Create me. - shared_ptr chatMessage; + // TODO: Use cache, do not fetch the same message twice. + shared_ptr chatMessage = make_shared(chatRoom); + + chatMessage->getPrivate()->setState(static_cast(state)); + chatMessage->getPrivate()->setDirection(static_cast(direction)); + chatMessage->setIsSecured(static_cast(isSecured)); + + if (direction == static_cast(ChatMessage::Direction::Outgoing)) { + chatMessage->setFromAddress(Address(localSipAddress)); + chatMessage->setToAddress(Address(remoteSipAddress)); + } else { + chatMessage->setFromAddress(Address(remoteSipAddress)); + chatMessage->setToAddress(Address(localSipAddress)); + } // TODO: Use cache. return make_shared( @@ -867,7 +896,7 @@ MainDb::MainDb (Core *core) : AbstractDb(*new MainDbPrivate) { list> MainDb::getConferenceNotifiedEvents ( const string &peerAddress, unsigned int lastNotifyId - ) { + ) const { static const string query = "SELECT id, type, date FROM event" " WHERE id IN (" " SELECT event_id FROM conference_notified_event WHERE event_id IN (" @@ -1126,6 +1155,9 @@ MainDb::MainDb (Core *core) : AbstractDb(*new MainDbPrivate) { return list>(); } + shared_ptr core = getCore(); + L_ASSERT(core); + list> chatRooms; L_BEGIN_LOG_EXCEPTION @@ -1135,7 +1167,7 @@ MainDb::MainDb (Core *core) : AbstractDb(*new MainDbPrivate) { soci::rowset rows = (session->prepare << query); for (const auto &row : rows) { string sipAddress = row.get(0); - shared_ptr chatRoom = d->core->findChatRoom(Address(sipAddress)); + shared_ptr chatRoom = core->findChatRoom(Address(sipAddress)); if (chatRoom) { lInfo() << "Don't fetch chat room from database: `" << sipAddress << "`, it already exists."; chatRooms.push_back(chatRoom); @@ -1155,10 +1187,10 @@ MainDb::MainDb (Core *core) : AbstractDb(*new MainDbPrivate) { (void)lastNotifyId; if (capabilities & static_cast(ChatRoom::Capabilities::Basic)) { - chatRoom = d->core ? d->core->getPrivate()->createChatRoom( + chatRoom = core->getPrivate()->createChatRoom( Address(sipAddress), capabilities & static_cast(ChatRoom::Capabilities::RealTimeText) - ) : nullptr; + ); } else if (capabilities & static_cast(ChatRoom::Capabilities::Conference)) { // TODO: Set sip address and participants. } @@ -1391,7 +1423,7 @@ MainDb::MainDb (Core *core) : AbstractDb(*new MainDbPrivate) { list> MainDb::getConferenceNotifiedEvents ( const string &peerAddress, unsigned int notifyId - ) { + ) const { return list>(); } diff --git a/src/db/main-db.h b/src/db/main-db.h index 161e6c66f..6fb3ef51c 100644 --- a/src/db/main-db.h +++ b/src/db/main-db.h @@ -23,6 +23,7 @@ #include #include "abstract/abstract-db.h" +#include "core/core-accessor.h" // ============================================================================= @@ -34,7 +35,7 @@ class Core; class EventLog; class MainDbPrivate; -class LINPHONE_PUBLIC MainDb : public AbstractDb { +class LINPHONE_PUBLIC MainDb : public CoreAccessor, public AbstractDb { public: enum Filter { NoFilter = 0x0, @@ -45,7 +46,7 @@ public: typedef int FilterMask; - MainDb (Core *core); + MainDb (const std::shared_ptr &core); // --------------------------------------------------------------------------- // Generic. @@ -63,7 +64,7 @@ public: std::list> getConferenceNotifiedEvents ( const std::string &peerAddress, unsigned int lastNotifyId - ); + ) const; // --------------------------------------------------------------------------- // Conference chat message events. diff --git a/src/object/object-p.h b/src/object/object-p.h index 842fd3c6f..bcc3b787e 100644 --- a/src/object/object-p.h +++ b/src/object/object-p.h @@ -31,11 +31,8 @@ LINPHONE_BEGIN_NAMESPACE class ObjectPrivate : public BaseObjectPrivate { - friend class ObjectFactory; - private: std::unordered_map properties; - std::weak_ptr weak; L_DECLARE_PUBLIC(Object); }; diff --git a/src/object/object.cpp b/src/object/object.cpp index 179e2392a..e22adb37f 100644 --- a/src/object/object.cpp +++ b/src/object/object.cpp @@ -24,8 +24,6 @@ // ============================================================================= -#define GET_SHARED_FROM_THIS_FATAL_ERROR "Object was not created with `ObjectFactory::create`." - using namespace std; LINPHONE_BEGIN_NAMESPACE @@ -37,24 +35,13 @@ shared_ptr Object::getSharedFromThis () { } shared_ptr Object::getSharedFromThis () const { - shared_ptr object; - try { - object = getPrivate()->weak.lock(); - if (!object) - lFatal() << GET_SHARED_FROM_THIS_FATAL_ERROR; + return shared_from_this(); } catch (const exception &) { - lFatal() << GET_SHARED_FROM_THIS_FATAL_ERROR; + lFatal() << "Object " << this << " was not created with make_shared."; } - return object; -} - -void ObjectFactory::setPublic (const shared_ptr &object) { - L_ASSERT(object); - ObjectPrivate *d = object->getPrivate(); - d->mPublic = object.get(); - d->weak = object; + return nullptr; } LINPHONE_END_NAMESPACE diff --git a/src/object/object.h b/src/object/object.h index 0721cc0ef..f929df63a 100644 --- a/src/object/object.h +++ b/src/object/object.h @@ -34,41 +34,26 @@ LINPHONE_BEGIN_NAMESPACE * Supports properties and shared from this. * Must be built with ObjectFactory. */ -class LINPHONE_PUBLIC Object : public BaseObject, public PropertyContainer { +class LINPHONE_PUBLIC Object : + public std::enable_shared_from_this, + public BaseObject, + public PropertyContainer { friend class ObjectFactory; public: virtual ~Object () = default; -protected: - explicit Object (ObjectPrivate &p); - std::shared_ptr getSharedFromThis (); std::shared_ptr getSharedFromThis () const; +protected: + explicit Object (ObjectPrivate &p); + private: L_DECLARE_PRIVATE(Object); L_DISABLE_COPY(Object); }; -class ObjectFactory { -public: - template - static inline std::shared_ptr create (Args &&...args) { - static_assert(std::is_base_of::value, "Not an object."); - std::shared_ptr object = std::make_shared(args...); - setPublic(object); - return object; - } - -private: - ObjectFactory () = delete; - - static void setPublic (const std::shared_ptr &object); - - L_DISABLE_COPY(ObjectFactory); -}; - LINPHONE_END_NAMESPACE #endif // ifndef _OBJECT_H_ diff --git a/tester/cpim-tester.cpp b/tester/cpim-tester.cpp index ab0a11d2c..079ff130b 100644 --- a/tester/cpim-tester.cpp +++ b/tester/cpim-tester.cpp @@ -395,7 +395,7 @@ static void cpim_chat_message_modifier_base(bool_t use_multipart) { lp_config_set_int(config, "sip", "use_cpim", 1); Address paulineAddress(linphone_address_as_string_uri_only(pauline->identity)); - shared_ptr marieRoom = ObjectFactory::create(marie->lc->cppCore, paulineAddress); + shared_ptr marieRoom = make_shared(marie->lc->cppCore, paulineAddress); shared_ptr marieMessage = marieRoom->createMessage("Hello CPIM"); if (use_multipart) { diff --git a/tester/main-db-tester.cpp b/tester/main-db-tester.cpp index 495671421..99b98de2f 100644 --- a/tester/main-db-tester.cpp +++ b/tester/main-db-tester.cpp @@ -17,9 +17,12 @@ */ #include "address/address.h" +#include "core/core.h" #include "db/main-db.h" #include "event-log/events.h" +#include "private.h" + #include "liblinphone_tester.h" // ============================================================================= @@ -37,14 +40,37 @@ static const string getDatabasePath () { // ----------------------------------------------------------------------------- +class MainDbProvider { +public: + MainDbProvider () { + mCoreManager = linphone_core_manager_new("marie_rc"); + mMainDb = new MainDb(mCoreManager->lc->cppCore->getSharedFromThis()); + BC_ASSERT_TRUE(mMainDb->connect(MainDb::Sqlite3, getDatabasePath())); + } + + ~MainDbProvider () { + delete mMainDb; + linphone_core_manager_destroy(mCoreManager); + } + + const MainDb &getMainDb () { + return *mMainDb; + } + +private: + LinphoneCoreManager *mCoreManager; + MainDb *mMainDb; +}; + +// ----------------------------------------------------------------------------- + static void open_database () { - MainDb mainDb(nullptr); - BC_ASSERT_TRUE(mainDb.connect(MainDb::Sqlite3, getDatabasePath())); + MainDbProvider provider; } static void get_events_count () { - MainDb mainDb(nullptr); - BC_ASSERT_TRUE(mainDb.connect(MainDb::Sqlite3, getDatabasePath())); + MainDbProvider provider; + const MainDb &mainDb = provider.getMainDb(); BC_ASSERT_EQUAL(mainDb.getEventsCount(), 4994, int, "%d"); BC_ASSERT_EQUAL(mainDb.getEventsCount(MainDb::ConferenceCallFilter), 0, int, "%d"); BC_ASSERT_EQUAL(mainDb.getEventsCount(MainDb::ConferenceInfoFilter), 18, int, "%d"); @@ -53,22 +79,22 @@ static void get_events_count () { } static void get_messages_count () { - MainDb mainDb(nullptr); - BC_ASSERT_TRUE(mainDb.connect(MainDb::Sqlite3, getDatabasePath())); + MainDbProvider provider; + const MainDb &mainDb = provider.getMainDb(); BC_ASSERT_EQUAL(mainDb.getChatMessagesCount(), 4976, int, "%d"); BC_ASSERT_EQUAL(mainDb.getChatMessagesCount("sip:test-39@sip.linphone.org"), 3, int, "%d"); } static void get_unread_messages_count () { - MainDb mainDb(nullptr); - BC_ASSERT_TRUE(mainDb.connect(MainDb::Sqlite3, getDatabasePath())); + MainDbProvider provider; + const MainDb &mainDb = provider.getMainDb(); BC_ASSERT_EQUAL(mainDb.getUnreadChatMessagesCount(), 2, int, "%d"); BC_ASSERT_EQUAL(mainDb.getUnreadChatMessagesCount("sip:test-39@sip.linphone.org"), 0, int, "%d"); } static void get_history () { - MainDb mainDb(nullptr); - BC_ASSERT_TRUE(mainDb.connect(MainDb::Sqlite3, getDatabasePath())); + MainDbProvider provider; + const MainDb &mainDb = provider.getMainDb(); BC_ASSERT_EQUAL( mainDb.getHistoryRange("sip:test-39@sip.linphone.org", 0, -1, MainDb::Filter::ConferenceChatMessageFilter).size(), 3, @@ -96,8 +122,8 @@ static void get_history () { } static void get_conference_notified_events () { - MainDb mainDb(nullptr); - BC_ASSERT_TRUE(mainDb.connect(MainDb::Sqlite3, getDatabasePath())); + MainDbProvider provider; + const MainDb &mainDb = provider.getMainDb(); list> events = mainDb.getConferenceNotifiedEvents("sip:fake-group-2@sip.linphone.org", 1); BC_ASSERT_EQUAL(events.size(), 3, int, "%d"); if (events.size() != 3) diff --git a/tester/multipart-tester.cpp b/tester/multipart-tester.cpp index 4e781281d..f1b6617e6 100644 --- a/tester/multipart-tester.cpp +++ b/tester/multipart-tester.cpp @@ -39,7 +39,7 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_tcp_rc"); Address paulineAddress(linphone_address_as_string_uri_only(pauline->identity)); - shared_ptr marieRoom = ObjectFactory::create(marie->lc->cppCore, paulineAddress); + shared_ptr marieRoom = make_shared(marie->lc->cppCore, paulineAddress); shared_ptr marieMessage; if (first_file_transfer) {