wrap_in_html(): process message in bulk rather than line-by-line
authorMichael Haggerty <mhagger@alum.mit.edu>
Sun, 25 Nov 2012 11:08:41 +0000 (12:08 +0100)
committerJunio C Hamano <gitster@pobox.com>
Sun, 2 Dec 2012 09:21:58 +0000 (01:21 -0800)
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>
imap-send.c

index b73c913f4ec3256681f122fc94d524e6adebaa15..e521e2fd223766eee22705674dd3becbb3d52a57 100644 (file)
@@ -1342,30 +1342,23 @@ static int imap_store_msg(struct store *gctx, struct msg_data *msg)
 static void wrap_in_html(struct strbuf *msg)
 {
        struct strbuf buf = STRBUF_INIT;
-       struct strbuf **lines;
-       struct strbuf **p;
        static char *content_type = "Content-Type: text/html;\n";
        static char *pre_open = "<pre>\n";
        static char *pre_close = "</pre>\n";
-       int added_header = 0;
-
-       lines = strbuf_split(msg, '\n');
-       for (p = lines; *p; p++) {
-               if (! added_header) {
-                       if ((*p)->len == 1 && *((*p)->buf) == '\n') {
-                               strbuf_addstr(&buf, content_type);
-                               strbuf_addbuf(&buf, *p);
-                               strbuf_addstr(&buf, pre_open);
-                               added_header = 1;
-                       } else {
-                               strbuf_addbuf(&buf, *p);
-                       }
-               } else {
-                       strbuf_addstr_xml_quoted(&buf, (*p)->buf);
-               }
-       }
+       const char *body = strstr(msg->buf, "\n\n");
+
+       if (!body)
+               return; /* Headers but no body; no wrapping needed */
+
+       body += 2;
+
+       strbuf_add(&buf, msg->buf, body - msg->buf - 1);
+       strbuf_addstr(&buf, content_type);
+       strbuf_addch(&buf, '\n');
+       strbuf_addstr(&buf, pre_open);
+       strbuf_addstr_xml_quoted(&buf, body);
        strbuf_addstr(&buf, pre_close);
-       strbuf_list_free(lines);
+
        strbuf_release(msg);
        *msg = buf;
 }