From 5b9afdca3c850e7b33ac9555e8dc3e5e77d4e241 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Sun, 1 May 2016 22:54:40 -0700 Subject: Added partID to RFC 822 messages, provided a way to retrieve data for serialized MessageParser --- src/core/renderer/MCHTMLRenderer.cpp | 53 +++++++++----- src/core/renderer/MCHTMLRenderer.h | 2 + src/core/renderer/MCHTMLRendererCallback.cpp | 8 ++- src/core/renderer/MCHTMLRendererCallback.h | 7 ++ src/core/rfc822/MCAttachment.cpp | 15 +++- src/core/rfc822/MCAttachment.h | 5 ++ src/core/rfc822/MCMessageParser.cpp | 102 ++++++++++++++++++++++++++- src/core/rfc822/MCMessageParser.h | 15 ++++ src/core/rfc822/MCMessagePart.cpp | 19 +++++ src/core/rfc822/MCMessagePart.h | 10 ++- src/core/rfc822/MCMultipart.cpp | 19 +++++ src/core/rfc822/MCMultipart.h | 10 ++- 12 files changed, 241 insertions(+), 24 deletions(-) (limited to 'src/core') diff --git a/src/core/renderer/MCHTMLRenderer.cpp b/src/core/renderer/MCHTMLRenderer.cpp index c42bcb45..4c149df9 100644 --- a/src/core/renderer/MCHTMLRenderer.cpp +++ b/src/core/renderer/MCHTMLRenderer.cpp @@ -16,7 +16,7 @@ using namespace mailcore; -class HTMLRendererIMAPDummyCallback : public HTMLRendererIMAPCallback { +class HTMLRendererIMAPDummyCallback : public HTMLRendererIMAPCallback, public HTMLRendererRFC822Callback { private: Array *mRequiredParts; @@ -44,6 +44,12 @@ public: return mRequiredParts; } + virtual Data * dataForRFC822Part(String * folder, Attachment * part) + { + mRequiredParts->addObject(part); + return Data::data(); + } + }; enum { @@ -53,7 +59,8 @@ enum { }; struct htmlRendererContext { - HTMLRendererIMAPCallback * dataCallback; + HTMLRendererIMAPCallback * imapDataCallback; + HTMLRendererRFC822Callback * rfc822DataCallback; HTMLRendererTemplateCallback * htmlCallback; int firstRendered; String * folder; @@ -82,6 +89,7 @@ static String * renderTemplate(String * templateContent, HashMap * values); static String * htmlForAbstractMessage(String * folder, AbstractMessage * message, HTMLRendererIMAPCallback * dataCallback, + HTMLRendererRFC822Callback * rfc822DataCallback, HTMLRendererTemplateCallback * htmlCallback, Array * attachments, Array * relatedAttachments); @@ -176,7 +184,8 @@ static bool messagePartContainsMimeType(AbstractMessagePart * part, String * mim } static String * htmlForAbstractMessage(String * folder, AbstractMessage * message, - HTMLRendererIMAPCallback * dataCallback, + HTMLRendererIMAPCallback * imapDataCallback, + HTMLRendererRFC822Callback * rfc822DataCallback, HTMLRendererTemplateCallback * htmlCallback, Array * attachments, Array * relatedAttachments) @@ -197,7 +206,8 @@ static String * htmlForAbstractMessage(String * folder, AbstractMessage * messag MCAssert(mainPart != NULL); htmlRendererContext context; - context.dataCallback = dataCallback; + context.imapDataCallback = imapDataCallback; + context.rfc822DataCallback = rfc822DataCallback; context.htmlCallback = htmlCallback; context.relatedAttachments = NULL; context.attachments = NULL; @@ -310,10 +320,15 @@ static String * htmlForAbstractSinglePart(AbstractPart * part, htmlRendererConte String * charset = part->charset(); Data * data = NULL; if (part->className()->isEqual(MCSTR("mailcore::IMAPPart"))) { - data = context->dataCallback->dataForIMAPPart(context->folder, (IMAPPart *) part); + data = context->imapDataCallback->dataForIMAPPart(context->folder, (IMAPPart *) part); } else if (part->className()->isEqual(MCSTR("mailcore::Attachment"))) { data = ((Attachment *) part)->data(); + if (data == NULL) { + // It may be NULL when mailcore::MessageParser::attachments() is invoked when + // when mailcore::MessageParser has been serialized/unserialized. + data = context->rfc822DataCallback->dataForRFC822Part(context->folder, (Attachment *) part); + } MCAssert(data != NULL); } if (data == NULL) @@ -329,12 +344,15 @@ static String * htmlForAbstractSinglePart(AbstractPart * part, htmlRendererConte String * charset = part->charset(); Data * data = NULL; if (part->className()->isEqual(MCSTR("mailcore::IMAPPart"))) { - data = context->dataCallback->dataForIMAPPart(context->folder, (IMAPPart *) part); + data = context->imapDataCallback->dataForIMAPPart(context->folder, (IMAPPart *) part); } else if (part->className()->isEqual(MCSTR("mailcore::Attachment"))) { data = ((Attachment *) part)->data(); - // It may be NULL when mailcore::MessageParser::attachments() is invoked when - // when mailcore::MessageParser has been serialized/unserialized. + if (data == NULL) { + // It may be NULL when mailcore::MessageParser::attachments() is invoked when + // when mailcore::MessageParser has been serialized/unserialized. + data = context->rfc822DataCallback->dataForRFC822Part(context->folder, (Attachment *) part); + } } if (data == NULL) return NULL; @@ -381,7 +399,7 @@ static String * htmlForAbstractSinglePart(AbstractPart * part, htmlRendererConte if (context->htmlCallback->canPreviewPart(part)) { if (part->className()->isEqual(MCSTR("mailcore::IMAPPart"))) { - context->dataCallback->prefetchImageIMAPPart(context->folder, (IMAPPart *) part); + context->imapDataCallback->prefetchImageIMAPPart(context->folder, (IMAPPart *) part); } String * url = String::stringWithUTF8Format("x-mailcore-image:%s", part->uniqueID()->UTF8Characters()); @@ -391,7 +409,7 @@ static String * htmlForAbstractSinglePart(AbstractPart * part, htmlRendererConte } else { if (part->className()->isEqual(MCSTR("mailcore::IMAPPart"))) { - context->dataCallback->prefetchAttachmentIMAPPart(context->folder, (IMAPPart *) part); + context->imapDataCallback->prefetchAttachmentIMAPPart(context->folder, (IMAPPart *) part); } HashMap * values = context->htmlCallback->templateValuesForPart(part); content = renderTemplate(context->htmlCallback->templateForAttachment(part), values); @@ -552,9 +570,10 @@ static String * renderTemplate(String * templateContent, HashMap * values) } String * HTMLRenderer::htmlForRFC822Message(MessageParser * message, + HTMLRendererRFC822Callback * dataCallback, HTMLRendererTemplateCallback * htmlCallback) { - return htmlForAbstractMessage(NULL, message, NULL, htmlCallback, NULL, NULL); + return htmlForAbstractMessage(NULL, message, NULL, dataCallback, htmlCallback, NULL, NULL); } String * HTMLRenderer::htmlForIMAPMessage(String * folder, @@ -562,14 +581,14 @@ String * HTMLRenderer::htmlForIMAPMessage(String * folder, HTMLRendererIMAPCallback * dataCallback, HTMLRendererTemplateCallback * htmlCallback) { - return htmlForAbstractMessage(folder, message, dataCallback, htmlCallback, NULL, NULL); + return htmlForAbstractMessage(folder, message, dataCallback, NULL, htmlCallback, NULL, NULL); } Array * HTMLRenderer::attachmentsForMessage(AbstractMessage * message) { Array * attachments = Array::array(); - HTMLRendererIMAPCallback * dataCallback = new HTMLRendererIMAPDummyCallback(); - String * ignoredResult = htmlForAbstractMessage(NULL, message, dataCallback, NULL, attachments, NULL); + HTMLRendererIMAPDummyCallback * dataCallback = new HTMLRendererIMAPDummyCallback(); + String * ignoredResult = htmlForAbstractMessage(NULL, message, dataCallback, dataCallback, NULL, attachments, NULL); delete dataCallback; dataCallback = NULL; (void) ignoredResult; // remove unused variable warning. @@ -579,8 +598,8 @@ Array * HTMLRenderer::attachmentsForMessage(AbstractMessage * message) Array * HTMLRenderer::htmlInlineAttachmentsForMessage(AbstractMessage * message) { Array * htmlInlineAttachments = Array::array(); - HTMLRendererIMAPCallback * dataCallback = new HTMLRendererIMAPDummyCallback(); - String * ignoredResult = htmlForAbstractMessage(NULL, message, dataCallback, NULL, NULL, htmlInlineAttachments); + HTMLRendererIMAPDummyCallback * dataCallback = new HTMLRendererIMAPDummyCallback(); + String * ignoredResult = htmlForAbstractMessage(NULL, message, dataCallback, dataCallback, NULL, NULL, htmlInlineAttachments); delete dataCallback; dataCallback = NULL; (void) ignoredResult; // remove unused variable warning. @@ -590,7 +609,7 @@ Array * HTMLRenderer::htmlInlineAttachmentsForMessage(AbstractMessage * message) Array * HTMLRenderer::requiredPartsForRendering(AbstractMessage * message) { HTMLRendererIMAPDummyCallback * dataCallback = new HTMLRendererIMAPDummyCallback(); - String * ignoredResult = htmlForAbstractMessage(NULL, message, dataCallback, NULL, NULL, NULL); + String * ignoredResult = htmlForAbstractMessage(NULL, message, dataCallback, dataCallback, NULL, NULL, NULL); Array *requiredParts = dataCallback->requiredParts(); diff --git a/src/core/renderer/MCHTMLRenderer.h b/src/core/renderer/MCHTMLRenderer.h index dc527b2f..b3926a31 100644 --- a/src/core/renderer/MCHTMLRenderer.h +++ b/src/core/renderer/MCHTMLRenderer.h @@ -21,10 +21,12 @@ namespace mailcore { class MessageParser; class HTMLRendererTemplateCallback; class HTMLRendererIMAPCallback; + class HTMLRendererRFC822Callback; class MAILCORE_EXPORT HTMLRenderer { public: static String * htmlForRFC822Message(MessageParser * message, + HTMLRendererRFC822Callback * dataCallback, HTMLRendererTemplateCallback * htmlCallback); static String * htmlForIMAPMessage(String * folder, diff --git a/src/core/renderer/MCHTMLRendererCallback.cpp b/src/core/renderer/MCHTMLRendererCallback.cpp index 194416ba..20c4873c 100644 --- a/src/core/renderer/MCHTMLRendererCallback.cpp +++ b/src/core/renderer/MCHTMLRendererCallback.cpp @@ -181,9 +181,11 @@ mailcore::HashMap * HTMLRendererTemplateCallback::templateValuesForPart(mailcore } else if (part->className()->isEqual(MCSTR("mailcore::Attachment"))) { mailcore::Attachment * attachment = (mailcore::Attachment *) part; - mailcore::String * value = mailcore::SizeFormatter::stringWithSize(attachment->data()->length()); - result->setObjectForKey(MCSTR("SIZE"), value); - result->setObjectForKey(MCSTR("HASSIZE"), mailcore::HashMap::hashMap()); + if (attachment->data() != NULL) { + mailcore::String * value = mailcore::SizeFormatter::stringWithSize(attachment->data()->length()); + result->setObjectForKey(MCSTR("SIZE"), value); + result->setObjectForKey(MCSTR("HASSIZE"), mailcore::HashMap::hashMap()); + } } else { result->setObjectForKey(MCSTR("NOSIZE"), mailcore::HashMap::hashMap()); diff --git a/src/core/renderer/MCHTMLRendererCallback.h b/src/core/renderer/MCHTMLRendererCallback.h index 4a4fc40f..6078f9eb 100644 --- a/src/core/renderer/MCHTMLRendererCallback.h +++ b/src/core/renderer/MCHTMLRendererCallback.h @@ -19,6 +19,7 @@ namespace mailcore { class MessageParser; + class Attachment; class MAILCORE_EXPORT HTMLRendererIMAPCallback { public: @@ -59,6 +60,12 @@ namespace mailcore { // Can be used to hide quoted text. virtual String * filterHTMLForMessage(String * html); }; + + class MAILCORE_EXPORT HTMLRendererRFC822Callback { + public: + virtual Data * dataForRFC822Part(String * folder, Attachment * part) { return NULL; } + + }; } diff --git a/src/core/rfc822/MCAttachment.cpp b/src/core/rfc822/MCAttachment.cpp index cdee201b..e6ebc9c9 100644 --- a/src/core/rfc822/MCAttachment.cpp +++ b/src/core/rfc822/MCAttachment.cpp @@ -223,6 +223,7 @@ Attachment * Attachment::attachmentWithText(String * text) void Attachment::init() { mData = NULL; + mPartID = NULL; setMimeType(MCSTR("application/octet-stream")); } @@ -234,11 +235,13 @@ Attachment::Attachment() Attachment::Attachment(Attachment * other) : AbstractPart(other) { init(); - MC_SAFE_REPLACE_RETAIN(Data, mData, other->mData); + setData(other->data()); + setPartID(other->partID()); } Attachment::~Attachment() { + MC_SAFE_RELEASE(mPartID); MC_SAFE_RELEASE(mData); } @@ -278,6 +281,16 @@ Object * Attachment::copy() return new Attachment(this); } +void Attachment::setPartID(String * partID) +{ + MC_SAFE_REPLACE_COPY(String, mPartID, partID); +} + +String * Attachment::partID() +{ + return mPartID; +} + void Attachment::setData(Data * data) { MC_SAFE_REPLACE_RETAIN(Data, mData, data); diff --git a/src/core/rfc822/MCAttachment.h b/src/core/rfc822/MCAttachment.h index deacf75e..ae02d256 100644 --- a/src/core/rfc822/MCAttachment.h +++ b/src/core/rfc822/MCAttachment.h @@ -25,6 +25,9 @@ namespace mailcore { Attachment(); virtual ~Attachment(); + virtual void setPartID(String * partID); + virtual String * partID(); + virtual void setData(Data * data); virtual Data * data(); virtual String * decodedString(); @@ -39,6 +42,8 @@ namespace mailcore { private: Data * mData; + String * mPartID; + void init(); static void fillMultipartSubAttachments(AbstractMultipart * multipart, struct mailmime * mime); static AbstractPart * attachmentsWithMIMEWithMain(struct mailmime * mime, bool isMain); diff --git a/src/core/rfc822/MCMessageParser.cpp b/src/core/rfc822/MCMessageParser.cpp index beddeebc..e68d701b 100644 --- a/src/core/rfc822/MCMessageParser.cpp +++ b/src/core/rfc822/MCMessageParser.cpp @@ -71,6 +71,8 @@ void MessageParser::setBytes(char * dataBytes, unsigned int dataLength) mailimf_fields_free(fields); } mailmessage_free(msg); + + setupPartID(); } MessageParser::MessageParser() @@ -91,6 +93,7 @@ MessageParser::MessageParser(MessageParser * other) : AbstractMessage(other) init(); MC_SAFE_REPLACE_RETAIN(Data, mData, other->mData); MC_SAFE_REPLACE_RETAIN(AbstractPart, mMainPart, other->mMainPart); + setupPartID(); } MessageParser::~MessageParser() @@ -148,6 +151,7 @@ void MessageParser::importSerializable(HashMap * serializable) if (mMainPart != NULL) { mMainPart->applyUniquePartID(); } + setupPartID(); } Object * MessageParser::copy() @@ -173,7 +177,13 @@ AbstractPart * MessageParser::partForUniqueID(String * uniqueID) String * MessageParser::htmlRendering(HTMLRendererTemplateCallback * htmlCallback) { - return HTMLRenderer::htmlForRFC822Message(this, htmlCallback); + return HTMLRenderer::htmlForRFC822Message(this, NULL, htmlCallback); +} + +String * MessageParser::htmlRenderingWithDataCallback(HTMLRendererTemplateCallback * htmlCallback, + HTMLRendererRFC822Callback * dataCallback) +{ + return HTMLRenderer::htmlForRFC822Message(this, dataCallback, htmlCallback); } String * MessageParser::htmlBodyRendering() @@ -201,6 +211,96 @@ String * MessageParser::plainTextBodyRendering(bool stripWhitespace) return plainTextBodyString; } +void MessageParser::setupPartID() +{ + if (mMainPart == NULL) { + return; + } + recursiveSetupPartIDWithPart(mMainPart, MCSTR("")); +} + +void MessageParser::recursiveSetupPartIDWithPart(mailcore::AbstractPart * part, + mailcore::String * partIDPrefix) +{ + switch (part->partType()) { + case PartTypeSingle: + { + String * partID = NULL; + if (partIDPrefix->length() == 0) { + partID = MCSTR("1"); + } + else { + partID = partIDPrefix; + } + return recursiveSetupPartIDWithSinglePart((Attachment *) part, partID); + } + case PartTypeMessage: + { + String * partID = NULL; + if (partIDPrefix->length() == 0) { + partID = MCSTR("1"); + } + else { + partID = partIDPrefix; + } + return recursiveSetupPartIDWithMessagePart((MessagePart *) part, partID); + } + case PartTypeMultipartMixed: + case PartTypeMultipartRelated: + case PartTypeMultipartAlternative: + case PartTypeMultipartSigned: + return recursiveSetupPartIDWithMultipart((Multipart *) part, partIDPrefix); + default: + MCAssert(0); + } +} + +void MessageParser::recursiveSetupPartIDWithSinglePart(mailcore::Attachment * part, + mailcore::String * partIDPrefix) +{ + part->setPartID(partIDPrefix); +} + +void MessageParser::recursiveSetupPartIDWithMessagePart(mailcore::MessagePart * part, + mailcore::String * partIDPrefix) +{ + part->setPartID(partIDPrefix); + String * partID = NULL; + switch (part->mainPart()->partType()) { + case PartTypeSingle: + case PartTypeMessage: + { + if (partIDPrefix->length() == 0) { + partID = MCSTR("1"); + } + else { + partID = partIDPrefix->stringByAppendingUTF8Characters(".1"); + } + break; + } + default: + partID = partIDPrefix; + break; + } + recursiveSetupPartIDWithPart(part->mainPart(), partID); +} + +void MessageParser::recursiveSetupPartIDWithMultipart(mailcore::Multipart * part, + mailcore::String * partIDPrefix) +{ + part->setPartID(partIDPrefix); + mc_foreacharrayIndex(idx, AbstractPart, subpart, part->parts()) { + String * partID = NULL; + if (partIDPrefix->length() == 0) { + partID = String::stringWithUTF8Format("%u", idx + 1); + } + else { + partID = partIDPrefix->stringByAppendingUTF8Format(".%u", idx + 1); + } + recursiveSetupPartIDWithPart(subpart, partID); + } +} + static void * createObject() { return new MessageParser(); diff --git a/src/core/rfc822/MCMessageParser.h b/src/core/rfc822/MCMessageParser.h index 9682bfce..4541b41c 100644 --- a/src/core/rfc822/MCMessageParser.h +++ b/src/core/rfc822/MCMessageParser.h @@ -14,6 +14,10 @@ namespace mailcore { class HTMLRendererTemplateCallback; + class HTMLRendererRFC822Callback; + class Multipart; + class MessagePart; + class Attachment; class MAILCORE_EXPORT MessageParser : public AbstractMessage { public: @@ -28,6 +32,8 @@ namespace mailcore { virtual Data * data(); virtual String * htmlRendering(HTMLRendererTemplateCallback * htmlCallback = NULL); + virtual String * htmlRenderingWithDataCallback(HTMLRendererTemplateCallback * htmlCallback, + HTMLRendererRFC822Callback * dataCallback); virtual String * htmlBodyRendering(); virtual String * plainTextRendering(); @@ -61,6 +67,15 @@ namespace mailcore { private: void setBytes(char * bytes, unsigned int length); Data * dataFromNSData(); + void setupPartID(); + void recursiveSetupPartIDWithPart(mailcore::AbstractPart * part, + mailcore::String * partIDPrefix); + void recursiveSetupPartIDWithSinglePart(mailcore::Attachment * part, + mailcore::String * partIDPrefix); + void recursiveSetupPartIDWithMessagePart(mailcore::MessagePart * part, + mailcore::String * partIDPrefix); + void recursiveSetupPartIDWithMultipart(mailcore::Multipart * part, + mailcore::String * partIDPrefix); }; }; diff --git a/src/core/rfc822/MCMessagePart.cpp b/src/core/rfc822/MCMessagePart.cpp index abd98ac2..9862bc29 100644 --- a/src/core/rfc822/MCMessagePart.cpp +++ b/src/core/rfc822/MCMessagePart.cpp @@ -6,14 +6,33 @@ using namespace mailcore; MessagePart::MessagePart() { + init(); } MessagePart::MessagePart(MessagePart * other) : AbstractMessagePart(other) { + init(); + setPartID(other->partID()); +} + +void MessagePart::init() +{ + mPartID = NULL; } MessagePart::~MessagePart() { + MC_SAFE_RELEASE(mPartID); +} + +void MessagePart::setPartID(String * partID) +{ + MC_SAFE_REPLACE_COPY(String, mPartID, partID); +} + +String * MessagePart::partID() +{ + return mPartID; } Object * MessagePart::copy() diff --git a/src/core/rfc822/MCMessagePart.h b/src/core/rfc822/MCMessagePart.h index 894cd3e5..04879ba3 100644 --- a/src/core/rfc822/MCMessagePart.h +++ b/src/core/rfc822/MCMessagePart.h @@ -13,10 +13,18 @@ namespace mailcore { public: MessagePart(); virtual ~MessagePart(); - + + virtual void setPartID(String * partID); + virtual String * partID(); + public: // subclass behavior MessagePart(MessagePart * other); virtual Object * copy(); + + private: + String * mPartID; + + void init(); }; } diff --git a/src/core/rfc822/MCMultipart.cpp b/src/core/rfc822/MCMultipart.cpp index 0be76430..0e3ee1ab 100644 --- a/src/core/rfc822/MCMultipart.cpp +++ b/src/core/rfc822/MCMultipart.cpp @@ -6,14 +6,33 @@ using namespace mailcore; Multipart::Multipart() { + init(); } Multipart::Multipart(Multipart * other) : AbstractMultipart(other) { + init(); + setPartID(other->partID()); +} + +void Multipart::init() +{ + mPartID = NULL; } Multipart::~Multipart() { + MC_SAFE_RELEASE(mPartID); +} + +void Multipart::setPartID(String * partID) +{ + MC_SAFE_REPLACE_COPY(String, mPartID, partID); +} + +String * Multipart::partID() +{ + return mPartID; } Object * Multipart::copy() diff --git a/src/core/rfc822/MCMultipart.h b/src/core/rfc822/MCMultipart.h index 40b0a48b..d389f522 100644 --- a/src/core/rfc822/MCMultipart.h +++ b/src/core/rfc822/MCMultipart.h @@ -13,10 +13,18 @@ namespace mailcore { public: Multipart(); virtual ~Multipart(); - + + virtual void setPartID(String * partID); + virtual String * partID(); + public: // subclass behavior Multipart(Multipart * other); virtual Object * copy(); + + private: + String * mPartID; + + void init(); }; } -- cgit v1.2.3