/* * c-content.cpp * Copyright (C) 2010-2018 Belledonne Communications SARL * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "linphone/api/c-content.h" #include "linphone/wrapper_utils.h" #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" // ============================================================================= using namespace std; L_DECLARE_C_CLONABLE_OBJECT_IMPL(Content, void *cryptoContext; /**< crypto context used to encrypt file for RCS file transfer */ mutable char *name; mutable char *type; mutable char *subtype; mutable char *body; mutable size_t size; mutable char *encoding; mutable char *key; ) // ============================================================================= // Reference and user data handling functions. // ============================================================================= LinphoneContent * linphone_content_ref(LinphoneContent *content) { belle_sip_object_ref(content); return content; } void linphone_content_unref(LinphoneContent *content) { belle_sip_object_unref(content); } void *linphone_content_get_user_data(const LinphoneContent *content) { return L_GET_USER_DATA_FROM_C_OBJECT(content); } void linphone_content_set_user_data(LinphoneContent *content, void *ud) { return L_SET_USER_DATA_FROM_C_OBJECT(content, ud); } // ============================================================================= const char * linphone_content_get_type(const LinphoneContent *content) { if (content->type) ms_free(content->type); content->type = ms_strdup(L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getType())); return content->type; } 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) { if (content->subtype) ms_free(content->subtype); content->subtype = ms_strdup(L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getSubType())); return content->subtype; } 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 (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) { if (content->body) ms_free(content->body); content->body = ms_strdup(L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsString())); return content->body; } 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) { size_t size = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getSize(); if (size == 0) { size = content->size; } return size; } void linphone_content_set_size(LinphoneContent *content, size_t size) { content->size = size; } const char * linphone_content_get_encoding(const LinphoneContent *content) { return content->encoding; } void linphone_content_set_encoding(LinphoneContent *content, const char *encoding) { if (content->encoding) ms_free(content->encoding); content->encoding = ms_strdup(encoding); } const char * linphone_content_get_name(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); if (content->name) ms_free(content->name); content->name = ms_strdup(L_STRING_TO_C(fc->getFileName())); } else if (c->isFileTransfer()) { 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) { if (content->name) ms_free(content->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->isFileTransfer()) { 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) { SalBodyHandler *body_handler = sal_body_handler_from_content(content); bool_t multipart = sal_body_handler_is_multipart(body_handler); sal_body_handler_unref(body_handler); return multipart; } LinphoneContent * linphone_content_get_part(const LinphoneContent *content, int idx) { SalBodyHandler *part_body_handler; SalBodyHandler *body_handler = sal_body_handler_from_content(content); if (!sal_body_handler_is_multipart(body_handler)) { sal_body_handler_unref(body_handler); return NULL; } part_body_handler = sal_body_handler_get_part(body_handler, idx); sal_body_handler_unref(body_handler); 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) { SalBodyHandler *part_body_handler; SalBodyHandler *body_handler = sal_body_handler_from_content(content); if (!sal_body_handler_is_multipart(body_handler)) { sal_body_handler_unref(body_handler); return NULL; } part_body_handler = sal_body_handler_find_part_by_header(body_handler, header_name, header_value); sal_body_handler_unref(body_handler); return linphone_content_from_sal_body_handler(part_body_handler); } const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *header_name) { SalBodyHandler *body_handler = sal_body_handler_from_content(content); const char *header = sal_body_handler_get_header(body_handler, header_name); sal_body_handler_unref(body_handler); return header; } const char *linphone_content_get_key(const LinphoneContent *content) { if (content->key) ms_free(content->key); const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); if (c->isFileTransfer()) { const LinphonePrivate::FileTransferContent *ftc = static_cast(c); content->key = ms_strdup(ftc->getFileKeyAsString()); } return content->key; } size_t linphone_content_get_key_size(const LinphoneContent *content) { const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); if (c->isFileTransfer()) { const LinphonePrivate::FileTransferContent *ftc = static_cast(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); if (c->isFileTransfer()) { LinphonePrivate::FileTransferContent *ftc = static_cast(c); ftc->setFileKey(key, keyLength); } } // ============================================================================= // Private functions. // ============================================================================= static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler *body_handler) { LinphoneContent *content = L_INIT(Content); content->cryptoContext = NULL; LinphonePrivate::Content *c = new LinphonePrivate::Content(); L_SET_CPP_PTR_FROM_C_OBJECT(content, c); if (body_handler != NULL) { linphone_content_set_type(content, sal_body_handler_get_type(body_handler)); linphone_content_set_subtype(content, sal_body_handler_get_subtype(body_handler)); linphone_content_set_string_buffer(content, (char *)sal_body_handler_get_data(body_handler)); linphone_content_set_encoding(content, sal_body_handler_get_encoding(body_handler)); } return content; } LinphoneContent * linphone_content_new(void) { return linphone_content_new_with_body_handler(NULL); } LinphoneContent * linphone_content_copy(const LinphoneContent *ref) { return (LinphoneContent *)belle_sip_object_ref(belle_sip_object_clone(BELLE_SIP_OBJECT(ref))); } LinphoneContent * linphone_core_create_content(LinphoneCore *lc) { 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); } LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_handler) { if (body_handler) { return linphone_content_new_with_body_handler(body_handler); } return NULL; } SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) { if (content == NULL) return NULL; SalBodyHandler *body_handler = sal_body_handler_new(); sal_body_handler_set_type(body_handler, belle_sip_strdup(linphone_content_get_type(content))); sal_body_handler_set_subtype(body_handler, belle_sip_strdup(linphone_content_get_subtype(content))); sal_body_handler_set_size(body_handler, linphone_content_get_size(content)); sal_body_handler_set_data(body_handler, belle_sip_strdup(linphone_content_get_string_buffer(content))); sal_body_handler_set_encoding(body_handler, belle_sip_strdup(linphone_content_get_encoding(content))); return body_handler; }