diff --git a/include/linphone/api/c-chat-room.h b/include/linphone/api/c-chat-room.h index 392bce10f..aea3a7f61 100644 --- a/include/linphone/api/c-chat-room.h +++ b/include/linphone/api/c-chat-room.h @@ -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 diff --git a/src/c-wrapper/api/c-chat-message.cpp b/src/c-wrapper/api/c-chat-message.cpp index da453b39c..59bffa2d9 100644 --- a/src/c-wrapper/api/c-chat-message.cpp +++ b/src/c-wrapper/api/c-chat-message.cpp @@ -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; } // ============================================================================= diff --git a/src/c-wrapper/api/c-chat-room.cpp b/src/c-wrapper/api/c-chat-room.cpp index 3288f1073..11f89e053 100644 --- a/src/c-wrapper/api/c-chat-room.cpp +++ b/src/c-wrapper/api/c-chat-room.cpp @@ -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 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 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; diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index cfb569732..7af4b4073 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -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(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(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(c); + fc->setFileName(L_C_TO_STRING(name)); + } else if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + LinphonePrivate::FileTransferContent *ftc = static_cast(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(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(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(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; } \ No newline at end of file diff --git a/src/chat/chat-message/chat-message-p.h b/src/chat/chat-message/chat-message-p.h index 0eae6c24e..b47355e3b 100644 --- a/src/chat/chat-message/chat-message-p.h +++ b/src/chat/chat-message/chat-message-p.h @@ -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 (); diff --git a/src/chat/chat-message/chat-message.cpp b/src/chat/chat-message/chat-message.cpp index d6f7d3f95..855dbd902 100644 --- a/src/chat/chat-message/chat-message.cpp +++ b/src/chat/chat-message/chat-message.cpp @@ -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 () { diff --git a/src/chat/chat-room/abstract-chat-room.h b/src/chat/chat-room/abstract-chat-room.h index 46f5aec29..6cd260a82 100644 --- a/src/chat/chat-room/abstract-chat-room.h +++ b/src/chat/chat-room/abstract-chat-room.h @@ -87,8 +87,7 @@ public: virtual std::shared_ptr createChatMessage () = 0; virtual std::shared_ptr createChatMessage (const std::string &text) = 0; - // TODO: Remove LinphoneContent by LinphonePrivate::Content. - virtual std::shared_ptr createFileTransferMessage (const LinphoneContent *initialContent) = 0; + virtual std::shared_ptr createFileTransferMessage (Content *initialContent) = 0; virtual std::shared_ptr findChatMessage (const std::string &messageId) const = 0; virtual std::shared_ptr findChatMessage ( diff --git a/src/chat/chat-room/chat-room.cpp b/src/chat/chat-room/chat-room.cpp index 14e92cf85..03b8cd079 100644 --- a/src/chat/chat-room/chat-room.cpp +++ b/src/chat/chat-room/chat-room.cpp @@ -393,7 +393,7 @@ shared_ptr ChatRoom::createChatMessage (const string &text) { return chatMessage; } -shared_ptr ChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) { +shared_ptr ChatRoom::createFileTransferMessage (Content *initialContent) { shared_ptr chatMessage = createChatMessage(); chatMessage->getPrivate()->setFileTransferInformation(initialContent); return chatMessage; diff --git a/src/chat/chat-room/chat-room.h b/src/chat/chat-room/chat-room.h index 35d887e59..9c6dbb999 100644 --- a/src/chat/chat-room/chat-room.h +++ b/src/chat/chat-room/chat-room.h @@ -61,8 +61,7 @@ public: std::shared_ptr createChatMessage () override; std::shared_ptr createChatMessage (const std::string &text) override; - // TODO: Remove LinphoneContent by LinphonePrivate::Content. - std::shared_ptr createFileTransferMessage (const LinphoneContent *initialContent) override; + std::shared_ptr createFileTransferMessage (Content *initialContent) override; std::shared_ptr findChatMessage (const std::string &messageId) const override; std::shared_ptr findChatMessage ( diff --git a/src/chat/chat-room/proxy-chat-room.cpp b/src/chat/chat-room/proxy-chat-room.cpp index bf984d2a1..29a9ddb80 100644 --- a/src/chat/chat-room/proxy-chat-room.cpp +++ b/src/chat/chat-room/proxy-chat-room.cpp @@ -264,7 +264,7 @@ shared_ptr ProxyChatRoom::createChatMessage (const string &text) { return d->chatRoom->createChatMessage(text); } -shared_ptr ProxyChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) { +shared_ptr ProxyChatRoom::createFileTransferMessage (Content *initialContent) { L_D(); return d->chatRoom->createFileTransferMessage(initialContent); } diff --git a/src/chat/chat-room/proxy-chat-room.h b/src/chat/chat-room/proxy-chat-room.h index 16a5c49aa..6b9a75428 100644 --- a/src/chat/chat-room/proxy-chat-room.h +++ b/src/chat/chat-room/proxy-chat-room.h @@ -62,8 +62,7 @@ public: std::shared_ptr createChatMessage () override; std::shared_ptr createChatMessage (const std::string &text) override; - // TODO: Remove LinphoneContent by LinphonePrivate::Content. - std::shared_ptr createFileTransferMessage (const LinphoneContent *initialContent) override; + std::shared_ptr createFileTransferMessage (Content *initialContent) override; std::shared_ptr findChatMessage (const std::string &messageId) const override; std::shared_ptr findChatMessage ( diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.cpp b/src/chat/modifier/file-transfer-chat-message-modifier.cpp index 30d088d2c..ac99d2201 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.cpp +++ b/src/chat/modifier/file-transfer-chat-message-modifier.cpp @@ -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); diff --git a/src/content/content.cpp b/src/content/content.cpp index 732996494..93fd2f6e4 100644 --- a/src/content/content.cpp +++ b/src/content/content.cpp @@ -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 diff --git a/src/content/content.h b/src/content/content.h index 4885feadf..da3c9e055 100644 --- a/src/content/content.h +++ b/src/content/content.h @@ -71,9 +71,6 @@ public: virtual bool isFile () const; - // TODO: Remove me later. - virtual LinphoneContent *toLinphoneContent () const; - protected: explicit Content (ContentPrivate &p); diff --git a/src/content/file-content.cpp b/src/content/file-content.cpp index 09de486b6..a2d1df851 100644 --- a/src/content/file-content.cpp +++ b/src/content/file-content.cpp @@ -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 diff --git a/src/content/file-content.h b/src/content/file-content.h index 4876370fb..79dfe5629 100644 --- a/src/content/file-content.h +++ b/src/content/file-content.h @@ -53,9 +53,6 @@ public: bool isFile () const override; - // TODO: Remove me later. - LinphoneContent *toLinphoneContent () const override; - private: L_DECLARE_PRIVATE(FileContent); }; diff --git a/src/content/file-transfer-content.cpp b/src/content/file-transfer-content.cpp index 4ce62bc19..628080c7c 100644 --- a/src/content/file-transfer-content.cpp +++ b/src/content/file-transfer-content.cpp @@ -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; } diff --git a/src/content/file-transfer-content.h b/src/content/file-transfer-content.h index 4b668a0ac..4abc4369f 100644 --- a/src/content/file-transfer-content.h +++ b/src/content/file-transfer-content.h @@ -57,9 +57,6 @@ public: bool isFile () const override; - // TODO: Remove me later. - LinphoneContent *toLinphoneContent () const override; - private: L_DECLARE_PRIVATE(FileTransferContent); };