[evolution-patches] 65058, take 2, content-location patch
- From: Not Zed <notzed ximian com>
- To: asdf <evolution-patches lists ximian com>
- Subject: [evolution-patches] 65058, take 2, content-location patch
- Date: Wed, 22 Sep 2004 17:12:10 +0800
Another stupidly big patch that ruined my day ... since the current code works in most practical cases maybe it should only go into 2.1.
It makes content-location 'work better', it passes all the tests jeff has, test 18 still fails, but the mail is just broken (the img tags refer to a remote location not the internal ones). All my spam still seems to render ok (woohoo).
I couldn't guarantee that it doesn't add new bugs, but as far as i can tell it should fix more than it makes.
Index: camel/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/camel/ChangeLog,v
retrieving revision 1.2251.2.4
diff -u -3 -r1.2251.2.4 ChangeLog
--- camel/ChangeLog 22 Sep 2004 01:11:39 -0000 1.2251.2.4
+++ camel/ChangeLog 22 Sep 2004 08:56:45 -0000
@@ -1,5 +1,8 @@
2004-09-22 Not Zed <NotZed Ximian com>
+ * camel-url.c (camel_url_new_with_base): don't try to dereference
+ base->path if it is NULL.
+
* camel-folder-summary.c (camel_folder_summary_decode_token):
handle a zero-length token read rather than failing.
Index: camel/camel-url.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-url.c,v
retrieving revision 1.40
diff -u -3 -r1.40 camel-url.c
--- camel/camel-url.c 11 Jun 2004 08:28:41 -0000 1.40
+++ camel/camel-url.c 22 Sep 2004 08:56:48 -0000
@@ -210,8 +210,8 @@
} else if (*url->path != '/') {
char *newpath, *last, *p, *q;
- last = strrchr (base->path, '/');
- if (last) {
+ if (base->path
+ && (last = strrchr (base->path, '/'))) {
newpath = g_strdup_printf ("%.*s/%s",
last - base->path,
base->path,
Index: mail/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/mail/ChangeLog,v
retrieving revision 1.3444.2.9
diff -u -3 -r1.3444.2.9 ChangeLog
--- mail/ChangeLog 22 Sep 2004 01:31:16 -0000 1.3444.2.9
+++ mail/ChangeLog 22 Sep 2004 08:56:55 -0000
@@ -1,3 +1,49 @@
+2004-09-22 Not Zed <NotZed Ximian com>
+
+ ** See bug #65058 (more complete fix).
+
+ * em-format-html.c (efh_format_do): fixed for changed data
+ structures.
+ (efh_multipart_related): clean up some code with new apis
+
+ * em-format.h (EMFormatPURI): Added a parent pointer to the tree
+ structure, and made the uri mutli-valued for alternatives.
+
+ * em-format-html.h (EMFormatHTMLJob): Removed the pending uri
+ level and base url, the puri has pointers to this info now.
+
+ * em-format-html.c (emfh_getpuri): close the stream to indicate
+ successful output, and handle the pending uri level for the job
+ based on the pending uri now.
+
+ * em-format.c (em_format_add_puri): also check the filename as a
+ possible content-location fallback, and don't use an absolute uri
+ as the content-id for made-up parts. We also now have a list of
+ uri's rather than a single one.
+ (em_format_pull_level): reset the part-id string as well as the
+ level pointer.
+ (dump_visible_rec, dump_visible): some messy debug stuff.
+ (em_format_find_visible_puri): make this search below the current
+ point as well as above it.
+ (emf_find_puri_rec, emf_find_puri): helpers for above since we
+ need to search more uris now.
+ (emf_clear_puri_node): free the multiple uris and the base url for
+ this level.
+ (emf_multipart_mixed): push a wrapper level incase the
+ multipart/mixed has a content-location value.
+ (emf_multipart_alternative): ditto for multipart/alternative.
+ (emf_multipart_related): use the new push_level stuff to kill some
+ code.
+
+ * em-format.h: removed base from emformat, put it in the puri
+ level tree instead.
+
+ * em-format.c (em_format_push_level): add uri and partid arguments
+ to push level of. We now keep track of the base-url for each
+ level explictly too.
+
+ * em-format-html.c (emfh_gethttp): d() out debug printf.
+
2004-09-03 Not Zed <NotZed Ximian com>
** See bug #65058.
Index: mail/em-format-html.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-format-html.c,v
retrieving revision 1.63.4.1
diff -u -3 -r1.63.4.1 em-format-html.c
--- mail/em-format-html.c 22 Sep 2004 01:31:16 -0000 1.63.4.1
+++ mail/em-format-html.c 22 Sep 2004 08:56:59 -0000
@@ -410,11 +410,8 @@
struct _EMFormatHTMLJob *job = g_malloc0(sizeof(*job));
job->format = emfh;
- job->puri_level = ((EMFormat *)emfh)->pending_uri_level;
job->callback = callback;
job->u.data = data;
- if (((EMFormat *)emfh)->base)
- job->base = camel_url_copy(((EMFormat *)emfh)->base);
return job;
}
@@ -432,8 +429,16 @@
static void emfh_getpuri(struct _EMFormatHTMLJob *job, int cancelled)
{
d(printf(" running getpuri task\n"));
- if (!cancelled)
+ if (!cancelled) {
+ struct _EMFormatPURITree *puri_level;
+
+ puri_level = ((EMFormat *)job->format)->pending_uri_level;
+ ((EMFormat *)job->format)->pending_uri_level = job->u.puri->level;
+
job->u.puri->func((EMFormat *)job->format, job->stream, job->u.puri);
+ camel_stream_close(job->stream);
+ ((EMFormat *)job->format)->pending_uri_level = puri_level;
+ }
}
static void emfh_gethttp(struct _EMFormatHTMLJob *job, int cancelled)
@@ -455,7 +460,7 @@
if (instream == NULL) {
char *proxy;
- printf(" load http %d now=%d\n", job->format->load_http, job->format->load_http_now);
+ d(printf(" load http %d now=%d\n", job->format->load_http, job->format->load_http_now));
if (!(job->format->load_http_now
|| job->format->load_http == MAIL_CONFIG_HTTP_ALWAYS
@@ -824,8 +829,9 @@
}
puri = em_format_add_puri((EMFormat *)efh, sizeof(EMFormatPURI), NULL, part, efh_write_text_html);
- location = puri->uri?puri->uri:puri->cid;
+ location = puri->uris&&puri->uris[0]?puri->uris[0]:puri->cid;
d(printf("adding iframe, location %s\n", location));
+
camel_stream_printf(stream,
"<iframe src=\"%s\" frameborder=0 scrolling=no>could not get %s</iframe>\n"
"</td></tr></table>\n"
@@ -973,12 +979,12 @@
d(printf(" running multipart/related check task\n"));
oldpartid = g_strdup(((EMFormat *)job->format)->part_id->str);
- ptree = job->puri_level;
+ ptree = (struct _EMFormatPURITree *)job->u.data;
puri = (EMFormatPURI *)ptree->uri_list.head;
purin = puri->next;
while (purin) {
if (puri->use_count == 0) {
- d(printf("part '%s' '%s' used '%d'\n", puri->uri?puri->uri:"", puri->cid, puri->use_count));
+ d(printf("part '%s' '%s' used '%d'\n", puri->uris?puri->uris[0]:"", puri->cid, puri->use_count));
if (puri->func == emfh_write_related) {
g_string_printf(((EMFormat *)job->format)->part_id, puri->part_id);
em_format_part((EMFormat *)job->format, (CamelStream *)job->stream, puri->part);
@@ -1000,9 +1006,8 @@
CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part);
CamelMimePart *body_part, *display_part = NULL;
CamelContentType *content_type;
- const char *location, *start;
+ const char *start;
int i, nparts, partidlen, displayid = 0;
- CamelURL *base_save = NULL;
EMFormatPURI *puri;
struct _EMFormatHTMLJob *job;
@@ -1041,45 +1046,32 @@
return;
}
- /* stack of present location and pending uri's */
- location = camel_mime_part_get_content_location(part);
- if (location) {
- d(printf("setting content location %s\n", location));
- base_save = emf->base;
- emf->base = camel_url_new(location, NULL);
- }
- em_format_push_level(emf);
-
+ em_format_push_level(emf, camel_mime_part_get_content_location(part), ".related");
partidlen = emf->part_id->len;
/* queue up the parts for possible inclusion */
for (i = 0; i < nparts; i++) {
body_part = camel_multipart_get_part(mp, i);
if (body_part != display_part) {
- g_string_append_printf(emf->part_id, "related.%d", i);
+ g_string_append_printf(emf->part_id, ".%d", i);
puri = em_format_add_puri(emf, sizeof(EMFormatPURI), NULL, body_part, emfh_write_related);
g_string_truncate(emf->part_id, partidlen);
- d(printf(" part '%s' '%s' added\n", puri->uri?puri->uri:"", puri->cid));
+ d(printf(" part '%s' '%s' added\n", puri->uris?puri->uris[0]:"", puri->cid));
}
}
- g_string_append_printf(emf->part_id, "related.%d", displayid);
+ g_string_append_printf(emf->part_id, ".%d", displayid);
em_format_part(emf, stream, display_part);
g_string_truncate(emf->part_id, partidlen);
camel_stream_flush(stream);
/* queue a job to check for un-referenced parts to add as attachments */
- job = em_format_html_job_new((EMFormatHTML *)emf, emfh_multipart_related_check, NULL);
+ job = em_format_html_job_new((EMFormatHTML *)emf, emfh_multipart_related_check, emf->pending_uri_level);
job->stream = stream;
camel_object_ref(stream);
em_format_html_job_queue((EMFormatHTML *)emf, job);
em_format_pull_level(emf);
-
- if (location) {
- camel_url_free(emf->base);
- emf->base = base_save;
- }
}
static void
@@ -1167,9 +1159,7 @@
{
struct _format_msg *m = (struct _format_msg *)mm;
struct _EMFormatHTMLJob *job;
- struct _EMFormatPURITree *puri_level;
int cancelled = FALSE;
- CamelURL *base;
if (m->format->html == NULL)
return;
@@ -1195,9 +1185,6 @@
camel_object_unref(m->estream);
m->estream = NULL;
- puri_level = ((EMFormat *)m->format)->pending_uri_level;
- base = ((EMFormat *)m->format)->base;
-
/* now dispatch any added tasks ... */
g_mutex_lock(m->format->priv->lock);
while ((job = (struct _EMFormatHTMLJob *)e_dlist_remhead(&m->format->priv->pending_jobs))) {
@@ -1212,24 +1199,16 @@
cancelled = camel_operation_cancel_check(NULL);
/* call jobs even if cancelled, so they can clean up resources */
- ((EMFormat *)m->format)->pending_uri_level = job->puri_level;
- if (job->base)
- ((EMFormat *)m->format)->base = job->base;
job->callback(job, cancelled);
- ((EMFormat *)m->format)->base = base;
/* clean up the job */
camel_object_unref(job->stream);
- if (job->base)
- camel_url_free(job->base);
g_free(job);
g_mutex_lock(m->format->priv->lock);
}
g_mutex_unlock(m->format->priv->lock);
d(printf("out of jobs, done\n"));
-
- ((EMFormat *)m->format)->pending_uri_level = puri_level;
}
static void efh_format_done(struct _mail_msg *mm)
Index: mail/em-format-html.h
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-format-html.h,v
retrieving revision 1.14
diff -u -3 -r1.14 em-format-html.h
--- mail/em-format-html.h 18 May 2004 07:48:19 -0000 1.14
+++ mail/em-format-html.h 22 Sep 2004 08:56:59 -0000
@@ -55,17 +55,11 @@
EMFormatHTML *format;
struct _CamelStream *stream;
- /* We need to track the state of the visibility tree at
- the point this uri was generated */
- struct _EMFormatPURITree *puri_level;
- struct _CamelURL *base;
-
void (*callback)(struct _EMFormatHTMLJob *job, int cancelled);
union {
char *uri;
struct _CamelMedium *msg;
EMFormatPURI *puri;
- struct _EMFormatPURITree *puri_level;
void *data;
} u;
};
Index: mail/em-format.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-format.c,v
retrieving revision 1.38.8.1
diff -u -3 -r1.38.8.1 em-format.c
--- mail/em-format.c 7 Sep 2004 14:22:12 -0000 1.38.8.1
+++ mail/em-format.c 22 Sep 2004 08:57:00 -0000
@@ -327,41 +327,68 @@
}
if (part != NULL && cid == NULL) {
+ CamelURL *url, *base;
+ int uri = 0, i;
+
tmp = camel_mime_part_get_content_id(part);
if (tmp)
puri->cid = g_strdup_printf("cid:%s", tmp);
else
- puri->cid = g_strdup_printf("em-no-cid:%s", emf->part_id->str);
+ puri->cid = g_strdup_printf("%s", emf->part_id->str);
d(printf("built cid '%s'\n", puri->cid));
- /* not quite same as old behaviour, it also put in the relative uri and a fallback for no parent uri */
- tmp = camel_mime_part_get_content_location(part);
- puri->uri = NULL;
- if (tmp == NULL) {
- if (emf->base)
- puri->uri = camel_url_to_string(emf->base, 0);
- } else {
- if (strchr(tmp, ':') == NULL && emf->base != NULL) {
- CamelURL *uri;
-
- uri = camel_url_new_with_base(emf->base, tmp);
- puri->uri = camel_url_to_string(uri, 0);
- camel_url_free(uri);
- } else {
- puri->uri = g_strdup(tmp);
+ if (emf->pending_uri_level && emf->pending_uri_level->base)
+ base = emf->pending_uri_level->base;
+ else
+ base = NULL;
+
+ /* we only have 2 possibilities max, this is null terminated */
+ puri->uris = g_malloc0(sizeof(*puri->uris)*3);
+
+ /* 1: try location, 2: try filename */
+ for (i=0;i<2;i++) {
+ if (i == 0)
+ tmp = camel_mime_part_get_content_location(part);
+ else
+ tmp = camel_mime_part_get_filename(part);
+ if (tmp) {
+ if (strchr(tmp, ':') == NULL && base != NULL) {
+ url = camel_url_new_with_base(base, tmp);
+ puri->uris[uri++] = camel_url_to_string(url, 0);
+ camel_url_free(url);
+ } else {
+ puri->uris[uri++] = g_strdup(tmp);
+ }
}
}
+
+ /* last chance */
+ if (uri == 0 && base)
+ puri->uris[uri++] = camel_url_to_string(base, 0);
+
+ if (uri == 0) {
+ g_free(puri->uris);
+ puri->uris = NULL;
+ }
}
g_assert(puri->cid != NULL);
g_assert(emf->pending_uri_level != NULL);
g_assert(emf->pending_uri_table != NULL);
+ d(printf("adding puri cid:'%s' uri[0]:'%s''\n", puri->cid, puri->uris?puri->uris[0]:"<unset>"));
+
+ puri->level = emf->pending_uri_level;
e_dlist_addtail(&emf->pending_uri_level->uri_list, (EDListNode *)puri);
- if (puri->uri)
- g_hash_table_insert(emf->pending_uri_table, puri->uri, puri);
+ if (puri->uris) {
+ int i;
+
+ for (i=0;puri->uris[i];i++)
+ g_hash_table_insert(emf->pending_uri_table, puri->uris[i], puri);
+ }
+
g_hash_table_insert(emf->pending_uri_table, puri->cid, puri);
return puri;
@@ -370,27 +397,44 @@
/**
* em_format_push_level:
* @emf:
+ * @uri: absolute or relative uri of this part. May be null.
+ * @partid: part-id prefix of this part. May be null.
*
* This is used to build a heirarchy of visible PURI objects based on
* the structure of the message. Used by multipart/alternative formatter.
*
- * FIXME: This could probably also take a uri so it can automaticall update
- * the base location.
+ * It also updates the base uri and partid string
+ * appropriately.
**/
void
-em_format_push_level(EMFormat *emf)
+em_format_push_level(EMFormat *emf, const char *uri, const char *partid)
{
- struct _EMFormatPURITree *purilist;
+ struct _EMFormatPURITree *purilist, *parent;
- d(printf("em_format_push_level\n"));
+ parent = emf->pending_uri_level;
+
+ d(printf("em_format_push_level '%s' '%s'\n", uri?uri:"<none>", partid?partid:"<none>"));
purilist = g_malloc0(sizeof(*purilist));
e_dlist_init(&purilist->children);
e_dlist_init(&purilist->uri_list);
- purilist->parent = emf->pending_uri_level;
- if (emf->pending_uri_tree == NULL) {
+ purilist->parent = parent;
+
+ if (uri) {
+ if (parent && parent->base)
+ purilist->base = camel_url_new_with_base(parent->base, uri);
+ else
+ purilist->base = camel_url_new(uri, NULL);
+ } else if (parent && parent->base)
+ purilist->base = camel_url_copy(parent->base);
+
+ purilist->idlen = emf->part_id->len;
+ if (partid)
+ g_string_append(emf->part_id, partid);
+
+ if (parent == NULL) {
emf->pending_uri_tree = purilist;
} else {
- e_dlist_addtail(&emf->pending_uri_level->children, (EDListNode *)purilist);
+ e_dlist_addtail(&parent->children, (EDListNode *)purilist);
}
emf->pending_uri_level = purilist;
}
@@ -399,14 +443,129 @@
* em_format_pull_level:
* @emf:
*
- * Drop a level of visibility back to the parent. Note that
- * no PURI values are actually freed.
+ * Drop a level of visibility back to the parent. Note that no PURI
+ * values are actually freed. This resets the partid string and
+ * emf->base uri to what they were before.
**/
void
em_format_pull_level(EMFormat *emf)
{
+ struct _EMFormatPURITree *ptree;
+
d(printf("em_format_pull_level\n"));
- emf->pending_uri_level = emf->pending_uri_level->parent;
+
+ ptree = emf->pending_uri_level;
+ g_string_truncate(emf->part_id, ptree->idlen);
+ emf->pending_uri_level = ptree->parent;
+}
+
+#if d(!)0
+static void
+dump_visible_rec(struct _EMFormatPURITree *root, struct _EMFormatPURITree *here, int level)
+{
+ char *s;
+ EMFormatPURI *pw;
+ struct _EMFormatPURITree *child;
+
+ s = alloca(level+2);
+ memset(s, ' ', level+1);
+ s[level+1] = 0;
+
+ while (root->next) {
+ if (root == here)
+ s[0] = '*';
+ else
+ s[0] = ' ';
+
+ pw = (EMFormatPURI *)root->uri_list.head;
+ while (pw->next) {
+ printf("%spw->uri[0] = '%s' pw->cid = '%s\n", s, pw->uris?pw->uris[0]:"", pw->cid);
+ pw = pw->next;
+ }
+
+ child = root->children.head;
+ while (child->next) {
+ dump_visible_rec(child, here, level+1);
+ child = child->next;
+ }
+
+ root = root->next;
+ }
+}
+
+static void
+dump_visible(struct _EMFormatPURITree *root, struct _EMFormatPURITree *here, int level)
+{
+ char *s;
+ EMFormatPURI *pw;
+ struct _EMFormatPURITree *child;
+
+ s = alloca(level+2);
+ memset(s, ' ', level+1);
+ s[level+1] = 0;
+
+ if (root == here)
+ s[0] = '*';
+
+ printf("tree:<\n");
+ pw = (EMFormatPURI *)root->uri_list.head;
+ while (pw->next) {
+ printf("%spw->uri[0] = '%s' pw->cid = '%s\n", s, pw->uris?pw->uris[0]:"", pw->cid);
+ pw = pw->next;
+ }
+ child = root->children.head;
+ while (child->next) {
+ dump_visible_rec(child, here, level+1);
+ child = child->next;
+ }
+ root = root->next;
+ printf(">\n");
+}
+#endif
+
+static EMFormatPURI *
+emf_find_puri(EMFormatPURI *pw, const char *uri)
+{
+ while (pw->next) {
+ if (pw->uris) {
+ int i;
+
+ for (i=0;pw->uris[i];i++) {
+ d(printf(" pw->uri[%d] = '%s'\n", i, pw->uris[i]));
+ if (!strcmp(pw->uris[i], uri)) {
+ d(printf("match!\n"));
+ return pw;
+ }
+ }
+ }
+
+ d(printf(" pw->cid = '%s'\n", pw->cid));
+ if (!strcmp(pw->cid, uri)) {
+ d(printf("match!\n"));
+ return pw;
+ }
+ pw = pw->next;
+ }
+
+ return NULL;
+}
+
+static EMFormatPURI *
+emf_find_puri_rec(struct _EMFormatPURITree *ptree, const char *uri)
+{
+ while (ptree->next) {
+ EMFormatPURI *pw;
+
+ pw = emf_find_puri((EMFormatPURI *)ptree->uri_list.head, uri);
+ if (pw != NULL)
+ return pw;
+ pw = emf_find_puri_rec((struct _EMFormatPURITree *)ptree->children.head, uri);
+ if (pw != NULL)
+ return pw;
+ ptree = ptree->next;
+ }
+
+ return NULL;
}
/**
@@ -426,19 +585,24 @@
struct _EMFormatPURITree *ptree;
d(printf("checking for visible uri '%s'\n", uri));
+ if (emf->pending_uri_tree)
+ d(dump_visible(emf->pending_uri_tree, emf->pending_uri_level, 0));
ptree = emf->pending_uri_level;
while (ptree) {
- pw = (EMFormatPURI *)ptree->uri_list.head;
- while (pw->next) {
- d(printf(" pw->uri = '%s' pw->cid = '%s\n", pw->uri?pw->uri:"", pw->cid));
- if ((pw->uri && !strcmp(pw->uri, uri)) || !strcmp(pw->cid, uri))
- return pw;
- pw = pw->next;
- }
+ /* first at this level */
+ pw = emf_find_puri((EMFormatPURI *)ptree->uri_list.head, uri);
+ if (pw != NULL)
+ return pw;
+ /* and then all children recursively */
+ pw = emf_find_puri_rec((struct _EMFormatPURITree *)ptree->children.head, uri);
+ if (pw != NULL)
+ return pw;
ptree = ptree->parent;
}
+ d(printf("no match?\n"));
+
return NULL;
}
@@ -468,7 +632,13 @@
pw = (EMFormatPURI *)node->uri_list.head;
pn = pw->next;
while (pn) {
- g_free(pw->uri);
+ if (pw->uris) {
+ int i;
+
+ for (i=0;pw->uris[i];i++)
+ g_free(pw->uris[i]);
+ g_free(pw->uris);
+ }
g_free(pw->cid);
g_free(pw->part_id);
if (pw->part)
@@ -487,6 +657,8 @@
cn = cw->next;
while (cn) {
emf_clear_puri_node(cw);
+ if (cw->base)
+ camel_url_free(cw->base);
cw = cn;
cn = cn->next;
}
@@ -514,7 +686,7 @@
emf->pending_uri_tree = NULL;
}
emf->pending_uri_table = g_hash_table_new(g_str_hash, g_str_equal);
- em_format_push_level(emf);
+ em_format_push_level(emf, NULL, NULL);
}
/* use mime_type == NULL to force showing as application/octet-stream */
@@ -1144,14 +1316,18 @@
return;
}
+ em_format_push_level(emf, camel_mime_part_get_content_location(part), ".mixed");
len = emf->part_id->len;
+
nparts = camel_multipart_get_number(mp);
for (i = 0; i < nparts; i++) {
part = camel_multipart_get_part(mp, i);
- g_string_append_printf(emf->part_id, ".mixed.%d", i);
+ g_string_append_printf(emf->part_id, ".%d", i);
em_format_part(emf, stream, part);
g_string_truncate(emf->part_id, len);
}
+
+ em_format_pull_level(emf);
}
/* RFC 1740 */
@@ -1189,11 +1365,10 @@
}
if (best) {
- int len = emf->part_id->len;
-
- g_string_append_printf(emf->part_id, ".alternative.%d", bestid);
+ em_format_push_level(emf, camel_mime_part_get_content_location(part), ".alternative");
+ g_string_append_printf(emf->part_id, ".%d", bestid);
em_format_part(emf, stream, best);
- g_string_truncate(emf->part_id, len);
+ em_format_pull_level(emf);
} else
emf_multipart_mixed(emf, stream, part, info);
}
@@ -1262,10 +1437,8 @@
CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part);
CamelMimePart *body_part, *display_part = NULL;
CamelContentType *content_type;
- const char *location, *start;
+ const char *start;
int i, nparts, partidlen, displayid = 0;
- char *oldpartid;
- CamelURL *base_save = NULL;
struct _EMFormatPURITree *ptree;
EMFormatPURI *puri, *purin;
@@ -1304,17 +1477,8 @@
emf_multipart_mixed(emf, stream, part, info);
return;
}
-
- /* stack of present location and pending uri's */
- location = camel_mime_part_get_content_location(part);
- if (location) {
- d(printf("setting content location %s\n", location));
- base_save = emf->base;
- emf->base = camel_url_new(location, NULL);
- }
- em_format_push_level(emf);
- oldpartid = g_strdup(emf->part_id->str);
+ em_format_push_level(emf, camel_mime_part_get_content_location(part), ".related");
partidlen = emf->part_id->len;
/* queue up the parts for possible inclusion */
@@ -1322,14 +1486,14 @@
body_part = camel_multipart_get_part(mp, i);
if (body_part != display_part) {
/* set the partid since add_puri uses it */
- g_string_append_printf(emf->part_id, ".related.%d", i);
+ g_string_append_printf(emf->part_id, ".%d", i);
puri = em_format_add_puri(emf, sizeof(EMFormatPURI), NULL, body_part, emf_write_related);
g_string_truncate(emf->part_id, partidlen);
- d(printf(" part '%s' '%s' added\n", puri->uri?puri->uri:"", puri->cid));
+ d(printf(" part '%s' '%s' added\n", puri->uris?puri->uris[0]:"", puri->cid));
}
}
- g_string_append_printf(emf->part_id, ".related.%d", displayid);
+ g_string_append_printf(emf->part_id, ".%d", displayid);
em_format_part(emf, stream, display_part);
g_string_truncate(emf->part_id, partidlen);
camel_stream_flush(stream);
@@ -1339,26 +1503,18 @@
purin = puri->next;
while (purin) {
if (puri->use_count == 0) {
- d(printf("part '%s' '%s' used '%d'\n", puri->uri?puri->uri:"", puri->cid, puri->use_count));
+ d(printf("part '%s' '%s' used '%d'\n", puri->uris?puri->uris[0]:"", puri->cid, puri->use_count));
if (puri->func == emf_write_related) {
g_string_printf(emf->part_id, "%s", puri->part_id);
em_format_part(emf, stream, puri->part);
} else
- printf("unreferenced uri generated by format code: %s\n", puri->uri?puri->uri:puri->cid);
+ printf("unreferenced uri generated by format code: %s\n", puri->uris?puri->uris[0]:puri->cid);
}
puri = purin;
purin = purin->next;
}
- g_string_printf(emf->part_id, "%s", oldpartid);
- g_free(oldpartid);
-
em_format_pull_level(emf);
-
- if (location) {
- camel_url_free(emf->base);
- emf->base = base_save;
- }
}
static void
Index: mail/em-format.h
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-format.h,v
retrieving revision 1.12
diff -u -3 -r1.12 em-format.h
--- mail/em-format.h 10 Jul 2004 01:31:04 -0000 1.12
+++ mail/em-format.h 22 Sep 2004 08:57:00 -0000
@@ -74,13 +74,15 @@
struct _EMFormat *format;
- char *uri; /* will be the location of the part, may be empty */
+ char **uris; /* posible location of the part, starting with most likely, null terminated array */
char *cid; /* will always be set, a fake one created if needed */
char *part_id; /* will always be set, emf->part_id->str for this part */
EMFormatPURIFunc func;
struct _CamelMimePart *part;
+ struct _EMFormatPURITree *level;
+
unsigned int use_count; /* used by multipart/related to see if it was accessed */
};
@@ -90,6 +92,9 @@
EDList uri_list;
EDList children;
+
+ int idlen; /* old part-id len */
+ struct _CamelURL *base; /* url base of saved part */
};
struct _EMFormatHeader {
@@ -117,7 +122,6 @@
EDList header_list; /* if empty, then all */
struct _CamelSession *session; /* session, used for authentication when required */
- struct _CamelURL *base; /* current location (base url) */
const char *snoop_mime_type; /* if we snooped an application/octet-stream type, what we snooped */
@@ -209,7 +213,7 @@
EMFormatPURI *em_format_find_visible_puri(EMFormat *emf, const char *uri);
EMFormatPURI *em_format_find_puri(EMFormat *emf, const char *uri);
void em_format_clear_puri_tree(EMFormat *emf);
-void em_format_push_level(EMFormat *emf);
+void em_format_push_level(EMFormat *emf, const char *uri, const char *partid);
void em_format_pull_level(EMFormat *emf);
/* clones inline state/view and format, or use to redraw */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]