wrap_in_html(): process message in bulk rather than line-by-line

Now that we can xml-quote an arbitrary string in O(N), there is no reason to process the message line by line. This change saves lots of memory allocations and copying. The old code would have created invalid output when there was no body, emitting a closing </pre> without a blank line nor an opening <pre> after the header. The new code simply returns in this situation without doing harm (even though either would not make much sense in the context of imap-send that is meant to send out patches). Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Michael Haggerty committed Nov 25, 2012 at 12:08 UTC 118a68f9ddbca6ffd87ab6e32b60771143d9d014
1 file changed +13 -20
imap-send.c
+13 -20
@@ -1342,30 +1342,23 @@ static int imap_store_msg(struct store *gctx, struct msg_data *msg)
1342 static void wrap_in_html(struct strbuf *msg)
1343 {
1344 struct strbuf buf = STRBUF_INIT;
1345 - struct strbuf **lines;
1346 - struct strbuf **p;
1345 static char *content_type = "Content-Type: text/html;\n";
1346 static char *pre_open = "<pre>\n";
1347 static char *pre_close = "</pre>\n";
1350 - int added_header = 0;
1351 -
1352 - lines = strbuf_split(msg, '\n');
1353 - for (p = lines; *p; p++) {
1354 - if (! added_header) {
1355 - if ((*p)->len == 1 && *((*p)->buf) == '\n') {
1356 - strbuf_addstr(&buf, content_type);
1357 - strbuf_addbuf(&buf, *p);
1358 - strbuf_addstr(&buf, pre_open);
1359 - added_header = 1;
1360 - } else {
1361 - strbuf_addbuf(&buf, *p);
1362 - }
1363 - } else {
1364 - strbuf_addstr_xml_quoted(&buf, (*p)->buf);
1365 - }
1366 - }
1348 + const char *body = strstr(msg->buf, "\n\n");
1349 +
1350 + if (!body)
1351 + return; /* Headers but no body; no wrapping needed */
1352 +
1353 + body += 2;
1354 +
1355 + strbuf_add(&buf, msg->buf, body - msg->buf - 1);
1356 + strbuf_addstr(&buf, content_type);
1357 + strbuf_addch(&buf, '\n');
1358 + strbuf_addstr(&buf, pre_open);
1359 + strbuf_addstr_xml_quoted(&buf, body);
1360 strbuf_addstr(&buf, pre_close);
1368 - strbuf_list_free(lines);
1361 +
1362 strbuf_release(msg);
1363 *msg = buf;
1364 }