[PATCH v5b] show: indicate length, encoding of omitted body content
If a leaf part's body content is omitted, return the encoded length and transfer encoding in --format=json output. This information may be used by the consumer, e.g. to decide whether to download a large attachment over a slow link. Returning the _encoded_ content length is more efficient than returning the _decoded_ content length. Returning the transfer encoding allows the consumer to estimate the decoded content length. --- devel/schemata | 9 - notmuch-show.c | 16 ++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/devel/schemata b/devel/schemata index d1ab983..7d167be 100644 --- a/devel/schemata +++ b/devel/schemata @@ -75,7 +75,14 @@ part = { # A leaf part's body content is optional, but may be included if # it can be correctly encoded as a string. Consumers should use # this in preference to fetching the part content separately. -content?: string +content?: string, +# If a leaf part's body content is not included, the length of +# the encoded content (in bytes) may be given instead. +content-length?: int, +# If a leaf part's body content is not included, its transfer encoding +# may be given. Using this and the encoded content length, it is +# possible for the consumer to estimate the decoded content length. +content-transfer-encoding?: string } # The headers of a message or part (format_headers_sprinter with reply = FALSE) diff --git a/notmuch-show.c b/notmuch-show.c index 6a9278c..2d59865 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -600,14 +600,26 @@ format_part_text (const void *ctx, sprinter_t *sp, mime_node_t *node, } static void -format_omitted_part_meta_sprinter (sprinter_t *sp, GMimeObject *meta) +format_omitted_part_meta_sprinter (sprinter_t *sp, GMimeObject *meta, GMimePart *part) { const char *content_charset = g_mime_object_get_content_type_parameter (meta, "charset"); +const char *cte = g_mime_object_get_header (meta, "content-transfer-encoding"); +GMimeDataWrapper *wrapper = g_mime_part_get_content_object (part); +GMimeStream *stream = g_mime_data_wrapper_get_stream (wrapper); +ssize_t content_length = g_mime_stream_length (stream); if (content_charset != NULL) { sp->map_key (sp, "content-charset"); sp->string (sp, content_charset); } +if (cte != NULL) { + sp->map_key (sp, "content-transfer-encoding"); + sp->string (sp, cte); +} +if (content_length >= 0) { + sp->map_key (sp, "content-length"); + sp->integer (sp, content_length); +} } void @@ -699,7 +711,7 @@ format_part_sprinter (const void *ctx, sprinter_t *sp, mime_node_t *node, sp->string_len (sp, (char *) part_content->data, part_content->len); g_object_unref (stream_memory); } else { - format_omitted_part_meta_sprinter (sp, meta); + format_omitted_part_meta_sprinter (sp, meta, GMIME_PART (node->part)); } } else if (GMIME_IS_MULTIPART (node->part)) { sp->map_key (sp, "content"); -- 1.7.12.1
[PATCH v5b] show: indicate length, encoding of omitted body content
If a leaf part's body content is omitted, return the encoded length and transfer encoding in --format=json output. This information may be used by the consumer, e.g. to decide whether to download a large attachment over a slow link. Returning the _encoded_ content length is more efficient than returning the _decoded_ content length. Returning the transfer encoding allows the consumer to estimate the decoded content length. --- devel/schemata | 9 - notmuch-show.c | 16 ++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/devel/schemata b/devel/schemata index d1ab983..7d167be 100644 --- a/devel/schemata +++ b/devel/schemata @@ -75,7 +75,14 @@ part = { # A leaf part's body content is optional, but may be included if # it can be correctly encoded as a string. Consumers should use # this in preference to fetching the part content separately. -content?: string +content?: string, +# If a leaf part's body content is not included, the length of +# the encoded content (in bytes) may be given instead. +content-length?: int, +# If a leaf part's body content is not included, its transfer encoding +# may be given. Using this and the encoded content length, it is +# possible for the consumer to estimate the decoded content length. +content-transfer-encoding?: string } # The headers of a message or part (format_headers_sprinter with reply = FALSE) diff --git a/notmuch-show.c b/notmuch-show.c index 6a9278c..2d59865 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -600,14 +600,26 @@ format_part_text (const void *ctx, sprinter_t *sp, mime_node_t *node, } static void -format_omitted_part_meta_sprinter (sprinter_t *sp, GMimeObject *meta) +format_omitted_part_meta_sprinter (sprinter_t *sp, GMimeObject *meta, GMimePart *part) { const char *content_charset = g_mime_object_get_content_type_parameter (meta, charset); +const char *cte = g_mime_object_get_header (meta, content-transfer-encoding); +GMimeDataWrapper *wrapper = g_mime_part_get_content_object (part); +GMimeStream *stream = g_mime_data_wrapper_get_stream (wrapper); +ssize_t content_length = g_mime_stream_length (stream); if (content_charset != NULL) { sp-map_key (sp, content-charset); sp-string (sp, content_charset); } +if (cte != NULL) { + sp-map_key (sp, content-transfer-encoding); + sp-string (sp, cte); +} +if (content_length = 0) { + sp-map_key (sp, content-length); + sp-integer (sp, content_length); +} } void @@ -699,7 +711,7 @@ format_part_sprinter (const void *ctx, sprinter_t *sp, mime_node_t *node, sp-string_len (sp, (char *) part_content-data, part_content-len); g_object_unref (stream_memory); } else { - format_omitted_part_meta_sprinter (sp, meta); + format_omitted_part_meta_sprinter (sp, meta, GMIME_PART (node-part)); } } else if (GMIME_IS_MULTIPART (node-part)) { sp-map_key (sp, content); -- 1.7.12.1 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch