Reworked ChatMessageModifiers to use a shared_ptr<ChatMessage> instead of ChatMessagePrivate*

This commit is contained in:
Sylvain Berfini 2017-10-06 10:30:37 +02:00
parent d20d39b232
commit df8aedecc3
9 changed files with 58 additions and 48 deletions

View file

@ -980,11 +980,11 @@ LinphoneReason ChatMessagePrivate::receive() {
if (getContentType() == ContentType::Cpim) { if (getContentType() == ContentType::Cpim) {
CpimChatMessageModifier ccmm; CpimChatMessageModifier ccmm;
ccmm.decode(this, &errorCode); ccmm.decode(q->getSharedFromThis(), &errorCode);
} }
EncryptionChatMessageModifier ecmm; EncryptionChatMessageModifier ecmm;
ChatMessageModifier::Result result = ecmm.decode(this, &errorCode); ChatMessageModifier::Result result = ecmm.decode(q->getSharedFromThis(), &errorCode);
if (result == ChatMessageModifier::Result::Error) { if (result == ChatMessageModifier::Result::Error) {
/* Unable to decrypt message */ /* Unable to decrypt message */
chatRoom->getPrivate()->notifyUndecryptableMessageReceived(q->getSharedFromThis()); chatRoom->getPrivate()->notifyUndecryptableMessageReceived(q->getSharedFromThis());
@ -994,7 +994,7 @@ LinphoneReason ChatMessagePrivate::receive() {
} }
MultipartChatMessageModifier mcmm; MultipartChatMessageModifier mcmm;
mcmm.decode(this, &errorCode); mcmm.decode(q->getSharedFromThis(), &errorCode);
// --------------------------------------- // ---------------------------------------
// End of message modification // End of message modification
@ -1101,7 +1101,7 @@ void ChatMessagePrivate::send() {
} else { } else {
if (contents.size() > 1) { if (contents.size() > 1) {
MultipartChatMessageModifier mcmm; MultipartChatMessageModifier mcmm;
mcmm.encode(this, &errorCode); mcmm.encode(q->getSharedFromThis(), &errorCode);
} }
currentSendStep |= ChatMessagePrivate::Step::Multipart; currentSendStep |= ChatMessagePrivate::Step::Multipart;
} }
@ -1110,7 +1110,7 @@ void ChatMessagePrivate::send() {
lInfo() << "Encryption step already done, skipping"; lInfo() << "Encryption step already done, skipping";
} else { } else {
EncryptionChatMessageModifier ecmm; EncryptionChatMessageModifier ecmm;
ChatMessageModifier::Result result = ecmm.encode(this, &errorCode); ChatMessageModifier::Result result = ecmm.encode(q->getSharedFromThis(), &errorCode);
if (result == ChatMessageModifier::Result::Error) { if (result == ChatMessageModifier::Result::Error) {
sal_error_info_set((SalErrorInfo *)op->get_error_info(), SalReasonNotAcceptable, "SIP", errorCode, "Unable to encrypt IM", nullptr); sal_error_info_set((SalErrorInfo *)op->get_error_info(), SalReasonNotAcceptable, "SIP", errorCode, "Unable to encrypt IM", nullptr);
q->updateState(ChatMessage::State::NotDelivered); q->updateState(ChatMessage::State::NotDelivered);
@ -1128,7 +1128,7 @@ void ChatMessagePrivate::send() {
} else { } else {
if (lp_config_get_int(chatRoom->getCore()->config, "sip", "use_cpim", 0) == 1) { if (lp_config_get_int(chatRoom->getCore()->config, "sip", "use_cpim", 0) == 1) {
CpimChatMessageModifier ccmm; CpimChatMessageModifier ccmm;
ccmm.encode(this, &errorCode); ccmm.encode(q->getSharedFromThis(), &errorCode);
} }
currentSendStep |= ChatMessagePrivate::Step::Cpim; currentSendStep |= ChatMessagePrivate::Step::Cpim;
} }
@ -1352,6 +1352,11 @@ const Content& ChatMessage::getInternalContent() const {
return d->internalContent; return d->internalContent;
} }
void ChatMessage::setInternalContent(const Content& content) {
L_D();
d->internalContent = content;
}
string ChatMessage::getCustomHeaderValue (const string &headerName) const { string ChatMessage::getCustomHeaderValue (const string &headerName) const {
L_D(); L_D();
try { try {

View file

@ -126,7 +126,9 @@ public:
const std::list<Content>& getContents() const; const std::list<Content>& getContents() const;
void addContent(const Content& content); void addContent(const Content& content);
void removeContent(const Content& content); void removeContent(const Content& content);
const Content& getInternalContent() const; const Content& getInternalContent() const;
void setInternalContent(const Content& content);
std::string getCustomHeaderValue(const std::string &headerName) const; std::string getCustomHeaderValue(const std::string &headerName) const;
void addCustomHeader(const std::string &headerName, const std::string &headerValue); void addCustomHeader(const std::string &headerName, const std::string &headerValue);

View file

@ -21,13 +21,14 @@
#define _CHAT_MESSAGE_MODIFIER_H_ #define _CHAT_MESSAGE_MODIFIER_H_
#include "linphone/utils/general.h" #include "linphone/utils/general.h"
#include "object/object.h"
#include "private.h" #include "private.h"
// ============================================================================= // =============================================================================
LINPHONE_BEGIN_NAMESPACE LINPHONE_BEGIN_NAMESPACE
class ChatMessagePrivate; class ChatMessage;
class ChatMessageModifier { class ChatMessageModifier {
public: public:
@ -45,13 +46,13 @@ public:
* It should check first if the internalContent is filled. * It should check first if the internalContent is filled.
* If so, it should apply it's changes to it, otherwise it should use the contentsList. * If so, it should apply it's changes to it, otherwise it should use the contentsList.
*/ */
virtual Result encode (ChatMessagePrivate *messagePrivate, int *errorCode) = 0; virtual Result encode (std::shared_ptr<ChatMessage> message, int *errorCode) = 0;
/** /**
* This method will be called when the message is about to be received. * This method will be called when the message is about to be received.
* It should apply it's changes to the internal content, the last modifier will take care of filling the contentsList. * It should apply it's changes to the internal content, the last modifier will take care of filling the contentsList.
*/ */
virtual Result decode (ChatMessagePrivate *messagePrivate, int *errorCode) = 0; virtual Result decode (std::shared_ptr<ChatMessage> message, int *errorCode) = 0;
}; };
LINPHONE_END_NAMESPACE LINPHONE_END_NAMESPACE

View file

@ -32,22 +32,22 @@ using namespace std;
LINPHONE_BEGIN_NAMESPACE LINPHONE_BEGIN_NAMESPACE
ChatMessageModifier::Result CpimChatMessageModifier::encode (ChatMessagePrivate *messagePrivate, int *errorCode) { ChatMessageModifier::Result CpimChatMessageModifier::encode (shared_ptr<ChatMessage> message, int *errorCode) {
Cpim::Message message; Cpim::Message cpimMessage;
Cpim::GenericHeader cpimContentTypeHeader; Cpim::GenericHeader cpimContentTypeHeader;
cpimContentTypeHeader.setName("Content-Type"); cpimContentTypeHeader.setName("Content-Type");
cpimContentTypeHeader.setValue("Message/CPIM"); cpimContentTypeHeader.setValue("Message/CPIM");
message.addCpimHeader(cpimContentTypeHeader); cpimMessage.addCpimHeader(cpimContentTypeHeader);
Content content; Content content;
if (!messagePrivate->internalContent.isEmpty()) { if (!message->getInternalContent().isEmpty()) {
// Another ChatMessageModifier was called before this one, we apply our changes on the private content // Another ChatMessageModifier was called before this one, we apply our changes on the private content
content = messagePrivate->internalContent; content = message->getInternalContent();
} else { } else {
// We're the first ChatMessageModifier to be called, we'll create the private content from the public one // 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 // 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 // So we should not be in this block
content = messagePrivate->contents.front(); content = message->getContents().front();
} }
string contentType = content.getContentType().asString(); string contentType = content.getContentType().asString();
@ -57,11 +57,11 @@ ChatMessageModifier::Result CpimChatMessageModifier::encode (ChatMessagePrivate
Cpim::GenericHeader contentTypeHeader; Cpim::GenericHeader contentTypeHeader;
contentTypeHeader.setName("Content-Type"); contentTypeHeader.setName("Content-Type");
contentTypeHeader.setValue(contentType); contentTypeHeader.setValue(contentType);
message.addContentHeader(contentTypeHeader); cpimMessage.addContentHeader(contentTypeHeader);
message.setContent(contentBody); cpimMessage.setContent(contentBody);
if (!message.isValid()) { if (!cpimMessage.isValid()) {
lError() << "[CPIM] Message is invalid: " << contentBody; lError() << "[CPIM] Message is invalid: " << contentBody;
*errorCode = 500; *errorCode = 500;
return ChatMessageModifier::Result::Error; return ChatMessageModifier::Result::Error;
@ -69,30 +69,30 @@ ChatMessageModifier::Result CpimChatMessageModifier::encode (ChatMessagePrivate
Content newContent; Content newContent;
ContentType newContentType("Message/CPIM"); ContentType newContentType("Message/CPIM");
newContent.setContentType(newContentType); newContent.setContentType(newContentType);
newContent.setBody(message.asString()); newContent.setBody(cpimMessage.asString());
messagePrivate->internalContent = newContent; message->setInternalContent(newContent);
} }
return ChatMessageModifier::Result::Done; return ChatMessageModifier::Result::Done;
} }
ChatMessageModifier::Result CpimChatMessageModifier::decode (ChatMessagePrivate *messagePrivate, int *errorCode) { ChatMessageModifier::Result CpimChatMessageModifier::decode (shared_ptr<ChatMessage> message, int *errorCode) {
Content content; Content content;
if (!messagePrivate->internalContent.isEmpty()) { if (!message->getInternalContent().isEmpty()) {
content = messagePrivate->internalContent; content = message->getInternalContent();
} else { } else {
content = messagePrivate->contents.front(); content = message->getContents().front();
} }
if (content.getContentType() == ContentType::Cpim) { if (content.getContentType() == ContentType::Cpim) {
const vector<char> body = content.getBody(); const vector<char> body = content.getBody();
string contentBody(body.begin(), body.end()); string contentBody(body.begin(), body.end());
shared_ptr<const Cpim::Message> message = Cpim::Message::createFromString(contentBody); shared_ptr<const Cpim::Message> cpimMessage = Cpim::Message::createFromString(contentBody);
if (message && message->isValid()) { if (cpimMessage && cpimMessage->isValid()) {
Content newContent; Content newContent;
ContentType newContentType(message->getContentHeaders()->front()->getValue()); ContentType newContentType(cpimMessage->getContentHeaders()->front()->getValue());
newContent.setContentType(newContentType); newContent.setContentType(newContentType);
newContent.setBody(message->getContent()); newContent.setBody(cpimMessage->getContent());
messagePrivate->internalContent = newContent; message->setInternalContent(newContent);
} else { } else {
lError() << "[CPIM] Message is invalid: " << contentBody; lError() << "[CPIM] Message is invalid: " << contentBody;
*errorCode = 500; *errorCode = 500;

View file

@ -30,8 +30,8 @@ class CpimChatMessageModifier : public ChatMessageModifier {
public: public:
CpimChatMessageModifier () = default; CpimChatMessageModifier () = default;
Result encode (ChatMessagePrivate *messagePrivate, int *errorCode) override; Result encode (std::shared_ptr<ChatMessage> message, int *errorCode) override;
Result decode (ChatMessagePrivate *messagePrivate, int *errorCode) override; Result decode (std::shared_ptr<ChatMessage> message, int *errorCode) override;
}; };
LINPHONE_END_NAMESPACE LINPHONE_END_NAMESPACE

View file

@ -34,16 +34,17 @@ using namespace std;
LINPHONE_BEGIN_NAMESPACE LINPHONE_BEGIN_NAMESPACE
ChatMessageModifier::Result EncryptionChatMessageModifier::encode (ChatMessagePrivate *messagePrivate, int *errorCode) { ChatMessageModifier::Result EncryptionChatMessageModifier::encode (shared_ptr<ChatMessage> message, int *errorCode) {
int retval = -1; int retval = -1;
LinphoneImEncryptionEngine *imee = messagePrivate->chatRoom->getCore()->im_encryption_engine; shared_ptr<ChatRoom> chatRoom = message->getChatRoom();
LinphoneImEncryptionEngine *imee = chatRoom->getCore()->im_encryption_engine;
if (imee) { if (imee) {
LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee); LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee);
LinphoneImEncryptionEngineCbsOutgoingMessageCb cbProcessOutgoingMessage = linphone_im_encryption_engine_cbs_get_process_outgoing_message(imeeCbs); LinphoneImEncryptionEngineCbsOutgoingMessageCb cbProcessOutgoingMessage = linphone_im_encryption_engine_cbs_get_process_outgoing_message(imeeCbs);
if (cbProcessOutgoingMessage) { if (cbProcessOutgoingMessage) {
retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(messagePrivate->chatRoom), L_GET_C_BACK_PTR(messagePrivate->getPublic()->getSharedFromThis())); retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(chatRoom), L_GET_C_BACK_PTR(message->getSharedFromThis()));
if (retval == 0 || retval == 1) { if (retval == 0 || retval == 1) {
messagePrivate->isSecured = true; message->setIsSecured(true);
if (retval == 1) { if (retval == 1) {
return ChatMessageModifier::Result::Suspended; return ChatMessageModifier::Result::Suspended;
} }
@ -58,16 +59,17 @@ ChatMessageModifier::Result EncryptionChatMessageModifier::encode (ChatMessagePr
return ChatMessageModifier::Result::Skipped; return ChatMessageModifier::Result::Skipped;
} }
ChatMessageModifier::Result EncryptionChatMessageModifier::decode (ChatMessagePrivate *messagePrivate, int *errorCode) { ChatMessageModifier::Result EncryptionChatMessageModifier::decode (shared_ptr<ChatMessage> message, int *errorCode) {
int retval = -1; int retval = -1;
LinphoneImEncryptionEngine *imee = messagePrivate->chatRoom->getCore()->im_encryption_engine; shared_ptr<ChatRoom> chatRoom = message->getChatRoom();
LinphoneImEncryptionEngine *imee = chatRoom->getCore()->im_encryption_engine;
if (imee) { if (imee) {
LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee); LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee);
LinphoneImEncryptionEngineCbsIncomingMessageCb cbProcessIncomingMessage = linphone_im_encryption_engine_cbs_get_process_incoming_message(imeeCbs); LinphoneImEncryptionEngineCbsIncomingMessageCb cbProcessIncomingMessage = linphone_im_encryption_engine_cbs_get_process_incoming_message(imeeCbs);
if (cbProcessIncomingMessage) { if (cbProcessIncomingMessage) {
retval = cbProcessIncomingMessage(imee, L_GET_C_BACK_PTR(messagePrivate->chatRoom), L_GET_C_BACK_PTR(messagePrivate->getPublic()->getSharedFromThis())); retval = cbProcessIncomingMessage(imee, L_GET_C_BACK_PTR(chatRoom), L_GET_C_BACK_PTR(message->getSharedFromThis()));
if (retval == 0) { if (retval == 0) {
messagePrivate->isSecured = true; message->setIsSecured(true);
return ChatMessageModifier::Result::Done; return ChatMessageModifier::Result::Done;
} else if (retval == -1) { } else if (retval == -1) {
return ChatMessageModifier::Result::Skipped; return ChatMessageModifier::Result::Skipped;

View file

@ -30,8 +30,8 @@ class EncryptionChatMessageModifier : public ChatMessageModifier {
public: public:
EncryptionChatMessageModifier () = default; EncryptionChatMessageModifier () = default;
Result encode (ChatMessagePrivate *messagePrivate, int *errorCode) override; Result encode (std::shared_ptr<ChatMessage> message, int *errorCode) override;
Result decode (ChatMessagePrivate *messagePrivate, int *errorCode) override; Result decode (std::shared_ptr<ChatMessage> message, int *errorCode) override;
}; };
LINPHONE_END_NAMESPACE LINPHONE_END_NAMESPACE

View file

@ -27,22 +27,22 @@ using namespace std;
LINPHONE_BEGIN_NAMESPACE LINPHONE_BEGIN_NAMESPACE
ChatMessageModifier::Result MultipartChatMessageModifier::encode (ChatMessagePrivate *messagePrivate, int *errorCode) { ChatMessageModifier::Result MultipartChatMessageModifier::encode (shared_ptr<ChatMessage> message, int *errorCode) {
if (messagePrivate->contents.size() > 1) { if (message->getContents().size() > 1) {
//TODO //TODO
return ChatMessageModifier::Result::Done; return ChatMessageModifier::Result::Done;
} }
return ChatMessageModifier::Result::Skipped; return ChatMessageModifier::Result::Skipped;
} }
ChatMessageModifier::Result MultipartChatMessageModifier::decode (ChatMessagePrivate *messagePrivate, int *errorCode) { ChatMessageModifier::Result MultipartChatMessageModifier::decode (shared_ptr<ChatMessage> message, int *errorCode) {
//TODO //TODO
if (false) { // Multipart required if (false) { // Multipart required
return ChatMessageModifier::Result::Done; return ChatMessageModifier::Result::Done;
} else if (messagePrivate->contents.size() == 0) { } else if (message->getContents().size() == 0) {
// All previous modifiers only altered the internal content, let's fill the content list because we're the last modifier to be called // All previous modifiers only altered the internal content, let's fill the content list because we're the last modifier to be called
messagePrivate->contents.push_back(messagePrivate->internalContent); message->addContent(message->getInternalContent());
} }
return ChatMessageModifier::Result::Skipped; return ChatMessageModifier::Result::Skipped;
} }

View file

@ -30,8 +30,8 @@ class MultipartChatMessageModifier : public ChatMessageModifier {
public: public:
MultipartChatMessageModifier () = default; MultipartChatMessageModifier () = default;
Result encode (ChatMessagePrivate *message, int *errorCode) override; Result encode (std::shared_ptr<ChatMessage> message, int *errorCode) override;
Result decode (ChatMessagePrivate *message, int *errorCode) override; Result decode (std::shared_ptr<ChatMessage> message, int *errorCode) override;
}; };
LINPHONE_END_NAMESPACE LINPHONE_END_NAMESPACE