More work on C/C++ Contents

This commit is contained in:
Sylvain Berfini 2018-02-08 11:24:30 +01:00
parent 933081e72f
commit 122098ac04
18 changed files with 132 additions and 96 deletions

View file

@ -90,7 +90,7 @@ LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message_2(Linphon
* @param initial_content #LinphoneContent initial content. #LinphoneCoreVTable.file_transfer_send is invoked later to notify file transfer progress and collect next chunk of the message if LinphoneContent.data is NULL.
* @return a new #LinphoneChatMessage
*/
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, const LinphoneContent* initial_content);
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, LinphoneContent* initial_content);
/**
* get peer address \link linphone_core_get_chat_room() associated to \endlink this #LinphoneChatRoom

View file

@ -283,7 +283,9 @@ int linphone_chat_message_set_text(LinphoneChatMessage *msg, const char* text) {
}
LinphoneContent *linphone_chat_message_get_file_transfer_information(LinphoneChatMessage *msg) {
return L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferInformation();
const LinphonePrivate::Content *content = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferInformation();
if (content) return L_GET_C_BACK_PTR(content);
return NULL;
}
// =============================================================================

View file

@ -350,8 +350,8 @@ const bctbx_list_t *linphone_chat_room_get_composing_addresses (LinphoneChatRoom
return cr->composingAddresses;
}
LinphoneChatMessage *linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, const LinphoneContent *initial_content) {
shared_ptr<LinphonePrivate::ChatMessage> cppPtr = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->createFileTransferMessage(initial_content);
LinphoneChatMessage *linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, LinphoneContent *initial_content) {
shared_ptr<LinphonePrivate::ChatMessage> cppPtr = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->createFileTransferMessage(L_GET_CPP_PTR_FROM_C_OBJECT(initial_content));
LinphoneChatMessage *object = L_INIT(ChatMessage);
L_SET_CPP_PTR_FROM_C_OBJECT(object, cppPtr);
return object;

View file

@ -23,6 +23,9 @@
#include "c-wrapper/c-wrapper.h"
#include "content/content.h"
#include "content/content-type.h"
#include "content/file-content.h"
#include "content/file-transfer-content.h"
// =============================================================================
@ -31,6 +34,7 @@ using namespace std;
L_DECLARE_C_CLONABLE_OBJECT_IMPL(Content,
SalBodyHandler *body_handler;
void *cryptoContext; /**< crypto context used to encrypt file for RCS file transfer */
mutable char *name;
)
// =============================================================================
@ -57,112 +61,176 @@ void linphone_content_set_user_data(LinphoneContent *content, void *ud) {
// =============================================================================
const char * linphone_content_get_type(const LinphoneContent *content) {
return NULL;
return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getType());
}
void linphone_content_set_type(LinphoneContent *content, const char *type) {
LinphonePrivate::ContentType ct = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType();
ct.setType(L_C_TO_STRING(type));
L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentType(ct);
}
const char * linphone_content_get_subtype(const LinphoneContent *content) {
return NULL;
return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getSubType());
}
void linphone_content_set_subtype(LinphoneContent *content, const char *subtype) {
LinphonePrivate::ContentType ct = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType();
ct.setSubType(L_C_TO_STRING(subtype));
L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentType(ct);
}
uint8_t * linphone_content_get_buffer(const LinphoneContent *content) {
return NULL;
return (uint8_t *)L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsString());
}
void linphone_content_set_buffer(LinphoneContent *content, const uint8_t *buffer, size_t size) {
L_GET_CPP_PTR_FROM_C_OBJECT(content)->setBody(buffer, size);
}
const char * linphone_content_get_string_buffer(const LinphoneContent *content) {
return NULL;
return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsString());
}
void linphone_content_set_string_buffer(LinphoneContent *content, const char *buffer) {
L_GET_CPP_PTR_FROM_C_OBJECT(content)->setBody(L_C_TO_STRING(buffer));
}
size_t linphone_content_get_size(const LinphoneContent *content) {
return 0;
size_t size = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getSize();
if (size == 0) {
size = sal_body_handler_get_size(content->body_handler);
}
return size;
}
void linphone_content_set_size(LinphoneContent *content, size_t size) {
sal_body_handler_set_size(content->body_handler, size);
}
const char * linphone_content_get_encoding(const LinphoneContent *content) {
return NULL;
return sal_body_handler_get_encoding(content->body_handler);
}
void linphone_content_set_encoding(LinphoneContent *content, const char *encoding) {
sal_body_handler_set_encoding(content->body_handler, encoding);
}
const char * linphone_content_get_name(const LinphoneContent *content) {
return NULL;
const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content);
if (c->isFile()) {
const LinphonePrivate::FileContent *fc = static_cast<const LinphonePrivate::FileContent *>(c);
if (content->name) ms_free(content->name);
content->name = ms_strdup(L_STRING_TO_C(fc->getFileName()));
} else if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) {
const LinphonePrivate::FileTransferContent *ftc = static_cast<const LinphonePrivate::FileTransferContent *>(c);
if (content->name) ms_free(content->name);
content->name = ms_strdup(L_STRING_TO_C(ftc->getFileName()));
}
return content->name;
}
void linphone_content_set_name(LinphoneContent *content, const char *name) {
LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content);
if (c->isFile()) {
LinphonePrivate::FileContent *fc = static_cast<LinphonePrivate::FileContent *>(c);
fc->setFileName(L_C_TO_STRING(name));
} else if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) {
LinphonePrivate::FileTransferContent *ftc = static_cast<LinphonePrivate::FileTransferContent *>(c);
ftc->setFileName(L_C_TO_STRING(name));
}
content->name = ms_strdup(name);
}
bool_t linphone_content_is_multipart(const LinphoneContent *content) {
return FALSE;
return sal_body_handler_is_multipart(content->body_handler);
}
LinphoneContent * linphone_content_get_part(const LinphoneContent *content, int idx) {
return NULL;
SalBodyHandler *part_body_handler;
if (!linphone_content_is_multipart(content)) return NULL;
part_body_handler = sal_body_handler_get_part(content->body_handler, idx);
return linphone_content_from_sal_body_handler(part_body_handler);
}
LinphoneContent * linphone_content_find_part_by_header(const LinphoneContent *content, const char *header_name, const char *header_value) {
return NULL;
SalBodyHandler *part_body_handler;
if (!linphone_content_is_multipart(content)) return NULL;
part_body_handler = sal_body_handler_find_part_by_header(content->body_handler, header_name, header_value);
return linphone_content_from_sal_body_handler(part_body_handler);
}
const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *header_name) {
return NULL;
return sal_body_handler_get_header(content->body_handler, header_name);
}
const char *linphone_content_get_key(const LinphoneContent *content) {
const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content);
if (c->isFile()) {
const LinphonePrivate::FileContent *fc = static_cast<const LinphonePrivate::FileContent *>(c);
return L_STRING_TO_C(fc->getFileKey());
}
return NULL;
}
size_t linphone_content_get_key_size(const LinphoneContent *content) {
const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content);
if (c->isFile()) {
const LinphonePrivate::FileContent *fc = static_cast<const LinphonePrivate::FileContent *>(c);
return fc->getFileKey().length();
}
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);
if (c->isFile()) {
LinphonePrivate::FileContent *fc = static_cast<LinphonePrivate::FileContent *>(c);
fc->setFileKey(L_C_TO_STRING(key));
}
}
// =============================================================================
// Private functions.
// =============================================================================
LinphoneContent * linphone_content_new(void) {
return NULL;
}
LinphoneContent * linphone_content_copy(const LinphoneContent *ref) {
return NULL;
static void linphone_content_set_sal_body_handler(LinphoneContent *content, SalBodyHandler *body_handler) {
if (content->body_handler != NULL) {
sal_body_handler_unref(content->body_handler);
content->body_handler = NULL;
}
content->body_handler = sal_body_handler_ref(body_handler);
}
static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler *body_handler) {
return NULL;
LinphoneContent *content = L_INIT(Content);
content->cryptoContext = NULL;
if (body_handler == NULL) {
linphone_content_set_sal_body_handler(content, sal_body_handler_new());
} else {
linphone_content_set_sal_body_handler(content, body_handler);
}
LinphonePrivate::Content *c = new LinphonePrivate::Content();
L_SET_CPP_PTR_FROM_C_OBJECT(content, c);
return content;
}
LinphoneContent * linphone_content_new(void) {
return linphone_content_new_with_body_handler(NULL);
}
LinphoneContent * linphone_content_copy(const LinphoneContent *ref) {
//TODO
return (LinphoneContent *)belle_sip_object_ref(belle_sip_object_clone(BELLE_SIP_OBJECT(ref)));
}
LinphoneContent * linphone_core_create_content(LinphoneCore *lc) {
return NULL;
return linphone_content_new();
}
/* 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->cryptoContext);
}
LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_handler) {
@ -173,5 +241,6 @@ LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_ha
}
SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) {
return NULL;
if (content == NULL) return NULL;
return content->body_handler;
}

View file

@ -119,8 +119,8 @@ public:
bool hasFileTransferContent () const;
const Content* getFileTransferContent () const;
LinphoneContent *getFileTransferInformation () const;
void setFileTransferInformation (const LinphoneContent *content);
const Content* getFileTransferInformation () const;
void setFileTransferInformation (Content *content);
bool downloadFile ();

View file

@ -284,33 +284,36 @@ void ChatMessagePrivate::setText (const string &text) {
}
}
LinphoneContent *ChatMessagePrivate::getFileTransferInformation () const {
const Content *ChatMessagePrivate::getFileTransferInformation () const {
if (hasFileTransferContent()) {
return getFileTransferContent()->toLinphoneContent();
return getFileTransferContent();
}
for (const Content *c : contents) {
if (c->isFile()) {
FileContent *fileContent = (FileContent *)c;
return fileContent->toLinphoneContent();
return fileContent;
}
}
return NULL;
}
void ChatMessagePrivate::setFileTransferInformation (const LinphoneContent *c_content) {
void ChatMessagePrivate::setFileTransferInformation (Content *content) {
L_Q();
// Create a FileContent, it will create the FileTransferContent at upload time
FileContent *fileContent = new FileContent();
ContentType contentType(linphone_content_get_type(c_content), linphone_content_get_subtype(c_content));
fileContent->setContentType(contentType);
fileContent->setFileSize(linphone_content_get_size(c_content));
fileContent->setFileName(linphone_content_get_name(c_content));
if (linphone_content_get_string_buffer(c_content) != NULL) {
fileContent->setBody(linphone_content_get_string_buffer(c_content));
if (content->isFile()) {
q->addContent(*content);
} else {
// This scenario is more likely to happen because the caller is using the C API
LinphoneContent *c_content = L_GET_C_BACK_PTR(content);
FileContent *fileContent = new FileContent();
fileContent->setContentType(content->getContentType());
fileContent->setFileSize(linphone_content_get_size(c_content)); // This information is only available from C Content if it was created from C API
fileContent->setFileName(linphone_content_get_name(c_content)); // This information is only available from C Content if it was created from C API
if (!content->isEmpty()) {
fileContent->setBody(content->getBody());
}
q->addContent(*fileContent);
}
q->addContent(*fileContent);
}
bool ChatMessagePrivate::downloadFile () {

View file

@ -87,8 +87,7 @@ public:
virtual std::shared_ptr<ChatMessage> createChatMessage () = 0;
virtual std::shared_ptr<ChatMessage> createChatMessage (const std::string &text) = 0;
// TODO: Remove LinphoneContent by LinphonePrivate::Content.
virtual std::shared_ptr<ChatMessage> createFileTransferMessage (const LinphoneContent *initialContent) = 0;
virtual std::shared_ptr<ChatMessage> createFileTransferMessage (Content *initialContent) = 0;
virtual std::shared_ptr<ChatMessage> findChatMessage (const std::string &messageId) const = 0;
virtual std::shared_ptr<ChatMessage> findChatMessage (

View file

@ -393,7 +393,7 @@ shared_ptr<ChatMessage> ChatRoom::createChatMessage (const string &text) {
return chatMessage;
}
shared_ptr<ChatMessage> ChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) {
shared_ptr<ChatMessage> ChatRoom::createFileTransferMessage (Content *initialContent) {
shared_ptr<ChatMessage> chatMessage = createChatMessage();
chatMessage->getPrivate()->setFileTransferInformation(initialContent);
return chatMessage;

View file

@ -61,8 +61,7 @@ public:
std::shared_ptr<ChatMessage> createChatMessage () override;
std::shared_ptr<ChatMessage> createChatMessage (const std::string &text) override;
// TODO: Remove LinphoneContent by LinphonePrivate::Content.
std::shared_ptr<ChatMessage> createFileTransferMessage (const LinphoneContent *initialContent) override;
std::shared_ptr<ChatMessage> createFileTransferMessage (Content *initialContent) override;
std::shared_ptr<ChatMessage> findChatMessage (const std::string &messageId) const override;
std::shared_ptr<ChatMessage> findChatMessage (

View file

@ -264,7 +264,7 @@ shared_ptr<ChatMessage> ProxyChatRoom::createChatMessage (const string &text) {
return d->chatRoom->createChatMessage(text);
}
shared_ptr<ChatMessage> ProxyChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) {
shared_ptr<ChatMessage> ProxyChatRoom::createFileTransferMessage (Content *initialContent) {
L_D();
return d->chatRoom->createFileTransferMessage(initialContent);
}

View file

@ -62,8 +62,7 @@ public:
std::shared_ptr<ChatMessage> createChatMessage () override;
std::shared_ptr<ChatMessage> createChatMessage (const std::string &text) override;
// TODO: Remove LinphoneContent by LinphonePrivate::Content.
std::shared_ptr<ChatMessage> createFileTransferMessage (const LinphoneContent *initialContent) override;
std::shared_ptr<ChatMessage> createFileTransferMessage (Content *initialContent) override;
std::shared_ptr<ChatMessage> findChatMessage (const std::string &messageId) const override;
std::shared_ptr<ChatMessage> findChatMessage (

View file

@ -100,7 +100,7 @@ void FileTransferChatMessageModifier::fileTransferOnProgress (
LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message);
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent();
LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer);
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);
} else {
@ -150,7 +150,7 @@ int FileTransferChatMessageModifier::onSendBody (
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
LinphoneChatMessageCbsFileTransferSendCb file_transfer_send_cb =
linphone_chat_message_cbs_get_file_transfer_send(cbs);
LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent();
LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer);
if (file_transfer_send_cb) {
LinphoneBuffer *lb = file_transfer_send_cb(msg, content, offset, *size);
if (lb) {
@ -706,7 +706,7 @@ void FileTransferChatMessageModifier::onRecvBody (belle_sip_user_body_handler_t
if (currentFileContentToTransfer->getFilePath().empty()) {
LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message);
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent();
LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer);
if (linphone_chat_message_cbs_get_file_transfer_recv(cbs)) {
LinphoneBuffer *lb = linphone_buffer_new_from_data(buffer, size);
linphone_chat_message_cbs_get_file_transfer_recv(cbs)(msg, content, lb);
@ -747,7 +747,7 @@ void FileTransferChatMessageModifier::onRecvEnd (belle_sip_user_body_handler_t *
if (currentFileContentToTransfer->getFilePath().empty()) {
LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message);
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent();
LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer);
if (linphone_chat_message_cbs_get_file_transfer_recv(cbs)) {
LinphoneBuffer *lb = linphone_buffer_new();
linphone_chat_message_cbs_get_file_transfer_recv(cbs)(msg, content, lb);

View file

@ -172,11 +172,4 @@ bool Content::isFile () const {
return false;
}
LinphoneContent *Content::toLinphoneContent () const {
LinphoneContent *content = linphone_core_create_content(nullptr);
linphone_content_set_type(content, getContentType().getType().c_str());
linphone_content_set_subtype(content, getContentType().getSubType().c_str());
return content;
}
LINPHONE_END_NAMESPACE

View file

@ -71,9 +71,6 @@ public:
virtual bool isFile () const;
// TODO: Remove me later.
virtual LinphoneContent *toLinphoneContent () const;
protected:
explicit Content (ContentPrivate &p);

View file

@ -135,14 +135,4 @@ bool FileContent::isFile () const {
return true;
}
LinphoneContent *FileContent::toLinphoneContent () const {
LinphoneContent *content = linphone_core_create_content(nullptr);
linphone_content_set_type(content, getContentType().getType().c_str());
linphone_content_set_subtype(content, getContentType().getSubType().c_str());
linphone_content_set_name(content, getFileName().c_str());
linphone_content_set_size(content, getFileSize());
linphone_content_set_key(content, getFileKey().c_str(), getFileKey().size());
return content;
}
LINPHONE_END_NAMESPACE

View file

@ -53,9 +53,6 @@ public:
bool isFile () const override;
// TODO: Remove me later.
LinphoneContent *toLinphoneContent () const override;
private:
L_DECLARE_PRIVATE(FileContent);
};

View file

@ -146,15 +146,6 @@ size_t FileTransferContent::getFileSize () const {
return d->fileSize;
}
LinphoneContent *FileTransferContent::toLinphoneContent () const {
LinphoneContent *content = linphone_core_create_content(nullptr);
linphone_content_set_type(content, getContentType().getType().c_str());
linphone_content_set_subtype(content, getContentType().getSubType().c_str());
linphone_content_set_name(content, getFileName().c_str());
linphone_content_set_size(content, getFileSize());
return content;
}
bool FileTransferContent::isFile () const {
return false;
}

View file

@ -57,9 +57,6 @@ public:
bool isFile () const override;
// TODO: Remove me later.
LinphoneContent *toLinphoneContent () const override;
private:
L_DECLARE_PRIVATE(FileTransferContent);
};