diff options
author | Hoà V. DINH <dinh.viet.hoa@gmail.com> | 2014-08-02 17:51:40 -0700 |
---|---|---|
committer | Hoà V. DINH <dinh.viet.hoa@gmail.com> | 2014-08-02 17:51:40 -0700 |
commit | 3db6e0e46595a617468cf239eae9fe1978e60651 (patch) | |
tree | 6c97ad9f4ac89b24c7cc65aea356e8aff178c120 /src/core/rfc822 | |
parent | 085e89548ed3acc377b21e82bf822dad9836839e (diff) | |
parent | c1efc1d44b0a315b17701aed28c7de096b413337 (diff) |
Merge pull request #814 from foxinushka/feature/attachment-extra-parameters
Added extra parameters to attachment
Diffstat (limited to 'src/core/rfc822')
-rw-r--r-- | src/core/rfc822/MCAttachment.cc | 73 | ||||
-rw-r--r-- | src/core/rfc822/MCAttachment.h | 8 | ||||
-rw-r--r-- | src/core/rfc822/MCMessageBuilder.cc | 81 |
3 files changed, 139 insertions, 23 deletions
diff --git a/src/core/rfc822/MCAttachment.cc b/src/core/rfc822/MCAttachment.cc index d016ad0e..172881cb 100644 --- a/src/core/rfc822/MCAttachment.cc +++ b/src/core/rfc822/MCAttachment.cc @@ -211,6 +211,8 @@ Attachment * Attachment::attachmentWithText(String * text) void Attachment::init() { mData = NULL; + mContentTypeParameters = NULL; + mlcContentTypeParameters = NULL; setMimeType(MCSTR("application/octet-stream")); } @@ -223,11 +225,14 @@ Attachment::Attachment(Attachment * other) : AbstractPart(other) { init(); MC_SAFE_REPLACE_RETAIN(Data, mData, other->mData); + setContentTypeParameters(other->mContentTypeParameters); } Attachment::~Attachment() { MC_SAFE_RELEASE(mData); + MC_SAFE_RELEASE(mContentTypeParameters); + MC_SAFE_RELEASE(mlcContentTypeParameters); } String * Attachment::description() @@ -256,6 +261,11 @@ String * Attachment::description() else { result->appendUTF8Format("no data\n"); } + if (mContentTypeParameters != NULL) { + mc_foreachhashmapKeyAndValue(String, key, String, value, mContentTypeParameters) { + result->appendUTF8Format("%s: %s\n", key->UTF8Characters(), value->UTF8Characters()); + } + } result->appendUTF8Format(">"); return result; @@ -286,6 +296,55 @@ String * Attachment::decodedString() } } +void Attachment::setContentTypeParameters(HashMap * parameters) +{ + MC_SAFE_REPLACE_COPY(HashMap, mContentTypeParameters, parameters); + MC_SAFE_RELEASE(mlcContentTypeParameters); + if (mContentTypeParameters != NULL) { + mlcContentTypeParameters = new HashMap(); + mc_foreachhashmapKeyAndValue(String, key, String, value, mContentTypeParameters) { + mlcContentTypeParameters->setObjectForKey(key->lowercaseString(), value); + } + } +} + +Array * Attachment::allContentTypeParametersNames() +{ + if (mContentTypeParameters == NULL) + return Array::array(); + return mContentTypeParameters->allKeys(); +} + +void Attachment::setContentTypeParameter(String * name, String * object) +{ + if (mContentTypeParameters == NULL) { + mContentTypeParameters = new HashMap(); + } + if (mlcContentTypeParameters == NULL) { + mlcContentTypeParameters = new HashMap(); + } + if (object == NULL) { + removeContentTypeParameter(name); + return; + } + mContentTypeParameters->setObjectForKey(name, object); + mlcContentTypeParameters->setObjectForKey(name->lowercaseString(), object); +} + +void Attachment::removeContentTypeParameter(String * name) +{ + if (mContentTypeParameters == NULL) + return; + mContentTypeParameters->removeObjectForKey(name); + mlcContentTypeParameters->removeObjectForKey(name); +} + +String * Attachment::contentTypeParameterValueForName(String * name) +{ + if (mlcContentTypeParameters == NULL) + return NULL; + return (String *) mlcContentTypeParameters->objectForKey(name->lowercaseString()); +} AbstractPart * Attachment::attachmentsWithMIME(struct mailmime * mime) { @@ -503,6 +562,7 @@ Attachment * Attachment::attachmentWithSingleMIME(struct mailmime * mime) char * description; char * loc; Encoding encoding; + clist * ct_parameters; MCAssert(mime->mm_type == MAILMIME_SINGLE); @@ -531,6 +591,7 @@ Attachment * Attachment::attachmentWithSingleMIME(struct mailmime * mime) content_id = single_fields.fld_id; description = single_fields.fld_description; loc = single_fields.fld_location; + ct_parameters = single_fields.fld_content->ct_parameters; if (filename != NULL) { result->setFilename(String::stringByDecodingMIMEHeaderValue(filename)); @@ -551,6 +612,18 @@ Attachment * Attachment::attachmentWithSingleMIME(struct mailmime * mime) result->setContentLocation(String::stringWithUTF8Characters(loc)); } + if (ct_parameters != NULL) { + clistiter * iter = clist_begin(ct_parameters); + struct mailmime_parameter * param; + while (iter != NULL) { + param = (struct mailmime_parameter *) clist_content(iter); + if (param != NULL) { + result->setContentTypeParameter(String::stringWithUTF8Characters(param->pa_name), String::stringWithUTF8Characters(param->pa_value)); + } + iter = clist_next(iter); + } + } + if (single_fields.fld_disposition != NULL) { if (single_fields.fld_disposition->dsp_type != NULL) { if (single_fields.fld_disposition->dsp_type->dsp_type == MAILMIME_DISPOSITION_TYPE_INLINE) { diff --git a/src/core/rfc822/MCAttachment.h b/src/core/rfc822/MCAttachment.h index 7dd15b89..069688f2 100644 --- a/src/core/rfc822/MCAttachment.h +++ b/src/core/rfc822/MCAttachment.h @@ -29,6 +29,11 @@ namespace mailcore { virtual Data * data(); virtual String * decodedString(); + virtual void setContentTypeParameter(String * name, String * value); + virtual void removeContentTypeParameter(String * name); + virtual String * contentTypeParameterValueForName(String *name); + virtual Array * allContentTypeParametersNames(); + public: // subclass behavior Attachment(Attachment * other); virtual String * description(); @@ -39,6 +44,8 @@ namespace mailcore { private: Data * mData; + HashMap * mContentTypeParameters; + HashMap * mlcContentTypeParameters; void init(); static void fillMultipartSubAttachments(AbstractMultipart * multipart, struct mailmime * mime); static AbstractPart * attachmentsWithMIMEWithMain(struct mailmime * mime, bool isMain); @@ -46,6 +53,7 @@ namespace mailcore { static MessagePart * attachmentWithMessageMIME(struct mailmime * mime); static Encoding encodingForMIMEEncoding(struct mailmime_mechanism * mechanism, int defaultMimeEncoding); static HashMap * readMimeTypesFile(String * filename); + void setContentTypeParameters(HashMap * parameters); }; } diff --git a/src/core/rfc822/MCMessageBuilder.cc b/src/core/rfc822/MCMessageBuilder.cc index cd87009e..3e63ce4a 100644 --- a/src/core/rfc822/MCMessageBuilder.cc +++ b/src/core/rfc822/MCMessageBuilder.cc @@ -134,7 +134,7 @@ err: static struct mailmime * get_text_part(const char * mime_type, const char * charset, const char * content_id, const char * description, - const char * text, size_t length, int encoding_type) + const char * text, size_t length, int encoding_type, clist * contentTypeParameters) { struct mailmime_fields * mime_fields; struct mailmime * mime; @@ -165,6 +165,10 @@ static struct mailmime * get_text_part(const char * mime_type, const char * char param = mailmime_param_new_with_data((char *) "charset", (char *) charset); } clist_append(content->ct_parameters, param); + if (contentTypeParameters != NULL) { + clist_concat(content->ct_parameters, contentTypeParameters); + } + mime = part_new_empty(content, mime_fields, NULL, 1); mailmime_set_body_text(mime, (char *) text, length); @@ -173,7 +177,7 @@ static struct mailmime * get_text_part(const char * mime_type, const char * char static struct mailmime * get_plain_text_part(const char * mime_type, const char * charset, const char * content_id, const char * description, - const char * text, size_t length) + const char * text, size_t length, clist * contentTypeParameters) { bool needsQuotedPrintable; int mechanism; @@ -189,20 +193,20 @@ static struct mailmime * get_plain_text_part(const char * mime_type, const char if (needsQuotedPrintable) { mechanism = MAILMIME_MECHANISM_QUOTED_PRINTABLE; } - return get_text_part(mime_type, charset, content_id, description, text, length, mechanism); + return get_text_part(mime_type, charset, content_id, description, text, length, mechanism, contentTypeParameters); } static struct mailmime * get_other_text_part(const char * mime_type, const char * charset, const char * content_id, const char * description, - const char * text, size_t length) + const char * text, size_t length, clist * contentTypeParameters) { - return get_text_part(mime_type, charset, content_id, description, text, length, MAILMIME_MECHANISM_QUOTED_PRINTABLE); + return get_text_part(mime_type, charset, content_id, description, text, length, MAILMIME_MECHANISM_QUOTED_PRINTABLE, contentTypeParameters); } static struct mailmime * get_file_part(const char * filename, const char * mime_type, int is_inline, const char * content_id, const char * content_description, - const char * text, size_t length) + const char * text, size_t length, clist * contentTypeParameters) { char * disposition_name; int encoding_type; @@ -238,6 +242,11 @@ static struct mailmime * get_file_part(const char * filename, const char * mime_ dup_content_description = strdup(content_description); mime_fields = mailmime_fields_new_with_data(encoding, dup_content_id, dup_content_description, disposition, NULL); + + if (contentTypeParameters != NULL) { + clist_concat(content->ct_parameters, contentTypeParameters); + } + mime = part_new_empty(content, mime_fields, NULL, 1); mailmime_set_body_text(mime, (char *) text, length); @@ -246,6 +255,23 @@ static struct mailmime * get_file_part(const char * filename, const char * mime_ #define MIME_ENCODED_STR(str) (str != NULL ? str->encodedMIMEHeaderValue()->bytes() : NULL) +static clist * content_type_parameters_from_attachment(Attachment * att) +{ + clist * contentTypeParameters = NULL; + struct mailmime_parameter * param; + + mc_foreacharray(String, name, att->allContentTypeParametersNames()) { + if (contentTypeParameters == NULL) { + contentTypeParameters = clist_new(); + } + String * value = att->contentTypeParameterValueForName(name); + param = mailmime_param_new_with_data((char *)name->UTF8Characters(), (char *)value->UTF8Characters()); + clist_append(contentTypeParameters, param); + } + + return contentTypeParameters; +} + static struct mailmime * mime_from_attachment(Attachment * att) { struct mailmime * mime; @@ -262,24 +288,33 @@ static struct mailmime * mime_from_attachment(Attachment * att) if (r != MAILIMF_NO_ERROR) return NULL; } - else if (att->isInlineAttachment() && att->mimeType()->lowercaseString()->isEqual(MCSTR("text/plain"))) { - mime = get_plain_text_part(MCUTF8(att->mimeType()), MCUTF8(att->charset()), - MCUTF8(att->contentID()), - MIME_ENCODED_STR(att->contentDescription()), - data->bytes(), data->length()); - } - else if (att->isInlineAttachment() && att->mimeType()->lowercaseString()->hasPrefix(MCSTR("text/"))) { - mime = get_other_text_part(MCUTF8(att->mimeType()), MCUTF8(att->charset()), - MCUTF8(att->contentID()), - MIME_ENCODED_STR(att->contentDescription()), - data->bytes(), data->length()); - } else { - mime = get_file_part(MIME_ENCODED_STR(att->filename()), - MCUTF8(att->mimeType()), att->isInlineAttachment(), - MCUTF8(att->contentID()), - MIME_ENCODED_STR(att->contentDescription()), - data->bytes(), data->length()); + clist * contentTypeParameters = content_type_parameters_from_attachment(att); + if (att->isInlineAttachment() && att->mimeType()->lowercaseString()->isEqual(MCSTR("text/plain"))) { + mime = get_plain_text_part(MCUTF8(att->mimeType()), MCUTF8(att->charset()), + MCUTF8(att->contentID()), + MIME_ENCODED_STR(att->contentDescription()), + data->bytes(), data->length(), + contentTypeParameters); + } + else if (att->isInlineAttachment() && att->mimeType()->lowercaseString()->hasPrefix(MCSTR("text/"))) { + mime = get_other_text_part(MCUTF8(att->mimeType()), MCUTF8(att->charset()), + MCUTF8(att->contentID()), + MIME_ENCODED_STR(att->contentDescription()), + data->bytes(), data->length(), + contentTypeParameters); + } + else { + mime = get_file_part(MIME_ENCODED_STR(att->filename()), + MCUTF8(att->mimeType()), att->isInlineAttachment(), + MCUTF8(att->contentID()), + MIME_ENCODED_STR(att->contentDescription()), + data->bytes(), data->length(), + contentTypeParameters); + } + if (contentTypeParameters != NULL) { + clist_free(contentTypeParameters); + } } return mime; } |