
2 changed files with 319 additions and 0 deletions
@ -0,0 +1,246 @@ |
|||
#include "message_cache.hh" |
|||
|
|||
pEp::MessageCache message_cache; |
|||
|
|||
namespace pEp { |
|||
DYNAMIC_API PEP_STATUS MessageCache::cache_decrypt_message( |
|||
PEP_SESSION session, |
|||
message *src, |
|||
message **dst, |
|||
stringlist_t **keylist, |
|||
PEP_rating *rating, |
|||
PEP_decrypt_flags_t *flags |
|||
) |
|||
{ |
|||
return message_cache.decrypt_message(session, src, dst, keylist, |
|||
rating, flags); |
|||
} |
|||
|
|||
DYNAMIC_API PEP_STATUS MessageCache::cached_mime_encode_message( |
|||
which one, |
|||
const message * msg, |
|||
bool omit_fields, |
|||
char **mimetext, |
|||
bool has_pEp_msg_attachment |
|||
) |
|||
{ |
|||
return message_cache.mime_encode_message(one, msg, omit_fields, |
|||
mimetext, has_pEp_msg_attachment); |
|||
} |
|||
|
|||
static char *dup(const char *src) |
|||
{ |
|||
if (!src) |
|||
return nullptr; |
|||
|
|||
char * dst = ::strdup(src); |
|||
assert(dst); |
|||
if (!dst) |
|||
throw std::bad_alloc(); |
|||
|
|||
return dst; |
|||
} |
|||
|
|||
static timestamp *dup(const ::timestamp *src) |
|||
{ |
|||
if (!src) |
|||
return nullptr; |
|||
|
|||
::timestamp * dst = ::timestamp_dup(src); |
|||
if (!dst) |
|||
throw std::bad_alloc(); |
|||
|
|||
return dst; |
|||
} |
|||
|
|||
static ::pEp_identity *dup(const ::pEp_identity *src) |
|||
{ |
|||
if (!src) |
|||
return nullptr; |
|||
|
|||
::pEp_identity * dst = ::identity_dup(src); |
|||
if (!dst) |
|||
throw std::bad_alloc(); |
|||
|
|||
return dst; |
|||
} |
|||
|
|||
static identity_list *dup(const ::identity_list *src) |
|||
{ |
|||
if (!src) |
|||
return nullptr; |
|||
|
|||
::identity_list * dst = ::identity_list_dup(src); |
|||
if (!dst) |
|||
throw std::bad_alloc(); |
|||
|
|||
return dst; |
|||
} |
|||
|
|||
static stringlist_t *dup(const ::stringlist_t *src) |
|||
{ |
|||
if (!src) |
|||
return nullptr; |
|||
|
|||
::stringlist_t * dst = ::stringlist_dup(src); |
|||
if (!dst) |
|||
throw std::bad_alloc(); |
|||
|
|||
return dst; |
|||
} |
|||
|
|||
static stringpair_list_t *dup(const ::stringpair_list_t *src) |
|||
{ |
|||
if (!src) |
|||
return nullptr; |
|||
|
|||
::stringpair_list_t * dst = ::stringpair_list_dup(src); |
|||
if (!dst) |
|||
throw std::bad_alloc(); |
|||
|
|||
return dst; |
|||
} |
|||
|
|||
static ::message_ref_list *dup(const ::message_ref_list *src) { |
|||
if (!src) |
|||
return nullptr; |
|||
|
|||
::message_ref_list *dst = (::message_ref_list *) ::calloc(1, |
|||
sizeof(::message_ref_list)); |
|||
assert(dst); |
|||
if (!dst) |
|||
throw std::bad_alloc(); |
|||
|
|||
::message_ref_list *d = dst; |
|||
for (const message_ref_list *s = src; s; s = s->next) { |
|||
d->msg_ref = s->msg_ref; |
|||
if (s->next) { |
|||
d->next = (::message_ref_list *) ::calloc(1, |
|||
sizeof(::message_ref_list)); |
|||
assert(d); |
|||
if (!d) |
|||
throw std::bad_alloc(); |
|||
d = d->next; |
|||
} |
|||
} |
|||
|
|||
return dst; |
|||
} |
|||
|
|||
static bool emptystr(const char *str) |
|||
{ |
|||
if (!(str && str[0])) |
|||
return true; |
|||
return false; |
|||
} |
|||
|
|||
::message *MessageCache::empty_message_copy(::message *src) |
|||
{ |
|||
if (!src) |
|||
return nullptr; |
|||
|
|||
::message *dst = ::new_message(src->dir); |
|||
if (!dst) |
|||
throw std::bad_alloc(); |
|||
|
|||
dst->id = dup(src->id); |
|||
dst->shortmsg = dup(src->shortmsg); |
|||
|
|||
if (!emptystr(src->longmsg)) |
|||
dst->longmsg = dup("pEp"); |
|||
|
|||
if (!emptystr(src->longmsg_formatted)) |
|||
dst->longmsg_formatted = dup("<pEp/>"); |
|||
|
|||
// attachments are never copied
|
|||
|
|||
dst->rawmsg_ref = src->rawmsg_ref; |
|||
dst->rawmsg_size = src->rawmsg_size; |
|||
|
|||
dst->sent = dup(src->sent); |
|||
dst->recv = dup(src->recv); |
|||
|
|||
dst->from = dup(src->from); |
|||
dst->to = dup(src->to); |
|||
dst->cc = dup(src->cc); |
|||
dst->bcc = dup(src->bcc); |
|||
|
|||
dst->reply_to = dup(src->reply_to); |
|||
dst->in_reply_to = dup(src->in_reply_to); |
|||
|
|||
dst->refering_msg_ref = src->refering_msg_ref; |
|||
dst->references = dup(src->references); |
|||
dst->refered_by = dup(src->refered_by); |
|||
|
|||
dst->keywords = dup(src->keywords); |
|||
dst->comments = dup(src->comments); |
|||
dst->opt_fields = dup(src->opt_fields); |
|||
dst->enc_format = src->enc_format; |
|||
dst->_sender_fpr = dup(src->_sender_fpr); |
|||
|
|||
return dst; |
|||
} |
|||
|
|||
DYNAMIC_API PEP_STATUS MessageCache::decrypt_message( |
|||
PEP_SESSION session, |
|||
message *src, |
|||
message **dst, |
|||
stringlist_t **keylist, |
|||
PEP_rating *rating, |
|||
PEP_decrypt_flags_t *flags |
|||
) |
|||
{ |
|||
if (!src || emptystr(src->id)) |
|||
return PEP_ILLEGAL_VALUE; |
|||
|
|||
PEP_STATUS status = ::decrypt_message(session, src, dst, keylist, |
|||
rating, flags); |
|||
|
|||
::message *_cpy = empty_message_copy(src); |
|||
|
|||
::message *_src; |
|||
::memcpy(_src, src, sizeof(::message)); |
|||
::memcpy(src, _cpy, sizeof(::message)); |
|||
|
|||
::message *_dst = *dst; |
|||
*dst = empty_message_copy(_dst); |
|||
|
|||
message_cache._cache.emplace(std::make_pair(std::string(_src->id), |
|||
cache_entry(_src, _dst))); |
|||
return status; |
|||
} |
|||
|
|||
DYNAMIC_API PEP_STATUS MessageCache::mime_encode_message( |
|||
which one, |
|||
const message * msg, |
|||
bool omit_fields, |
|||
char **mimetext, |
|||
bool has_pEp_msg_attachment |
|||
) |
|||
{ |
|||
if (!msg || emptystr(msg->id)) |
|||
return PEP_ILLEGAL_VALUE; |
|||
|
|||
if (one != msg_src && one != msg_dst) |
|||
return PEP_ILLEGAL_VALUE; |
|||
|
|||
::message *_msg; |
|||
if (one == msg_src) { |
|||
_msg = _cache.at(std::string(msg->id)).src; |
|||
::free_message(_cache.at(msg->id).dst); |
|||
} |
|||
else /* msg_dst */ { |
|||
_msg = _cache.at(std::string(msg->id)).dst; |
|||
::free_message(_cache.at(msg->id).src); |
|||
} |
|||
|
|||
PEP_STATUS status = ::mime_encode_message(_msg, omit_fields, mimetext, |
|||
has_pEp_msg_attachment); |
|||
|
|||
::free_message(_msg); |
|||
_cache.erase(msg->id); |
|||
|
|||
return status; |
|||
} |
|||
}; |
|||
|
@ -0,0 +1,73 @@ |
|||
#pragma once |
|||
|
|||
#include <string> |
|||
#include <unordered_map> |
|||
#include <mutex> |
|||
#include <pEp/message_api.h> |
|||
#include <pEp/mime.h> |
|||
|
|||
namespace pEp { |
|||
class MessageCache { |
|||
struct cache_entry { |
|||
cache_entry(::message *s, ::message *d) |
|||
: src(s), dst(d) { } |
|||
~cache_entry() { |
|||
::free_message(src); |
|||
::free_message(dst); |
|||
}; |
|||
|
|||
::message *src; |
|||
::message *dst; |
|||
}; |
|||
|
|||
using cache = std::unordered_map<std::string, cache_entry>; |
|||
|
|||
cache _cache; |
|||
std::mutex _mtx; |
|||
|
|||
public: |
|||
static |
|||
DYNAMIC_API PEP_STATUS cache_decrypt_message( |
|||
PEP_SESSION session, |
|||
message *src, |
|||
message **dst, |
|||
stringlist_t **keylist, |
|||
PEP_rating *rating, |
|||
PEP_decrypt_flags_t *flags |
|||
); |
|||
|
|||
enum which { msg_src, msg_dst };; |
|||
|
|||
static |
|||
DYNAMIC_API PEP_STATUS cached_mime_encode_message( |
|||
which one, |
|||
const message * msg, |
|||
bool omit_fields, |
|||
char **mimetext, |
|||
bool has_pEp_msg_attachment |
|||
); |
|||
|
|||
protected: |
|||
DYNAMIC_API PEP_STATUS decrypt_message( |
|||
PEP_SESSION session, |
|||
message *src, |
|||
message **dst, |
|||
stringlist_t **keylist, |
|||
PEP_rating *rating, |
|||
PEP_decrypt_flags_t *flags |
|||
); |
|||
|
|||
DYNAMIC_API PEP_STATUS mime_encode_message( |
|||
which one, |
|||
const message * src, |
|||
bool omit_fields, |
|||
char **mimetext, |
|||
bool has_pEp_msg_attachment |
|||
); |
|||
|
|||
static ::message *empty_message_copy(::message *src); |
|||
}; |
|||
|
|||
extern MessageCache message_cache; |
|||
}; |
|||
|
Loading…
Reference in new issue