diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 397e951d03b02046e429a0ed954bf9a79ae19dec..cc4b300c417e5b8b3272f226b81e963ad9838a18 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1180,7 +1180,7 @@ static void process_response_from_post_file_log_collection(void *data, const bel } else if (code == 200) { /* The file has been uploaded correctly, get the server reply */ const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response); FileTransferChatMessageModifier fileTransferModifier = FileTransferChatMessageModifier(NULL); - FileTransferContent *content = new FileTransferContent(); + auto content = FileTransferContent::create<FileTransferContent>(); fileTransferModifier.parseFileTransferXmlIntoContent(body, content); string fileUrl = content->getFileUrl(); @@ -1190,7 +1190,6 @@ static void process_response_from_post_file_log_collection(void *data, const bel core, LinphoneCoreLogCollectionUploadStateDelivered, url); } - delete content; clean_log_collection_upload_context(core); } else { ms_error("Unexpected HTTP response code %i during log collection upload to %s", code, @@ -2789,7 +2788,7 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc, const char *factoryUri = linphone_proxy_config_get_conference_factory_uri(proxy); if (factoryUri && (strcmp(resourceAddrUri.c_str(), factoryUri) == 0)) { L_GET_PRIVATE_FROM_C_OBJECT(lc)->remoteListEventHandler->notifyReceived( - ev, body ? L_GET_CPP_PTR_FROM_C_OBJECT(body) : nullptr); + ev, body ? Content::toCpp(body)->getSharedFromThis() : nullptr); return; } } @@ -2800,7 +2799,7 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc, shared_ptr<MediaConference::Conference> audioVideoConference = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findAudioVideoConference(conferenceId); - Content content = body ? *L_GET_CPP_PTR_FROM_C_OBJECT(body) : Content(); + Content content = body ? *Content::toCpp(body) : Content(); if (chatRoom) { shared_ptr<ClientGroupChatRoom> cgcr; if (chatRoom->getCapabilities() & ChatRoom::Capabilities::Proxy) @@ -4990,16 +4989,16 @@ LinphoneCall *linphone_core_invite_address_with_params_2(LinphoneCore *lc, const char *subject, const LinphoneContent *content) { CoreLogContextualizer logContextualizer(lc); - const char *from = NULL; - LinphoneAccount *account = NULL; - LinphoneAddress *temp_url = NULL; - LinphoneAddress *parsed_url2 = NULL; + const char *from = nullptr; + LinphoneAccount *account = nullptr; + LinphoneAddress *temp_url = nullptr; + LinphoneAddress *parsed_url2 = nullptr; LinphoneCall *call; LinphoneCallParams *cp; if (!addr) { ms_error("Can't invite a NULL address"); - return NULL; + return nullptr; } // Check that sound resources can be freed before moving on @@ -5011,7 +5010,7 @@ LinphoneCall *linphone_core_invite_address_with_params_2(LinphoneCore *lc, !Call::toCpp(current_call)->canSoundResourcesBeFreed())) { ms_error("linphone_core_invite_address_with_params(): sound are locked by another call and they cannot be " "freed. Call attempt is rejected."); - return NULL; + return nullptr; } } @@ -5026,7 +5025,7 @@ LinphoneCall *linphone_core_invite_address_with_params_2(LinphoneCore *lc, from = linphone_call_params_get_from_header(params); // If no account is found, then look up for one either using either the from or the to address - if (account == NULL) { + if (account == nullptr) { temp_url = from ? linphone_address_new(from) : linphone_address_clone(addr); account = linphone_core_lookup_known_account(lc, temp_url); if (account && !from) { @@ -5038,24 +5037,24 @@ LinphoneCall *linphone_core_invite_address_with_params_2(LinphoneCore *lc, // If variable is still NULL, then the SDK has to make a decision because one is dependent from // the other one. In such a scenario, it is assumed that the application wishes to use the default account - if (account == NULL) account = linphone_core_get_default_account(lc); + if (account == nullptr) account = linphone_core_get_default_account(lc); // If an account has been found earlier on either because it has been set in the call params or it is the default // one or it has been deduced thanks to the from or to addresses, then get the from address if not already set in // the call params - if ((from == NULL) && (account != NULL)) { + if ((from == nullptr) && (account != nullptr)) { const LinphoneAccountParams *account_params = linphone_account_get_params(account); from = linphone_account_params_get_identity(account_params); } /* if no account or no identity defined for this account, default to primary contact*/ - if (from == NULL) from = linphone_core_get_primary_contact(lc); + if (from == nullptr) from = linphone_core_get_primary_contact(lc); parsed_url2 = linphone_address_new(from); cp = _linphone_call_params_copy(params); if (!linphone_call_params_has_avpf_enabled_been_set(cp)) { - if (account != NULL) { + if (account != nullptr) { linphone_call_params_enable_avpf(cp, linphone_account_is_avpf_enabled(account)); const LinphoneAccountParams *account_params = linphone_account_get_params(account); linphone_call_params_set_avpf_rr_interval( @@ -5075,7 +5074,7 @@ LinphoneCall *linphone_core_invite_address_with_params_2(LinphoneCore *lc, ms_warning("we had a problem in adding the call into the invite ... weird"); linphone_call_unref(call); linphone_call_params_unref(cp); - return NULL; + return nullptr; } // Try to free up resources after adding it to the call list. @@ -5085,17 +5084,17 @@ LinphoneCall *linphone_core_invite_address_with_params_2(LinphoneCore *lc, ms_error("linphone_core_invite_address_with_params(): sound is required for this call but another call is " "already locking the sound resource. The call is automatically terminated."); linphone_call_terminate(call); - return NULL; + return nullptr; } /* Unless this call is for a conference, it becomes now the current one*/ if (linphone_call_params_get_local_conference_mode(params) == FALSE) L_GET_PRIVATE_FROM_C_OBJECT(lc)->setCurrentCall(Call::toCpp(call)->getSharedFromThis()); bool defer = Call::toCpp(call)->initiateOutgoing(L_C_TO_STRING(subject), - content ? L_GET_CPP_PTR_FROM_C_OBJECT(content) : NULL); + content ? Content::toCpp(content)->getSharedFromThis() : nullptr); if (!defer) { - if (Call::toCpp(call)->startInvite(NULL, L_C_TO_STRING(subject), - content ? L_GET_CPP_PTR_FROM_C_OBJECT(content) : NULL) != 0) { + if (Call::toCpp(call)->startInvite(nullptr, L_C_TO_STRING(subject), + content ? Content::toCpp(content)->getSharedFromThis() : nullptr) != 0) { /* The call has already gone to error and released state, so do not return it */ call = nullptr; } @@ -9560,7 +9559,23 @@ LinphoneConference *linphone_core_get_conference(LinphoneCore *lc) { } void linphone_core_enable_conference_server(LinphoneCore *lc, bool_t enable) { +#ifdef HAVE_LIME_X3DH + // We need to change the encryption engine if it has been instanciated before. + auto core = L_GET_CPP_PTR_FROM_C_OBJECT(lc); + bool enabled = core->limeX3dhEnabled(); + + if (enabled) { + core->enableLimeX3dh(false); + } +#endif + linphone_config_set_int(linphone_core_get_config(lc), "misc", "conference_server_enabled", enable); + +#ifdef HAVE_LIME_X3DH + if (enabled) { + core->enableLimeX3dh(true); + } +#endif } void linphone_core_enable_fec(LinphoneCore *lc, bool_t enable) { diff --git a/coreapi/local_conference.cpp b/coreapi/local_conference.cpp index 18e3ce71aa3674c58d6490c15d8ce463effe6c8f..fd9fbb1362aea691b67992c51c6e33a2c2300920 100644 --- a/coreapi/local_conference.cpp +++ b/coreapi/local_conference.cpp @@ -249,7 +249,7 @@ void LocalConference::updateConferenceInformation(SalCallOp *op) { void LocalConference::fillInvitedParticipantList(SalCallOp *op, bool cancelling) { mInvitedParticipants.clear(); - const auto resourceList = op->getContentInRemote(ContentType::ResourceLists); + const auto &resourceList = op->getContentInRemote(ContentType::ResourceLists); if (!resourceList.isEmpty()) { auto invitees = Utils::parseResourceLists(resourceList); mInvitedParticipants = invitees; @@ -968,21 +968,21 @@ bool LocalConference::dialOutAddresses(const std::list<std::shared_ptr<Address>> } } - Content resourceList; - resourceList.setBodyFromUtf8(Utils::getResourceLists(addresses)); - resourceList.setContentType(ContentType::ResourceLists); - resourceList.setContentDisposition(ContentDisposition::RecipientList); + auto resourceList = Content::create(); + resourceList->setBodyFromUtf8(Utils::getResourceLists(addresses)); + resourceList->setContentType(ContentType::ResourceLists); + resourceList->setContentDisposition(ContentDisposition::RecipientList); if (linphone_core_content_encoding_supported(getCore()->getCCore(), "deflate")) { - resourceList.setContentEncoding("deflate"); + resourceList->setContentEncoding("deflate"); } - if (!resourceList.isEmpty()) { + if (!resourceList->isEmpty()) { L_GET_CPP_PTR_FROM_C_OBJECT(new_params)->addCustomContent(resourceList); } - Content sipfrag; + auto sipfrag = Content::create(); const auto organizerUri = organizer->getUri(); - sipfrag.setBodyFromLocale("From: <" + organizerUri.toString() + ">"); - sipfrag.setContentType(ContentType::SipFrag); + sipfrag->setBodyFromLocale("From: <" + organizerUri.toString() + ">"); + sipfrag->setContentType(ContentType::SipFrag); L_GET_CPP_PTR_FROM_C_OBJECT(new_params)->addCustomContent(sipfrag); auto success = (inviteAddresses(addressList, new_params) == 0); linphone_call_params_unref(new_params); @@ -1332,7 +1332,7 @@ bool LocalConference::addParticipant(std::shared_ptr<LinphonePrivate::Call> call auto op = session->getPrivate()->getOp(); const auto resourceList = op ? op->getContentInRemote(ContentType::ResourceLists) : Content(); - // If no resource list is provided in the INVITE, there is not need to call participants + // If no resource list is provided in the INVITE, there is no need to call participants if ((initialState == ConferenceInterface::State::CreationPending) && dialout && !resourceList.isEmpty()) { list<std::shared_ptr<Address>> addresses; for (auto &participant : mInvitedParticipants) { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 647f83eab33b1bf42a87c574ca4e00a460ec90e2..114e4d669a135187b6885351ab13be8893fb0cc7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -188,7 +188,6 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES containers/lru-cache.h content/content-disposition.h content/content-manager.h - content/content-p.h content/content-type.h content/content.h content/file-content.h @@ -242,7 +241,6 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES nat/ice-service.h nat/stun-client.h nat/nat-policy.h - object/app-data-container.h object/base-object-p.h object/base-object.h object/clonable-object-p.h @@ -486,7 +484,6 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES nat/ice-service.cpp nat/stun-client.cpp nat/nat-policy.cpp - object/app-data-container.cpp object/base-object.cpp object/clonable-object.cpp object/object.cpp diff --git a/src/c-wrapper/api/c-call-params.cpp b/src/c-wrapper/api/c-call-params.cpp index e62e5a4bd3f8e65fdf86b57f7c088553c183c2e5..16dd0568b756946f61918a8af0a11626768c8c24 100644 --- a/src/c-wrapper/api/c-call-params.cpp +++ b/src/c-wrapper/api/c-call-params.cpp @@ -658,18 +658,19 @@ void linphone_call_params_set_conference_creation(LinphoneCallParams *params, bo } bctbx_list_t *linphone_call_params_get_custom_contents(const LinphoneCallParams *params) { - const list<LinphonePrivate::Content> &contents = L_GET_CPP_PTR_FROM_C_OBJECT(params)->getCustomContents(); + const list<std::shared_ptr<LinphonePrivate::Content>> &contents = + L_GET_CPP_PTR_FROM_C_OBJECT(params)->getCustomContents(); bctbx_list_t *c_contents = nullptr; for (auto &content : contents) { - LinphoneContent *c_content = L_GET_C_BACK_PTR(&content); + LinphoneContent *c_content = content->toC(); c_contents = bctbx_list_append(c_contents, linphone_content_ref(c_content)); } return c_contents; } void linphone_call_params_add_custom_content(LinphoneCallParams *params, LinphoneContent *content) { - LinphonePrivate::Content *cppContent = L_GET_CPP_PTR_FROM_C_OBJECT(content); - L_GET_CPP_PTR_FROM_C_OBJECT(params)->addCustomContent(*cppContent); + L_GET_CPP_PTR_FROM_C_OBJECT(params)->addCustomContent( + LinphonePrivate::Content::toCpp(content)->getSharedFromThis()); } bool_t linphone_call_params_rtp_bundle_enabled(const LinphoneCallParams *params) { diff --git a/src/c-wrapper/api/c-chat-message.cpp b/src/c-wrapper/api/c-chat-message.cpp index 4480f9f7b8384361a5c1250208dd98e54443f39d..a0f745532cc3e123571b4cb540654161da4bb739 100644 --- a/src/c-wrapper/api/c-chat-message.cpp +++ b/src/c-wrapper/api/c-chat-message.cpp @@ -381,8 +381,8 @@ LinphoneStatus linphone_chat_message_put_char(LinphoneChatMessage *msg, uint32_t void linphone_chat_message_add_file_content(LinphoneChatMessage *msg, LinphoneContent *c_content) { LinphonePrivate::ChatMessageLogContextualizer logContextualizer(msg); - LinphonePrivate::FileContent *fileContent = new LinphonePrivate::FileContent(); - LinphonePrivate::Content *content = L_GET_CPP_PTR_FROM_C_OBJECT(c_content); + auto fileContent = LinphonePrivate::FileContent::create<LinphonePrivate::FileContent>(); + auto content = LinphonePrivate::Content::toCpp(c_content); fileContent->setContentType(content->getContentType()); // If content type hasn't been set, use application/octet-stream @@ -413,7 +413,7 @@ void linphone_chat_message_add_file_content(LinphoneChatMessage *msg, LinphoneCo void linphone_chat_message_add_text_content(LinphoneChatMessage *msg, const char *text) { LinphonePrivate::ChatMessageLogContextualizer logContextualizer(msg); - LinphonePrivate::Content *content = new LinphonePrivate::Content(); + auto content = LinphonePrivate::Content::create(); LinphonePrivate::ContentType contentType = LinphonePrivate::ContentType::PlainText; content->setContentType(contentType); content->setBodyFromLocale(L_C_TO_STRING(text)); @@ -422,7 +422,7 @@ void linphone_chat_message_add_text_content(LinphoneChatMessage *msg, const char void linphone_chat_message_add_utf8_text_content(LinphoneChatMessage *msg, const char *text) { LinphonePrivate::ChatMessageLogContextualizer logContextualizer(msg); - LinphonePrivate::Content *content = new LinphonePrivate::Content(); + auto content = LinphonePrivate::Content::create(); LinphonePrivate::ContentType contentType = LinphonePrivate::ContentType::PlainText; content->setContentType(contentType); content->setBodyFromUtf8(L_C_TO_STRING(text)); @@ -432,13 +432,12 @@ void linphone_chat_message_add_utf8_text_content(LinphoneChatMessage *msg, const void linphone_chat_message_add_content(LinphoneChatMessage *msg, LinphoneContent *c_content) { LinphonePrivate::ChatMessageLogContextualizer logContextualizer(msg); if (linphone_content_is_voice_recording(c_content)) { - linphone_content_ref(c_content); - LinphonePrivate::Content *content = - static_cast<LinphonePrivate::FileContent *>(L_GET_CPP_PTR_FROM_C_OBJECT(c_content)); + auto content = dynamic_pointer_cast<LinphonePrivate::FileContent>( + LinphonePrivate::Content::toCpp(c_content)->getSharedFromThis()); L_GET_CPP_PTR_FROM_C_OBJECT(msg)->addContent(content); } else { - LinphonePrivate::Content *content = L_GET_CPP_PTR_FROM_C_OBJECT(c_content); - LinphonePrivate::Content *cppContent = new LinphonePrivate::Content(); + auto content = LinphonePrivate::Content::toCpp(c_content); + auto cppContent = LinphonePrivate::Content::create(); cppContent->setContentType(content->getContentType()); cppContent->setBody(content->getBody()); cppContent->setUserData(content->getUserData()); @@ -448,13 +447,14 @@ void linphone_chat_message_add_content(LinphoneChatMessage *msg, LinphoneContent void linphone_chat_message_remove_content(LinphoneChatMessage *msg, LinphoneContent *content) { LinphonePrivate::ChatMessageLogContextualizer logContextualizer(msg); - L_GET_CPP_PTR_FROM_C_OBJECT(msg)->removeContent(L_GET_CPP_PTR_FROM_C_OBJECT(content)); + L_GET_CPP_PTR_FROM_C_OBJECT(msg)->removeContent(LinphonePrivate::Content::toCpp(content)->toSharedPtr()); } const bctbx_list_t *linphone_chat_message_get_contents(const LinphoneChatMessage *msg) { LinphonePrivate::ChatMessageLogContextualizer logContextualizer(msg); if (msg->cache.contents) bctbx_free(msg->cache.contents); - msg->cache.contents = L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getContents()); + msg->cache.contents = + LinphonePrivate::Content::getCListFromCppList(L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getContents(), false); return msg->cache.contents; } @@ -465,7 +465,7 @@ bool_t linphone_chat_message_has_text_content(const LinphoneChatMessage *msg) { const char *linphone_chat_message_get_text_content(const LinphoneChatMessage *msg) { LinphonePrivate::ChatMessageLogContextualizer logContextualizer(msg); - const LinphonePrivate::Content *content = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getTextContent(); + const auto content = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getTextContent(); if (content->isEmpty()) return nullptr; msg->cache.textContentBody = content->getBodyAsString(); return L_STRING_TO_C(msg->cache.textContentBody); @@ -490,7 +490,7 @@ bctbx_list_t *linphone_chat_message_get_participants_by_imdn_state(const Linphon bool_t linphone_chat_message_download_content(LinphoneChatMessage *msg, LinphoneContent *c_content) { LinphonePrivate::ChatMessageLogContextualizer logContextualizer(msg); - LinphonePrivate::Content *content = L_GET_CPP_PTR_FROM_C_OBJECT(c_content); + auto content = LinphonePrivate::Content::toCpp(c_content)->getSharedFromThis(); if (!content->isFileTransfer()) { if (content->isFile()) { lError() << "LinphoneContent [" << content @@ -500,8 +500,7 @@ bool_t linphone_chat_message_download_content(LinphoneChatMessage *msg, Linphone } return false; } - LinphonePrivate::FileTransferContent *fileTransferContent = - static_cast<LinphonePrivate::FileTransferContent *>(content); + auto fileTransferContent = dynamic_pointer_cast<LinphonePrivate::FileTransferContent>(content); return !!L_GET_CPP_PTR_FROM_C_OBJECT(msg)->downloadFile(fileTransferContent); } @@ -558,8 +557,8 @@ int linphone_chat_message_set_utf8_text(LinphoneChatMessage *msg, const char *te } LinphoneContent *linphone_chat_message_get_file_transfer_information(const LinphoneChatMessage *msg) { - const LinphonePrivate::Content *content = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferInformation(); - if (content) return L_GET_C_BACK_PTR(content); + const auto &content = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferInformation(); + if (content) return content->toC(); return NULL; } diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index a94383323ca99de62d7659c6e94268f4dd36768f..fb8a92f50305fff2d7ef322357df9bff0c4b409f 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -21,7 +21,6 @@ #include <bctoolbox/defs.h> #include "linphone/api/c-content.h" -#include "linphone/wrapper_utils.h" #include "c-wrapper/c-wrapper.h" #include "content/content-type.h" @@ -32,97 +31,58 @@ // ============================================================================= using namespace std; - -static void _linphone_content_constructor(LinphoneContent *content); -static void _linphone_content_destructor(LinphoneContent *content); -static void _linphone_content_c_clone(LinphoneContent *dest, const LinphoneContent *src); - -L_DECLARE_C_CLONABLE_OBJECT_IMPL_WITH_XTORS( - Content, - _linphone_content_constructor, - _linphone_content_destructor, - _linphone_content_c_clone, - - void *cryptoContext; // Used to encrypt file for RCS file transfer. - - mutable size_t size; - bool_t is_dirty = FALSE; - SalBodyHandler * body_handler; - - struct Cache { - string name; - string type; - string subtype; - string buffer; - string file_path; - string header_value; - } mutable cache;) - -static void _linphone_content_constructor(LinphoneContent *content) { - new (&content->cache) LinphoneContent::Cache(); -} - -static void _linphone_content_destructor(LinphoneContent *content) { - content->cache.~Cache(); - if (content->body_handler) sal_body_handler_unref(content->body_handler); -} - -static void _linphone_content_c_clone(LinphoneContent *dest, const LinphoneContent *src) { - new (&dest->cache) LinphoneContent::Cache(); - dest->size = src->size; - dest->cache = src->cache; - if (!src->is_dirty && src->body_handler) dest->body_handler = sal_body_handler_ref(src->body_handler); -} +using namespace LinphonePrivate; // ============================================================================= // Reference and user data handling functions. // ============================================================================= LinphoneContent *linphone_content_ref(LinphoneContent *content) { - belle_sip_object_ref(content); + Content::toCpp(content)->ref(); return content; } void linphone_content_unref(LinphoneContent *content) { - belle_sip_object_unref(content); + Content::toCpp(content)->unref(); } void *linphone_content_get_user_data(const LinphoneContent *content) { - return L_GET_CPP_PTR_FROM_C_OBJECT(content)->getUserData().getValue<void *>(); + return Content::toCpp(content)->getUserData().getValue<void *>(); } void linphone_content_set_user_data(LinphoneContent *content, void *user_data) { - return L_GET_CPP_PTR_FROM_C_OBJECT(content)->setUserData(user_data); + return Content::toCpp(content)->setUserData(user_data); } // ============================================================================= const char *linphone_content_get_type(const LinphoneContent *content) { - content->cache.type = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getType(); - return content->cache.type.c_str(); + return L_STRING_TO_C(Content::toCpp(content)->getContentType().getType()); } void linphone_content_set_type(LinphoneContent *content, const char *type) { - LinphonePrivate::ContentType contentType = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType(); + auto contentCpp = Content::toCpp(content); + auto contentType = contentCpp->getContentType(); contentType.setType(L_C_TO_STRING(type)); - L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentType(contentType); + contentCpp->setContentType(contentType); } const char *linphone_content_get_subtype(const LinphoneContent *content) { - content->cache.subtype = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getSubType(); - return content->cache.subtype.c_str(); + return L_STRING_TO_C(Content::toCpp(content)->getContentType().getSubType()); } void linphone_content_set_subtype(LinphoneContent *content, const char *subtype) { - LinphonePrivate::ContentType contentType = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType(); + auto contentCpp = Content::toCpp(content); + ContentType contentType = contentCpp->getContentType(); contentType.setSubType(L_C_TO_STRING(subtype)); - L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentType(contentType); + contentCpp->setContentType(contentType); } void linphone_content_add_content_type_parameter(LinphoneContent *content, const char *name, const char *value) { - LinphonePrivate::ContentType contentType = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType(); + auto contentCpp = Content::toCpp(content); + ContentType contentType = contentCpp->getContentType(); contentType.addParameter(L_C_TO_STRING(name), L_C_TO_STRING(value)); - L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentType(contentType); + contentCpp->setContentType(contentType); } const uint8_t *linphone_content_get_buffer(const LinphoneContent *content) { @@ -130,101 +90,88 @@ const uint8_t *linphone_content_get_buffer(const LinphoneContent *content) { } void linphone_content_set_buffer(LinphoneContent *content, const uint8_t *buffer, size_t size) { - content->is_dirty = TRUE; - L_GET_CPP_PTR_FROM_C_OBJECT(content)->setBody(buffer, size); + Content::toCpp(content)->setBody(buffer, size); } const char *linphone_content_get_string_buffer(const LinphoneContent *content) { - content->cache.buffer = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsUtf8String(); - return content->cache.buffer.c_str(); + return L_STRING_TO_C(Content::toCpp(content)->getBodyAsUtf8String()); } const char *linphone_content_get_utf8_text(const LinphoneContent *content) { - content->cache.buffer = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsUtf8String(); - return content->cache.buffer.c_str(); + return L_STRING_TO_C(Content::toCpp(content)->getBodyAsUtf8String()); } void linphone_content_set_utf8_text(LinphoneContent *content, const char *buffer) { - content->is_dirty = TRUE; - L_GET_CPP_PTR_FROM_C_OBJECT(content)->setBodyFromUtf8(L_C_TO_STRING(buffer)); + Content::toCpp(content)->setBodyFromUtf8(L_C_TO_STRING(buffer)); } void linphone_content_set_string_buffer(LinphoneContent *content, const char *buffer) { - content->is_dirty = TRUE; - L_GET_CPP_PTR_FROM_C_OBJECT(content)->setBodyFromUtf8(L_C_TO_STRING(buffer)); + Content::toCpp(content)->setBodyFromUtf8(L_C_TO_STRING(buffer)); } size_t linphone_content_get_file_size(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + const auto c = Content::toCpp(content); size_t size = 0; - if (c->isFile()) size = static_cast<const LinphonePrivate::FileContent *>(c)->getFileSize(); - else if (c->isFileTransfer()) size = static_cast<const LinphonePrivate::FileTransferContent *>(c)->getFileSize(); + if (c->isFile()) size = dynamic_cast<const FileContent *>(c)->getFileSize(); + else if (c->isFileTransfer()) size = dynamic_cast<const FileTransferContent *>(c)->getFileSize(); return size; } size_t linphone_content_get_size(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - size_t size = c->getSize(); - if (size == 0) { - size = content->size; - } - return size; + return Content::toCpp(content)->getSize(); } void linphone_content_set_size(LinphoneContent *content, size_t size) { - content->size = size; + Content::toCpp(content)->setSize(size); } const char *linphone_content_get_encoding(const LinphoneContent *content) { - return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentEncoding()); + return L_STRING_TO_C(Content::toCpp(content)->getContentEncoding()); } void linphone_content_set_encoding(LinphoneContent *content, const char *encoding) { - L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentEncoding(L_C_TO_STRING(encoding)); + Content::toCpp(content)->setContentEncoding(L_C_TO_STRING(encoding)); } const char *linphone_content_get_disposition(const LinphoneContent *content) { - const LinphonePrivate::ContentDisposition &contentDisposition = - L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentDisposition(); + const auto &contentDisposition = Content::toCpp(content)->getContentDisposition(); return L_STRING_TO_C(contentDisposition.asString()); } void linphone_content_set_disposition(LinphoneContent *content, const char *disposition) { - if (disposition != nullptr) { - string strDisposition = L_C_TO_STRING(disposition); - if (!strDisposition.empty()) { - LinphonePrivate::ContentDisposition contentDisposition = - LinphonePrivate::ContentDisposition(strDisposition); - L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentDisposition(contentDisposition); - } + string strDisposition = L_C_TO_STRING(disposition); + if (!strDisposition.empty()) { + ContentDisposition contentDisposition = ContentDisposition(strDisposition); + Content::toCpp(content)->setContentDisposition(contentDisposition); } } const char *linphone_content_get_name(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->isFile()) return static_cast<const LinphonePrivate::FileContent *>(c)->getFileName().c_str(); - else if (c->isFileTransfer()) - return static_cast<const LinphonePrivate::FileTransferContent *>(c)->getFileName().c_str(); - return content->cache.name.c_str(); + const auto c = Content::toCpp(content); + + if (c->isFile()) return L_STRING_TO_C(dynamic_cast<const FileContent *>(c)->getFileName()); + else if (c->isFileTransfer()) return L_STRING_TO_C(dynamic_cast<const FileTransferContent *>(c)->getFileName()); + + return L_STRING_TO_C(c->getName()); } void linphone_content_set_name(LinphoneContent *content, const char *name) { - LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->isFile()) static_cast<LinphonePrivate::FileContent *>(c)->setFileName(L_C_TO_STRING(name)); - else if (c->isFileTransfer()) - static_cast<LinphonePrivate::FileTransferContent *>(c)->setFileName(L_C_TO_STRING(name)); - else content->cache.name = L_C_TO_STRING(name); + auto c = Content::toCpp(content); + if (c->isFile()) dynamic_cast<FileContent *>(c)->setFileName(L_C_TO_STRING(name)); + else if (c->isFileTransfer()) dynamic_cast<FileTransferContent *>(c)->setFileName(L_C_TO_STRING(name)); + else c->setName(L_C_TO_STRING(name)); } bool_t linphone_content_is_multipart(const LinphoneContent *content) { - return L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().isMultipart(); + return Content::toCpp(content)->getContentType().isMultipart(); } bctbx_list_t *linphone_content_get_parts(const LinphoneContent *content) { + const auto c = Content::toCpp(content); bctbx_list_t *parts = nullptr; SalBodyHandler *bodyHandler; - if (!content->is_dirty && content->body_handler) { - bodyHandler = sal_body_handler_ref(content->body_handler); + if (!c->isDirty() && c->getBodyHandler() != nullptr) { + bodyHandler = sal_body_handler_ref(c->getBodyHandler()); } else { bodyHandler = sal_body_handler_from_content(content); } @@ -235,9 +182,9 @@ bctbx_list_t *linphone_content_get_parts(const LinphoneContent *content) { } const bctbx_list_t *sal_parts = sal_body_handler_get_parts(bodyHandler); - bctbx_list_t *it = (bctbx_list_t *)sal_parts; + auto it = (bctbx_list_t *)sal_parts; while (it != nullptr) { - SalBodyHandler *bh = (SalBodyHandler *)it->data; + auto bh = (SalBodyHandler *)it->data; LinphoneContent *part = linphone_content_from_sal_body_handler(bh); parts = bctbx_list_append(parts, linphone_content_ref(part)); linphone_content_unref(part); @@ -249,9 +196,10 @@ bctbx_list_t *linphone_content_get_parts(const LinphoneContent *content) { } LinphoneContent *linphone_content_get_part(const LinphoneContent *content, int idx) { + const auto c = Content::toCpp(content); SalBodyHandler *bodyHandler; - if (!content->is_dirty && content->body_handler) { - bodyHandler = sal_body_handler_ref(content->body_handler); + if (!c->isDirty() && c->getBodyHandler() != nullptr) { + bodyHandler = sal_body_handler_ref(c->getBodyHandler()); } else { bodyHandler = sal_body_handler_from_content(content); } @@ -269,9 +217,10 @@ LinphoneContent *linphone_content_get_part(const LinphoneContent *content, int i LinphoneContent * linphone_content_find_part_by_header(const LinphoneContent *content, const char *headerName, const char *headerValue) { + const auto c = Content::toCpp(content); SalBodyHandler *bodyHandler; - if (!content->is_dirty && content->body_handler) { - bodyHandler = sal_body_handler_ref(content->body_handler); + if (!c->isDirty() && c->getBodyHandler() != nullptr) { + bodyHandler = sal_body_handler_ref(c->getBodyHandler()); } else { bodyHandler = sal_body_handler_from_content(content); } @@ -288,83 +237,67 @@ linphone_content_find_part_by_header(const LinphoneContent *content, const char } const char *linphone_content_get_custom_header(const LinphoneContent *content, const char *headerName) { - SalBodyHandler *bodyHandler; - if (!content->is_dirty && content->body_handler) { - bodyHandler = sal_body_handler_ref(content->body_handler); - } else { - bodyHandler = sal_body_handler_from_content(content); - } - - content->cache.header_value = L_C_TO_STRING(sal_body_handler_get_header(bodyHandler, headerName)); - sal_body_handler_unref(bodyHandler); - return content->cache.header_value.c_str(); + return L_STRING_TO_C(Content::toCpp(content)->getCustomHeader(L_C_TO_STRING(headerName))); } void linphone_content_add_custom_header(LinphoneContent *content, const char *header_name, const char *header_value) { - LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - c->addHeader(L_C_TO_STRING(header_name), L_C_TO_STRING(header_value)); + Content::toCpp(content)->addHeader(L_C_TO_STRING(header_name), L_C_TO_STRING(header_value)); } const char *linphone_content_get_key(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + const auto c = Content::toCpp(content); if (c->isFileTransfer()) { - const LinphonePrivate::FileTransferContent *ftc = static_cast<const LinphonePrivate::FileTransferContent *>(c); + auto ftc = dynamic_cast<const FileTransferContent *>(c); return ftc->getFileKey().data(); } return nullptr; } size_t linphone_content_get_key_size(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + const auto c = Content::toCpp(content); if (c->isFileTransfer()) { - const LinphonePrivate::FileTransferContent *ftc = static_cast<const LinphonePrivate::FileTransferContent *>(c); + auto ftc = dynamic_cast<const FileTransferContent *>(c); return ftc->getFileKeySize(); } return 0; } void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength) { - LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + auto c = Content::toCpp(content); if (c->isFileTransfer()) { - LinphonePrivate::FileTransferContent *ftc = static_cast<LinphonePrivate::FileTransferContent *>(c); + auto ftc = dynamic_cast<FileTransferContent *>(c); ftc->setFileKey(key, keyLength); } } const char *linphone_content_get_authTag(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + const auto c = Content::toCpp(content); if (c->isFileTransfer()) { - const LinphonePrivate::FileTransferContent *ftc = static_cast<const LinphonePrivate::FileTransferContent *>(c); + auto ftc = dynamic_cast<const FileTransferContent *>(c); return ftc->getFileAuthTag().data(); } return nullptr; } size_t linphone_content_get_authTag_size(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + const auto c = Content::toCpp(content); if (c->isFileTransfer()) { - const LinphonePrivate::FileTransferContent *ftc = static_cast<const LinphonePrivate::FileTransferContent *>(c); + auto ftc = dynamic_cast<const FileTransferContent *>(c); return ftc->getFileAuthTagSize(); } return 0; } void linphone_content_set_authTag(LinphoneContent *content, const char *tag, const size_t tagLength) { - LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + auto c = Content::toCpp(content); if (c->isFileTransfer()) { - LinphonePrivate::FileTransferContent *ftc = static_cast<LinphonePrivate::FileTransferContent *>(c); + auto ftc = dynamic_cast<FileTransferContent *>(c); ftc->setFileAuthTag(tag, tagLength); } } const char *linphone_content_get_file_path(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->isFile()) { - return L_STRING_TO_C(static_cast<const LinphonePrivate::FileContent *>(c)->getFilePath()); - } else if (c->isFileTransfer()) { - return L_STRING_TO_C(static_cast<const LinphonePrivate::FileTransferContent *>(c)->getFilePath()); - } - return L_STRING_TO_C(content->cache.file_path); + return L_STRING_TO_C(Content::toCpp(content)->getFilePath()); } /* function deprecated on 07/01/2022 export_plain_file is more explicit */ @@ -373,77 +306,66 @@ char *linphone_content_get_plain_file_path(const LinphoneContent *content) { } char *linphone_content_export_plain_file(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + const Content *c = Content::toCpp(content); if (c->isFile()) { - auto filePath = static_cast<const LinphonePrivate::FileContent *>(c)->exportPlainFile(); + auto filePath = dynamic_cast<const FileContent *>(c)->exportPlainFile(); return bctbx_strdup(L_STRING_TO_C(filePath)); } else if (c->isFileTransfer()) { - auto filePath = static_cast<const LinphonePrivate::FileTransferContent *>(c)->exportPlainFile(); + auto filePath = dynamic_cast<const FileTransferContent *>(c)->exportPlainFile(); return bctbx_strdup(L_STRING_TO_C(filePath)); } - return NULL; + return nullptr; } void linphone_content_set_file_path(LinphoneContent *content, const char *file_path) { - LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->isFile()) { - static_cast<LinphonePrivate::FileContent *>(c)->setFilePath(L_C_TO_STRING(file_path)); - } else if (c->isFileTransfer()) { - static_cast<LinphonePrivate::FileTransferContent *>(c)->setFilePath(L_C_TO_STRING(file_path)); - } - content->cache.file_path = L_C_TO_STRING(file_path); + Content::toCpp(content)->setFilePath(L_C_TO_STRING(file_path)); } int linphone_content_get_file_duration(LinphoneContent *content) { - LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->isFile()) return static_cast<LinphonePrivate::FileContent *>(c)->getFileDuration(); - else if (c->isFileTransfer()) return static_cast<LinphonePrivate::FileTransferContent *>(c)->getFileDuration(); + auto c = Content::toCpp(content); + if (c->isFile()) return dynamic_cast<FileContent *>(c)->getFileDuration(); + else if (c->isFileTransfer()) return dynamic_cast<FileTransferContent *>(c)->getFileDuration(); return -1; } bool_t linphone_content_is_text(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - return c->getContentType() == LinphonePrivate::ContentType::PlainText; + return Content::toCpp(content)->getContentType() == ContentType::PlainText; } bool_t linphone_content_is_voice_recording(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + const auto c = Content::toCpp(content); if (c->isFile()) { - return c->getContentType().strongEqual(LinphonePrivate::ContentType::VoiceRecording); + return c->getContentType().strongEqual(ContentType::VoiceRecording); } else if (c->isFileTransfer()) { - return static_cast<const LinphonePrivate::FileTransferContent *>(c)->getFileContentType().strongEqual( - LinphonePrivate::ContentType::VoiceRecording); + return dynamic_cast<const FileTransferContent *>(c)->getFileContentType().strongEqual( + ContentType::VoiceRecording); } return false; } bool_t linphone_content_is_icalendar(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + const auto c = Content::toCpp(content); if (c->isFileTransfer()) { - return static_cast<const LinphonePrivate::FileTransferContent *>(c)->getFileContentType().strongEqual( - LinphonePrivate::ContentType::Icalendar); + return dynamic_cast<const FileTransferContent *>(c)->getFileContentType().strongEqual(ContentType::Icalendar); } else { - return c->getContentType().strongEqual(LinphonePrivate::ContentType::Icalendar); + return c->getContentType().strongEqual(ContentType::Icalendar); } - return false; } bool_t linphone_content_is_file(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - return c->isFile(); + return Content::toCpp(content)->isFile(); } bool_t linphone_content_is_file_transfer(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - return c->isFileTransfer(); + return Content::toCpp(content)->isFileTransfer(); } bool_t linphone_content_is_file_encrypted(const LinphoneContent *content) { - const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + const auto c = Content::toCpp(content); if (c->isFile()) { - return static_cast<const LinphonePrivate::FileContent *>(c)->isEncrypted(); + return dynamic_cast<const FileContent *>(c)->isEncrypted(); } else if (c->isFileTransfer()) { - return static_cast<const LinphonePrivate::FileTransferContent *>(c)->isEncrypted(); + return dynamic_cast<const FileTransferContent *>(c)->isEncrypted(); } return FALSE; } @@ -453,54 +375,7 @@ bool_t linphone_content_is_file_encrypted(const LinphoneContent *content) { // ============================================================================= static LinphoneContent *linphone_content_new_with_body_handler(const SalBodyHandler *bodyHandler, bool parseMultipart) { - LinphoneContent *content = L_INIT(Content); - content->cryptoContext = nullptr; - LinphonePrivate::Content *c = new LinphonePrivate::Content(); - L_SET_CPP_PTR_FROM_C_OBJECT(content, c); - content->body_handler = nullptr; - - if (!bodyHandler) return content; - - content->body_handler = sal_body_handler_ref((SalBodyHandler *)bodyHandler); - - linphone_content_set_type(content, sal_body_handler_get_type(bodyHandler)); - linphone_content_set_subtype(content, sal_body_handler_get_subtype(bodyHandler)); - for (const belle_sip_list_t *params = sal_body_handler_get_content_type_parameters_names(bodyHandler); params; - params = params->next) { - const char *paramName = reinterpret_cast<const char *>(params->data); - const char *paramValue = sal_body_handler_get_content_type_parameter(bodyHandler, paramName); - linphone_content_add_content_type_parameter(content, paramName, paramValue); - } - - if (linphone_content_is_multipart(content) && parseMultipart) { - belle_sip_multipart_body_handler_t *mpbh = BELLE_SIP_MULTIPART_BODY_HANDLER(bodyHandler); - char *body = belle_sip_object_to_string(mpbh); - linphone_content_set_utf8_text(content, body); - belle_sip_free(body); - } else { - linphone_content_set_utf8_text(content, reinterpret_cast<char *>(sal_body_handler_get_data(bodyHandler))); - } - - const belle_sip_list_t *headers = - reinterpret_cast<const belle_sip_list_t *>(sal_body_handler_get_headers(bodyHandler)); - while (headers) { - belle_sip_header_t *cHeader = BELLE_SIP_HEADER(headers->data); - LinphonePrivate::Header header = - LinphonePrivate::Header(belle_sip_header_get_name(cHeader), belle_sip_header_get_unparsed_value(cHeader)); - L_GET_CPP_PTR_FROM_C_OBJECT(content)->addHeader(header); - headers = headers->next; - } - - if (sal_body_handler_get_encoding(bodyHandler)) - linphone_content_set_encoding(content, sal_body_handler_get_encoding(bodyHandler)); - - const char *disposition = sal_body_handler_get_content_disposition(bodyHandler); - if (disposition) { - LinphonePrivate::ContentDisposition contentDisposition = LinphonePrivate::ContentDisposition(disposition); - L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentDisposition(contentDisposition); - } - - return content; + return Content::createCObject(bodyHandler, parseMultipart); } LinphoneContent *linphone_content_new(void) { @@ -508,7 +383,7 @@ LinphoneContent *linphone_content_new(void) { } LinphoneContent *linphone_content_copy(const LinphoneContent *ref) { - return reinterpret_cast<LinphoneContent *>(belle_sip_object_clone(BELLE_SIP_OBJECT(ref))); + return Content::toCpp(ref)->clone()->toC(); } LinphoneContent *linphone_core_create_content(BCTBX_UNUSED(LinphoneCore *lc)) { @@ -518,7 +393,7 @@ LinphoneContent *linphone_core_create_content(BCTBX_UNUSED(LinphoneCore *lc)) { // Crypto context is managed(allocated/freed) by the encryption function, // so provide the address of field in the private structure. void **linphone_content_get_cryptoContext_address(LinphoneContent *content) { - return &content->cryptoContext; + return Content::toCpp(content)->getCryptoContextAddress(); } LinphoneContent *linphone_content_from_sal_body_handler(const SalBodyHandler *bodyHandler, bool parseMultipart) { @@ -528,57 +403,5 @@ LinphoneContent *linphone_content_from_sal_body_handler(const SalBodyHandler *bo SalBodyHandler *sal_body_handler_from_content(const LinphoneContent *content, bool parseMultipart) { if (!content) return nullptr; - - if (!content->is_dirty && content->body_handler) return sal_body_handler_ref(content->body_handler); - - auto cppContent = L_GET_CPP_PTR_FROM_C_OBJECT(content); - - SalBodyHandler *bodyHandler; - LinphonePrivate::ContentType contentType = cppContent->getContentType(); - if (contentType.isMultipart() && parseMultipart) { - size_t size = linphone_content_get_size(content); - char *buffer = bctbx_strdup(cppContent->getBodyAsUtf8String().c_str()); - const char *boundary = L_STRING_TO_C(contentType.getParameter("boundary").getValue()); - belle_sip_multipart_body_handler_t *bh = NULL; - if (boundary) bh = belle_sip_multipart_body_handler_new_from_buffer(buffer, size, boundary); - else if (size > 2) { - size_t startIndex = 2, index; - while (startIndex < size && - (buffer[startIndex] != '-' || buffer[startIndex - 1] != '-' // Take accout of first "--" - || (startIndex > 2 && buffer[startIndex - 2] != '\n'))) // Must be at the beginning of the line - ++startIndex; - index = startIndex; - while (index < size && buffer[index] != '\n' && buffer[index] != '\r') - ++index; - if (startIndex != index) { - char *boundaryStr = bctbx_strndup(buffer + startIndex, (int)(index - startIndex)); - bh = belle_sip_multipart_body_handler_new_from_buffer(buffer, size, boundaryStr); - bctbx_free(boundaryStr); - } - } - - bodyHandler = reinterpret_cast<SalBodyHandler *>(BELLE_SIP_BODY_HANDLER(bh)); - bctbx_free(buffer); - } else { - bodyHandler = sal_body_handler_new(); - sal_body_handler_set_data(bodyHandler, belle_sip_strdup(cppContent->getBodyAsUtf8String().c_str())); - } - - for (const auto &header : cppContent->getHeaders()) { - sal_body_handler_add_header(bodyHandler, header.getName().c_str(), header.getValueWithParams().c_str()); - } - - sal_body_handler_set_type(bodyHandler, contentType.getType().c_str()); - sal_body_handler_set_subtype(bodyHandler, contentType.getSubType().c_str()); - sal_body_handler_set_size(bodyHandler, linphone_content_get_size(content)); - for (const auto ¶m : contentType.getParameters()) - sal_body_handler_set_content_type_parameter(bodyHandler, param.getName().c_str(), param.getValue().c_str()); - - if (linphone_content_get_encoding(content)) - sal_body_handler_set_encoding(bodyHandler, linphone_content_get_encoding(content)); - - const LinphonePrivate::ContentDisposition &disposition = cppContent->getContentDisposition(); - if (disposition.isValid()) sal_body_handler_set_content_disposition(bodyHandler, disposition.asString().c_str()); - - return bodyHandler; + return Content::getBodyHandlerFromContent(*Content::toCpp(content), parseMultipart); } diff --git a/src/c-wrapper/api/c-event.cpp b/src/c-wrapper/api/c-event.cpp index f6fe47d6fad4947222816d55863634bc4e49def1..9c685c1c3d5af474085cd05c0774a14adadeb3d1 100644 --- a/src/c-wrapper/api/c-event.cpp +++ b/src/c-wrapper/api/c-event.cpp @@ -514,18 +514,20 @@ LinphoneEvent *linphone_event_new_subscribe_with_op(LinphoneCore *lc, SalSubscribeOp *op, LinphoneSubscriptionDir dir, const char *name) { - return (new EventSubscribe(L_GET_CPP_PTR_FROM_C_OBJECT(lc), op, dir, L_C_TO_STRING(name), false))->toC(); + return EventSubscribe::createCObject<EventSubscribe>(L_GET_CPP_PTR_FROM_C_OBJECT(lc), op, dir, L_C_TO_STRING(name), + false); } LinphoneEvent *linphone_event_new_subscribe_with_out_of_dialog_op(LinphoneCore *lc, SalSubscribeOp *op, LinphoneSubscriptionDir dir, const char *name) { - return (new EventSubscribe(L_GET_CPP_PTR_FROM_C_OBJECT(lc), op, dir, L_C_TO_STRING(name), true))->toC(); + return EventSubscribe::createCObject<EventSubscribe>(L_GET_CPP_PTR_FROM_C_OBJECT(lc), op, dir, L_C_TO_STRING(name), + true); } LinphoneEvent *linphone_event_new_publish_with_op(LinphoneCore *lc, SalPublishOp *op, const char *name) { - return (new EventPublish(L_GET_CPP_PTR_FROM_C_OBJECT(lc), op, L_C_TO_STRING(name)))->toC(); + return EventPublish::createCObject<EventPublish>(L_GET_CPP_PTR_FROM_C_OBJECT(lc), op, L_C_TO_STRING(name)); } #endif /* LINPHONE_EVENT_H_ */ diff --git a/src/c-wrapper/api/c-recorder.cpp b/src/c-wrapper/api/c-recorder.cpp index 798197e08b5e6f3191a597dff128b8e1f86aae1e..f533fb5fcc6dc928e09c7ff1604748c7a5f970db 100644 --- a/src/c-wrapper/api/c-recorder.cpp +++ b/src/c-wrapper/api/c-recorder.cpp @@ -76,9 +76,10 @@ float linphone_recorder_get_capture_volume(const LinphoneRecorder *recorder) { } LinphoneContent *linphone_recorder_create_content(LinphoneRecorder *recorder) { - LinphonePrivate::Content *fileContent = Recorder::toCpp(recorder)->createContent(); + auto fileContent = Recorder::toCpp(recorder)->createContent(); if (fileContent != nullptr) { - return L_GET_C_BACK_PTR(fileContent); + fileContent->ref(); + return fileContent->toC(); } return nullptr; } diff --git a/src/call/call.cpp b/src/call/call.cpp index f309344f005d651a79a907207fc22d7ecc095766..46190cc2fe43b9b1d7dcca7c200e90c5130c6ae4 100644 --- a/src/call/call.cpp +++ b/src/call/call.cpp @@ -182,7 +182,7 @@ void Call::initiateIncoming() { getActiveSession()->initiateIncoming(); } -bool Call::initiateOutgoing(const string &subject, const Content *content) { +bool Call::initiateOutgoing(const string &subject, const std::shared_ptr<const Content> content) { shared_ptr<CallSession> session = getActiveSession(); bool defer = session->initiateOutgoing(subject, content); session->getPrivate()->createOp(); @@ -215,7 +215,9 @@ void Call::pauseForTransfer() { static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->pauseForTransfer(); } -int Call::startInvite(const std::shared_ptr<Address> &destination, const std::string subject, const Content *content) { +int Call::startInvite(const std::shared_ptr<Address> &destination, + const std::string subject, + const std::shared_ptr<const Content> content) { return getActiveSession()->startInvite(destination, subject, content); } diff --git a/src/call/call.h b/src/call/call.h index b371d286de9638f984781b9d6f5a580ba22f4c59..21fd5228df317029606585ff9a880a7bb78584fd 100644 --- a/src/call/call.h +++ b/src/call/call.h @@ -213,7 +213,7 @@ public: // ----------------------------------------------------------------------------- void createPlayer() const; void initiateIncoming(); - bool initiateOutgoing(const std::string &subject = "", const Content *content = nullptr); + bool initiateOutgoing(const std::string &subject = "", const std::shared_ptr<const Content> content = nullptr); void iterate(time_t currentRealTime, bool oneSecondElapsed); void notifyRinging(); void startIncomingNotification(); @@ -222,7 +222,7 @@ public: void pauseForTransfer(); int startInvite(const std::shared_ptr<Address> &destination, const std::string subject = std::string(), - const Content *content = nullptr); + const std::shared_ptr<const Content> content = nullptr); std::shared_ptr<Call> startReferredCall(const MediaSessionParams *params); // ----------------------------------------------------------------------------- diff --git a/src/chat/chat-message/chat-message-p.h b/src/chat/chat-message/chat-message-p.h index 40691e961d72e36b89a46fab4a886b90bdb6cee4..e28b37e634dbe73d6ec7507c688629a7a2ca832c 100644 --- a/src/chat/chat-message/chat-message-p.h +++ b/src/chat/chat-message/chat-message-p.h @@ -120,12 +120,12 @@ public: void loadContentsFromDatabase() const; - std::list<Content *> &getContents() { + std::list<std::shared_ptr<Content>> &getContents() { loadContentsFromDatabase(); return contents; } - const std::list<Content *> &getContents() const { + const std::list<std::shared_ptr<Content>> &getContents() const { loadContentsFromDatabase(); return contents; } @@ -224,16 +224,16 @@ public: void setCallId(const std::string &id); bool hasTextContent() const; - const Content *getTextContent() const; + const std::shared_ptr<Content> getTextContent() const; bool hasConferenceInvitationContent() const; bool hasFileTransferContent() const; - const Content *getFileTransferContent() const; - const Content *getFileTransferInformation() const; + const std::shared_ptr<Content> getFileTransferContent() const; + const std::shared_ptr<Content> getFileTransferInformation() const; - void addContent(Content *content); - void removeContent(Content *content); - void replaceContent(Content *contentToRemove, Content *contentToAdd); + void addContent(std::shared_ptr<Content> content); + void removeContent(std::shared_ptr<Content> content); + void replaceContent(std::shared_ptr<Content> contentToRemove, std::shared_ptr<Content> contentToAdd); bool downloadFile(); @@ -312,7 +312,7 @@ private: long ephemeralLifetime = 0; time_t ephemeralExpireTime = 0; - std::list<Content *> contents; + std::list<std::shared_ptr<Content>> contents; mutable std::list<std::shared_ptr<ChatMessageReaction>> reactions; bool encryptionPrevented = false; diff --git a/src/chat/chat-message/chat-message-reaction.cpp b/src/chat/chat-message/chat-message-reaction.cpp index 97541eade51e099e1cd9ea8a381c59edb9e8037c..671a7d05d208a4d003e658414e4100d4f3018ea5 100644 --- a/src/chat/chat-message/chat-message-reaction.cpp +++ b/src/chat/chat-message/chat-message-reaction.cpp @@ -118,7 +118,7 @@ void ChatMessageReaction::send() { reactionMessage->addListener(getSharedFromThis()); reactionMessage->getPrivate()->setReactionToMessageId(messageId); - Content *content = new Content(); + auto content = Content::create(); content->setContentType(ContentType::PlainText); content->setBodyFromUtf8(reaction); reactionMessage->addContent(content); diff --git a/src/chat/chat-message/chat-message.cpp b/src/chat/chat-message/chat-message.cpp index d759e2c97d341e2b23e82220edf2f693b904a8d2..6bf0e6659a8ea998a01d1a9b268ce4739032aefd 100644 --- a/src/chat/chat-message/chat-message.cpp +++ b/src/chat/chat-message/chat-message.cpp @@ -65,14 +65,6 @@ ChatMessagePrivate::ChatMessagePrivate(const std::shared_ptr<AbstractChatRoom> & } ChatMessagePrivate::~ChatMessagePrivate() { - for (Content *content : contents) { - if (content->isFileTransfer()) { - FileTransferContent *fileTransferContent = static_cast<FileTransferContent *>(content); - delete fileTransferContent->getFileContent(); - } - delete content; - } - if (salOp) { salOp->setUserPointer(nullptr); salOp->unref(); @@ -466,7 +458,7 @@ string ChatMessagePrivate::getSalCustomHeaderValue(const string &name) const { // ----------------------------------------------------------------------------- bool ChatMessagePrivate::hasTextContent() const { - for (const Content *c : getContents()) { + for (const auto &c : getContents()) { if (c->getContentType() == ContentType::PlainText) { return true; } @@ -474,17 +466,17 @@ bool ChatMessagePrivate::hasTextContent() const { return false; } -const Content *ChatMessagePrivate::getTextContent() const { - for (const Content *c : getContents()) { +const std::shared_ptr<Content> ChatMessagePrivate::getTextContent() const { + for (const auto &c : getContents()) { if (c->getContentType() == ContentType::PlainText) { return c; } } - return &Utils::getEmptyConstRefObject<Content>(); + return nullptr; } bool ChatMessagePrivate::hasConferenceInvitationContent() const { - for (const Content *c : getContents()) { + for (const auto &c : getContents()) { if (c->getContentType().strongEqual(ContentType::Icalendar)) { return true; } @@ -493,7 +485,7 @@ bool ChatMessagePrivate::hasConferenceInvitationContent() const { } bool ChatMessagePrivate::hasFileTransferContent() const { - for (const Content *c : contents) { + for (const auto &c : contents) { if (c->isFileTransfer()) { return true; } @@ -501,13 +493,13 @@ bool ChatMessagePrivate::hasFileTransferContent() const { return false; } -const Content *ChatMessagePrivate::getFileTransferContent() const { - for (const Content *c : contents) { +const std::shared_ptr<Content> ChatMessagePrivate::getFileTransferContent() const { + for (const auto &c : contents) { if (c->isFileTransfer()) { return c; } } - return &Utils::getEmptyConstRefObject<Content>(); + return nullptr; } const string &ChatMessagePrivate::getFileTransferFilepath() const { @@ -523,9 +515,10 @@ void ChatMessagePrivate::setEphemeralExpireTime(time_t expireTime) { } const string &ChatMessagePrivate::getAppdata() const { - for (const Content *c : getContents()) { - if (!c->getAppData("legacy").empty()) { - return c->getAppData("legacy"); + for (const auto &c : getContents()) { + const auto &legacy = c->getProperty("legacy"); + if (legacy.isValid() && !legacy.getValue<string>().empty()) { + return legacy.getValue<string>(); } } return Utils::getEmptyConstRefObject<string>(); @@ -533,8 +526,8 @@ const string &ChatMessagePrivate::getAppdata() const { void ChatMessagePrivate::setAppdata(const string &data) { bool contentFound = false; - for (Content *c : getContents()) { - c->setAppData("legacy", data); + for (auto &c : getContents()) { + c->setProperty("legacy", Variant{data}); contentFound = true; break; } @@ -548,7 +541,7 @@ const string &ChatMessagePrivate::getExternalBodyUrl() const { return externalBodyUrl; } if (hasFileTransferContent()) { - FileTransferContent *content = (FileTransferContent *)getFileTransferContent(); + const auto &content = static_pointer_cast<FileTransferContent>(getFileTransferContent()); return content->getFileUrl(); } return Utils::getEmptyConstRefObject<string>(); @@ -562,7 +555,7 @@ const ContentType &ChatMessagePrivate::getContentType() const { loadContentsFromDatabase(); if (direction == ChatMessage::Direction::Incoming) { if (!contents.empty()) { - Content *content = contents.front(); + auto &content = contents.front(); cContentType = content->getContentType(); } else { cContentType = internalContent.getContentType(); @@ -572,7 +565,7 @@ const ContentType &ChatMessagePrivate::getContentType() const { cContentType = internalContent.getContentType(); } else { if (!contents.empty()) { - Content *content = contents.front(); + auto &content = contents.front(); cContentType = content->getContentType(); } } @@ -599,7 +592,7 @@ const string &ChatMessagePrivate::getText() const { if (hasTextContent()) { cText = getTextContent()->getBodyAsString(); } else if (!contents.empty()) { - Content *content = contents.front(); + auto &content = contents.front(); cText = content->getBodyAsString(); } else { cText = internalContent.getBodyAsString(); @@ -609,7 +602,7 @@ const string &ChatMessagePrivate::getText() const { cText = internalContent.getBodyAsString(); } else { if (!contents.empty()) { - Content *content = contents.front(); + auto &content = contents.front(); cText = content->getBodyAsString(); } } @@ -636,7 +629,7 @@ const string &ChatMessagePrivate::getUtf8Text() const { if (hasTextContent()) { cText = getTextContent()->getBodyAsUtf8String(); } else if (!contents.empty()) { - Content *content = contents.front(); + auto &content = contents.front(); cText = content->getBodyAsUtf8String(); } else { cText = internalContent.getBodyAsUtf8String(); @@ -646,7 +639,7 @@ const string &ChatMessagePrivate::getUtf8Text() const { cText = internalContent.getBodyAsUtf8String(); } else { if (!contents.empty()) { - Content *content = contents.front(); + auto &content = contents.front(); cText = content->getBodyAsUtf8String(); } } @@ -671,14 +664,13 @@ void ChatMessagePrivate::setUtf8Text(const string &text) { } } -const Content *ChatMessagePrivate::getFileTransferInformation() const { +const std::shared_ptr<Content> ChatMessagePrivate::getFileTransferInformation() const { if (hasFileTransferContent()) { return getFileTransferContent(); } - for (const Content *c : getContents()) { + for (const auto &c : getContents()) { if (c->isFile()) { - FileContent *fileContent = (FileContent *)c; - return fileContent; + return c; } } return nullptr; @@ -688,23 +680,24 @@ bool ChatMessagePrivate::downloadFile() { L_Q(); for (auto &content : getContents()) - if (content->isFileTransfer()) return q->downloadFile(static_cast<FileTransferContent *>(content)); + if (content->isFileTransfer()) return q->downloadFile(static_pointer_cast<FileTransferContent>(content)); return false; } -void ChatMessagePrivate::addContent(Content *content) { +void ChatMessagePrivate::addContent(std::shared_ptr<Content> content) { getContents().push_back(content); } -void ChatMessagePrivate::removeContent(Content *content) { +void ChatMessagePrivate::removeContent(std::shared_ptr<Content> content) { getContents().remove(content); } -void ChatMessagePrivate::replaceContent(Content *contentToRemove, Content *contentToAdd) { - list<Content *>::iterator it = contents.begin(); +void ChatMessagePrivate::replaceContent(std::shared_ptr<Content> contentToRemove, + std::shared_ptr<Content> contentToAdd) { + list<std::shared_ptr<Content>>::iterator it = contents.begin(); while (it != contents.end()) { - Content *content = *it; + auto &content = *it; if (content == contentToRemove) { it = contents.erase(it); it = contents.insert(it, contentToAdd); @@ -870,7 +863,7 @@ LinphoneReason ChatMessagePrivate::receive() { if (contents.empty()) { // All previous modifiers only altered the internal content, let's fill the content list - contents.push_back(new Content(internalContent)); + contents.push_back(Content::create(internalContent)); } for (auto &content : contents) { @@ -904,7 +897,7 @@ LinphoneReason ChatMessagePrivate::receive() { if (errorCode <= 0) { bool foundSupportContentType = false; - for (Content *c : contents) { + for (auto &c : contents) { ContentType ct(c->getContentType()); ct.cleanParameters(); string contenttype = ct.getType() + "/" + ct.getSubType(); @@ -1019,9 +1012,9 @@ void ChatMessagePrivate::handleAutoDownload() { bool_t autoDownloadVoiceRecordings = linphone_core_is_auto_download_voice_recordings_enabled(q->getCore()->getCCore()); bool_t autoDownloadIcalendars = linphone_core_is_auto_download_icalendars_enabled(q->getCore()->getCCore()); - for (Content *c : contents) { + for (auto &c : contents) { if (c->isFileTransfer()) { - FileTransferContent *ftc = static_cast<FileTransferContent *>(c); + auto ftc = static_pointer_cast<FileTransferContent>(c); ContentType fileContentType = ftc->getFileContentType(); if ((maxSize == 0 || (maxSize > 0 && ftc->getFileSize() <= (size_t)maxSize)) || @@ -1061,12 +1054,12 @@ void ChatMessagePrivate::handleAutoDownload() { // Accepted when a message is sent setParticipantState(chatRoom->getMe()->getAddress(), ChatMessage::State::Delivered, ::ms_time(NULL)); - for (Content *c : contents) { + for (auto &c : contents) { ContentType contentType = c->getContentType(); if (contentType.strongEqual(ContentType::Icalendar)) { - LinphoneConferenceInfo *cConfInfo = linphone_factory_create_conference_info_from_icalendar_content( - linphone_factory_get(), L_GET_C_BACK_PTR(c)); + LinphoneConferenceInfo *cConfInfo = + linphone_factory_create_conference_info_from_icalendar_content(linphone_factory_get(), c->toC()); if (cConfInfo != nullptr) { auto confInfo = ConferenceInfo::toCpp(cConfInfo)->getSharedFromThis(); @@ -1090,16 +1083,15 @@ void ChatMessagePrivate::restoreFileTransferContentAsFileContent() { } // Restore FileContents and remove FileTransferContents - list<Content *>::iterator it = contents.begin(); + list<std::shared_ptr<Content>>::iterator it = contents.begin(); while (it != contents.end()) { - Content *content = *it; + auto &content = *it; if (content && content->isFileTransfer()) { - FileTransferContent *fileTransferContent = static_cast<FileTransferContent *>(content); - FileContent *fileContent = fileTransferContent->getFileContent(); + auto fileTransferContent = static_pointer_cast<FileTransferContent>(content); + auto fileContent = fileTransferContent->getFileContent(); if (fileContent) { it = contents.erase(it); it = contents.insert(it, fileContent); - delete fileTransferContent; } else { lWarning() << "Found FileTransferContent but no associated FileContent"; it++; @@ -1293,7 +1285,7 @@ void ChatMessagePrivate::send() { if (internalContent.isEmpty()) { if (!contents.empty()) { - internalContent = *(contents.front()); + internalContent = Content(*contents.front()); } else if (externalBodyUrl.empty()) { // When using external body url, there is no content lError() << "Trying to send a message without any content !"; return; @@ -1764,17 +1756,17 @@ bool ChatMessage::isReadOnly() const { return d->isReadOnly; } -const list<Content *> &ChatMessage::getContents() const { +const list<std::shared_ptr<Content>> &ChatMessage::getContents() const { L_D(); return d->getContents(); } -void ChatMessage::addContent(Content *content) { +void ChatMessage::addContent(std::shared_ptr<Content> content) { L_D(); if (!d->isReadOnly) d->addContent(content); } -void ChatMessage::removeContent(Content *content) { +void ChatMessage::removeContent(std::shared_ptr<Content> content) { L_D(); if (!d->isReadOnly) d->removeContent(content); } @@ -1810,7 +1802,7 @@ void ChatMessage::send() { getChatRoom()->getPrivate()->sendChatMessage(getSharedFromThis()); } -bool ChatMessage::downloadFile(FileTransferContent *fileTransferContent) { +bool ChatMessage::downloadFile(std::shared_ptr<FileTransferContent> fileTransferContent) { L_D(); return d->fileTransferChatMessageModifier.downloadFile(getSharedFromThis(), fileTransferContent); } diff --git a/src/chat/chat-message/chat-message.h b/src/chat/chat-message/chat-message.h index a34c4804c13b94ac0d922f9e3395e9eb0392ff70..7d3bcb94201f4c037f745855f7ddcd4c59a72428 100644 --- a/src/chat/chat-message/chat-message.h +++ b/src/chat/chat-message/chat-message.h @@ -150,9 +150,9 @@ public: bool getToBeStored() const; virtual void setToBeStored(bool value); - const std::list<Content *> &getContents() const; - void addContent(Content *content); - void removeContent(Content *content); + const std::list<std::shared_ptr<Content>> &getContents() const; + void addContent(std::shared_ptr<Content> content); + void removeContent(std::shared_ptr<Content> content); std::list<ParticipantImdnState> getParticipantsByImdnState(State state) const; std::list<ParticipantImdnState> getParticipantsState() const; @@ -160,7 +160,7 @@ public: const Content &getInternalContent() const; void setInternalContent(const Content &content); - bool downloadFile(FileTransferContent *content); + bool downloadFile(std::shared_ptr<FileTransferContent> content); bool isFileTransferInProgress() const; void fileUploadEndBackgroundTask(); diff --git a/src/chat/chat-message/imdn-message.cpp b/src/chat/chat-message/imdn-message.cpp index 71b0b3561176c6a313d8206955e0ad47ef6753bf..b0fbdd1f4f0ecd0d15d9c8c8fd9b01b485020807 100644 --- a/src/chat/chat-message/imdn-message.cpp +++ b/src/chat/chat-message/imdn-message.cpp @@ -79,7 +79,7 @@ ImdnMessage::ImdnMessage(const Context &context) : NotificationMessage(*new Imdn continue; } - Content *content = new Content(); + auto content = Content::create(); content->setContentDisposition(ContentDisposition::Notification); content->setContentType(ContentType::Imdn); content->setBodyFromUtf8( @@ -94,7 +94,7 @@ ImdnMessage::ImdnMessage(const Context &context) : NotificationMessage(*new Imdn continue; } - Content *content = new Content(); + auto content = Content::create(); content->setContentDisposition(ContentDisposition::Notification); content->setContentType(ContentType::Imdn); content->setBodyFromUtf8( @@ -109,7 +109,7 @@ ImdnMessage::ImdnMessage(const Context &context) : NotificationMessage(*new Imdn continue; } - Content *content = new Content(); + auto content = Content::create(); content->setContentDisposition(ContentDisposition::Notification); content->setContentType(ContentType::Imdn); content->setBodyFromUtf8( diff --git a/src/chat/chat-message/is-composing-message.cpp b/src/chat/chat-message/is-composing-message.cpp index d2c99cb2696705f21c99a5aba0324a2c93ec04e7..23ce20c516c821b0dc129062b848da4781ef9498 100644 --- a/src/chat/chat-message/is-composing-message.cpp +++ b/src/chat/chat-message/is-composing-message.cpp @@ -35,7 +35,7 @@ IsComposingMessage::IsComposingMessage(const shared_ptr<AbstractChatRoom> &chatR bool isComposing) : NotificationMessage(*new NotificationMessagePrivate(chatRoom, ChatMessage::Direction::Outgoing)) { L_D(); - Content *content = new Content(); + auto content = Content::create(); content->setContentType(ContentType::ImIsComposing); content->setBodyFromUtf8(isComposingHandler.createXml(isComposing)); addContent(content); diff --git a/src/chat/chat-room/abstract-chat-room.h b/src/chat/chat-room/abstract-chat-room.h index 2a7f719c127032ebc7e459a46dad0aba533f0706..8f380f5e27d081f0e80f481109fdcf7e7884e6c4 100644 --- a/src/chat/chat-room/abstract-chat-room.h +++ b/src/chat/chat-room/abstract-chat-room.h @@ -135,7 +135,7 @@ public: virtual std::shared_ptr<ChatMessage> createChatMessage(const std::string &text) = 0; virtual std::shared_ptr<ChatMessage> createChatMessageFromUtf8(const std::string &text) = 0; - virtual std::shared_ptr<ChatMessage> createFileTransferMessage(FileContent *content) = 0; + virtual std::shared_ptr<ChatMessage> createFileTransferMessage(const std::shared_ptr<FileContent> &content) = 0; virtual std::shared_ptr<ChatMessage> createForwardMessage(const std::shared_ptr<ChatMessage> &msg) = 0; virtual std::shared_ptr<ChatMessage> createReplyMessage(const std::shared_ptr<ChatMessage> &msg) = 0; diff --git a/src/chat/chat-room/chat-room.cpp b/src/chat/chat-room/chat-room.cpp index 1e865019cf469ea1e48d58fbf98243b14cf445e4..d00c1f194c2f060a4a5f628dddc1065f7f800541 100644 --- a/src/chat/chat-room/chat-room.cpp +++ b/src/chat/chat-room/chat-room.cpp @@ -166,7 +166,7 @@ void ChatRoomPrivate::realtimeTextReceived(uint32_t character, const shared_ptr< shared_ptr<ChatMessage> pendingMessage = q->createChatMessage(); pendingMessage->getPrivate()->setDirection(ChatMessage::Direction::Incoming); - Content *content = new Content(); + auto content = Content::create(); content->setContentType(ContentType::PlainText); content->setBodyFromUtf8(completeText); pendingMessage->addContent(content); @@ -699,7 +699,7 @@ shared_ptr<ChatMessage> ChatRoom::createChatMessage() { // Deprecated shared_ptr<ChatMessage> ChatRoom::createChatMessage(const string &text) { shared_ptr<ChatMessage> chatMessage = createChatMessage(); - Content *content = new Content(); + auto content = Content::create(); content->setContentType(ContentType::PlainText); content->setBodyFromLocale(text); chatMessage->addContent(content); @@ -708,14 +708,14 @@ shared_ptr<ChatMessage> ChatRoom::createChatMessage(const string &text) { shared_ptr<ChatMessage> ChatRoom::createChatMessageFromUtf8(const string &text) { shared_ptr<ChatMessage> chatMessage = createChatMessage(); - Content *content = new Content(); + auto content = Content::create(); content->setContentType(ContentType::PlainText); content->setBodyFromUtf8(text); chatMessage->addContent(content); return chatMessage; } -shared_ptr<ChatMessage> ChatRoom::createFileTransferMessage(FileContent *content) { +shared_ptr<ChatMessage> ChatRoom::createFileTransferMessage(const std::shared_ptr<FileContent> &content) { shared_ptr<ChatMessage> chatMessage = createChatMessage(); chatMessage->addContent(content); return chatMessage; @@ -723,8 +723,8 @@ shared_ptr<ChatMessage> ChatRoom::createFileTransferMessage(FileContent *content shared_ptr<ChatMessage> ChatRoom::createForwardMessage(const shared_ptr<ChatMessage> &msg) { shared_ptr<ChatMessage> chatMessage = createChatMessage(); - for (const Content *c : msg->getContents()) { - chatMessage->addContent(c->clone()); + for (const auto &c : msg->getContents()) { + chatMessage->addContent(c->clone()->toSharedPtr()); } // set forward info diff --git a/src/chat/chat-room/chat-room.h b/src/chat/chat-room/chat-room.h index c78b1a599a99617f000d18fea5d5a47f8369f2ee..29cc8e5c0dcf5ae7d1ccb427b145402ca6324de9 100644 --- a/src/chat/chat-room/chat-room.h +++ b/src/chat/chat-room/chat-room.h @@ -78,7 +78,7 @@ public: std::shared_ptr<ChatMessage> createChatMessage(const std::string &text) override; std::shared_ptr<ChatMessage> createChatMessageFromUtf8(const std::string &text) override; - std::shared_ptr<ChatMessage> createFileTransferMessage(FileContent *content) override; + std::shared_ptr<ChatMessage> createFileTransferMessage(const std::shared_ptr<FileContent> &content) override; std::shared_ptr<ChatMessage> createForwardMessage(const std::shared_ptr<ChatMessage> &msg) override; std::shared_ptr<ChatMessage> createReplyMessage(const std::shared_ptr<ChatMessage> &msg) override; diff --git a/src/chat/chat-room/client-group-chat-room.cpp b/src/chat/chat-room/client-group-chat-room.cpp index 5a90c5784331c8e7af7a0027d0f7239d15d55830..a2c6b01af808f49b3bbf94275cbf723a2626dda6 100644 --- a/src/chat/chat-room/client-group-chat-room.cpp +++ b/src/chat/chat-room/client-group-chat-room.cpp @@ -725,14 +725,14 @@ bool ClientGroupChatRoom::addParticipants(const list<std::shared_ptr<Address>> & void ClientGroupChatRoom::sendInvite(std::shared_ptr<CallSession> &session, const list<std::shared_ptr<Address>> &addressList) { - Content content; - content.setBodyFromUtf8(Utils::getResourceLists(addressList)); - content.setContentType(ContentType::ResourceLists); - content.setContentDisposition(ContentDisposition::RecipientList); + auto content = Content::create(); + content->setBodyFromUtf8(Utils::getResourceLists(addressList)); + content->setContentType(ContentType::ResourceLists); + content->setContentDisposition(ContentDisposition::RecipientList); if (linphone_core_content_encoding_supported(getCore()->getCCore(), "deflate")) { - content.setContentEncoding("deflate"); + content->setContentEncoding("deflate"); } - session->startInvite(nullptr, getUtf8Subject(), &content); + session->startInvite(nullptr, getUtf8Subject(), content); } bool ClientGroupChatRoom::removeParticipant(const shared_ptr<Participant> &participant) { @@ -862,20 +862,20 @@ void ClientGroupChatRoom::exhume() { << "]"; d->localExhumePending = true; - Content content; + auto content = Content::create(); list<std::shared_ptr<Address>> addresses; addresses.push_front(remoteParticipant); - content.setBodyFromUtf8(Utils::getResourceLists(addresses)); - content.setContentType(ContentType::ResourceLists); - content.setContentDisposition(ContentDisposition::RecipientList); + content->setBodyFromUtf8(Utils::getResourceLists(addresses)); + content->setContentType(ContentType::ResourceLists); + content->setContentDisposition(ContentDisposition::RecipientList); if (linphone_core_content_encoding_supported(getCore()->getCCore(), "deflate")) { - content.setContentEncoding("deflate"); + content->setContentEncoding("deflate"); } const auto &conferenceFactoryAddress = Core::getConferenceFactoryAddress(getCore(), getConferenceId().getLocalAddress()); auto session = d->createSessionTo(conferenceFactoryAddress); - session->startInvite(nullptr, getUtf8Subject(), &content); + session->startInvite(nullptr, getUtf8Subject(), content); setState(ConferenceInterface::State::CreationPending); } diff --git a/src/chat/chat-room/proxy-chat-room.cpp b/src/chat/chat-room/proxy-chat-room.cpp index fe9bdf650b44aa2caecae9b0e0d2b21cb8cbd4e3..c539ae951e2138d46cf3208d9cb4b2a2179f71ba 100644 --- a/src/chat/chat-room/proxy-chat-room.cpp +++ b/src/chat/chat-room/proxy-chat-room.cpp @@ -216,7 +216,7 @@ shared_ptr<ChatMessage> ProxyChatRoom::createChatMessageFromUtf8(const string &t L_D(); return d->chatRoom->createChatMessageFromUtf8(text); } -shared_ptr<ChatMessage> ProxyChatRoom::createFileTransferMessage(FileContent *content) { +shared_ptr<ChatMessage> ProxyChatRoom::createFileTransferMessage(const std::shared_ptr<FileContent> &content) { L_D(); return d->chatRoom->createFileTransferMessage(content); } diff --git a/src/chat/chat-room/proxy-chat-room.h b/src/chat/chat-room/proxy-chat-room.h index 8a69f72e6334aeee7cbe78e20c828b6224c11772..5ba41e882f3c481927256df7f23866251af6dd5f 100644 --- a/src/chat/chat-room/proxy-chat-room.h +++ b/src/chat/chat-room/proxy-chat-room.h @@ -74,7 +74,7 @@ public: createChatMessage(const std::string &text) override; // Deprecated. Text is in System Locale std::shared_ptr<ChatMessage> createChatMessageFromUtf8(const std::string &text) override; - std::shared_ptr<ChatMessage> createFileTransferMessage(FileContent *content) override; + std::shared_ptr<ChatMessage> createFileTransferMessage(const std::shared_ptr<FileContent> &content) override; std::shared_ptr<ChatMessage> createForwardMessage(const std::shared_ptr<ChatMessage> &msg) override; std::shared_ptr<ChatMessage> createReplyMessage(const std::shared_ptr<ChatMessage> &msg) override; diff --git a/src/chat/chat-room/server-group-chat-room.cpp b/src/chat/chat-room/server-group-chat-room.cpp index d63e2957c32918c3b7a559d7b9f646b8d73d63f6..115f9adc5539cdf8932d6db35223bf5eefa14cc9 100644 --- a/src/chat/chat-room/server-group-chat-room.cpp +++ b/src/chat/chat-room/server-group-chat-room.cpp @@ -1106,13 +1106,13 @@ void ServerGroupChatRoomPrivate::inviteDevice(const shared_ptr<ParticipantDevice return; } - Content content; - content.setBodyFromUtf8(Utils::getResourceLists(addressesList)); - content.setContentType(ContentType::ResourceLists); - content.setContentDisposition(ContentDisposition::RecipientListHistory); + auto content = Content::create(); + content->setBodyFromUtf8(Utils::getResourceLists(addressesList)); + content->setContentType(ContentType::ResourceLists); + content->setContentDisposition(ContentDisposition::RecipientListHistory); if (linphone_core_content_encoding_supported(q->getCore()->getCCore(), "deflate")) - content.setContentEncoding("deflate"); - session->startInvite(nullptr, q->getUtf8Subject(), &content); + content->setContentEncoding("deflate"); + session->startInvite(nullptr, q->getUtf8Subject(), content); } void ServerGroupChatRoomPrivate::byeDevice(const std::shared_ptr<ParticipantDevice> &device) { diff --git a/src/chat/encryption/encryption-engine.h b/src/chat/encryption/encryption-engine.h index fe92754a50be44a3fd64ecd1d21ac15a23aa2627..bbeaba602208c75254766aa56c96c5e86a8df598 100644 --- a/src/chat/encryption/encryption-engine.h +++ b/src/chat/encryption/encryption-engine.h @@ -64,9 +64,10 @@ public: return false; } - virtual void generateFileTransferKey(BCTBX_UNUSED(const std::shared_ptr<AbstractChatRoom> &ChatRoom), - BCTBX_UNUSED(const std::shared_ptr<ChatMessage> &message), - BCTBX_UNUSED(FileTransferContent *fileTransferContent)) { + virtual void + generateFileTransferKey(BCTBX_UNUSED(const std::shared_ptr<AbstractChatRoom> &ChatRoom), + BCTBX_UNUSED(const std::shared_ptr<ChatMessage> &message), + BCTBX_UNUSED(const std::shared_ptr<FileTransferContent> &fileTransferContent)) { } virtual int downloadingFile(BCTBX_UNUSED(const std::shared_ptr<ChatMessage> &message), @@ -74,7 +75,7 @@ public: BCTBX_UNUSED(const uint8_t *buffer), BCTBX_UNUSED(size_t size), BCTBX_UNUSED(uint8_t *decryptedBuffer), - BCTBX_UNUSED(FileTransferContent *fileTransferContent)) { + BCTBX_UNUSED(const std::shared_ptr<FileTransferContent> &fileTransferContent)) { return 0; } @@ -83,11 +84,11 @@ public: BCTBX_UNUSED(const uint8_t *buffer), BCTBX_UNUSED(size_t *size), BCTBX_UNUSED(uint8_t *encryptedBuffer), - BCTBX_UNUSED(FileTransferContent *fileTransferContent)) { + BCTBX_UNUSED(const std::shared_ptr<FileTransferContent> &fileTransferContent)) { return 0; } - virtual int cancelFileTransfer(BCTBX_UNUSED(FileTransferContent *fileTransferContent)) { + virtual int cancelFileTransfer(BCTBX_UNUSED(const std::shared_ptr<FileTransferContent> &fileTransferContent)) { return 0; } diff --git a/src/chat/encryption/legacy-encryption-engine.cpp b/src/chat/encryption/legacy-encryption-engine.cpp index 59d9e220bf2423a603cba454195e8505be90f508..117fa9dc9bdbca3a4d02032521056c3cbf853d7a 100644 --- a/src/chat/encryption/legacy-encryption-engine.cpp +++ b/src/chat/encryption/legacy-encryption-engine.cpp @@ -96,9 +96,10 @@ bool LegacyEncryptionEngine::isEncryptionEnabledForFileTransfer(const shared_ptr return false; } -void LegacyEncryptionEngine::generateFileTransferKey(const shared_ptr<AbstractChatRoom> &chatRoom, - const shared_ptr<ChatMessage> &message, - BCTBX_UNUSED(FileTransferContent *fileTransferContent)) { +void LegacyEncryptionEngine::generateFileTransferKey( + const shared_ptr<AbstractChatRoom> &chatRoom, + const shared_ptr<ChatMessage> &message, + BCTBX_UNUSED(const std::shared_ptr<FileTransferContent> &fileTransferContent)) { LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(chatRoom->getCore()->getCCore()); LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee); LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb generate_file_transfer_key_cb = @@ -108,12 +109,13 @@ void LegacyEncryptionEngine::generateFileTransferKey(const shared_ptr<AbstractCh } } -int LegacyEncryptionEngine::downloadingFile(const shared_ptr<ChatMessage> &message, - size_t offset, - const uint8_t *buffer, - size_t size, - uint8_t *decryptedBuffer, - BCTBX_UNUSED(FileTransferContent *fileTransferContent)) { +int LegacyEncryptionEngine::downloadingFile( + const shared_ptr<ChatMessage> &message, + size_t offset, + const uint8_t *buffer, + size_t size, + uint8_t *decryptedBuffer, + BCTBX_UNUSED(const std::shared_ptr<FileTransferContent> &fileTransferContent)) { shared_ptr<AbstractChatRoom> chatRoom = message->getChatRoom(); LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(chatRoom->getCore()->getCCore()); LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee); @@ -125,12 +127,13 @@ int LegacyEncryptionEngine::downloadingFile(const shared_ptr<ChatMessage> &messa return -1; } -int LegacyEncryptionEngine::uploadingFile(const shared_ptr<ChatMessage> &message, - size_t offset, - const uint8_t *buffer, - size_t *size, - uint8_t *encryptedBuffer, - BCTBX_UNUSED(FileTransferContent *fileTransferContent)) { +int LegacyEncryptionEngine::uploadingFile( + const shared_ptr<ChatMessage> &message, + size_t offset, + const uint8_t *buffer, + size_t *size, + uint8_t *encryptedBuffer, + BCTBX_UNUSED(const std::shared_ptr<FileTransferContent> &fileTransferContent)) { shared_ptr<AbstractChatRoom> chatRoom = message->getChatRoom(); LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(chatRoom->getCore()->getCCore()); LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee); @@ -142,7 +145,8 @@ int LegacyEncryptionEngine::uploadingFile(const shared_ptr<ChatMessage> &message return -1; } -int LegacyEncryptionEngine::cancelFileTransfer(BCTBX_UNUSED(FileTransferContent *fileTransferContent)) { +int LegacyEncryptionEngine::cancelFileTransfer( + BCTBX_UNUSED(const std::shared_ptr<FileTransferContent> &fileTransferContent)) { return 0; } diff --git a/src/chat/encryption/legacy-encryption-engine.h b/src/chat/encryption/legacy-encryption-engine.h index 4a2b5cec49f22aec9fa9cbbb8802de3a8a12dfe8..c0e84e5bad17813f3886f5d8da1231b68a31c519 100644 --- a/src/chat/encryption/legacy-encryption-engine.h +++ b/src/chat/encryption/legacy-encryption-engine.h @@ -38,20 +38,20 @@ public: bool isEncryptionEnabledForFileTransfer(const std::shared_ptr<AbstractChatRoom> &ChatRoom) override; void generateFileTransferKey(const std::shared_ptr<AbstractChatRoom> &ChatRoom, const std::shared_ptr<ChatMessage> &message, - FileTransferContent *fileTransferContent) override; + const std::shared_ptr<FileTransferContent> &fileTransferContent) override; int downloadingFile(const std::shared_ptr<ChatMessage> &message, size_t offset, const uint8_t *buffer, size_t size, uint8_t *decrypted_buffer, - FileTransferContent *fileTransferContent) override; + const std::shared_ptr<FileTransferContent> &fileTransferContent) override; int uploadingFile(const std::shared_ptr<ChatMessage> &message, size_t offset, const uint8_t *buffer, size_t *size, uint8_t *encrypted_buffer, - FileTransferContent *fileTransferContent) override; - int cancelFileTransfer(FileTransferContent *fileTransferContent) override; + const std::shared_ptr<FileTransferContent> &fileTransferContent) override; + int cancelFileTransfer(const std::shared_ptr<FileTransferContent> &fileTransferContent) override; }; LINPHONE_END_NAMESPACE diff --git a/src/chat/encryption/lime-x3dh-encryption-engine.cpp b/src/chat/encryption/lime-x3dh-encryption-engine.cpp index 7bee4e4b1801185a800cf7df11b28702ec2da84e..ba241a3a9f54a4be97e08188e14318ff9226d5c6 100644 --- a/src/chat/encryption/lime-x3dh-encryption-engine.cpp +++ b/src/chat/encryption/lime-x3dh-encryption-engine.cpp @@ -356,19 +356,19 @@ ChatMessageModifier::Result LimeX3dhEncryptionEngine::processOutgoingMessage(con } } - list<Content *> contents; + list<shared_ptr<Content>> contents; // ---------------------------------------------- CPIM // Replaces SIPFRAG since version 4.4.0 CpimChatMessageModifier ccmm; - Content *cpimContent = ccmm.createMinimalCpimContentForLimeMessage(message); + auto cpimContent = ccmm.createMinimalCpimContentForLimeMessage(message); contents.push_back(std::move(cpimContent)); // ---------------------------------------------- SIPFRAG // For backward compatibility only since 4.4.0 - Content *sipfrag = new Content(); + auto sipfrag = Content::create(); sipfrag->setBodyFromLocale("From: <" + localDeviceId + ">"); sipfrag->setContentType(ContentType::SipFrag); contents.push_back(std::move(sipfrag)); @@ -377,7 +377,7 @@ ChatMessageModifier::Result LimeX3dhEncryptionEngine::processOutgoingMessage(con for (const lime::RecipientData &recipient : filteredRecipients) { string cipherHeaderB64 = bctoolbox::encodeBase64(recipient.DRmessage); - Content *cipherHeader = new Content(); + auto cipherHeader = Content::create(); cipherHeader->setBodyFromLocale(cipherHeaderB64); cipherHeader->setContentType(ContentType::LimeKey); cipherHeader->addHeader("Content-Id", recipient.deviceId); @@ -390,13 +390,13 @@ ChatMessageModifier::Result LimeX3dhEncryptionEngine::processOutgoingMessage(con const vector<uint8_t> *binaryCipherMessage = cipherMessage.get(); string cipherMessageB64 = bctoolbox::encodeBase64(*binaryCipherMessage); - Content *cipherMessage = new Content(); - cipherMessage->setBodyFromLocale(cipherMessageB64); - cipherMessage->setContentType(ContentType::OctetStream); - cipherMessage->addHeader("Content-Description", "Encrypted message"); - contents.push_back(std::move(cipherMessage)); + auto cipherMessageC = Content::create(); + cipherMessageC->setBodyFromLocale(cipherMessageB64); + cipherMessageC->setContentType(ContentType::OctetStream); + cipherMessageC->addHeader("Content-Description", "Encrypted message"); + contents.push_back(std::move(cipherMessageC)); - Content finalContent = ContentManager::contentListToMultipart(contents, true); + auto finalContent = ContentManager::contentListToMultipart(contents, true); /* Septembre 2022 note: * Because of a scandalous ancient bug in belle-sip, we are forced to set @@ -418,10 +418,6 @@ ChatMessageModifier::Result LimeX3dhEncryptionEngine::processOutgoingMessage(con message->getPrivate()->send(); *result = ChatMessageModifier::Result::Done; - // TODO can be improved - for (const auto &content : contents) { - delete content; - } } else { lError() << "[LIME] operation failed: " << errorMessage; message->getPrivate()->setParticipantState(message->getChatRoom()->getMe()->getAddress(), @@ -454,10 +450,10 @@ ChatMessageModifier::Result LimeX3dhEncryptionEngine::processIncomingMessage(con const Content *internalContent; if (!message->getInternalContent().isEmpty()) internalContent = &(message->getInternalContent()); - else internalContent = message->getContents().front(); + else internalContent = message->getContents().front().get(); // Check if the message is encrypted and unwrap the multipart - if (!isMessageEncrypted(internalContent)) { + if (!isMessageEncrypted(*internalContent)) { lError() << "[LIME] unexpected content-type: " << internalContent->getContentType(); // Set unencrypted content warning flag because incoming message type is unexpected message->getPrivate()->setUnencryptedContentWarning(true); @@ -590,9 +586,10 @@ bool LimeX3dhEncryptionEngine::isEncryptionEnabledForFileTransfer(const shared_p #define FILE_TRANSFER_AUTH_TAG_SIZE 16 #define FILE_TRANSFER_KEY_SIZE 32 -void LimeX3dhEncryptionEngine::generateFileTransferKey(BCTBX_UNUSED(const shared_ptr<AbstractChatRoom> &chatRoom), - BCTBX_UNUSED(const shared_ptr<ChatMessage> &message), - FileTransferContent *fileTransferContent) { +void LimeX3dhEncryptionEngine::generateFileTransferKey( + BCTBX_UNUSED(const shared_ptr<AbstractChatRoom> &chatRoom), + BCTBX_UNUSED(const shared_ptr<ChatMessage> &message), + const std::shared_ptr<FileTransferContent> &fileTransferContent) { char keyBuffer[FILE_TRANSFER_KEY_SIZE]; // temporary storage of generated key: 192 bits of key + 64 bits of initial // vector // generate a random 192 bits key + 64 bits of initial vector and store it into the file_transfer_information->key @@ -607,18 +604,18 @@ int LimeX3dhEncryptionEngine::downloadingFile(BCTBX_UNUSED(const shared_ptr<Chat const uint8_t *buffer, size_t size, uint8_t *decrypted_buffer, - FileTransferContent *fileTransferContent) { + const std::shared_ptr<FileTransferContent> &fileTransferContent) { if (fileTransferContent == nullptr) return -1; - Content *content = static_cast<Content *>(fileTransferContent); + auto content = static_pointer_cast<Content>(fileTransferContent); const char *fileKey = fileTransferContent->getFileKey().data(); if (!fileKey) return -1; if (!buffer) { // get the authentication tag char authTag[FILE_TRANSFER_AUTH_TAG_SIZE]; // store the authentication tag generated at the end of decryption - int ret = bctbx_aes_gcm_decryptFile(linphone_content_get_cryptoContext_address(L_GET_C_BACK_PTR(content)), NULL, - FILE_TRANSFER_AUTH_TAG_SIZE, authTag, NULL); + int ret = bctbx_aes_gcm_decryptFile(content->getCryptoContextAddress(), NULL, FILE_TRANSFER_AUTH_TAG_SIZE, + authTag, NULL); if (ret < 0) return ret; // compare auth tag if we have one const size_t fileAuthTagSize = fileTransferContent->getFileAuthTagSize(); @@ -636,8 +633,8 @@ int LimeX3dhEncryptionEngine::downloadingFile(BCTBX_UNUSED(const shared_ptr<Chat } } - return bctbx_aes_gcm_decryptFile(linphone_content_get_cryptoContext_address(L_GET_C_BACK_PTR(content)), - (unsigned char *)fileKey, size, (char *)decrypted_buffer, (char *)buffer); + return bctbx_aes_gcm_decryptFile(content->getCryptoContextAddress(), (unsigned char *)fileKey, size, + (char *)decrypted_buffer, (char *)buffer); } int LimeX3dhEncryptionEngine::uploadingFile(BCTBX_UNUSED(const shared_ptr<ChatMessage> &message), @@ -645,10 +642,10 @@ int LimeX3dhEncryptionEngine::uploadingFile(BCTBX_UNUSED(const shared_ptr<ChatMe const uint8_t *buffer, size_t *size, uint8_t *encrypted_buffer, - FileTransferContent *fileTransferContent) { + const std::shared_ptr<FileTransferContent> &fileTransferContent) { if (fileTransferContent == nullptr) return -1; - Content *content = static_cast<Content *>(fileTransferContent); + auto content = static_pointer_cast<Content>(fileTransferContent); const char *fileKey = fileTransferContent->getFileKey().data(); if (!fileKey) return -1; @@ -656,8 +653,8 @@ int LimeX3dhEncryptionEngine::uploadingFile(BCTBX_UNUSED(const shared_ptr<ChatMe if (!buffer || *size == 0) { char authTag[FILE_TRANSFER_AUTH_TAG_SIZE]; // store the authentication tag generated at the end of encryption, // size is fixed at 16 bytes - int ret = bctbx_aes_gcm_encryptFile(linphone_content_get_cryptoContext_address(L_GET_C_BACK_PTR(content)), NULL, - FILE_TRANSFER_AUTH_TAG_SIZE, NULL, authTag); + int ret = bctbx_aes_gcm_encryptFile(content->getCryptoContextAddress(), NULL, FILE_TRANSFER_AUTH_TAG_SIZE, NULL, + authTag); fileTransferContent->setFileAuthTag(authTag, 16); return ret; } @@ -670,18 +667,16 @@ int LimeX3dhEncryptionEngine::uploadingFile(BCTBX_UNUSED(const shared_ptr<ChatMe *size -= (*size % 16); } - return bctbx_aes_gcm_encryptFile(linphone_content_get_cryptoContext_address(L_GET_C_BACK_PTR(content)), - (unsigned char *)fileKey, *size, (char *)buffer, (char *)encrypted_buffer); + return bctbx_aes_gcm_encryptFile(content->getCryptoContextAddress(), (unsigned char *)fileKey, *size, + (char *)buffer, (char *)encrypted_buffer); return 0; } -int LimeX3dhEncryptionEngine::cancelFileTransfer(FileTransferContent *fileTransferContent) { - Content *content = static_cast<Content *>(fileTransferContent); +int LimeX3dhEncryptionEngine::cancelFileTransfer(const std::shared_ptr<FileTransferContent> &fileTransferContent) { // calling decrypt with no data and no buffer to write the tag will simply release the encryption context and delete // it - return bctbx_aes_gcm_decryptFile(linphone_content_get_cryptoContext_address(L_GET_C_BACK_PTR(content)), NULL, 0, - NULL, NULL); + return bctbx_aes_gcm_decryptFile(fileTransferContent->getCryptoContextAddress(), NULL, 0, NULL, NULL); } EncryptionEngine::EngineType LimeX3dhEncryptionEngine::getEngineType() { diff --git a/src/chat/encryption/lime-x3dh-encryption-engine.h b/src/chat/encryption/lime-x3dh-encryption-engine.h index a970bf7891ee49a1191e5b7610a3ccf86bcfc985..7f9f6eea9649eed13e0f72fe8c291bbafcb98936 100644 --- a/src/chat/encryption/lime-x3dh-encryption-engine.h +++ b/src/chat/encryption/lime-x3dh-encryption-engine.h @@ -69,23 +69,23 @@ public: void generateFileTransferKey(const std::shared_ptr<AbstractChatRoom> &ChatRoom, const std::shared_ptr<ChatMessage> &message, - FileTransferContent *fileTransferContent) override; + const std::shared_ptr<FileTransferContent> &fileTransferContent) override; int downloadingFile(const std::shared_ptr<ChatMessage> &message, size_t offset, const uint8_t *buffer, size_t size, uint8_t *decrypted_buffer, - FileTransferContent *fileTransferContent) override; + const std::shared_ptr<FileTransferContent> &fileTransferContent) override; int uploadingFile(const std::shared_ptr<ChatMessage> &message, size_t offset, const uint8_t *buffer, size_t *size, uint8_t *encrypted_buffer, - FileTransferContent *fileTransferContent) override; + const std::shared_ptr<FileTransferContent> &fileTransferContent) override; - int cancelFileTransfer(FileTransferContent *fileTransferContent) override; + int cancelFileTransfer(const std::shared_ptr<FileTransferContent> &fileTransferContent) override; void mutualAuthentication(MSZrtpContext *zrtpContext, const std::shared_ptr<SalMediaDescription> &localMediaDescription, diff --git a/src/chat/encryption/lime-x3dh-server-engine.cpp b/src/chat/encryption/lime-x3dh-server-engine.cpp index 50ae7faeb4b90282033766f262586885efd3a86e..8181ef664f5a038fa35b1de3f7b61dfe035b0a05 100644 --- a/src/chat/encryption/lime-x3dh-server-engine.cpp +++ b/src/chat/encryption/lime-x3dh-server-engine.cpp @@ -69,10 +69,10 @@ LimeX3dhEncryptionServerEngine::processOutgoingMessage(const std::shared_ptr<Cha } if (!message->getInternalContent().isEmpty()) internalContent = &(message->getInternalContent()); - else internalContent = message->getContents().front(); + else internalContent = message->getContents().front().get(); // Check if the message is encrypted - if (!internalContent || !isMessageEncrypted(internalContent)) { + if (!internalContent || !isMessageEncrypted(*internalContent)) { return ChatMessageModifier::Result::Skipped; } @@ -112,8 +112,8 @@ EncryptionEngine::EngineType LimeX3dhEncryptionServerEngine::getEngineType() { return engineType; } -bool LimeX3dhUtils::isMessageEncrypted(const Content *internalContent) { - const ContentType &incomingContentType = internalContent->getContentType(); +bool LimeX3dhUtils::isMessageEncrypted(const Content &internalContent) { + const ContentType &incomingContentType = internalContent.getContentType(); ContentType expectedContentType = ContentType::Encrypted; if (incomingContentType == expectedContentType) { diff --git a/src/chat/encryption/lime-x3dh-server-engine.h b/src/chat/encryption/lime-x3dh-server-engine.h index 2a26f749554d6c7dc9a6e1a2a471de562e40de74..68a1421cd31af3d7009b3f2235760045ba16c91d 100644 --- a/src/chat/encryption/lime-x3dh-server-engine.h +++ b/src/chat/encryption/lime-x3dh-server-engine.h @@ -30,7 +30,7 @@ LINPHONE_BEGIN_NAMESPACE class LimeX3dhUtils { public: - static bool isMessageEncrypted(const Content *internalContent); + static bool isMessageEncrypted(const Content &internalContent); }; class LimeX3dhEncryptionServerEngine : public EncryptionEngine, public CoreListener, private LimeX3dhUtils { diff --git a/src/chat/modifier/cpim-chat-message-modifier.cpp b/src/chat/modifier/cpim-chat-message-modifier.cpp index 3bdef9d2d79fd6e006b9bfc5e6d529de3b0e2ee0..c572875e44ba71cb9454c73fd7b08bf1eb50dacf 100644 --- a/src/chat/modifier/cpim-chat-message-modifier.cpp +++ b/src/chat/modifier/cpim-chat-message-modifier.cpp @@ -138,7 +138,7 @@ ChatMessageModifier::Result CpimChatMessageModifier::encode(const shared_ptr<Cha // We're the first ChatMessageModifier to be called, we'll create the private content from the public one // We take the first one because if there is more of them, the multipart modifier should have been called first // So we should not be in this block - content = message->getContents().front(); + content = message->getContents().front().get(); } const string contentBody = content->getBodyAsUtf8String(); @@ -163,7 +163,7 @@ ChatMessageModifier::Result CpimChatMessageModifier::encode(const shared_ptr<Cha ChatMessageModifier::Result CpimChatMessageModifier::decode(const shared_ptr<ChatMessage> &message, int &errorCode) { const Content *content = nullptr; if (!message->getInternalContent().isEmpty()) content = &(message->getInternalContent()); - else if (message->getContents().size() > 0) content = message->getContents().front(); + else if (message->getContents().size() > 0) content = message->getContents().front().get(); if (content == nullptr) { lError() << "[CPIM] Couldn't find a valid content in the message"; @@ -299,7 +299,8 @@ string CpimChatMessageModifier::cpimAddressUri(const std::shared_ptr<Address> &a return addr->asStringUriOnly(); } -Content *CpimChatMessageModifier::createMinimalCpimContentForLimeMessage(const shared_ptr<ChatMessage> &message) const { +std::shared_ptr<Content> +CpimChatMessageModifier::createMinimalCpimContentForLimeMessage(const shared_ptr<ChatMessage> &message) const { shared_ptr<AbstractChatRoom> chatRoom = message->getChatRoom(); const string &localDeviceId = chatRoom->getLocalAddress()->asStringUriOnly(); @@ -310,7 +311,7 @@ Content *CpimChatMessageModifier::createMinimalCpimContentForLimeMessage(const s Cpim::GenericHeader(imdnNamespace + "." + imdnMessageIdHeader, message->getImdnMessageId())); cpimMessage.addContentHeader(Cpim::GenericHeader("Content-Type", ContentType::PlainText.getMediaType())); - Content *cpimContent = new Content(); + auto cpimContent = Content::create(); cpimContent->setContentType(ContentType::Cpim); cpimContent->setBodyFromLocale(cpimMessage.asString()); @@ -321,16 +322,16 @@ std::shared_ptr<LinphonePrivate::Address> CpimChatMessageModifier::parseFromHeaderCpimContentInLimeMessage(const std::shared_ptr<ChatMessage> &message) const { const Content *content = nullptr; if (!message->getInternalContent().isEmpty()) content = &(message->getInternalContent()); - else if (message->getContents().size() > 0) content = message->getContents().front(); + else if (message->getContents().size() > 0) content = message->getContents().front().get(); if (content == nullptr) { return nullptr; } list<Content> contentList = ContentManager::multipartToContentList(*content); - for (const auto &content : contentList) { - if (content.getContentType() != ContentType::Cpim) continue; - const string contentBody = content.getBodyAsString(); + for (const auto &c : contentList) { + if (c.getContentType() != ContentType::Cpim) continue; + const string contentBody = c.getBodyAsString(); const shared_ptr<const Cpim::Message> cpimMessage = Cpim::Message::createFromString(contentBody); if (cpimMessage && cpimMessage->getMessageHeader("From")) { return Address::create( diff --git a/src/chat/modifier/cpim-chat-message-modifier.h b/src/chat/modifier/cpim-chat-message-modifier.h index 1f06b5675f3feee8d431743a7f6a1aeb61220c8e..8749e667245d6ba750a72f5e381a9e174328eb66 100644 --- a/src/chat/modifier/cpim-chat-message-modifier.h +++ b/src/chat/modifier/cpim-chat-message-modifier.h @@ -33,7 +33,7 @@ public: Result encode(const std::shared_ptr<ChatMessage> &message, int &errorCode) override; Result decode(const std::shared_ptr<ChatMessage> &message, int &errorCode) override; - Content *createMinimalCpimContentForLimeMessage(const std::shared_ptr<ChatMessage> &message) const; + std::shared_ptr<Content> createMinimalCpimContentForLimeMessage(const std::shared_ptr<ChatMessage> &message) const; std::string parseMinimalCpimContentInLimeMessage(const std::shared_ptr<ChatMessage> &message, const Content &cpimContent) const; std::shared_ptr<LinphonePrivate::Address> diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.cpp b/src/chat/modifier/file-transfer-chat-message-modifier.cpp index b1676d21d0f316efb7af39341bb80a44ae567427..7ff79b8ef11218aef0ff313acf0c253493c3e3c6 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.cpp +++ b/src/chat/modifier/file-transfer-chat-message-modifier.cpp @@ -32,7 +32,6 @@ #include "chat/encryption/encryption-engine.h" #include "conference/participant.h" #include "content/content-type.h" -#include "content/content.h" #include "core/core.h" #include "logger/logger.h" @@ -72,10 +71,10 @@ ChatMessageModifier::Result FileTransferChatMessageModifier::encode(const shared currentFileContentToTransfer = nullptr; currentFileTransferContent = nullptr; // For each FileContent, upload it and create a FileTransferContent - for (Content *content : message->getContents()) { + for (auto &content : message->getContents()) { if (content->isFile()) { lInfo() << "Found file content [" << content << "], set it for file upload"; - FileContent *fileContent = (FileContent *)content; + auto fileContent = static_pointer_cast<FileContent>(content); currentFileContentToTransfer = fileContent; break; } @@ -115,7 +114,7 @@ void FileTransferChatMessageModifier::fileTransferOnProgress(BCTBX_UNUSED(belle_ LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); - LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer); + LinphoneContent *content = currentFileContentToTransfer->toC(); // Deprecated: use list of callbacks now if (linphone_chat_message_cbs_get_file_transfer_progress_indication(cbs)) { linphone_chat_message_cbs_get_file_transfer_progress_indication(cbs)(msg, content, offset, total); @@ -156,14 +155,14 @@ int FileTransferChatMessageModifier::onSendBody(BCTBX_UNUSED(belle_sip_user_body return BELLE_SIP_STOP; } - // if we've not reach the end of file yet, ask for more data + // if we've not reached the end of file yet, ask for more data // in case of file body handler, won't be called if (currentFileContentToTransfer->getFilePath().empty() && offset < currentFileContentToTransfer->getFileSize()) { // get data from call back LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); LinphoneChatMessageCbsFileTransferSendCb file_transfer_send_cb = linphone_chat_message_cbs_get_file_transfer_send(cbs); - LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer); + LinphoneContent *content = currentFileContentToTransfer->toC(); // Deprecated: use list of callbacks now if (file_transfer_send_cb) { LinphoneBuffer *lb = file_transfer_send_cb(msg, content, offset, *size); @@ -247,7 +246,7 @@ FileTransferChatMessageModifier::prepare_upload_body_handler(shared_ptr<ChatMess EncryptionEngine *imee = message->getCore()->getEncryptionEngine(); if (imee) isFileEncryptionEnabled = imee->isEncryptionEnabledForFileTransfer(chatRoom); - FileTransferContent *fileTransferContent = new FileTransferContent(); + auto fileTransferContent = FileTransferContent::create<FileTransferContent>(); fileTransferContent->setContentType(ContentType::FileTransfer); fileTransferContent->setFileSize(currentFileContentToTransfer->getFileSize()); // Copy file size information fileTransferContent->setFilePath(currentFileContentToTransfer->getFilePath()); // Copy file path information @@ -291,7 +290,7 @@ FileTransferChatMessageModifier::prepare_upload_body_handler(shared_ptr<ChatMess uint8_t *buf = (uint8_t *)ms_malloc(buf_size); memcpy(buf, currentFileContentToTransfer->getBody().data(), buf_size); - EncryptionEngine *imee = message->getCore()->getEncryptionEngine(); + imee = message->getCore()->getEncryptionEngine(); if (imee) { size_t max_size = buf_size; uint8_t *encrypted_buffer = (uint8_t *)ms_malloc0(max_size); @@ -340,7 +339,7 @@ void FileTransferChatMessageModifier::processResponseFromPostFile(const belle_ht auto bh = prepare_upload_body_handler(message); // Save currentFileContentToTransfer pointer as it will be set to NULL in releaseHttpRequest - FileContent *fileContent = currentFileContentToTransfer; + auto fileContent = currentFileContentToTransfer; releaseHttpRequest(); currentFileContentToTransfer = fileContent; @@ -349,7 +348,7 @@ void FileTransferChatMessageModifier::processResponseFromPostFile(const belle_ht } else if (code == 200) { // file has been uploaded correctly, get server reply and send it const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response); if (body && strlen(body) > 0) { - FileTransferContent *parsedXmlFileTransferContent = new FileTransferContent(); + auto parsedXmlFileTransferContent = FileTransferContent::create<FileTransferContent>(); parseFileTransferXmlIntoContent(body, parsedXmlFileTransferContent); if (parsedXmlFileTransferContent->getFileName().empty() || @@ -357,7 +356,6 @@ void FileTransferChatMessageModifier::processResponseFromPostFile(const belle_ht lWarning() << "Received response from server but unable to parse file name or URL, file transfer failed"; message->getPrivate()->replaceContent(currentFileTransferContent, currentFileContentToTransfer); - delete currentFileTransferContent; currentFileTransferContent = nullptr; message->getPrivate()->setParticipantState(message->getChatRoom()->getMe()->getAddress(), @@ -365,7 +363,6 @@ void FileTransferChatMessageModifier::processResponseFromPostFile(const belle_ht releaseHttpRequest(); fileUploadEndBackgroundTask(); - delete parsedXmlFileTransferContent; return; } @@ -386,7 +383,6 @@ void FileTransferChatMessageModifier::processResponseFromPostFile(const belle_ht string xml_body = dumpFileTransferContentAsXmlString( parsedXmlFileTransferContent, contentKey, contentKeySize, contentAuthTag, contentAuthTagSize, escapeFileName(currentFileContentToTransfer->getFileNameUtf8())); - delete parsedXmlFileTransferContent; currentFileTransferContent->setBodyFromUtf8(xml_body.c_str()); currentFileTransferContent = nullptr; @@ -399,7 +395,6 @@ void FileTransferChatMessageModifier::processResponseFromPostFile(const belle_ht } else { lWarning() << "Received empty response from server, file transfer failed"; message->getPrivate()->replaceContent(currentFileTransferContent, currentFileContentToTransfer); - delete currentFileTransferContent; currentFileTransferContent = nullptr; message->getPrivate()->setParticipantState(message->getChatRoom()->getMe()->getAddress(), @@ -411,7 +406,6 @@ void FileTransferChatMessageModifier::processResponseFromPostFile(const belle_ht lWarning() << "Received HTTP code response " << code << " for file transfer, probably meaning file is too large"; message->getPrivate()->replaceContent(currentFileTransferContent, currentFileContentToTransfer); - delete currentFileTransferContent; currentFileTransferContent = nullptr; message->getPrivate()->setParticipantState(message->getChatRoom()->getMe()->getAddress(), @@ -422,7 +416,6 @@ void FileTransferChatMessageModifier::processResponseFromPostFile(const belle_ht lWarning() << "Received HTTP code response " << code << " for file transfer, probably meaning that our credentials were rejected"; message->getPrivate()->replaceContent(currentFileTransferContent, currentFileContentToTransfer); - delete currentFileTransferContent; currentFileTransferContent = nullptr; message->getPrivate()->setParticipantState(message->getChatRoom()->getMe()->getAddress(), @@ -432,7 +425,6 @@ void FileTransferChatMessageModifier::processResponseFromPostFile(const belle_ht } else { lWarning() << "Unhandled HTTP code response " << code << " for file transfer"; message->getPrivate()->replaceContent(currentFileTransferContent, currentFileContentToTransfer); - delete currentFileTransferContent; currentFileTransferContent = nullptr; message->getPrivate()->setParticipantState(message->getChatRoom()->getMe()->getAddress(), @@ -592,9 +584,9 @@ ChatMessageModifier::Result FileTransferChatMessageModifier::decode(const shared BCTBX_UNUSED(int &errorCode)) { chatMessage = message; - Content internalContent = message->getInternalContent(); + const auto &internalContent = message->getInternalContent(); if (internalContent.getContentType() == ContentType::FileTransfer) { - FileTransferContent *fileTransferContent = new FileTransferContent(); + auto fileTransferContent = FileTransferContent::create<FileTransferContent>(); fileTransferContent->setContentType(internalContent.getContentType()); fileTransferContent->setBody(internalContent.getBody()); string xml_body = fileTransferContent->getBodyAsUtf8String(); @@ -603,9 +595,9 @@ ChatMessageModifier::Result FileTransferChatMessageModifier::decode(const shared return ChatMessageModifier::Result::Done; } - for (Content *content : message->getContents()) { + for (auto &content : message->getContents()) { if (content->isFileTransfer()) { - FileTransferContent *fileTransferContent = static_cast<FileTransferContent *>(content); + auto fileTransferContent = static_pointer_cast<FileTransferContent>(content); string xml_body = fileTransferContent->getBodyAsUtf8String(); parseFileTransferXmlIntoContent(xml_body.c_str(), fileTransferContent); } @@ -658,7 +650,7 @@ void FileTransferChatMessageModifier::onRecvBody(BCTBX_UNUSED(belle_sip_user_bod if (currentFileContentToTransfer->getFilePath().empty()) { LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); - LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer); + LinphoneContent *content = currentFileContentToTransfer->toC(); LinphoneBuffer *lb = linphone_buffer_new_from_data(buffer, size); // Deprecated: use list of callbacks now if (linphone_chat_message_cbs_get_file_transfer_recv(cbs)) { @@ -683,7 +675,7 @@ static void _chat_message_on_recv_end(belle_sip_user_body_handler_t *bh, void *d d->onRecvEnd(bh); } -static void renameFileAfterAutoDownload(shared_ptr<Core> core, FileContent *fileContent) { +static void renameFileAfterAutoDownload(shared_ptr<Core> core, shared_ptr<FileContent> fileContent) { string file = fileContent->getFileNameSys(); size_t foundDot = file.find_last_of("."); string fileName = file; @@ -730,7 +722,7 @@ void FileTransferChatMessageModifier::onRecvEnd(BCTBX_UNUSED(belle_sip_user_body if (currentFileContentToTransfer->getFilePath().empty()) { LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); - LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer); + LinphoneContent *content = currentFileContentToTransfer->toC(); LinphoneBuffer *lb = linphone_buffer_new(); // Deprecated: use list of callbacks now if (linphone_chat_message_cbs_get_file_transfer_recv(cbs)) { @@ -745,13 +737,12 @@ void FileTransferChatMessageModifier::onRecvEnd(BCTBX_UNUSED(belle_sip_user_body if (message->getState() != ChatMessage::State::FileTransferError) { // Remove the FileTransferContent from the message and store the FileContent - FileContent *fileContent = currentFileContentToTransfer; + auto fileContent = currentFileContentToTransfer; if (currentFileTransferContent != nullptr) { lInfo() << "Found downloaded file transfer content [" << currentFileTransferContent << "], removing it to keep only the file content [" << fileContent << "]"; message->getPrivate()->replaceContent(currentFileTransferContent, fileContent); - delete currentFileTransferContent; currentFileTransferContent = nullptr; } else { lWarning() << "Download seems successful but file transfer content not found, adding file content [" @@ -781,8 +772,8 @@ static void _chat_process_response_headers_from_get_file(void *data, const belle d->processResponseHeadersFromGetFile(event); } -static FileContent *createFileTransferInformationFromHeaders(const belle_sip_message_t *m) { - FileContent *fileContent = new FileContent(); +static std::shared_ptr<FileContent> createFileTransferInformationFromHeaders(const belle_sip_message_t *m) { + auto fileContent = FileContent::create<FileContent>(); belle_sip_header_content_length_t *content_length_hdr = BELLE_SIP_HEADER_CONTENT_LENGTH(belle_sip_message_get_header(m, "Content-Length")); @@ -832,7 +823,7 @@ void FileTransferChatMessageModifier::processResponseHeadersFromGetFile(const be lInfo() << "Extracted content length " << currentFileContentToTransfer->getFileSize() << " from header"; } else { lWarning() << "No file transfer information for message [" << message << "]: creating..."; - FileContent *content = createFileTransferInformationFromHeaders(response); + auto content = createFileTransferInformationFromHeaders(response); message->addContent(content); } @@ -932,8 +923,8 @@ void FileTransferChatMessageModifier::processResponseFromGetFile(const belle_htt } } -static void createFileContentFromFileTransferContent(FileTransferContent *fileTransferContent) { - FileContent *fileContent = new FileContent(); +static void createFileContentFromFileTransferContent(std::shared_ptr<FileTransferContent> &fileTransferContent) { + auto fileContent = FileContent::create<FileContent>(); fileContent->setFileName(fileTransferContent->getFileName()); fileContent->setFileSize(fileTransferContent->getFileSize()); @@ -946,7 +937,7 @@ static void createFileContentFromFileTransferContent(FileTransferContent *fileTr } bool FileTransferChatMessageModifier::downloadFile(const shared_ptr<ChatMessage> &message, - FileTransferContent *fileTransferContent) { + std::shared_ptr<FileTransferContent> &fileTransferContent) { chatMessage = message; if (httpRequest) { @@ -958,8 +949,11 @@ bool FileTransferChatMessageModifier::downloadFile(const shared_ptr<ChatMessage> lError() << "Content type is not a FileTransfer."; return false; } - FileContent *fileContent = fileTransferContent->getFileContent(); - if (fileContent) delete fileContent; + auto fileContent = fileTransferContent->getFileContent(); + if (fileContent) { + fileTransferContent->setFileContent(nullptr); + fileContent.reset(); + } createFileContentFromFileTransferContent(fileTransferContent); fileContent = fileTransferContent->getFileContent(); currentFileContentToTransfer = fileContent; @@ -1075,7 +1069,7 @@ string FileTransferChatMessageModifier::createFakeFileTransferFromUrl(const stri } string FileTransferChatMessageModifier::dumpFileTransferContentAsXmlString( - const FileTransferContent *parsedXmlFileTransferContent, + const std::shared_ptr<FileTransferContent> &parsedXmlFileTransferContent, const unsigned char *contentKey, size_t contentKeySize, const unsigned char *contentAuthTag, @@ -1156,12 +1150,12 @@ static std::string cleanDownloadFileName(std::string fileName) { } #endif -void FileTransferChatMessageModifier::parseFileTransferXmlIntoContent(const char *xml, - FileTransferContent *fileTransferContent) const { +void FileTransferChatMessageModifier::parseFileTransferXmlIntoContent( + const char *xml, std::shared_ptr<FileTransferContent> &fileTransferContent) const { #ifdef HAVE_XML2 xmlDocPtr xmlMessageBody; xmlNodePtr cur; - /* parse the msg body to get all informations from it */ + /* parse the msg body to get all information from it */ xmlMessageBody = xmlParseDoc((const xmlChar *)xml); cur = xmlDocGetRootElement(xmlMessageBody); @@ -1201,13 +1195,11 @@ void FileTransferChatMessageModifier::parseFileTransferXmlIntoContent(const char xmlFree(fileDuration); } if (!xmlStrcmp(cur->name, (const xmlChar *)"data")) { - xmlChar *fileUrl = nullptr; - fileUrl = xmlGetProp(cur, (const xmlChar *)"url"); + xmlChar *fileUrl = xmlGetProp(cur, (const xmlChar *)"url"); fileTransferContent->setFileUrl(fileUrl ? (const char *)fileUrl : ""); xmlFree(fileUrl); - xmlChar *validUntil = nullptr; - validUntil = xmlGetProp(cur, (const xmlChar *)"until"); + xmlChar *validUntil = xmlGetProp(cur, (const xmlChar *)"until"); if (validUntil != NULL) { // Will be null when fake XML is made for external body URL message fileTransferContent->setProperty("validUntil", std::string((char *)validUntil)); diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.h b/src/chat/modifier/file-transfer-chat-message-modifier.h index 208f89edda21266b5da30149d9da09e3f9dfc134..c2f0c0f4e41e7a7f6b1b601d86fd3cf363f1145a 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.h +++ b/src/chat/modifier/file-transfer-chat-message-modifier.h @@ -63,19 +63,22 @@ public: void processIoErrorDownload(const belle_sip_io_error_event_t *event); void processResponseFromGetFile(const belle_http_response_event_t *event); - bool downloadFile(const std::shared_ptr<ChatMessage> &message, FileTransferContent *fileTransferContent); + bool downloadFile(const std::shared_ptr<ChatMessage> &message, + std::shared_ptr<FileTransferContent> &fileTransferContent); void cancelFileTransfer(); bool isFileTransferInProgressAndValid() const; std::string createFakeFileTransferFromUrl(const std::string &url); void fileUploadEndBackgroundTask(); - void parseFileTransferXmlIntoContent(const char *xml, FileTransferContent *fileTransferContent) const; - std::string dumpFileTransferContentAsXmlString(const FileTransferContent *parsedXmlFileTransferContent, - const unsigned char *contentKey, - size_t contentKeySize, - const unsigned char *contentAuthTag, - size_t contentAuthTagSize, - const std::string &realFileName) const; + void parseFileTransferXmlIntoContent(const char *xml, + std::shared_ptr<FileTransferContent> &fileTransferContent) const; + std::string + dumpFileTransferContentAsXmlString(const std::shared_ptr<FileTransferContent> &parsedXmlFileTransferContent, + const unsigned char *contentKey, + size_t contentKeySize, + const unsigned char *contentAuthTag, + size_t contentAuthTagSize, + const std::string &realFileName) const; private: // Body handler is optional, but if set this method takes owneship of it, even in error cases. @@ -95,8 +98,8 @@ private: std::string unEscapeFileName(const std::string &fileName) const; std::weak_ptr<ChatMessage> chatMessage; - FileContent *currentFileContentToTransfer = nullptr; - FileTransferContent *currentFileTransferContent = nullptr; + std::shared_ptr<FileContent> currentFileContentToTransfer = nullptr; + std::shared_ptr<FileTransferContent> currentFileTransferContent = nullptr; belle_http_request_t *httpRequest = nullptr; belle_http_request_listener_t *httpListener = nullptr; diff --git a/src/chat/modifier/multipart-chat-message-modifier.cpp b/src/chat/modifier/multipart-chat-message-modifier.cpp index b0adc284633970d728aa71d8958a577778e4fec9..2536c34cd3287da0649ab8a87bd584bb4b109b3f 100644 --- a/src/chat/modifier/multipart-chat-message-modifier.cpp +++ b/src/chat/modifier/multipart-chat-message-modifier.cpp @@ -41,7 +41,7 @@ ChatMessageModifier::Result MultipartChatMessageModifier::encode(const shared_pt BCTBX_UNUSED(int &errorCode)) { if (message->getContents().size() <= 1) return ChatMessageModifier::Result::Skipped; - Content content = ContentManager::contentListToMultipart(message->getContents()); + auto content = ContentManager::contentListToMultipart(message->getContents()); message->setInternalContent(content); return ChatMessageModifier::Result::Done; @@ -50,10 +50,10 @@ ChatMessageModifier::Result MultipartChatMessageModifier::encode(const shared_pt ChatMessageModifier::Result MultipartChatMessageModifier::decode(const shared_ptr<ChatMessage> &message, BCTBX_UNUSED(int &errorCode)) { if (message->getInternalContent().getContentType().isMultipart()) { - for (Content &c : ContentManager::multipartToContentList(message->getInternalContent())) { - Content *content; + for (auto &c : ContentManager::multipartToContentList(message->getInternalContent())) { + std::shared_ptr<Content> content; if (c.getContentType() == ContentType::FileTransfer) { - content = new FileTransferContent(); + content = FileTransferContent::create<FileTransferContent>(); content->setContentType(c.getContentType()); content->setContentDisposition(c.getContentDisposition()); content->setContentEncoding(c.getContentEncoding()); @@ -62,7 +62,7 @@ ChatMessageModifier::Result MultipartChatMessageModifier::decode(const shared_pt } content->setBody(c.getBody()); } else { - content = new Content(c); + content = Content::create(c); } message->addContent(content); } diff --git a/src/conference/conference-scheduler.cpp b/src/conference/conference-scheduler.cpp index 71df127fb5e8cdc3bf4a589c8fbc339e3a727145..78cbff3109b232367d22f4ddf95c0f91d96037a5 100644 --- a/src/conference/conference-scheduler.cpp +++ b/src/conference/conference-scheduler.cpp @@ -369,12 +369,12 @@ void ConferenceScheduler::onCallSessionSetTerminated(const shared_ptr<CallSessio addressesList.unique([](const auto &addr1, const auto &addr2) { return addr1->weakEqual(*addr2); }); if (!addressesList.empty()) { - Content content; - content.setBodyFromUtf8(Utils::getResourceLists(addressesList)); - content.setContentType(ContentType::ResourceLists); - content.setContentDisposition(ContentDisposition::RecipientList); + auto content = Content::create(); + content->setBodyFromUtf8(Utils::getResourceLists(addressesList)); + content->setContentType(ContentType::ResourceLists); + content->setContentDisposition(ContentDisposition::RecipientList); if (linphone_core_content_encoding_supported(getCore()->getCCore(), "deflate")) { - content.setContentEncoding("deflate"); + content->setContentEncoding("deflate"); } L_GET_CPP_PTR_FROM_C_OBJECT(new_params)->addCustomContent(content); @@ -435,7 +435,7 @@ shared_ptr<ChatMessage> ConferenceScheduler::createInvitationChatMessage(shared_ message = chatRoom->createChatMessageFromUtf8(mConferenceInfo->toIcsString(cancel, sequence)); message->getPrivate()->setContentType(ContentType::Icalendar); } else { - FileContent *content = new FileContent(); // content will be deleted by ChatMessage + auto content = FileContent::create<FileContent>(); // content will be deleted by ChatMessage content->setContentType(ContentType::Icalendar); content->setFileName("conference.ics"); content->setBodyFromUtf8(mConferenceInfo->toIcsString(cancel, sequence)); diff --git a/src/conference/handlers/local-conference-event-handler.cpp b/src/conference/handlers/local-conference-event-handler.cpp index ee1b5aa102a3b536b942fe042369f825c9fb232b..80a4d80a7af9743489fdb919aea7f0eed4cc0154 100644 --- a/src/conference/handlers/local-conference-event-handler.cpp +++ b/src/conference/handlers/local-conference-event-handler.cpp @@ -60,11 +60,12 @@ LocalConferenceEventHandler::LocalConferenceEventHandler(Conference *conference, // ----------------------------------------------------------------------------- -void LocalConferenceEventHandler::notifyFullState(const Content ¬ify, const shared_ptr<ParticipantDevice> &device) { +void LocalConferenceEventHandler::notifyFullState(const std::shared_ptr<Content> ¬ify, + const shared_ptr<ParticipantDevice> &device) { notifyParticipantDevice(notify, device); } -void LocalConferenceEventHandler::notifyAllExceptDevice(const Content ¬ify, +void LocalConferenceEventHandler::notifyAllExceptDevice(const std::shared_ptr<Content> ¬ify, const shared_ptr<ParticipantDevice> &exceptDevice) { for (const auto &participant : conf->getParticipants()) { for (const auto &device : participant->getDevices()) { @@ -76,7 +77,7 @@ void LocalConferenceEventHandler::notifyAllExceptDevice(const Content ¬ify, } } -void LocalConferenceEventHandler::notifyAllExcept(const Content ¬ify, +void LocalConferenceEventHandler::notifyAllExcept(const std::shared_ptr<Content> ¬ify, const shared_ptr<Participant> &exceptParticipant) { for (const auto &participant : conf->getParticipants()) { if (participant != exceptParticipant) { @@ -85,13 +86,13 @@ void LocalConferenceEventHandler::notifyAllExcept(const Content ¬ify, } } -void LocalConferenceEventHandler::notifyAll(const Content ¬ify) { +void LocalConferenceEventHandler::notifyAll(const std::shared_ptr<Content> ¬ify) { for (const auto &participant : conf->getParticipants()) { notifyParticipant(notify, participant); } } -Content LocalConferenceEventHandler::createNotifyFullState(const shared_ptr<EventSubscribe> &ev) { +std::shared_ptr<Content> LocalConferenceEventHandler::createNotifyFullState(const shared_ptr<EventSubscribe> &ev) { vector<string> acceptedContents = vector<string>(); if (ev) { const auto message = (belle_sip_message_t *)ev->getOp()->getRecvCustomHeaders(); @@ -399,12 +400,12 @@ void LocalConferenceEventHandler::addMediaCapabilities(const std::shared_ptr<Par endpoint.getMedia().push_back(text); } -Content LocalConferenceEventHandler::createNotifyMultipart(int notifyId) { +std::shared_ptr<Content> LocalConferenceEventHandler::createNotifyMultipart(int notifyId) { list<shared_ptr<EventLog>> events = conf->getCore()->getPrivate()->mainDb->getConferenceNotifiedEvents( ConferenceId(conf->getConferenceAddress(), conf->getConferenceAddress()), static_cast<unsigned int>(notifyId)); - list<Content> contents; + list<shared_ptr<Content>> contents; for (const auto &eventLog : events) { string body; shared_ptr<ConferenceNotifiedEvent> notifiedEvent = static_pointer_cast<ConferenceNotifiedEvent>(eventLog); @@ -493,15 +494,12 @@ Content LocalConferenceEventHandler::createNotifyMultipart(int notifyId) { contents.emplace_back(makeContent(body)); } - if (contents.empty()) return Content(); + if (contents.empty()) return Content::create(); - list<Content *> contentPtrs; - for (auto &content : contents) - contentPtrs.push_back(&content); - Content multipart = ContentManager::contentListToMultipart(contentPtrs); + Content multipart = ContentManager::contentListToMultipart(contents); if (linphone_core_content_encoding_supported(conf->getCore()->getCCore(), "deflate")) multipart.setContentEncoding("deflate"); - return multipart; + return Content::create(multipart); } string LocalConferenceEventHandler::createNotifyParticipantAdded(const std::shared_ptr<Address> &pAddress) { @@ -949,7 +947,8 @@ string LocalConferenceEventHandler::createNotifyAvailableMediaChanged( return createNotify(confInfo); } -void LocalConferenceEventHandler::notifyParticipant(const Content ¬ify, const shared_ptr<Participant> &participant) { +void LocalConferenceEventHandler::notifyParticipant(const std::shared_ptr<Content> ¬ify, + const shared_ptr<Participant> &participant) { for (const auto &device : participant->getDevices()) { /* Only notify to device that are present in the conference. */ switch (device->getState()) { @@ -969,7 +968,7 @@ void LocalConferenceEventHandler::notifyParticipant(const Content ¬ify, const } } -void LocalConferenceEventHandler::notifyParticipantDevice(const Content ¬ify, +void LocalConferenceEventHandler::notifyParticipantDevice(const shared_ptr<Content> ¬ify, const shared_ptr<ParticipantDevice> &device) { if (!device->isSubscribedToConferenceEventPackage()) return; @@ -979,7 +978,7 @@ void LocalConferenceEventHandler::notifyParticipantDevice(const Content ¬ify, cbs->notifyResponseCb = notifyResponseCb; ev->addCallbacks(cbs); - LinphoneContent *cContent = notify.isEmpty() ? nullptr : L_GET_C_BACK_PTR(¬ify); + LinphoneContent *cContent = notify->isEmpty() ? nullptr : notify->toC(); ev->notify(cContent); linphone_core_notify_notify_sent(conf->getCore()->getCCore(), ev->toC(), cContent); } @@ -1064,7 +1063,7 @@ LinphoneStatus LocalConferenceEventHandler::subscribeReceived(const shared_ptr<E << lastNotify << "] - sending a notify full state in an attempt to recover from this situation"; notifyFullState(createNotifyFullState(ev), device); } else { - notifyParticipantDevice(Content(), device); + notifyParticipantDevice(Content::create(), device); } } @@ -1088,7 +1087,8 @@ void LocalConferenceEventHandler::subscriptionStateChanged(const shared_ptr<Even } } -Content LocalConferenceEventHandler::getNotifyForId(int notifyId, const shared_ptr<EventSubscribe> &ev) { +std::shared_ptr<Content> LocalConferenceEventHandler::getNotifyForId(int notifyId, + const shared_ptr<EventSubscribe> &ev) { unsigned int lastNotify = conf->getLastNotify(); const int fullStateTrigger = linphone_config_get_int(linphone_core_get_config(conf->getCore()->getCCore()), "misc", @@ -1097,25 +1097,23 @@ Content LocalConferenceEventHandler::getNotifyForId(int notifyId, const shared_p (notifyId > static_cast<int>(lastNotify)) || (static_cast<int>(lastNotify) - notifyId) > fullStateTrigger; if ((notifyId == 0) || forceFullState) { auto content = createNotifyFullState(ev); - list<Content *> contentPtrs; - contentPtrs.push_back(&content); - auto multipart = ContentManager::contentListToMultipart(contentPtrs); - return multipart; + auto multipart = ContentManager::contentListToMultipart({content}); + return Content::create(multipart); } else if (notifyId < static_cast<int>(lastNotify)) { return createNotifyMultipart(notifyId); } - return Content(); + return Content::create(); } -Content LocalConferenceEventHandler::makeContent(const std::string &xml) { - Content content; - content.setContentType(ContentType::ConferenceInfo); +std::shared_ptr<Content> LocalConferenceEventHandler::makeContent(const std::string &xml) { + auto content = Content::create(); + content->setContentType(ContentType::ConferenceInfo); if (linphone_core_content_encoding_supported(conf->getCore()->getCCore(), "deflate")) { - content.setContentEncoding("deflate"); + content->setContentEncoding("deflate"); } if (!xml.empty()) { - content.setBodyFromUtf8(xml); + content->setBodyFromUtf8(xml); } return content; } diff --git a/src/conference/handlers/local-conference-event-handler.h b/src/conference/handlers/local-conference-event-handler.h index 33eeef9698df27be19292e1f39402c86c7fb443d..ab53f66df1b92c2ef83db44f3df2eb62c467b525 100644 --- a/src/conference/handlers/local-conference-event-handler.h +++ b/src/conference/handlers/local-conference-event-handler.h @@ -65,15 +65,16 @@ public: LinphoneStatus subscribeReceived(const std::shared_ptr<EventSubscribe> &ev); void subscriptionStateChanged(const std::shared_ptr<EventSubscribe> &ev, LinphoneSubscriptionState state); - Content getNotifyForId(int notifyId, const std::shared_ptr<EventSubscribe> &ev); + std::shared_ptr<Content> getNotifyForId(int notifyId, const std::shared_ptr<EventSubscribe> &ev); // protected: - void notifyFullState(const Content ¬ify, const std::shared_ptr<ParticipantDevice> &device); - void notifyAllExcept(const Content ¬ify, const std::shared_ptr<Participant> &exceptParticipant); - void notifyAllExceptDevice(const Content ¬ify, const std::shared_ptr<ParticipantDevice> &exceptDevice); - void notifyAll(const Content ¬ify); - Content createNotifyFullState(const std::shared_ptr<EventSubscribe> &ev); - Content createNotifyMultipart(int notifyId); + void notifyFullState(const std::shared_ptr<Content> ¬ify, const std::shared_ptr<ParticipantDevice> &device); + void notifyAllExcept(const std::shared_ptr<Content> ¬ify, const std::shared_ptr<Participant> &exceptParticipant); + void notifyAllExceptDevice(const std::shared_ptr<Content> ¬ify, + const std::shared_ptr<ParticipantDevice> &exceptDevice); + void notifyAll(const std::shared_ptr<Content> ¬ify); + std::shared_ptr<Content> createNotifyFullState(const std::shared_ptr<EventSubscribe> &ev); + std::shared_ptr<Content> createNotifyMultipart(int notifyId); // Conference std::string createNotifyAvailableMediaChanged(const std::map<ConferenceMediaCapabilities, bool> mediaCapabilities); @@ -216,9 +217,10 @@ private: std::string createNotifySubjectChanged(const std::string &subject); std::string createNotifyEphemeralLifetime(const long &lifetime); std::string createNotifyEphemeralMode(const EventLog::Type &type); - Content makeContent(const std::string &xml); - void notifyParticipant(const Content ¬ify, const std::shared_ptr<Participant> &participant); - void notifyParticipantDevice(const Content ¬ify, const std::shared_ptr<ParticipantDevice> &device); + std::shared_ptr<Content> makeContent(const std::string &xml); + void notifyParticipant(const std::shared_ptr<Content> ¬ify, const std::shared_ptr<Participant> &participant); + void notifyParticipantDevice(const std::shared_ptr<Content> ¬ify, + const std::shared_ptr<ParticipantDevice> &device); std::shared_ptr<Participant> getConferenceParticipant(const std::shared_ptr<Address> &address) const; diff --git a/src/conference/handlers/local-conference-list-event-handler.cpp b/src/conference/handlers/local-conference-list-event-handler.cpp index 9c2199e2df341d52e3eb39008253343280999b07..6da1aef8c84138612476535b78c81add26fcf018 100644 --- a/src/conference/handlers/local-conference-list-event-handler.cpp +++ b/src/conference/handlers/local-conference-list-event-handler.cpp @@ -144,15 +144,15 @@ void LocalConferenceListEventHandler::subscribeReceived(const std::shared_ptr<Ev int notifyId = (notifyIdStr.empty() || device->getState() == ParticipantDevice::State::Joining) ? 0 : Utils::stoi(notifyIdStr); - Content content = handler->getNotifyForId(notifyId, device->getConferenceSubscribeEvent()); - if (content.isEmpty()) continue; + auto content = handler->getNotifyForId(notifyId, device->getConferenceSubscribeEvent()); + if (content->isEmpty()) continue; noContent = false; char token[17]; belle_sip_random_token(token, sizeof(token)); - content.addHeader("Content-Id", token); - content.addHeader("Content-Length", Utils::toString(content.getSize())); - contents.push_back(std::move(content)); + content->addHeader("Content-Id", token); + content->addHeader("Content-Length", Utils::toString(content->getSize())); + contents.push_back(std::move(*content)); // Add entry into the Rlmi content of the notify body Xsd::Rlmi::Resource resource(addr->asStringUriOnly()); @@ -185,7 +185,7 @@ void LocalConferenceListEventHandler::subscribeReceived(const std::shared_ptr<Ev Content multipart = ContentManager::contentListToMultipart(contentsAsPtr); if (linphone_core_content_encoding_supported(getCore()->getCCore(), "deflate")) multipart.setContentEncoding("deflate"); - LinphoneContent *cContent = L_GET_C_BACK_PTR(&multipart); + LinphoneContent *cContent = Content::createCObject(multipart); shared_ptr<EventCbs> cbs = EventCbs::create(); cbs->setUserData(this); cbs->notifyResponseCb = notifyResponseCb; diff --git a/src/conference/handlers/remote-conference-event-handler.cpp b/src/conference/handlers/remote-conference-event-handler.cpp index ca67637038076c3f694645887888e19816efa49a..ebe2eeb09caeab17fd2665e0432e1bd863a9d36c 100644 --- a/src/conference/handlers/remote-conference-event-handler.cpp +++ b/src/conference/handlers/remote-conference-event-handler.cpp @@ -805,8 +805,8 @@ void RemoteConferenceEventHandler::multipartNotifyReceived(std::shared_ptr<Event void RemoteConferenceEventHandler::multipartNotifyReceived(const Content &content) { lInfo() << "multipart NOTIFY received for conference: " << getConferenceId(); - for (const auto &content : ContentManager::multipartToContentList(content)) { - notifyReceived(content); + for (const auto &c : ContentManager::multipartToContentList(content)) { + notifyReceived(c); } } diff --git a/src/conference/handlers/remote-conference-list-event-handler.cpp b/src/conference/handlers/remote-conference-list-event-handler.cpp index e2d48333dfd42cccfa3b2940520fd4ccf3e75217..8e3d361c833e8d7e4b8d1b8f633d90532857dc1b 100644 --- a/src/conference/handlers/remote-conference-list-event-handler.cpp +++ b/src/conference/handlers/remote-conference-list-event-handler.cpp @@ -82,8 +82,8 @@ void RemoteConferenceListEventHandler::subscribe(const shared_ptr<Account> &acco if (handlers.empty()) return; - Content content; - content.setContentType(ContentType::ResourceLists); + auto content = Content::create(); + content->setContentType(ContentType::ResourceLists); Xsd::ResourceLists::ResourceLists rl = Xsd::ResourceLists::ResourceLists(); Xsd::ResourceLists::ListType l = Xsd::ResourceLists::ListType(); @@ -117,7 +117,7 @@ void RemoteConferenceListEventHandler::subscribe(const shared_ptr<Account> &acco Xsd::XmlSchema::NamespaceInfomap map; stringstream xmlBody; serializeResourceLists(xmlBody, rl, map); - content.setBodyFromUtf8(xmlBody.str()); + content->setBodyFromUtf8(xmlBody.str()); if (account->getState() != LinphoneRegistrationOk) return; @@ -138,11 +138,11 @@ void RemoteConferenceListEventHandler::subscribe(const shared_ptr<Account> &acco evSub->addCustomHeader("Content-Disposition", "recipient-list"); LinphoneCore *lc = getCore()->getCCore(); if (linphone_core_content_encoding_supported(lc, "deflate")) { - content.setContentEncoding("deflate"); + content->setContentEncoding("deflate"); evSub->addCustomHeader("Accept-Encoding", "deflate"); } evSub->setProperty("event-handler-private", this); - LinphoneContent *cContent = L_GET_C_BACK_PTR(&content); + LinphoneContent *cContent = content->toC(); evSub->send(cContent); levs.push_back(evSub); @@ -176,7 +176,8 @@ bool RemoteConferenceListEventHandler::getInitialSubscriptionUnderWayFlag(const return (handler) ? handler->getInitialSubscriptionUnderWayFlag() : false; } -void RemoteConferenceListEventHandler::notifyReceived(std::shared_ptr<Event> notifyLev, const Content *notifyContent) { +void RemoteConferenceListEventHandler::notifyReceived(std::shared_ptr<Event> notifyLev, + const std::shared_ptr<const Content> ¬ifyContent) { const auto &from = notifyLev->getFrom(); auto it = std::find_if(levs.begin(), levs.end(), [&from](const auto &lev) { return (*Address::create(lev->getOp()->getFrom()) == *from); }); diff --git a/src/conference/handlers/remote-conference-list-event-handler.h b/src/conference/handlers/remote-conference-list-event-handler.h index e455f4c4bffc051e94ba52ff3ddeb1dc8a8569dc..54aaf24897e39291bbb15d194a7ab6bf36939e93 100644 --- a/src/conference/handlers/remote-conference-list-event-handler.h +++ b/src/conference/handlers/remote-conference-list-event-handler.h @@ -53,7 +53,7 @@ public: void unsubscribe() override; void unsubscribe(const std::shared_ptr<Account> &account); void invalidateSubscription() override; - void notifyReceived(std::shared_ptr<Event> notifyLev, const Content *notifyContent); + void notifyReceived(std::shared_ptr<Event> notifyLev, const std::shared_ptr<const Content> ¬ifyContent); void addHandler(RemoteConferenceEventHandler *handler); void removeHandler(RemoteConferenceEventHandler *handler); void clearHandlers(); diff --git a/src/conference/params/call-session-params-p.h b/src/conference/params/call-session-params-p.h index 1ce2d63c34383b35d11782d5d32d7a311c4e526c..0e8d5a67e81865499de5e1d30536a1c9637d08b7 100644 --- a/src/conference/params/call-session-params-p.h +++ b/src/conference/params/call-session-params-p.h @@ -126,7 +126,7 @@ private: std::unordered_map<std::string, std::string> customContactParameters; std::shared_ptr<CallSession> referer; /* In case call creation is consecutive to an incoming transfer, this points to the original call */ - std::list<Content> customContents; + std::list<std::shared_ptr<Content>> customContents; std::list<LinphoneSrtpSuite> srtpSuites{}; time_t startTime = (time_t)-1; diff --git a/src/conference/params/call-session-params.cpp b/src/conference/params/call-session-params.cpp index 7f0cee2d03f95c668543a49d8b429581c2e4a4f7..da73b7760635fb9cbbc9a2f4d3cc2327cc0ae773 100644 --- a/src/conference/params/call-session-params.cpp +++ b/src/conference/params/call-session-params.cpp @@ -301,12 +301,12 @@ std::string CallSessionParams::getCustomContactParameter(const std::string ¶ // ----------------------------------------------------------------------------- -void CallSessionParams::addCustomContent(const Content &content) { +void CallSessionParams::addCustomContent(const std::shared_ptr<Content> &content) { L_D(); d->customContents.push_back(std::move(content)); } -const list<Content> &CallSessionParams::getCustomContents() const { +const list<std::shared_ptr<Content>> &CallSessionParams::getCustomContents() const { L_D(); return d->customContents; } diff --git a/src/conference/params/call-session-params.h b/src/conference/params/call-session-params.h index e186985186793c6aa792fb7173b27a6834722273..7808b0293e51a1fc0d72b4a1a6fe93be1d5506b5 100644 --- a/src/conference/params/call-session-params.h +++ b/src/conference/params/call-session-params.h @@ -85,8 +85,8 @@ public: void clearCustomContactParameters(); std::string getCustomContactParameter(const std::string ¶mName) const; - void addCustomContent(const Content &content); - const std::list<Content> &getCustomContents() const; + void addCustomContent(const std::shared_ptr<Content> &content); + const std::list<std::shared_ptr<Content>> &getCustomContents() const; std::shared_ptr<Account> getAccount() const; void setAccount(std::shared_ptr<Account> account); diff --git a/src/conference/session/call-session.cpp b/src/conference/session/call-session.cpp index 4f4273b32809c6604e16cf62ef4a7447f451ea91..7221d34eb537d251f398bf8094cd4306b8f2ed91 100644 --- a/src/conference/session/call-session.cpp +++ b/src/conference/session/call-session.cpp @@ -1108,13 +1108,13 @@ void CallSessionPrivate::repairByInviteWithReplaces() { string fromTag = op->getLocalTag(); string toTag = op->getRemoteTag(); // Restore INVITE body if any, for example while creating a chat room - Content content = Content(op->getLocalBody()); + auto content = Content::create(op->getLocalBody()); op->killDialog(); createOp(); op->setReplaces(callId.c_str(), fromTag, toTag.empty() ? "0" : toTag); // empty tag is set to 0 as defined by rfc3891 - q->startInvite(nullptr, subject, &content); // Don't forget to set subject from call-session (and not from OP) + q->startInvite(nullptr, subject, content); // Don't forget to set subject from call-session (and not from OP) } void CallSessionPrivate::refreshContactAddress() { @@ -1474,7 +1474,8 @@ bool CallSession::hasTransferPending() { void CallSession::initiateIncoming() { } -bool CallSession::initiateOutgoing(BCTBX_UNUSED(const string &subject), BCTBX_UNUSED(const Content *content)) { +bool CallSession::initiateOutgoing(BCTBX_UNUSED(const string &subject), + BCTBX_UNUSED(const std::shared_ptr<const Content> content)) { L_D(); bool defer = false; d->setState(CallSession::State::OutgoingInit, "Starting outgoing call"); @@ -1573,7 +1574,7 @@ void CallSession::startPushIncomingNotification() { int CallSession::startInvite(const std::shared_ptr<Address> &destination, const string &subject, - const Content *content) { + const std::shared_ptr<const Content> content) { L_D(); d->subject = subject; /* Try to be best-effort in giving real local or routable contact address */ @@ -1590,8 +1591,8 @@ int CallSession::startInvite(const std::shared_ptr<Address> &destination, } // If a custom Content has been set in the call params, create a multipart body for the INVITE - for (auto &content : d->params->getCustomContents()) { - d->op->addAdditionalLocalBody(content); + for (auto &c : d->params->getCustomContents()) { + d->op->addAdditionalLocalBody(*c); } int result = d->op->call(d->log->getFromAddress()->toString().c_str(), destinationStr, subject); @@ -1673,7 +1674,7 @@ LinphoneStatus CallSession::transfer(const string &dest) { LinphoneStatus CallSession::update(const CallSessionParams *csp, const UpdateMethod method, const string &subject, - const Content *content) { + const std::shared_ptr<Content> content) { L_D(); CallSession::State nextState; CallSession::State initialState = d->state; @@ -1834,7 +1835,7 @@ const CallSessionParams *CallSession::getRemoteParams() { const list<Content> additionnalContents = d->op->getAdditionalRemoteBodies(); for (auto &content : additionnalContents) - d->remoteParams->addCustomContent(content); + d->remoteParams->addCustomContent(Content::create(content)); return d->remoteParams; } diff --git a/src/conference/session/call-session.h b/src/conference/session/call-session.h index 7c4127cf415613888958c1be339b67683802caa5..89ecf43372789f4e36cf1be6434588744766fe89 100644 --- a/src/conference/session/call-session.h +++ b/src/conference/session/call-session.h @@ -131,7 +131,8 @@ public: bool isCapabilityNegotiationEnabled() const; const std::list<LinphoneMediaEncryption> getSupportedEncryptions() const; virtual void initiateIncoming(); - virtual bool initiateOutgoing(const std::string &subject = "", const Content *content = nullptr); + virtual bool initiateOutgoing(const std::string &subject = "", + const std::shared_ptr<const Content> content = nullptr); virtual void iterate(time_t currentRealTime, bool oneSecondElapsed); LinphoneStatus redirect(const std::string &redirectUri); LinphoneStatus redirect(const Address &redirectAddr); @@ -140,7 +141,7 @@ public: void startPushIncomingNotification(); virtual int startInvite(const std::shared_ptr<Address> &destination, const std::string &subject = "", - const Content *content = nullptr); + const std::shared_ptr<const Content> content = nullptr); LinphoneStatus terminate(const LinphoneErrorInfo *ei = nullptr); LinphoneStatus transfer(const std::shared_ptr<CallSession> &dest); LinphoneStatus transfer(const std::shared_ptr<Address> &dest); @@ -148,7 +149,7 @@ public: LinphoneStatus update(const CallSessionParams *csp, const UpdateMethod method = UpdateMethod::Default, const std::string &subject = "", - const Content *content = nullptr); + const std::shared_ptr<Content> content = nullptr); CallSessionParams *getCurrentParams() const; LinphoneCallDir getDirection() const; diff --git a/src/conference/session/media-session.cpp b/src/conference/session/media-session.cpp index 9346f525b5b1dca40097ff7ef2cbcae4ea6f813d..4341b8811f6a3021879dcd5d762f5aabf2c33918 100644 --- a/src/conference/session/media-session.cpp +++ b/src/conference/session/media-session.cpp @@ -4293,7 +4293,7 @@ void MediaSession::initiateIncoming() { } } -bool MediaSession::initiateOutgoing(const string &subject, const Content *content) { +bool MediaSession::initiateOutgoing(const string &subject, const std::shared_ptr<const Content> content) { L_D(); bool defer = CallSession::initiateOutgoing(subject, content); @@ -4633,7 +4633,7 @@ int MediaSession::getRandomRtpPort(const SalStreamDescription &stream) const { int MediaSession::startInvite(const std::shared_ptr<Address> &destination, const string &subject, - const Content *content) { + const std::shared_ptr<const Content> content) { L_D(); if (d->getOp() == nullptr) d->createOp(); @@ -5215,7 +5215,7 @@ const MediaSessionParams *MediaSession::getRemoteParams() { const list<Content> &additionnalContents = d->op->getAdditionalRemoteBodies(); for (auto &content : additionnalContents) { if (!params) params = new MediaSessionParams(); - params->addCustomContent(content); + params->addCustomContent(Content::create(content)); } d->setRemoteParams(params); if (!params) { diff --git a/src/conference/session/media-session.h b/src/conference/session/media-session.h index f617530052d74b95836ffc688201bb5badb68ff7..b4a95ca7580c5ee80bf100c2378543330e21fa55 100644 --- a/src/conference/session/media-session.h +++ b/src/conference/session/media-session.h @@ -77,7 +77,8 @@ public: const std::shared_ptr<const Address> &to) override; LinphoneStatus deferUpdate() override; void initiateIncoming() override; - bool initiateOutgoing(const std::string &subject = "", const Content *content = nullptr) override; + bool initiateOutgoing(const std::string &subject = "", + const std::shared_ptr<const Content> content = nullptr) override; void iterate(time_t currentRealTime, bool oneSecondElapsed) override; LinphoneStatus pauseFromConference(); LinphoneStatus pause(); @@ -89,7 +90,7 @@ public: void startIncomingNotification(bool notifyRinging = true) override; int startInvite(const std::shared_ptr<Address> &destination, const std::string &subject = "", - const Content *content = nullptr) override; + const std::shared_ptr<const Content> content = nullptr) override; bool startRecording(); void stopRecording(); bool isRecording(); diff --git a/src/content/content-disposition.cpp b/src/content/content-disposition.cpp index de5b99f92165ba5b60feabcb291ae56144174ac3..f2da56b0ca181c722f040fe7d7880fd35fe83270 100644 --- a/src/content/content-disposition.cpp +++ b/src/content/content-disposition.cpp @@ -35,7 +35,8 @@ class ContentDispositionPrivate : public ClonableObjectPrivate { public: string disposition; string parameter; - mutable string fullDisposition; // Introduced to be able to extract a C pointer from the string returned by asString for the c-wrapper function + mutable string fullDisposition; // Introduced to be able to extract a C pointer from the string returned by asString + // for the c-wrapper function }; // ----------------------------------------------------------------------------- @@ -98,12 +99,11 @@ void ContentDisposition::setParameter(const string ¶meter) { d->parameter = parameter; } -const string &ContentDisposition::asString () const{ +const string &ContentDisposition::asString() const { L_D(); if (isValid()) { d->fullDisposition = d->disposition; - if (!d->parameter.empty()) - d->fullDisposition += ";" + d->parameter; + if (!d->parameter.empty()) d->fullDisposition += ";" + d->parameter; } else { d->fullDisposition.clear(); } diff --git a/src/content/content-disposition.h b/src/content/content-disposition.h index 7a72494f727d673a8022898345a999bf4aded293..0736b397217e479296df42a4259452e101eb03d9 100644 --- a/src/content/content-disposition.h +++ b/src/content/content-disposition.h @@ -55,7 +55,7 @@ public: const std::string &getParameter() const; void setParameter(const std::string ¶meter); - const std::string &asString () const; + const std::string &asString() const; static const ContentDisposition Notification; static const ContentDisposition RecipientList; diff --git a/src/content/content-manager.cpp b/src/content/content-manager.cpp index c12c3a663c7f86c129eecfad188a20f035d6da68..ab81020282d6d78661c661c08be70778ed70eb63 100644 --- a/src/content/content-manager.cpp +++ b/src/content/content-manager.cpp @@ -39,16 +39,12 @@ LINPHONE_BEGIN_NAMESPACE // ----------------------------------------------------------------------------- list<Content> ContentManager::multipartToContentList(const Content &content) { - LinphoneContent *cContent = L_GET_C_BACK_PTR(&content); - SalBodyHandler *sbh = sal_body_handler_from_content(cContent); + SalBodyHandler *sbh = Content::getBodyHandlerFromContent(content); list<Content> contents; for (const belle_sip_list_t *parts = sal_body_handler_get_parts(sbh); parts; parts = parts->next) { - SalBodyHandler *part = (SalBodyHandler *)parts->data; - LinphoneContent *cContent = linphone_content_from_sal_body_handler(part, false); - Content *cppContent = L_GET_CPP_PTR_FROM_C_OBJECT(cContent); - contents.push_back(*cppContent); - linphone_content_unref(cContent); + auto part = (SalBodyHandler *)parts->data; + contents.emplace_back(part, false); } sal_body_handler_unref(sbh); @@ -61,32 +57,46 @@ ContentManager::contentListToMultipart(const list<Content *> &contents, const st belle_sip_multipart_body_handler_new(nullptr, nullptr, nullptr, boundary.empty() ? nullptr : boundary.c_str()); mpbh = (belle_sip_multipart_body_handler_t *)belle_sip_object_ref(mpbh); - for (Content *content : contents) { - LinphoneContent *cContent = L_GET_C_BACK_PTR(content); - SalBodyHandler *sbh = sal_body_handler_from_content(cContent, false); + for (auto &content : contents) { + SalBodyHandler *sbh = Content::getBodyHandlerFromContent(*content, false); belle_sip_multipart_body_handler_add_part(mpbh, BELLE_SIP_BODY_HANDLER(sbh)); } - SalBodyHandler *sbh = (SalBodyHandler *)mpbh; + auto sbh = (SalBodyHandler *)mpbh; sal_body_handler_set_type(sbh, ContentType::Multipart.getType().c_str()); sal_body_handler_set_subtype(sbh, encrypted ? ContentType::Encrypted.getSubType().c_str() : ContentType::Multipart.getSubType().c_str()); sal_body_handler_set_content_type_parameter(sbh, "boundary", belle_sip_multipart_body_handler_get_boundary(mpbh)); - LinphoneContent *cContent = linphone_content_from_sal_body_handler(sbh); + auto content = Content(sbh); belle_sip_object_unref(mpbh); - Content content = *L_GET_CPP_PTR_FROM_C_OBJECT(cContent); - linphone_content_unref(cContent); return content; } +Content ContentManager::contentListToMultipart(const list<shared_ptr<Content>> &contents, + const string &boundary, + bool encrypted) { + list<Content *> contentsPtrs; + for (const auto &c : contents) + contentsPtrs.push_back(c.get()); + return contentListToMultipart(contentsPtrs, boundary, encrypted); +} + Content ContentManager::contentListToMultipart(const std::list<Content *> &contents, bool encrypted) { return contentListToMultipart(contents, "", encrypted); } +Content ContentManager::contentListToMultipart(const list<shared_ptr<Content>> &contents, bool encrypted) { + return contentListToMultipart(contents, "", encrypted); +} + Content ContentManager::contentListToMultipart(const std::list<Content *> &contents) { return contentListToMultipart(contents, "", false); } +Content ContentManager::contentListToMultipart(const list<shared_ptr<Content>> &contents) { + return contentListToMultipart(contents, "", false); +} + LINPHONE_END_NAMESPACE diff --git a/src/content/content-manager.h b/src/content/content-manager.h index 3010d35db266b01879ab12c3260838edc60dfe84..0397a76671f250510474159c4b3ae559532486fb 100644 --- a/src/content/content-manager.h +++ b/src/content/content-manager.h @@ -36,9 +36,14 @@ LINPHONE_PUBLIC std::list<Content> multipartToContentList(const Content &content LINPHONE_PUBLIC Content contentListToMultipart(const std::list<Content *> &contents, const std::string &boundary, bool encrypted); +LINPHONE_PUBLIC Content contentListToMultipart(const std::list<std::shared_ptr<Content>> &contents, + const std::string &boundary, + bool encrypted); /* There is no reason to set the boundary, prefer this form of the encode method: */ LINPHONE_PUBLIC Content contentListToMultipart(const std::list<Content *> &contents, bool encrypted); +LINPHONE_PUBLIC Content contentListToMultipart(const std::list<std::shared_ptr<Content>> &contents, bool encrypted); LINPHONE_PUBLIC Content contentListToMultipart(const std::list<Content *> &contents); +LINPHONE_PUBLIC Content contentListToMultipart(const std::list<std::shared_ptr<Content>> &contents); } // namespace ContentManager LINPHONE_END_NAMESPACE diff --git a/src/content/content-p.h b/src/content/content-p.h deleted file mode 100644 index b8bb98a6d7d594a44db4d63fa22304afad38b182..0000000000000000000000000000000000000000 --- a/src/content/content-p.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010-2022 Belledonne Communications SARL. - * - * This file is part of Liblinphone - * (see https://gitlab.linphone.org/BC/public/liblinphone). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _L_CONTENT_P_H_ -#define _L_CONTENT_P_H_ - -#include "content-disposition.h" -#include "content-type.h" -#include "content.h" -#include "object/clonable-object-p.h" - -// ============================================================================= - -LINPHONE_BEGIN_NAMESPACE - -class Header; - -class ContentPrivate : public ClonableObjectPrivate { -private: - std::vector<char> body; - ContentType contentType; - ContentDisposition contentDisposition; - std::string contentEncoding; - std::list<Header> headers; - - const std::list<std::pair<std::string, std::string>>::const_iterator - findHeader(const std::string &headerName) const; - - L_DECLARE_PUBLIC(Content); -}; - -LINPHONE_END_NAMESPACE - -#endif // ifndef _L_CONTENT_P_H_ diff --git a/src/content/content.cpp b/src/content/content.cpp index 7194c33b6452e6de4c1b5f45456e571566d727c5..2b9f5ccddf0469e3b88724bed33d0339bd6d1ec3 100644 --- a/src/content/content.cpp +++ b/src/content/content.cpp @@ -18,19 +18,14 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -// TODO: Remove me later. -#include "linphone/core.h" - -#include "factory/factory.h" -#include "linphone/utils/algorithm.h" -#include "linphone/utils/utils.h" - -#include "content-p.h" -#include "content-type.h" -#include "header/header.h" +#include "content.h" #include "bctoolbox/port.h" #include "bctoolbox/vfs_encrypted.hh" + +#include "factory/factory.h" +#include "header/header-param.h" +#include "linphone/utils/algorithm.h" #include "logger/logger.h" // ============================================================================= @@ -41,166 +36,220 @@ LINPHONE_BEGIN_NAMESPACE // ============================================================================= -Content::Content() : ClonableObject(*new ContentPrivate) { -} +Content::Content(const SalBodyHandler *bodyHandler, bool parseMultipart) { + if (bodyHandler == nullptr) return; -Content::Content(const Content &other) : ClonableObject(*new ContentPrivate), AppDataContainer(other) { - copy(other); + mBodyHandler = sal_body_handler_ref((SalBodyHandler *)bodyHandler); + + mContentType.setType(sal_body_handler_get_type(bodyHandler)); + mContentType.setSubType(sal_body_handler_get_subtype(bodyHandler)); + for (const belle_sip_list_t *params = sal_body_handler_get_content_type_parameters_names(bodyHandler); params; + params = params->next) { + const char *paramName = reinterpret_cast<const char *>(params->data); + const char *paramValue = sal_body_handler_get_content_type_parameter(bodyHandler, paramName); + mContentType.addParameter(paramName, paramValue); + } + + if (mContentType.isMultipart() && parseMultipart) { + belle_sip_multipart_body_handler_t *mpbh = BELLE_SIP_MULTIPART_BODY_HANDLER(bodyHandler); + char *body = belle_sip_object_to_string(mpbh); + setBodyFromUtf8(body); + belle_sip_free(body); + } else { + setBodyFromUtf8(reinterpret_cast<char *>(sal_body_handler_get_data(bodyHandler))); + } + + auto headers = reinterpret_cast<const belle_sip_list_t *>(sal_body_handler_get_headers(bodyHandler)); + while (headers) { + belle_sip_header_t *cHeader = BELLE_SIP_HEADER(headers->data); + Header header = Header(belle_sip_header_get_name(cHeader), belle_sip_header_get_unparsed_value(cHeader)); + addHeader(header); + headers = headers->next; + } + + if (sal_body_handler_get_encoding(bodyHandler)) mContentEncoding = sal_body_handler_get_encoding(bodyHandler); + + const char *disposition = sal_body_handler_get_content_disposition(bodyHandler); + if (disposition) mContentDisposition = ContentDisposition(disposition); } -Content::Content(Content &&other) : ClonableObject(*new ContentPrivate), AppDataContainer(std::move(other)) { - L_D(); - ContentPrivate *dOther = other.getPrivate(); - d->body = std::move(dOther->body); - d->contentType = std::move(dOther->contentType); - d->contentDisposition = std::move(dOther->contentDisposition); - d->contentEncoding = std::move(dOther->contentEncoding); - d->headers = std::move(dOther->headers); +Content::Content(const Content &other) : HybridObject(other), PropertyContainer(other) { + copy(other); } -Content::Content(ContentPrivate &p) : ClonableObject(p) { +Content::Content(Content &&other) noexcept : HybridObject(std::move(other)) { + mBody = std::move(other.mBody); + mContentType = std::move(other.mContentType); + mContentDisposition = std::move(other.mContentDisposition); + mContentEncoding = std::move(other.mContentEncoding); + mHeaders = std::move(other.mHeaders); + mCryptoContext = std::move(other.mCryptoContext); + other.mCryptoContext = nullptr; + mSize = std::move(other.mSize); + mIsDirty = std::move(other.mIsDirty); + mBodyHandler = std::move(other.mBodyHandler); + other.mBodyHandler = nullptr; } Content::~Content() { - L_D(); /* * Fills the body with zeros before releasing since it may contain * private data like cipher keys or decoded messages. */ - d->body.assign(d->body.size(), 0); + mBody.assign(mBody.size(), 0); + if (mBodyHandler != nullptr) sal_body_handler_unref(mBodyHandler); } Content &Content::operator=(const Content &other) { if (this != &other) { - AppDataContainer::operator=(other); + PropertyContainer::operator=(other); copy(other); } return *this; } -Content &Content::operator=(Content &&other) { - L_D(); - AppDataContainer::operator=(std::move(other)); - ContentPrivate *dOther = other.getPrivate(); - d->body = std::move(dOther->body); - d->contentType = std::move(dOther->contentType); - d->contentDisposition = std::move(dOther->contentDisposition); - d->contentEncoding = std::move(dOther->contentEncoding); - d->headers = std::move(dOther->headers); +Content &Content::operator=(Content &&other) noexcept { + mBody = std::move(other.mBody); + mContentType = std::move(other.mContentType); + mContentDisposition = std::move(other.mContentDisposition); + mContentEncoding = std::move(other.mContentEncoding); + mHeaders = std::move(other.mHeaders); + mCryptoContext = std::move(other.mCryptoContext); + other.mCryptoContext = nullptr; + mSize = std::move(other.mSize); + mIsDirty = std::move(other.mIsDirty); + mBodyHandler = std::move(other.mBodyHandler); + other.mBodyHandler = nullptr; return *this; } bool Content::operator==(const Content &other) const { - L_D(); - return d->contentType == other.getContentType() && d->body == other.getBody() && - d->contentDisposition == other.getContentDisposition() && d->contentEncoding == other.getContentEncoding() && - d->headers == other.getHeaders(); + return mContentType == other.getContentType() && mBody == other.getBody() && + mContentDisposition == other.getContentDisposition() && mContentEncoding == other.getContentEncoding() && + mHeaders == other.getHeaders(); } void Content::copy(const Content &other) { - L_D(); - d->body = other.getBody(); - d->contentType = other.getContentType(); - d->contentDisposition = other.getContentDisposition(); - d->contentEncoding = other.getContentEncoding(); - d->headers = other.getHeaders(); + mBody = other.getBody(); + mContentType = other.getContentType(); + mContentDisposition = other.getContentDisposition(); + mContentEncoding = other.getContentEncoding(); + mHeaders = other.getHeaders(); + mSize = other.mSize; + mCache = other.mCache; + if (!mIsDirty && mBodyHandler != nullptr) mBodyHandler = sal_body_handler_ref(other.mBodyHandler); } const ContentType &Content::getContentType() const { - L_D(); - return d->contentType; + return mContentType; } ContentType &Content::getContentType() { - L_D(); - return d->contentType; + return mContentType; } void Content::setContentType(const ContentType &contentType) { - L_D(); - d->contentType = contentType; + mContentType = contentType; } const ContentDisposition &Content::getContentDisposition() const { - L_D(); - return d->contentDisposition; + return mContentDisposition; } void Content::setContentDisposition(const ContentDisposition &contentDisposition) { - L_D(); - d->contentDisposition = contentDisposition; + mContentDisposition = contentDisposition; } const string &Content::getContentEncoding() const { - L_D(); - return d->contentEncoding; + return mContentEncoding; } void Content::setContentEncoding(const string &contentEncoding) { - L_D(); - d->contentEncoding = contentEncoding; + mContentEncoding = contentEncoding; } const vector<char> &Content::getBody() const { - L_D(); - return d->body; + return mBody; } string Content::getBodyAsString() const { - L_D(); - return Utils::utf8ToLocale(string(d->body.begin(), d->body.end())); + return Utils::utf8ToLocale(string(mBody.begin(), mBody.end())); } -string Content::getBodyAsUtf8String() const { - L_D(); - return string(d->body.begin(), d->body.end()); +const string &Content::getBodyAsUtf8String() const { + mCache.buffer = string(mBody.begin(), mBody.end()); + return mCache.buffer; } void Content::setBody(const vector<char> &body) { - L_D(); - d->body = body; + mBody = body; } void Content::setBody(vector<char> &&body) { - L_D(); - d->body = std::move(body); + mBody = std::move(body); } void Content::setBodyFromLocale(const string &body) { - L_D(); string toUtf8 = Utils::localeToUtf8(body); - d->body = vector<char>(toUtf8.cbegin(), toUtf8.cend()); + mBody = vector<char>(toUtf8.cbegin(), toUtf8.cend()); } void Content::setBody(const void *buffer, size_t size) { - L_D(); + mIsDirty = true; + const char *start = static_cast<const char *>(buffer); - if (start != nullptr) d->body = vector<char>(start, start + size); - else d->body.clear(); + if (start != nullptr) mBody = vector<char>(start, start + size); + else mBody.clear(); } void Content::setBodyFromUtf8(const string &body) { - L_D(); - d->body = vector<char>(body.cbegin(), body.cend()); + mIsDirty = true; + + mBody = vector<char>(body.cbegin(), body.cend()); +} + +const std::string &Content::getName() const { + return mCache.name; +} + +void Content::setName(const std::string &name) { + mCache.name = name; } size_t Content::getSize() const { - L_D(); - return d->body.size(); + return mBody.empty() ? mSize : mBody.size(); +} + +void Content::setSize(size_t size) { + mSize = size; +} + +SalBodyHandler *Content::getBodyHandler() const { + return mBodyHandler; +} + +void Content::setBodyHandler(SalBodyHandler *bodyHandler) { + mBodyHandler = bodyHandler; +} + +void **Content::getCryptoContextAddress() { + return &mCryptoContext; } bool Content::isEmpty() const { return getSize() == 0; } +bool Content::isDirty() const { + return mIsDirty; +} + bool Content::isMultipart() const { - L_D(); - return d->contentType.isValid() && d->contentType == ContentType::Multipart; + return mContentType.isValid() && mContentType == ContentType::Multipart; } bool Content::isValid() const { - L_D(); - return d->contentType.isValid() || (d->contentType.isEmpty() && d->body.empty()); + return mContentType.isValid() || (mContentType.isEmpty() && mBody.empty()); } bool Content::isFile() const { @@ -211,42 +260,58 @@ bool Content::isFileTransfer() const { return false; } +const std::string &Content::getFilePath() const { + return mCache.filePath; +} + +void Content::setFilePath(const std::string &path) { + mCache.filePath = path; +} + void Content::addHeader(const string &headerName, const string &headerValue) { - L_D(); removeHeader(headerName); Header header = Header(headerName, headerValue); - d->headers.push_back(header); + mHeaders.push_back(header); } void Content::addHeader(const Header &header) { - L_D(); removeHeader(header.getName()); - d->headers.push_back(header); + mHeaders.push_back(header); } const list<Header> &Content::getHeaders() const { - L_D(); - return d->headers; + return mHeaders; } const Header &Content::getHeader(const string &headerName) const { - L_D(); - list<Header>::const_iterator it = findHeader(headerName); - if (it != d->headers.cend()) { + auto it = findHeader(headerName); + if (it != mHeaders.cend()) { return *it; } return Utils::getEmptyConstRefObject<Header>(); } void Content::removeHeader(const string &headerName) { - L_D(); auto it = findHeader(headerName); - if (it != d->headers.cend()) d->headers.remove(*it); + if (it != mHeaders.cend()) mHeaders.remove(*it); } list<Header>::const_iterator Content::findHeader(const string &headerName) const { - L_D(); - return findIf(d->headers, [&headerName](const Header &header) { return header.getName() == headerName; }); + return findIf(mHeaders, [&headerName](const Header &header) { return header.getName() == headerName; }); +} + +const std::string &Content::getCustomHeader(const std::string &headerName) const { + SalBodyHandler *bodyHandler; + + if (!mIsDirty && mBodyHandler != nullptr) { + bodyHandler = sal_body_handler_ref(mBodyHandler); + } else { + bodyHandler = getBodyHandlerFromContent(*this); + } + + mCache.headerValue = L_C_TO_STRING(sal_body_handler_get_header(bodyHandler, headerName.c_str())); + sal_body_handler_unref(bodyHandler); + return mCache.headerValue; } void Content::setUserData(const Variant &userData) { @@ -257,6 +322,58 @@ Variant Content::getUserData() const { return getProperty("LinphonePrivate::Content::userData"); } +SalBodyHandler *Content::getBodyHandlerFromContent(const Content &content, bool parseMultipart) { + if (!content.mIsDirty && content.mBodyHandler != nullptr) return sal_body_handler_ref(content.mBodyHandler); + + SalBodyHandler *bodyHandler; + ContentType contentType = content.mContentType; + if (contentType.isMultipart() && parseMultipart) { + size_t size = content.getSize(); + char *buffer = bctbx_strdup(content.getBodyAsUtf8String().c_str()); + const char *boundary = L_STRING_TO_C(contentType.getParameter("boundary").getValue()); + belle_sip_multipart_body_handler_t *bh = nullptr; + if (boundary) bh = belle_sip_multipart_body_handler_new_from_buffer(buffer, size, boundary); + else if (size > 2) { + size_t startIndex = 2, index; + while (startIndex < size && + (buffer[startIndex] != '-' || buffer[startIndex - 1] != '-' // Take accout of first "--" + || (startIndex > 2 && buffer[startIndex - 2] != '\n'))) // Must be at the beginning of the line + ++startIndex; + index = startIndex; + while (index < size && buffer[index] != '\n' && buffer[index] != '\r') + ++index; + if (startIndex != index) { + char *boundaryStr = bctbx_strndup(buffer + startIndex, (int)(index - startIndex)); + bh = belle_sip_multipart_body_handler_new_from_buffer(buffer, size, boundaryStr); + bctbx_free(boundaryStr); + } + } + + bodyHandler = reinterpret_cast<SalBodyHandler *>(BELLE_SIP_BODY_HANDLER(bh)); + bctbx_free(buffer); + } else { + bodyHandler = sal_body_handler_new(); + sal_body_handler_set_data(bodyHandler, belle_sip_strdup(content.getBodyAsUtf8String().c_str())); + } + + for (const auto &header : content.getHeaders()) { + sal_body_handler_add_header(bodyHandler, header.getName().c_str(), header.getValueWithParams().c_str()); + } + + sal_body_handler_set_type(bodyHandler, contentType.getType().c_str()); + sal_body_handler_set_subtype(bodyHandler, contentType.getSubType().c_str()); + sal_body_handler_set_size(bodyHandler, content.getSize()); + for (const auto ¶m : contentType.getParameters()) + sal_body_handler_set_content_type_parameter(bodyHandler, param.getName().c_str(), param.getValue().c_str()); + + if (!content.mContentEncoding.empty()) sal_body_handler_set_encoding(bodyHandler, content.mContentEncoding.c_str()); + + const ContentDisposition &disposition = content.getContentDisposition(); + if (disposition.isValid()) sal_body_handler_set_content_disposition(bodyHandler, disposition.asString().c_str()); + + return bodyHandler; +} + bool Content::isFileEncrypted(const string &filePath) const { if (filePath.empty()) { return false; @@ -287,7 +404,7 @@ const string Content::exportPlainFileFromEncryptedFile(const string &filePath) c return filePath; } - // plain files are stored in a "evfs" subdirectory of the cache directory + // plain files are stored in an "evfs" subdirectory of the cache directory std::string cacheDir(Factory::get()->getCacheDir(nullptr) + "/evfs/"); // Create the directory if it is not present diff --git a/src/content/content.h b/src/content/content.h index 85ffd5dd6ae5e6c6b8f8f1cb9255e325576f1fec..cb33f90a8f294da4572f5240d86b1a3d6a7a93b8 100644 --- a/src/content/content.h +++ b/src/content/content.h @@ -24,33 +24,33 @@ #include <list> #include <vector> -#include "object/app-data-container.h" -#include "object/clonable-object.h" +#include "belle-sip/object++.hh" -// ============================================================================= +#include "c-wrapper/internal/c-sal.h" +#include "content-disposition.h" +#include "content-type.h" +#include "header/header.h" +#include "linphone/api/c-types.h" +#include "object/property-container.h" -L_DECL_C_STRUCT(LinphoneContent); +// ============================================================================= LINPHONE_BEGIN_NAMESPACE -class ContentDisposition; -class ContentType; -class ContentPrivate; -class Header; - -class LINPHONE_PUBLIC Content : public ClonableObject, public AppDataContainer { +class LINPHONE_PUBLIC Content : public bellesip::HybridObject<LinphoneContent, Content>, public PropertyContainer { public: - Content(); + Content() = default; + explicit Content(const SalBodyHandler *bodyHandler, bool parseMultipart = true); Content(const Content &other); - Content(Content &&other); - ~Content(); + Content(Content &&other) noexcept; + virtual ~Content(); Content *clone() const override { return new Content(*this); } Content &operator=(const Content &other); - Content &operator=(Content &&other); + Content &operator=(Content &&other) noexcept; bool operator==(const Content &other) const; @@ -70,7 +70,7 @@ public: const std::vector<char> &getBody() const; std::string getBodyAsString() const; - std::string getBodyAsUtf8String() const; + const std::string &getBodyAsUtf8String() const; void setBody(const std::vector<char> &body); void setBody(std::vector<char> &&body); @@ -78,33 +78,63 @@ public: void setBody(const void *buffer, size_t size); void setBodyFromUtf8(const std::string &body); + const std::string &getName() const; + void setName(const std::string &name); + size_t getSize() const; + void setSize(size_t size); + + SalBodyHandler *getBodyHandler() const; + void setBodyHandler(SalBodyHandler *bodyHandler); + + void **getCryptoContextAddress(); bool isValid() const; bool isMultipart() const; bool isEmpty() const; + bool isDirty() const; virtual bool isFile() const; virtual bool isFileTransfer() const; + virtual const std::string &getFilePath() const; + virtual void setFilePath(const std::string &path); + const std::list<Header> &getHeaders() const; const Header &getHeader(const std::string &headerName) const; void addHeader(const std::string &headerName, const std::string &headerValue); void addHeader(const Header &header); void removeHeader(const std::string &headerName); std::list<Header>::const_iterator findHeader(const std::string &headerName) const; + const std::string &getCustomHeader(const std::string &headerName) const; void setUserData(const Variant &userData); Variant getUserData() const; -protected: - explicit Content(ContentPrivate &p); + static SalBodyHandler *getBodyHandlerFromContent(const Content &content, bool parseMultipart = true); +protected: bool isFileEncrypted(const std::string &filePath) const; const std::string exportPlainFileFromEncryptedFile(const std::string &filePath) const; private: - L_DECLARE_PRIVATE(Content); + std::vector<char> mBody; + ContentType mContentType; + ContentDisposition mContentDisposition; + std::string mContentEncoding; + std::list<Header> mHeaders; + + void *mCryptoContext = nullptr; // Used to encrypt file for RCS file transfer. + bool mIsDirty = false; + SalBodyHandler *mBodyHandler = nullptr; + + struct Cache { + std::string name; + std::string buffer; + std::string filePath; + std::string headerValue; + } mutable mCache; + mutable size_t mSize = 0; }; LINPHONE_END_NAMESPACE diff --git a/src/content/file-content.cpp b/src/content/file-content.cpp index d25ce2bfec36a85fce463441b4017a3b621be83a..ba1a6dd35b2ffa21ce1d6c3a7ba0f1108a0ae8c0 100644 --- a/src/content/file-content.cpp +++ b/src/content/file-content.cpp @@ -18,15 +18,14 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -// TODO: Remove me later. -#include "linphone/core.h" -#include "linphone/utils/utils.h" - -#include "bctoolbox/charconv.h" -#include "content-p.h" #include "file-content.h" + #include <algorithm> +#include "bctoolbox/charconv.h" + +#include "linphone/utils/utils.h" + // ============================================================================= using namespace std; @@ -35,81 +34,59 @@ LINPHONE_BEGIN_NAMESPACE // ----------------------------------------------------------------------------- -class FileContentPrivate : public ContentPrivate { -public: - string fileName; - string filePath; - size_t fileSize = 0; - int fileDuration = 0; -}; - -// ----------------------------------------------------------------------------- - -FileContent::FileContent() : Content(*new FileContentPrivate) { -} - -FileContent::FileContent(const FileContent &other) : Content(*new FileContentPrivate) { - L_D(); +FileContent::FileContent(const FileContent &other) : Content(other) { Content::copy(other); setFileName(other.getFileName()); setFilePath(other.getFilePath()); - d->fileSize = other.getFileSize(); - d->fileDuration = other.getFileDuration(); + mFileSize = other.getFileSize(); + mFileDuration = other.getFileDuration(); } -FileContent::FileContent(FileContent &&other) : Content(*new FileContentPrivate) { - L_D(); +FileContent::FileContent(FileContent &&other) noexcept : Content(other) { Content::copy(other); - d->fileName = std::move(other.getPrivate()->fileName); - d->filePath = std::move(other.getPrivate()->filePath); - d->fileSize = std::move(other.getPrivate()->fileSize); - d->fileDuration = std::move(other.getPrivate()->fileDuration); + mFileName = std::move(other.mFileName); + mFilePath = std::move(other.mFilePath); + mFileSize = std::move(other.mFileSize); + mFileDuration = std::move(other.mFileDuration); } FileContent &FileContent::operator=(const FileContent &other) { - L_D(); Content::operator=(other); setFileName(other.getFileName()); setFilePath(other.getFilePath()); - d->fileSize = other.getFileSize(); - d->fileDuration = other.getFileDuration(); + mFileSize = other.getFileSize(); + mFileDuration = other.getFileDuration(); return *this; } FileContent &FileContent::operator=(FileContent &&other) { - L_D(); Content::operator=(std::move(other)); - d->fileName = std::move(other.getPrivate()->fileName); - d->filePath = std::move(other.getPrivate()->filePath); - d->fileSize = std::move(other.getPrivate()->fileSize); - d->fileDuration = std::move(other.getPrivate()->fileDuration); + mFileName = std::move(other.mFileName); + mFilePath = std::move(other.mFilePath); + mFileSize = std::move(other.mFileSize); + mFileDuration = std::move(other.mFileDuration); return *this; } bool FileContent::operator==(const FileContent &other) const { - L_D(); return Content::operator==(other) && getFileName() == other.getFileName() && getFilePath() == other.getFilePath() && - d->fileSize == other.getFileSize() && d->fileDuration == other.getFileDuration(); + mFileSize == other.getFileSize() && mFileDuration == other.getFileDuration(); } void FileContent::setFileSize(size_t size) { - L_D(); - d->fileSize = size; + mFileSize = size; } size_t FileContent::getFileSize() const { - L_D(); - return d->fileSize; + return mFileSize; } void FileContent::setFileName(const string &name) { - L_D(); - d->fileName = Utils::normalizeFilename(name); + mFileName = Utils::normalizeFilename(name); } const string &FileContent::getFileName() const { - L_D(); - return d->fileName; + return mFileName; } void FileContent::setFileNameSys(const string &name) { @@ -129,13 +106,11 @@ string FileContent::getFileNameUtf8() const { } void FileContent::setFilePath(const string &path) { - L_D(); - d->filePath = path; + mFilePath = path; } const string &FileContent::getFilePath() const { - L_D(); - return d->filePath; + return mFilePath; } void FileContent::setFilePathSys(const string &path) { @@ -155,13 +130,11 @@ string FileContent::getFilePathUtf8() const { } void FileContent::setFileDuration(int durationInSeconds) { - L_D(); - d->fileDuration = durationInSeconds; + mFileDuration = durationInSeconds; } int FileContent::getFileDuration() const { - L_D(); - return d->fileDuration; + return mFileDuration; } bool FileContent::isFile() const { diff --git a/src/content/file-content.h b/src/content/file-content.h index a7562c324707a62a87009afd0f6c972fc9d91f34..8b8ac26dc562649da263293b3a85db5cbdc18e80 100644 --- a/src/content/file-content.h +++ b/src/content/file-content.h @@ -27,13 +27,11 @@ LINPHONE_BEGIN_NAMESPACE -class FileContentPrivate; - class LINPHONE_PUBLIC FileContent : public Content { public: - FileContent(); + FileContent() = default; FileContent(const FileContent &other); - FileContent(FileContent &&other); + FileContent(FileContent &&other) noexcept; FileContent *clone() const override { return new FileContent(*this); @@ -56,8 +54,8 @@ public: void setFileNameUtf8(const std::string &name); // UTF8 std::string getFileNameUtf8() const; - void setFilePath(const std::string &path); // App Locale - const std::string &getFilePath() const; + void setFilePath(const std::string &path) override; // App Locale + const std::string &getFilePath() const override; void setFilePathSys(const std::string &path); // System Locale std::string getFilePathSys() const; @@ -80,7 +78,10 @@ public: const std::string exportPlainFile() const; private: - L_DECLARE_PRIVATE(FileContent); + std::string mFileName; + std::string mFilePath; + size_t mFileSize = 0; + int mFileDuration = 0; }; LINPHONE_END_NAMESPACE diff --git a/src/content/file-transfer-content.cpp b/src/content/file-transfer-content.cpp index d9f2bf5acdc42058f3c4afc765abde69d0d321bc..a563a2625c5efb2c4c6d160a82a3b2d15bd66067 100644 --- a/src/content/file-transfer-content.cpp +++ b/src/content/file-transfer-content.cpp @@ -18,17 +18,14 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -// TODO: Remove me later. -#include "linphone/core.h" -#include "linphone/utils/utils.h" - -#include "bctoolbox/charconv.h" -#include "bctoolbox/crypto.h" -#include "content-p.h" #include "file-transfer-content.h" #include <algorithm> +#include "bctoolbox/charconv.h" + +#include "linphone/utils/utils.h" + // ============================================================================= using namespace std; @@ -37,107 +34,80 @@ LINPHONE_BEGIN_NAMESPACE // ----------------------------------------------------------------------------- -class FileTransferContentPrivate : public ContentPrivate { -public: - string fileName; - string fileUrl; - string filePath; - FileContent *fileContent = nullptr; - size_t fileSize = 0; - int fileDuration = 0; - std::vector<char> fileKey; - std::vector<char> fileAuthTag; - ContentType fileContentType; - ~FileTransferContentPrivate() { - if (!fileKey.empty()) { - bctbx_clean(fileKey.data(), fileKey.size()); - } - }; -}; - -// ----------------------------------------------------------------------------- - -FileTransferContent::FileTransferContent() : Content(*new FileTransferContentPrivate) { +FileTransferContent::FileTransferContent() { setContentType(ContentType::FileTransfer); } -FileTransferContent::FileTransferContent(const FileTransferContent &other) : Content(*new FileTransferContentPrivate) { - L_D(); +FileTransferContent::FileTransferContent(const FileTransferContent &other) : Content(other) { Content::copy(other); setFileName(other.getFileName()); setFilePath(other.getFilePath()); - d->fileUrl = other.getFileUrl(); - d->fileContent = other.getFileContent(); - d->fileSize = other.getFileSize(); - d->fileKey = other.getFileKey(); - d->fileAuthTag = other.getFileAuthTag(); - d->fileContentType = other.getFileContentType(); - d->fileDuration = other.getFileDuration(); + mFileUrl = other.getFileUrl(); + mFileContent = other.getFileContent(); + mFileSize = other.getFileSize(); + mFileKey = other.getFileKey(); + mFileAuthTag = other.getFileAuthTag(); + mFileContentType = other.getFileContentType(); + mFileDuration = other.getFileDuration(); } -FileTransferContent::FileTransferContent(FileTransferContent &&other) : Content(*new FileTransferContentPrivate) { - L_D(); +FileTransferContent::FileTransferContent(FileTransferContent &&other) : Content(other) { Content::copy(other); - d->fileName = std::move(other.getPrivate()->fileName); - d->fileUrl = std::move(other.getPrivate()->fileUrl); - d->filePath = std::move(other.getPrivate()->filePath); - d->fileContent = std::move(other.getPrivate()->fileContent); - d->fileSize = std::move(other.getPrivate()->fileSize); - d->fileKey = std::move(other.getPrivate()->fileKey); - d->fileAuthTag = std::move(other.getPrivate()->fileAuthTag); - d->fileContentType = std::move(other.getPrivate()->fileContentType); - d->fileDuration = std::move(other.getPrivate()->fileDuration); + mFileName = std::move(other.mFileName); + mFileUrl = std::move(other.mFileUrl); + mFilePath = std::move(other.mFilePath); + mFileContent = std::move(other.mFileContent); + mFileSize = std::move(other.mFileSize); + mFileKey = std::move(other.mFileKey); + mFileAuthTag = std::move(other.mFileAuthTag); + mFileContentType = std::move(other.mFileContentType); + mFileDuration = std::move(other.mFileDuration); } FileTransferContent &FileTransferContent::operator=(const FileTransferContent &other) { - L_D(); if (this != &other) { Content::operator=(other); setFileName(other.getFileName()); setFilePath(other.getFilePath()); - d->fileUrl = other.getFileUrl(); - d->fileContent = other.getFileContent(); - d->fileSize = other.getFileSize(); - d->fileKey = other.getFileKey(); - d->fileAuthTag = other.getFileAuthTag(); - d->fileContentType = other.getFileContentType(); - d->fileDuration = other.getFileDuration(); + mFileUrl = other.getFileUrl(); + mFileContent = other.getFileContent(); + mFileSize = other.getFileSize(); + mFileKey = other.getFileKey(); + mFileAuthTag = other.getFileAuthTag(); + mFileContentType = other.getFileContentType(); + mFileDuration = other.getFileDuration(); } return *this; } FileTransferContent &FileTransferContent::operator=(FileTransferContent &&other) { - L_D(); Content::operator=(std::move(other)); - d->fileName = std::move(other.getPrivate()->fileName); - d->fileUrl = std::move(other.getPrivate()->fileUrl); - d->filePath = std::move(other.getPrivate()->filePath); - d->fileContent = std::move(other.getPrivate()->fileContent); - d->fileSize = std::move(other.getPrivate()->fileSize); - d->fileKey = std::move(other.getPrivate()->fileKey); - d->fileAuthTag = std::move(other.getPrivate()->fileAuthTag); - d->fileContentType = std::move(other.getPrivate()->fileContentType); - d->fileDuration = std::move(other.getPrivate()->fileDuration); + mFileName = std::move(other.mFileName); + mFileUrl = std::move(other.mFileUrl); + mFilePath = std::move(other.mFilePath); + mFileContent = std::move(other.mFileContent); + mFileSize = std::move(other.mFileSize); + mFileKey = std::move(other.mFileKey); + mFileAuthTag = std::move(other.mFileAuthTag); + mFileContentType = std::move(other.mFileContentType); + mFileDuration = std::move(other.mFileDuration); return *this; } bool FileTransferContent::operator==(const FileTransferContent &other) const { - L_D(); - return Content::operator==(other) && getFileName() == other.getFileName() && d->fileUrl == other.getFileUrl() && - getFilePath() == other.getFilePath() && d->fileSize == other.getFileSize() && - d->fileContentType == other.getFileContentType() && d->fileDuration == other.getFileDuration(); + return Content::operator==(other) && getFileName() == other.getFileName() && mFileUrl == other.getFileUrl() && + getFilePath() == other.getFilePath() && mFileSize == other.getFileSize() && + mFileContentType == other.getFileContentType() && mFileDuration == other.getFileDuration(); } void FileTransferContent::setFileName(const string &name) { - L_D(); - d->fileName = Utils::normalizeFilename(name); + mFileName = Utils::normalizeFilename(name); } const string &FileTransferContent::getFileName() const { - L_D(); - return d->fileName; + return mFileName; } void FileTransferContent::setFileNameSys(const string &name) { @@ -157,23 +127,19 @@ string FileTransferContent::getFileNameUtf8() const { } void FileTransferContent::setFileUrl(const string &url) { - L_D(); - d->fileUrl = url; + mFileUrl = url; } const string &FileTransferContent::getFileUrl() const { - L_D(); - return d->fileUrl; + return mFileUrl; } void FileTransferContent::setFilePath(const string &path) { - L_D(); - d->filePath = path; + mFilePath = path; } const string &FileTransferContent::getFilePath() const { - L_D(); - return d->filePath; + return mFilePath; } void FileTransferContent::setFilePathSys(const string &path) { @@ -192,74 +158,60 @@ string FileTransferContent::getFilePathUtf8() const { return Utils::localeToUtf8(getFilePath()); } -void FileTransferContent::setFileContent(FileContent *content) { - L_D(); - d->fileContent = content; +void FileTransferContent::setFileContent(std::shared_ptr<FileContent> content) { + mFileContent = content; } -FileContent *FileTransferContent::getFileContent() const { - L_D(); - return d->fileContent; +std::shared_ptr<FileContent> FileTransferContent::getFileContent() const { + return mFileContent; } void FileTransferContent::setFileSize(size_t size) { - L_D(); - d->fileSize = size; + mFileSize = size; } size_t FileTransferContent::getFileSize() const { - L_D(); - return d->fileSize; + return mFileSize; } void FileTransferContent::setFileDuration(int durationInSeconds) { - L_D(); - d->fileDuration = durationInSeconds; + mFileDuration = durationInSeconds; } int FileTransferContent::getFileDuration() const { - L_D(); - return d->fileDuration; + return mFileDuration; } void FileTransferContent::setFileKey(const char *key, size_t size) { - L_D(); - d->fileKey = vector<char>(key, key + size); + mFileKey = vector<char>(key, key + size); } const vector<char> &FileTransferContent::getFileKey() const { - L_D(); - return d->fileKey; + return mFileKey; } size_t FileTransferContent::getFileKeySize() const { - L_D(); - return d->fileKey.size(); + return mFileKey.size(); } void FileTransferContent::setFileAuthTag(const char *tag, size_t size) { - L_D(); - d->fileAuthTag = vector<char>(tag, tag + size); + mFileAuthTag = vector<char>(tag, tag + size); } const vector<char> &FileTransferContent::getFileAuthTag() const { - L_D(); - return d->fileAuthTag; + return mFileAuthTag; } size_t FileTransferContent::getFileAuthTagSize() const { - L_D(); - return d->fileAuthTag.size(); + return mFileAuthTag.size(); } void FileTransferContent::setFileContentType(const ContentType &contentType) { - L_D(); - d->fileContentType = contentType; + mFileContentType = contentType; } const ContentType &FileTransferContent::getFileContentType() const { - L_D(); - return d->fileContentType; + return mFileContentType; } bool FileTransferContent::isFile() const { diff --git a/src/content/file-transfer-content.h b/src/content/file-transfer-content.h index aed8511b026ba2de7c27d4a83b2e000d248d7a47..c41bbe49d3b9aeb348c00fcff076d8f42c4fff4e 100644 --- a/src/content/file-transfer-content.h +++ b/src/content/file-transfer-content.h @@ -23,6 +23,8 @@ #include <vector> +#include "bctoolbox/crypto.h" + #include "content.h" // ============================================================================= @@ -30,7 +32,7 @@ LINPHONE_BEGIN_NAMESPACE class FileContent; -class FileTransferContentPrivate; +class ContentType; class LINPHONE_PUBLIC FileTransferContent : public Content { public: @@ -59,8 +61,8 @@ public: void setFileUrl(const std::string &url); const std::string &getFileUrl() const; - void setFilePath(const std::string &path); // App Locale - const std::string &getFilePath() const; + void setFilePath(const std::string &path) override; // App Locale + const std::string &getFilePath() const override; void setFilePathSys(const std::string &path); // System Locale std::string getFilePathSys() const; @@ -68,8 +70,8 @@ public: void setFilePathUtf8(const std::string &path); // UTF8 std::string getFilePathUtf8() const; - void setFileContent(FileContent *content); - FileContent *getFileContent() const; + void setFileContent(std::shared_ptr<FileContent> content); + std::shared_ptr<FileContent> getFileContent() const; void setFileSize(size_t size); size_t getFileSize() const; @@ -94,8 +96,23 @@ public: bool isEncrypted() const; const std::string exportPlainFile() const; +protected: + ~FileTransferContent() { + if (!mFileKey.empty()) { + bctbx_clean(mFileKey.data(), mFileKey.size()); + } + }; + private: - L_DECLARE_PRIVATE(FileTransferContent); + std::string mFileName; + std::string mFileUrl; + std::string mFilePath; + std::shared_ptr<FileContent> mFileContent = nullptr; + size_t mFileSize = 0; + int mFileDuration = 0; + std::vector<char> mFileKey; + std::vector<char> mFileAuthTag; + ContentType mFileContentType; }; LINPHONE_END_NAMESPACE diff --git a/src/core/core-chat-room.cpp b/src/core/core-chat-room.cpp index 8a0f78009518e6bc84129d1aef276533fafa553e..b664b2b0bf0e48421b02eccc1709ad2b18e632f1 100644 --- a/src/core/core-chat-room.cpp +++ b/src/core/core-chat-room.cpp @@ -700,10 +700,10 @@ list<shared_ptr<AbstractChatRoom>> Core::getChatRooms() const { } if (hideChatRoomsFromRemovedProxyConfig) { - const bctbx_list_t *it; + const bctbx_list_t *it2; bool found = false; - for (it = linphone_core_get_proxy_config_list(lc); it != NULL; it = it->next) { - LinphoneProxyConfig *cfg = (LinphoneProxyConfig *)it->data; + for (it2 = linphone_core_get_proxy_config_list(lc); it2 != nullptr; it2 = it2->next) { + auto cfg = (LinphoneProxyConfig *)it2->data; const LinphoneAddress *identityAddr = linphone_proxy_config_get_identity_address(cfg); auto localAddress = Address::toCpp(const_cast<LinphoneAddress *>(identityAddr))->getSharedFromThis(); if (localAddress->weakEqual(*chatRoom->getLocalAddress())) { diff --git a/src/core/core.cpp b/src/core/core.cpp index 2bb5c2128cce318cb6df3917b9f950307cb94e8e..7b8f70b85bc485fabe864b1f23f75a279bc05a1f 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -344,8 +344,11 @@ void CorePrivate::shutdown() { void CorePrivate::uninit() { L_Q(); - if (q->limeX3dhEnabled()) { - q->enableLimeX3dh(false); + // If we have an encryption engine, destroy it. + if (imee != nullptr) { + auto listener = dynamic_cast<CoreListener *>(q->getEncryptionEngine()); + if (listener) unregisterListener(listener); + imee.reset(); } const list<shared_ptr<AbstractChatRoom>> chatRooms = q->getChatRooms(); @@ -1804,12 +1807,12 @@ shared_ptr<CallSession> Core::createOrUpdateConferenceOnServer(const std::shared addressesList.unique(); if (!addressesList.empty()) { - Content content; - content.setBodyFromUtf8(Utils::getResourceLists(addressesList)); - content.setContentType(ContentType::ResourceLists); - content.setContentDisposition(ContentDisposition::RecipientList); + auto content = Content::create(); + content->setBodyFromUtf8(Utils::getResourceLists(addressesList)); + content->setContentType(ContentType::ResourceLists); + content->setContentDisposition(ContentDisposition::RecipientList); if (linphone_core_content_encoding_supported(lc, "deflate")) { - content.setContentEncoding("deflate"); + content->setContentEncoding("deflate"); } L_GET_CPP_PTR_FROM_C_OBJECT(params)->addCustomContent(content); diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index 371ac81d796d56f082155cf515758352fe0d7e60..9668184ea16c4bb441349058239e2003701b2dd0 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -350,10 +350,11 @@ void MainDbPrivate::insertContent(long long chatMessageId, const Content &conten soci::use(chatMessageContentId), soci::use(name), soci::use(size), soci::use(path), soci::use(duration); } - for (const auto &appData : content.getAppDataMap()) + for (const auto &property : content.getProperties()) { *session << "INSERT INTO chat_message_content_app_data (chat_message_content_id, name, data) VALUES" " (:chatMessageContentId, :name, :data)", - soci::use(chatMessageContentId), soci::use(appData.first), soci::use(appData.second); + soci::use(chatMessageContentId), soci::use(property.first), soci::use(property.second.getValue<string>()); + } #endif } @@ -1386,7 +1387,7 @@ long long MainDbPrivate::insertConferenceChatMessageEvent(const shared_ptr<Event soci::use(eventId), soci::use(ephemeralLifetime), soci::use(expireTime.first); } - for (const Content *content : chatMessage->getContents()) + for (const auto &content : chatMessage->getContents()) insertContent(eventId, *content); shared_ptr<AbstractChatRoom> chatRoom(chatMessage->getChatRoom()); @@ -2783,7 +2784,7 @@ void MainDbPrivate::importLegacyHistory(DbSession &inDbSession) { const string &text = getValueFromRow<string>(message, LegacyMessageColText, isNull); - unique_ptr<Content> content; + shared_ptr<Content> content; if (contentType == ContentType::FileTransfer) { const string appData = getValueFromRow<string>(message, LegacyMessageColAppData, isNull); if (isNull) { @@ -2797,12 +2798,12 @@ void MainDbPrivate::importLegacyHistory(DbSession &inDbSession) { continue; } ContentType fileContentType(contentTypeString); - content.reset(new FileContent()); + content = FileContent::create<FileContent>(); content->setContentType(fileContentType); - content->setAppData("legacy", appData); + content->setProperty("legacy", Variant{appData}); content->setBodyFromLocale(text); } else { - content.reset(new Content()); + content = Content::create(); content->setContentType(contentType); if (contentType == ContentType::PlainText) { if (isNull) { @@ -4747,7 +4748,7 @@ static void fetchContentAppData(soci::session *session, Content &content, long l soci::statement statement = (session->prepare << query, soci::use(contentId), soci::into(name), soci::into(data)); statement.execute(); while (statement.fetch()) - content.setAppData(name, blobToString(data)); + content.setProperty(name, Variant{blobToString(data)}); } #endif @@ -4771,14 +4772,14 @@ void MainDb::loadChatMessageContents(const shared_ptr<ChatMessage> &chatMessage) for (const auto &row : rows) { ContentType contentType(row.get<string>(2)); const long long &contentId = d->dbSession.resolveId(row, 0); - Content *content; + shared_ptr<Content> content; int bodyEncodingType = row.get<int>(4); if (contentType == ContentType::FileTransfer) { hasFileTransferContent = true; - content = new FileTransferContent(); + content = FileTransferContent::create<FileTransferContent>(); } else { - // 1.1 - Fetch contents' file informations if they exist + // 1.1 - Fetch contents' file information if they exist string name; int size; string path; @@ -4788,14 +4789,14 @@ void MainDb::loadChatMessageContents(const shared_ptr<ChatMessage> &chatMessage) " WHERE chat_message_content_id = :contentId", soci::into(name), soci::into(size), soci::into(path), soci::into(duration), soci::use(contentId); if (session->got_data()) { - FileContent *fileContent = new FileContent(); + auto fileContent = FileContent::create<FileContent>(); fileContent->setFileName(name); fileContent->setFileSize(size_t(size)); fileContent->setFilePath(path); fileContent->setFileDuration(duration); content = fileContent; } else { - content = new Content(); + content = Content::create(); } } diff --git a/src/factory/factory.cpp b/src/factory/factory.cpp index b82652c8a3981888147cff80f4c98a7b3b25cdd3..22e89a390bd81ed78c419fd505aace9b53bf492f 100644 --- a/src/factory/factory.cpp +++ b/src/factory/factory.cpp @@ -573,10 +573,10 @@ LinphoneContent *Factory::createContent() const { LinphoneContent *Factory::createContentFromFile(const std::string &file_path) const { std::string file_name = file_path.substr(file_path.find_last_of("/\\") + 1); - FileContent *content = new FileContent(); - content->setFilePath(file_path); - content->setFileName(file_name); - return L_GET_C_BACK_PTR(dynamic_cast<Content *>(content)); + auto content = FileContent::createCObject<FileContent>(); + linphone_content_set_file_path(content, file_path.c_str()); + linphone_content_set_name(content, file_name.c_str()); + return content; } LinphoneBuffer *Factory::createBuffer() const { @@ -774,7 +774,7 @@ std::shared_ptr<ConferenceInfo> Factory::createConferenceInfo() const { #endif // _MSC_VER std::shared_ptr<ConferenceInfo> Factory::createConferenceInfoFromIcalendarContent(LinphoneContent *content) const { #ifdef HAVE_ADVANCED_IM - LinphonePrivate::ContentType contentType = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType(); + LinphonePrivate::ContentType contentType = Content::toCpp(content)->getContentType(); if (!contentType.strongEqual(ContentType::Icalendar)) return nullptr; std::string filepath = ""; diff --git a/src/object/app-data-container.cpp b/src/object/app-data-container.cpp deleted file mode 100644 index 9a8eea95a724a2dd4852090ef32113708e6f679a..0000000000000000000000000000000000000000 --- a/src/object/app-data-container.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2010-2022 Belledonne Communications SARL. - * - * This file is part of Liblinphone - * (see https://gitlab.linphone.org/BC/public/liblinphone). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "linphone/utils/utils.h" - -#include "app-data-container.h" - -// ============================================================================= - -using namespace std; - -LINPHONE_BEGIN_NAMESPACE - -// ----------------------------------------------------------------------------- - -class AppDataContainerPrivate { -public: - shared_ptr<unordered_map<string, string>> appData; -}; - -// ----------------------------------------------------------------------------- - -AppDataContainer::AppDataContainer() : mPrivate(new AppDataContainerPrivate) { - L_D(); - d->appData = make_shared<unordered_map<string, string>>(); -} - -AppDataContainer::AppDataContainer(const AppDataContainer &other) : mPrivate(new AppDataContainerPrivate) { - L_D(); - d->appData = other.getPrivate()->appData; -} - -AppDataContainer::~AppDataContainer() { - delete mPrivate; -} - -AppDataContainer &AppDataContainer::operator=(const AppDataContainer &other) { - L_D(); - if (this != &other) d->appData = other.getPrivate()->appData; - return *this; -} - -const unordered_map<string, string> &AppDataContainer::getAppDataMap() const { - L_D(); - return *d->appData.get(); -} - -const string &AppDataContainer::getAppData(const string &name) const { - L_D(); - auto it = d->appData->find(name); - return it == d->appData->cend() ? Utils::getEmptyConstRefObject<string>() : it->second; -} - -void AppDataContainer::setAppData(const string &name, const string &appData) { - L_D(); - (*d->appData)[name] = appData; -} - -void AppDataContainer::setAppData(const string &name, string &&appData) { - L_D(); - (*d->appData)[name] = std::move(appData); -} - -LINPHONE_END_NAMESPACE diff --git a/src/object/app-data-container.h b/src/object/app-data-container.h deleted file mode 100644 index 45f5d52ffc54dbb155dba4f9690921447b5b19ec..0000000000000000000000000000000000000000 --- a/src/object/app-data-container.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2010-2022 Belledonne Communications SARL. - * - * This file is part of Liblinphone - * (see https://gitlab.linphone.org/BC/public/liblinphone). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _L_APP_DATA_CONTAINER_H_ -#define _L_APP_DATA_CONTAINER_H_ - -#include <string> -#include <unordered_map> - -#include "linphone/utils/general.h" - -// ============================================================================= - -LINPHONE_BEGIN_NAMESPACE - -class AppDataContainerPrivate; - -class LINPHONE_PUBLIC AppDataContainer { -public: - AppDataContainer(); - AppDataContainer(const AppDataContainer &other); - virtual ~AppDataContainer(); - - AppDataContainer &operator=(const AppDataContainer &other); - - const std::unordered_map<std::string, std::string> &getAppDataMap() const; - - const std::string &getAppData(const std::string &name) const; - void setAppData(const std::string &name, const std::string &appData); - void setAppData(const std::string &name, std::string &&appData); - -private: - AppDataContainerPrivate *mPrivate = nullptr; - - L_DECLARE_PRIVATE(AppDataContainer); -}; - -LINPHONE_END_NAMESPACE - -#endif // ifndef _L_APP_DATA_CONTAINER_H_ diff --git a/src/object/property-container.cpp b/src/object/property-container.cpp index b93d699f187a562632a72c34a583b14e86d205ad..92652d44bc3c7a3c86f0d11cc20029cdc5777962 100644 --- a/src/object/property-container.cpp +++ b/src/object/property-container.cpp @@ -18,10 +18,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <map> +#include "property-container.h" #include "bctoolbox/utils.hh" -#include "property-container.h" // ============================================================================= @@ -74,6 +73,11 @@ void PropertyContainer::setProperty(const string &name, Variant &&value) { mPrivate->properties[name] = std::move(value); } +const std::map<std::string, Variant> &PropertyContainer::getProperties() const { + if (!mPrivate) return bctoolbox::Utils::getEmptyConstRefObject<std::map<std::string, Variant>>(); + return mPrivate->properties; +} + int PropertyContainer::remove(const std::string &name) const { if (mPrivate) { auto it = mPrivate->properties.find(name); @@ -96,6 +100,7 @@ bool PropertyContainer::hasKey(const std::string &name) const { } return false; } + std::ostream &PropertyContainer::toStream(std::ostream &stream) const { for (const auto &p : mPrivate->properties) { stream << p.first << " : "; @@ -104,4 +109,5 @@ std::ostream &PropertyContainer::toStream(std::ostream &stream) const { } return stream; } + LINPHONE_END_NAMESPACE diff --git a/src/object/property-container.h b/src/object/property-container.h index eb9c6b0b9aac99cc59659c41481734f3119a22ad..60bf18c4cb1d065bd33d468405838ecbb90c9337 100644 --- a/src/object/property-container.h +++ b/src/object/property-container.h @@ -21,6 +21,8 @@ #ifndef _L_PROPERTY_CONTAINER_H_ #define _L_PROPERTY_CONTAINER_H_ +#include <map> + #include "variant/variant.h" // ============================================================================= @@ -41,6 +43,8 @@ public: void setProperty(const std::string &name, const Variant &value); void setProperty(const std::string &name, Variant &&value); + const std::map<std::string, Variant> &getProperties() const; + int remove(const std::string &name) const; void clear(); diff --git a/src/recorder/recorder.cpp b/src/recorder/recorder.cpp index 4f80688a180dce4723733264ded9b4c1c21fcd21..4c6e4e79398bbccc38195881d42d9b27c7b828c3 100644 --- a/src/recorder/recorder.cpp +++ b/src/recorder/recorder.cpp @@ -126,14 +126,14 @@ float Recorder::getCaptureVolume() const { return ms_media_recorder_get_capture_volume(mRecorder); } -FileContent *Recorder::createContent() const { +std::shared_ptr<FileContent> Recorder::createContent() const { LinphoneRecorderState currentState = getState(); if (currentState != LinphoneRecorderClosed) { lError() << "Cannot create Content from Recorder that isn't in Closed state, current state is " << currentState; return nullptr; } - FileContent *fileContent = new FileContent(); + auto fileContent = FileContent::create<FileContent>(); fileContent->setFilePath(mFilePath); fileContent->setContentType(ContentType::VoiceRecording); fileContent->setFileDuration(getDuration()); diff --git a/src/recorder/recorder.h b/src/recorder/recorder.h index 2055055e82b869cd8239ed941ef414edbd39f754..f121821f9498ce54ab192ecc4476a3c01cd1a873 100644 --- a/src/recorder/recorder.h +++ b/src/recorder/recorder.h @@ -54,7 +54,7 @@ public: LinphoneRecorderState getState() const; int getDuration() const; float getCaptureVolume() const; - FileContent *createContent() const; + std::shared_ptr<FileContent> createContent() const; void setParams(std::shared_ptr<RecorderParams> params); std::shared_ptr<const RecorderParams> getParams() const; diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index 314ca423155de67cd68da8a628b5cb6a2c8e75c0..4ebd0fdd2e6f9061291a655374362921b604d395 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -60,7 +60,9 @@ bool Utils::iequals(const string &a, const string &b) { #ifndef __ANDROID__ #define TO_STRING_IMPL(TYPE) \ - string Utils::toString(TYPE val) { return to_string(val); } + string Utils::toString(TYPE val) { \ + return to_string(val); \ + } #else #define TO_STRING_IMPL(TYPE) \ string Utils::toString(TYPE val) { \ @@ -91,7 +93,9 @@ string Utils::toString(const void *val) { // ----------------------------------------------------------------------------- #define STRING_TO_NUMBER_IMPL(TYPE, SUFFIX) \ - TYPE Utils::sto##SUFFIX(const string &str, size_t *idx, int base) { return sto##SUFFIX(str.c_str(), idx, base); } \ + TYPE Utils::sto##SUFFIX(const string &str, size_t *idx, int base) { \ + return sto##SUFFIX(str.c_str(), idx, base); \ + } \ TYPE Utils::sto##SUFFIX(const char *str, size_t *idx, int base) { \ char *p; \ TYPE v = strto##SUFFIX(str, &p, base); \ @@ -100,7 +104,9 @@ string Utils::toString(const void *val) { } #define STRING_TO_NUMBER_IMPL_BASE_LESS(TYPE, SUFFIX) \ - TYPE Utils::sto##SUFFIX(const string &str, size_t *idx) { return sto##SUFFIX(str.c_str(), idx); } \ + TYPE Utils::sto##SUFFIX(const string &str, size_t *idx) { \ + return sto##SUFFIX(str.c_str(), idx); \ + } \ TYPE Utils::sto##SUFFIX(const char *str, size_t *idx) { \ char *p; \ TYPE v = strto##SUFFIX(str, &p); \ diff --git a/src/variant/variant.h b/src/variant/variant.h index 37e171118a315f84b717d21b54831f4517a5907f..3dcc34dd26beaa81e9f7dda5c6c904bb91526b70 100644 --- a/src/variant/variant.h +++ b/src/variant/variant.h @@ -75,7 +75,7 @@ public: return bctoolbox::Utils::getEmptyConstRefObject<T>(); } - bool isValid() { + bool isValid() const { return mImplBase != nullptr; } std::ostream &toStream(std::ostream &stream) const { diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 0a15189419cb6592bfd44d4299d704faf4fd081e..af55b28f27394a7f1f899c065dc22aa13cccd3fb 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -4883,7 +4883,7 @@ void record_call(const char *filename, bool_t enableVideo, const char *video_cod LinphoneCallParams *marieParams = NULL; LinphoneCallParams *paulineParams = NULL; LinphoneCall *callInst = NULL; - const char **formats, *format; + const char **formats, *file_format; char *filepath; int dummy = 0, i; bool_t call_succeeded = FALSE; @@ -4932,8 +4932,8 @@ void record_call(const char *filename, bool_t enableVideo, const char *video_cod formats = linphone_core_get_supported_file_formats(marie->lc); - for (i = 0, format = formats[0]; format != NULL; i++, format = formats[i]) { - char *totalname = ms_strdup_printf("%s.%s", filename, format); + for (i = 0, file_format = formats[0]; file_format != NULL; i++, file_format = formats[i]) { + char *totalname = ms_strdup_printf("%s.%s", filename, file_format); filepath = bc_tester_file(totalname); ms_free(totalname); remove(filepath); @@ -4946,7 +4946,7 @@ void record_call(const char *filename, bool_t enableVideo, const char *video_cod ms_message("call_recording(): start recording into %s", filepath); linphone_call_start_recording(callInst); } - if (strcmp(format, "mkv") == 0 && enableVideo) { + if (strcmp(file_format, "mkv") == 0 && enableVideo) { VideoStream *pauline_vstream = (VideoStream *)linphone_call_get_stream(pauline_call, LinphoneStreamTypeVideo); /* make sure that Pauline receives a RTCP FIR (Full Intra Request) requested by Marie's recorder.*/ diff --git a/tester/conference-event-tester.cpp b/tester/conference-event-tester.cpp index f51ca3e651f8effc388c9f685f6e1b1c32a017ed..aa4c874bee3f17f97098e3e3c92905616828d854 100644 --- a/tester/conference-event-tester.cpp +++ b/tester/conference-event-tester.cpp @@ -1441,11 +1441,11 @@ void send_first_notify() { LocalConferenceEventHandler *localHandler = (L_ATTR_GET(localConf.get(), eventHandler)).get(); localConf->setConferenceAddress(addr); - Content content = localHandler->createNotifyFullState(NULL); + auto content = localHandler->createNotifyFullState(NULL); const_cast<ConferenceId &>(tester->handler->getConferenceId()).setPeerAddress(addr); - tester->handler->notifyReceived(content); + tester->handler->notifyReceived(*content); BC_ASSERT_STRING_EQUAL(tester->confSubject.c_str(), "A random test subject"); BC_ASSERT_EQUAL((int)tester->participants.size(), 2, int, "%d"); @@ -2367,11 +2367,11 @@ void one_to_one_keyword() { localConf->addParticipant(bobAddr); LocalConferenceEventHandler *localHandler = (L_ATTR_GET(localConf.get(), eventHandler)).get(); localConf->setConferenceAddress(addr); - Content content = localHandler->createNotifyFullState(NULL); + auto content = localHandler->createNotifyFullState(NULL); const_cast<ConferenceId &>(tester->handler->getConferenceId()).setPeerAddress(addr); - tester->handler->notifyReceived(content); + tester->handler->notifyReceived(*content); BC_ASSERT_EQUAL((int)tester->participantDevices.size(), 1, int, "%d"); BC_ASSERT_TRUE(tester->participantDevices.find(bobAddr->toString()) != tester->participantDevices.end()); diff --git a/tester/cpim-tester.cpp b/tester/cpim-tester.cpp index 9686b583e7577843a44fa4aabb26caf790133884..dba06afdd680e46820bd3c8fe2051261068e0180 100644 --- a/tester/cpim-tester.cpp +++ b/tester/cpim-tester.cpp @@ -286,7 +286,7 @@ static void cpim_chat_message_modifier_base(bool useMultipart) { shared_ptr<ChatMessage> marieMessage = marieRoom->createChatMessageFromUtf8("Hello CPIM"); if (useMultipart) { marieRoom->allowMultipart(true); - Content *content = new Content(); + auto content = Content::create(); content->setContentType(ContentType::PlainText); content->setBodyFromUtf8("Hello Part 2"); marieMessage->addContent(content); diff --git a/tester/main-db-tester.cpp b/tester/main-db-tester.cpp index e138ec49c184d33640789f4e77edfc0c4ecbcc66..dbc9867fa4679ab63201bdb5bbf5966eac7ab0ac 100644 --- a/tester/main-db-tester.cpp +++ b/tester/main-db-tester.cpp @@ -312,7 +312,7 @@ static void get_chat_rooms() { BC_ASSERT_PTR_NOT_NULL(lastMessage); BC_ASSERT_PTR_EQUAL(lastMessage, newMessage); mainDb.loadChatMessageContents(lastMessage); // Force read Database - for (const Content *content : lastMessage->getContents()) { + for (const auto &content : lastMessage->getContents()) { BC_ASSERT_EQUAL(content->getBodyAsUtf8String().compare(utf8Txt), 0, int, "%d"); } } @@ -346,7 +346,7 @@ static void get_chat_rooms() { BC_ASSERT_PTR_EQUAL(lastMessage, newMessage); BC_ASSERT_PTR_NOT_EQUAL(lastMessage, lastMessage2); mainDb.loadChatMessageContents(lastMessage); // Force read Database - for (const Content *content : lastMessage->getContents()) { + for (const auto &content : lastMessage->getContents()) { BC_ASSERT_EQUAL(content->getBodyAsUtf8String().compare(utf8Txt), 0, int, "%d"); } } diff --git a/tester/message_tester.c b/tester/message_tester.c index ccf7be1e3ce7f0261a72d102fc5f4cf8a386e263..46adba8750be337ac59ef4f232fccabc81554dec 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -411,60 +411,6 @@ void text_message_base_with_text_and_forward(LinphoneCoreManager *marie, linphone_chat_message_unref(msg); } -void check_reactions(LinphoneChatMessage *message, - size_t expected_reactions_count, - const bctbx_list_t *expected_reactions, - const bctbx_list_t *expected_reactions_from) { - bctbx_list_t *reactions = linphone_chat_message_get_reactions(message); - bctbx_list_t *reactions_it = reactions; - bctbx_list_t *expected_reactions_it = (bctbx_list_t *)expected_reactions; - bctbx_list_t *expected_reactions_from_it = (bctbx_list_t *)expected_reactions_from; - BC_ASSERT_PTR_NOT_NULL(reactions); - - if (reactions_it) { - size_t count = bctbx_list_size(reactions); - BC_ASSERT_EQUAL(count, expected_reactions_count, size_t, "%zu"); - for (size_t i = 0; i < count; i++) { - const LinphoneChatMessageReaction *reaction = - (const LinphoneChatMessageReaction *)bctbx_list_get_data(reactions_it); - reactions_it = bctbx_list_next(reactions_it); - - const char *expected_reaction = (const char *)bctbx_list_get_data(expected_reactions_it); - expected_reactions_it = bctbx_list_next(expected_reactions_it); - - const char *expected_reaction_from = (const char *)bctbx_list_get_data(expected_reactions_from_it); - expected_reactions_from_it = bctbx_list_next(expected_reactions_from_it); - - const char *reaction_body = linphone_chat_message_reaction_get_body(reaction); - BC_ASSERT_STRING_EQUAL(reaction_body, expected_reaction); - - const LinphoneAddress *from = linphone_chat_message_reaction_get_from_address(reaction); - char *address_as_string = linphone_address_as_string_uri_only(from); - BC_ASSERT_STRING_EQUAL(address_as_string, expected_reaction_from); - bctbx_free(address_as_string); - } - } - bctbx_list_free_with_data(reactions, (bctbx_list_free_func)linphone_chat_message_reaction_unref); -} - -void liblinphone_tester_chat_message_reaction_received(LinphoneChatMessage *msg, - const LinphoneChatMessageReaction *reaction) { - BC_ASSERT_PTR_NOT_NULL(msg); - BC_ASSERT_PTR_NOT_NULL(reaction); - - const LinphoneAddress *address = linphone_chat_message_reaction_get_from_address(reaction); - BC_ASSERT_PTR_NOT_NULL(address); - const char *body = linphone_chat_message_reaction_get_body(reaction); - BC_ASSERT_STRING_EQUAL(body, "ðŸ‘"); - - bctbx_list_t *expected_reaction = bctbx_list_append(NULL, "ðŸ‘"); - bctbx_list_t *expected_reaction_from = - bctbx_list_append(NULL, ms_strdup(linphone_address_as_string_uri_only(address))); - check_reactions(msg, 1, expected_reaction, expected_reaction_from); - bctbx_list_free(expected_reaction); - bctbx_list_free_with_data(expected_reaction_from, (bctbx_list_free_func)ms_free); -} - void text_message_base_with_text(LinphoneCoreManager *marie, LinphoneCoreManager *pauline, const char *text, diff --git a/tester/multipart-tester.cpp b/tester/multipart-tester.cpp index e8fce5ae7b8f29f8ce87d22464183fc19a5786c8..61f349f8419dd1139fc0d93a0ff2f2cf63389141 100644 --- a/tester/multipart-tester.cpp +++ b/tester/multipart-tester.cpp @@ -155,14 +155,14 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, shared_ptr<ChatMessage> marieMessage = marieRoom->createChatMessage(); if (first_file_transfer) { char *send_filepath = bc_tester_res("sounds/sintel_trailer_opus_h264.mkv"); - FileContent *content = new FileContent(); + auto content = FileContent::create<FileContent>(); content->setContentType(ContentType("video/mkv")); content->setFilePath(send_filepath); content->setFileName("sintel_trailer_opus_h264.mkv"); marieMessage->addContent(content); bc_free(send_filepath); } else { - Content *content = new Content(); + auto content = Content::create(); content->setContentType(ContentType::PlainText); content->setBodyFromUtf8("Hello part 1"); marieMessage->addContent(content); @@ -170,21 +170,21 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, if (second_file_transfer) { char *send_filepath = bc_tester_res("vcards/vcards.vcf"); - FileContent *content = new FileContent(); + auto content = FileContent::create<FileContent>(); content->setContentType(ContentType("file/vcf")); content->setFilePath(send_filepath); content->setFileName("vcards.vcf"); marieMessage->addContent(content); bc_free(send_filepath); } else { - Content *content = new Content(); + auto content = Content::create(); content->setContentType(ContentType::PlainText); content->setBodyFromUtf8("Hello part 2"); marieMessage->addContent(content); } if (third_content) { - Content *content = new Content(); + auto content = Content::create(); content->setContentType(ContentType::PlainText); content->setBodyFromUtf8("Hello part 3"); marieMessage->addContent(content);