+
+ /* The disposition and content-type metadata are associated with
+ * the envelope for message parts */
+ GMimeObject *meta = node->envelope_part ? (
+ GMIME_OBJECT (node->envelope_part) ) : node->part;
+ GMimeContentType *content_type = g_mime_object_get_content_type (meta);
+ char *content_string;
+ const char *disposition = _get_disposition (meta);
+ const char *cid = g_mime_object_get_content_id (meta);
+ const char *filename = GMIME_IS_PART (node->part) ? (
+ g_mime_part_get_filename (GMIME_PART (node->part) ) ) : NULL;
+ int nclose = 0;
+ int i;
+
+ sp->begin_map (sp);
+
+ sp->map_key (sp, "id");
+ sp->integer (sp, node->part_num);
+
+ if (node->decrypt_attempted) {
+ sp->map_key (sp, "encstatus");
+ sp->begin_list (sp);
+ sp->begin_map (sp);
+ sp->map_key (sp, "status");
+ sp->string (sp, node->decrypt_success ? "good" : "bad");
+ sp->end (sp);
+ sp->end (sp);
+ }
+
+ if (node->verify_attempted) {
+ sp->map_key (sp, "sigstatus");
+ format_part_sigstatus_sprinter (sp, node->sig_list);
+ }
+
+ sp->map_key (sp, "content-type");
+ content_string = g_mime_content_type_get_mime_type (content_type);
+ sp->string (sp, content_string);
+ g_free (content_string);
+
+ if (disposition) {
+ sp->map_key (sp, "content-disposition");
+ sp->string (sp, disposition);
+ }
+
+ if (cid) {
+ sp->map_key (sp, "content-id");
+ sp->string (sp, cid);
+ }
+
+ if (filename) {
+ sp->map_key (sp, "filename");
+ sp->string (sp, filename);
+ }
+
+ if (GMIME_IS_PART (node->part)) {
+ /* For non-HTML text parts, we include the content in the
+ * JSON. Since JSON must be Unicode, we handle charset
+ * decoding here and do not report a charset to the caller.
+ * For text/html parts, we do not include the content unless
+ * the --include-html option has been passed. If a html part
+ * is not included, it can be requested directly. This makes
+ * charset decoding the responsibility on the caller so we
+ * report the charset for text/html parts.
+ */
+ if (g_mime_content_type_is_type (content_type, "text", "*") &&
+ (include_html ||
+ ! g_mime_content_type_is_type (content_type, "text", "html"))) {
+ GMimeStream *stream_memory = g_mime_stream_mem_new ();
+ GByteArray *part_content;
+ show_text_part_content (node->part, stream_memory, 0);
+ part_content = g_mime_stream_mem_get_byte_array (GMIME_STREAM_MEM (stream_memory));
+ sp->map_key (sp, "content");
+ sp->string_len (sp, (char *) part_content->data, part_content->len);
+ g_object_unref (stream_memory);
+ } else {
+ /* if we have a child part despite being a standard
+ * (non-multipart) MIME part, that means there is
+ * something to unwrap, which we will present in
+ * content: */
+ if (node->nchildren) {
+ sp->map_key (sp, "content");
+ sp->begin_list (sp);
+ nclose = 1;
+ } else
+ format_omitted_part_meta_sprinter (sp, meta, GMIME_PART (node->part));
+ }
+ } else if (GMIME_IS_MULTIPART (node->part)) {
+ sp->map_key (sp, "content");
+ sp->begin_list (sp);
+ nclose = 1;
+ } else if (GMIME_IS_MESSAGE (node->part)) {
+ sp->map_key (sp, "content");
+ sp->begin_list (sp);
+ sp->begin_map (sp);
+
+ sp->map_key (sp, "headers");
+ format_headers_sprinter (sp, GMIME_MESSAGE (node->part), false, NULL);
+
+ sp->map_key (sp, "body");
+ sp->begin_list (sp);
+ nclose = 3;