--- /dev/null
+Return-Path: <tomi.ollila@iki.fi>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id 3EA6C431FBD\r
+ for <notmuch@notmuchmail.org>; Wed, 2 Apr 2014 09:43:22 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 0\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
+ autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id LP4k8hZe6jxm for <notmuch@notmuchmail.org>;\r
+ Wed, 2 Apr 2014 09:43:16 -0700 (PDT)\r
+Received: from guru.guru-group.fi (guru.guru-group.fi [46.183.73.34])\r
+ by olra.theworths.org (Postfix) with ESMTP id D7BCF431FAE\r
+ for <notmuch@notmuchmail.org>; Wed, 2 Apr 2014 09:43:15 -0700 (PDT)\r
+Received: from guru.guru-group.fi (localhost [IPv6:::1])\r
+ by guru.guru-group.fi (Postfix) with ESMTP id A55DD100051;\r
+ Wed, 2 Apr 2014 19:43:07 +0300 (EEST)\r
+From: Tomi Ollila <tomi.ollila@iki.fi>\r
+To: Austin Clements <amdragon@MIT.EDU>, David Bremner <david@tethera.net>\r
+Subject: Re: [Patch v5 3/6] util: add gz_readline\r
+In-Reply-To: <20140402032644.GB25677@mit.edu>\r
+References: <1396401381-18128-1-git-send-email-david@tethera.net>\r
+ <1396401381-18128-4-git-send-email-david@tethera.net>\r
+ <20140402032644.GB25677@mit.edu>\r
+User-Agent: Notmuch/0.17+174~gef82849 (http://notmuchmail.org) Emacs/24.3.1\r
+ (x86_64-unknown-linux-gnu)\r
+X-Face: HhBM'cA~<r"^Xv\KRN0P{vn'Y"Kd;zg_y3S[4)KSN~s?O\"QPoL\r
+ $[Xv_BD:i/F$WiEWax}R(MPS`^UaptOGD`*/=@\1lKoVa9tnrg0TW?"r7aRtgk[F\r
+ !)g;OY^,BjTbr)Np:%c_o'jj,Z\r
+Date: Wed, 02 Apr 2014 19:43:07 +0300\r
+Message-ID: <m2wqf73co4.fsf@guru.guru-group.fi>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain\r
+Cc: notmuch@notmuchmail.org\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Wed, 02 Apr 2014 16:43:22 -0000\r
+\r
+On Wed, Apr 02 2014, Austin Clements <amdragon@MIT.EDU> wrote:\r
+\r
+> Quoth David Bremner on Apr 01 at 10:16 pm:\r
+>> The idea is to provide a more or less drop in replacement for readline\r
+>> to read from zlib/gzip streams. Take the opportunity to replace\r
+>> malloc with talloc.\r
+>> ---\r
+>> util/Makefile.local | 2 +-\r
+>> util/util.h | 12 +++++++++\r
+>> util/zlib-extra.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++\r
+>> util/zlib-extra.h | 11 ++++++++\r
+>> 4 files changed, 100 insertions(+), 1 deletion(-)\r
+>> create mode 100644 util/util.h\r
+>> create mode 100644 util/zlib-extra.c\r
+>> create mode 100644 util/zlib-extra.h\r
+>> \r
+>> diff --git a/util/Makefile.local b/util/Makefile.local\r
+>> index 29c0ce6..e2a5b65 100644\r
+>> --- a/util/Makefile.local\r
+>> +++ b/util/Makefile.local\r
+>> @@ -4,7 +4,7 @@ dir := util\r
+>> extra_cflags += -I$(srcdir)/$(dir)\r
+>> \r
+>> libutil_c_srcs := $(dir)/xutil.c $(dir)/error_util.c $(dir)/hex-escape.c \\r
+>> - $(dir)/string-util.c $(dir)/talloc-extra.c\r
+>> + $(dir)/string-util.c $(dir)/talloc-extra.c $(dir)/zlib-extra.c\r
+>> \r
+>> libutil_modules := $(libutil_c_srcs:.c=.o)\r
+>> \r
+>> diff --git a/util/util.h b/util/util.h\r
+>> new file mode 100644\r
+>> index 0000000..8663cfc\r
+>> --- /dev/null\r
+>> +++ b/util/util.h\r
+>> @@ -0,0 +1,12 @@\r
+>> +#ifndef _UTIL_H\r
+>> +#define _UTIL_H\r
+>> +\r
+>> +typedef enum util_status {\r
+>> + UTIL_SUCCESS = 0,\r
+>> + UTIL_ERROR = 1,\r
+>> + UTIL_OUT_OF_MEMORY,\r
+>> + UTIL_EOF,\r
+>> + UTIL_FILE,\r
+>> +} util_status_t;\r
+>> +\r
+>> +#endif\r
+>> diff --git a/util/zlib-extra.c b/util/zlib-extra.c\r
+>> new file mode 100644\r
+>> index 0000000..cb1eba0\r
+>> --- /dev/null\r
+>> +++ b/util/zlib-extra.c\r
+>> @@ -0,0 +1,76 @@\r
+>> +/* zlib-extra.c - Extra or enhanced routines for compressed I/O.\r
+>> + *\r
+>> + * Copyright (c) 2014 David Bremner\r
+>> + *\r
+>> + * This program is free software: you can redistribute it and/or modify\r
+>> + * it under the terms of the GNU General Public License as published by\r
+>> + * the Free Software Foundation, either version 3 of the License, or\r
+>> + * (at your option) any later version.\r
+>> + *\r
+>> + * This program is distributed in the hope that it will be useful,\r
+>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+>> + * GNU General Public License for more details.\r
+>> + *\r
+>> + * You should have received a copy of the GNU General Public License\r
+>> + * along with this program. If not, see http://www.gnu.org/licenses/ .\r
+>> + *\r
+>> + * Author: David Bremner <david@tethera.net>\r
+>> + */\r
+>> +\r
+>> +#include "zlib-extra.h"\r
+>> +#include <talloc.h>\r
+>> +#include <stdio.h>\r
+>> +#include <string.h>\r
+>> +\r
+>> +/* mimic POSIX/glibc getline, but on a zlib gzFile stream, and using talloc */\r
+>> +util_status_t\r
+>> +gz_getline (void *talloc_ctx, char **bufptr, size_t *bufsiz, ssize_t *bytes_read,\r
+>\r
+> Talloc chunks know their size, so rather than taking bufsize, use\r
+> talloc_get_size (or talloc_array_length if you switch to talloc array\r
+> functions below).\r
+\r
+Now yoy David have a chance to drop the bufsiz argument altogether, as the\r
+info is available in *bufptr:s talloc context...\r
+\r
+>\r
+>> + gzFile stream)\r
+>> +{\r
+>> + size_t len = *bufsiz;\r
+>> + char *buf = *bufptr;\r
+>> + size_t offset = 0;\r
+>> +\r
+>> + if (len == 0 || buf == NULL) {\r
+>> + /* same as getdelim from gnulib */\r
+>> + len = 120;\r
+>\r
+> This is presumably because glibc's malloc has an 8 byte header. Fun\r
+> fact: talloc has a 104 byte header (on 64-bit and including the malloc\r
+> header).\r
+\r
+hmm, what should we choose here? 152 ? Some bikeshedding on IRC ?\r
+\r
+>> + buf = talloc_size (talloc_ctx, len);\r
+>> + if (buf == NULL)\r
+>> + return UTIL_OUT_OF_MEMORY;\r
+>> + }\r
+>> +\r
+>> + while (1) {\r
+>> + if (! gzgets (stream, buf + offset, len - offset)) {\r
+>> + int zlib_status = 0;\r
+>> + (void) gzerror (stream, &zlib_status);\r
+>> + switch (zlib_status) {\r
+>> + case Z_OK:\r
+>> + /* follow getline behaviour */\r
+>> + *bytes_read = -1;\r
+>\r
+> Is this really what getline does when the last line of a file isn't\r
+> \n-terminated?\r
+\r
+Maybe the previous call returned non-\n -terminated string and\r
+for this call there was 0 bytes left to return ???\r
+\r
+Tomi\r
+\r
+>> + return UTIL_EOF;\r
+>> + break;\r
+>> + case Z_ERRNO:\r
+>> + return UTIL_FILE;\r
+>> + break;\r
+>> + default:\r
+>> + return UTIL_ERROR;\r
+>> + }\r
+>> + }\r
+>> +\r
+>> + offset += strlen (buf + offset);\r
+>> +\r
+>> + if ( buf[offset - 1] == '\n' )\r
+>\r
+> Too many spaces!\r
+>\r
+>> + break;\r
+>> +\r
+>> + len *= 2;\r
+>> + buf = talloc_realloc (talloc_ctx, buf, char, len);\r
+>\r
+> Or talloc_realloc_size, to match the initial talloc_size.\r
+> Alternatively, the initial talloc_size could be a talloc_array.\r
+>\r
+>> + if (buf == NULL)\r
+>> + return UTIL_OUT_OF_MEMORY;\r
+>> + }\r
+>> +\r
+>> + *bufptr = buf;\r
+>> + *bufsiz = len;\r
+>> + *bytes_read = offset;\r
+>> + return UTIL_SUCCESS;\r
+>> +}\r
+>> diff --git a/util/zlib-extra.h b/util/zlib-extra.h\r
+>> new file mode 100644\r
+>> index 0000000..ed46ac1\r
+>> --- /dev/null\r
+>> +++ b/util/zlib-extra.h\r
+>> @@ -0,0 +1,11 @@\r
+>> +#ifndef _ZLIB_EXTRA_H\r
+>> +#define _ZLIB_EXTRA_H\r
+>> +\r
+>> +#include <zlib.h>\r
+>> +#include "util.h"\r
+>\r
+> I'd put "util.h" first so we're more likely to catch missing header\r
+> dependencies (obviously util.h doesn't have any right now, but in the\r
+> future).\r
+>\r
+> Also, I'd put a blank line after the #includes.\r
+>\r
+>> +/* Like getline, but read from a gzFile. Allocation is with talloc */\r
+>> +util_status_t\r
+>> +gz_getline (void *ctx, char **lineptr, size_t *line_size, ssize_t *bytes_read,\r
+>> + gzFile stream);\r
+>> +\r
+>> +#endif\r