Re: [Patch v5 3/6] util: add gz_readline
[notmuch-archives.git] / 69 / fc33f8785fb435655327e0e5ba4f32d4edcdbb
1 Return-Path: <tomi.ollila@iki.fi>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id 3EA6C431FBD\r
6         for <notmuch@notmuchmail.org>; Wed,  2 Apr 2014 09:43:22 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: 0\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
12         autolearn=disabled\r
13 Received: from olra.theworths.org ([127.0.0.1])\r
14         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
15         with ESMTP id LP4k8hZe6jxm for <notmuch@notmuchmail.org>;\r
16         Wed,  2 Apr 2014 09:43:16 -0700 (PDT)\r
17 Received: from guru.guru-group.fi (guru.guru-group.fi [46.183.73.34])\r
18         by olra.theworths.org (Postfix) with ESMTP id D7BCF431FAE\r
19         for <notmuch@notmuchmail.org>; Wed,  2 Apr 2014 09:43:15 -0700 (PDT)\r
20 Received: from guru.guru-group.fi (localhost [IPv6:::1])\r
21         by guru.guru-group.fi (Postfix) with ESMTP id A55DD100051;\r
22         Wed,  2 Apr 2014 19:43:07 +0300 (EEST)\r
23 From: Tomi Ollila <tomi.ollila@iki.fi>\r
24 To: Austin Clements <amdragon@MIT.EDU>, David Bremner <david@tethera.net>\r
25 Subject: Re: [Patch v5 3/6] util: add gz_readline\r
26 In-Reply-To: <20140402032644.GB25677@mit.edu>\r
27 References: <1396401381-18128-1-git-send-email-david@tethera.net>\r
28         <1396401381-18128-4-git-send-email-david@tethera.net>\r
29         <20140402032644.GB25677@mit.edu>\r
30 User-Agent: Notmuch/0.17+174~gef82849 (http://notmuchmail.org) Emacs/24.3.1\r
31         (x86_64-unknown-linux-gnu)\r
32 X-Face: HhBM'cA~<r"^Xv\KRN0P{vn'Y"Kd;zg_y3S[4)KSN~s?O\"QPoL\r
33         $[Xv_BD:i/F$WiEWax}R(MPS`^UaptOGD`*/=@\1lKoVa9tnrg0TW?"r7aRtgk[F\r
34         !)g;OY^,BjTbr)Np:%c_o'jj,Z\r
35 Date: Wed, 02 Apr 2014 19:43:07 +0300\r
36 Message-ID: <m2wqf73co4.fsf@guru.guru-group.fi>\r
37 MIME-Version: 1.0\r
38 Content-Type: text/plain\r
39 Cc: notmuch@notmuchmail.org\r
40 X-BeenThere: notmuch@notmuchmail.org\r
41 X-Mailman-Version: 2.1.13\r
42 Precedence: list\r
43 List-Id: "Use and development of the notmuch mail system."\r
44         <notmuch.notmuchmail.org>\r
45 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
46         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
47 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
48 List-Post: <mailto:notmuch@notmuchmail.org>\r
49 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
50 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
51         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
52 X-List-Received-Date: Wed, 02 Apr 2014 16:43:22 -0000\r
53 \r
54 On Wed, Apr 02 2014, Austin Clements <amdragon@MIT.EDU> wrote:\r
55 \r
56 > Quoth David Bremner on Apr 01 at 10:16 pm:\r
57 >> The idea is to provide a more or less drop in replacement for readline\r
58 >> to read from zlib/gzip streams.  Take the opportunity to replace\r
59 >> malloc with talloc.\r
60 >> ---\r
61 >>  util/Makefile.local |  2 +-\r
62 >>  util/util.h         | 12 +++++++++\r
63 >>  util/zlib-extra.c   | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++\r
64 >>  util/zlib-extra.h   | 11 ++++++++\r
65 >>  4 files changed, 100 insertions(+), 1 deletion(-)\r
66 >>  create mode 100644 util/util.h\r
67 >>  create mode 100644 util/zlib-extra.c\r
68 >>  create mode 100644 util/zlib-extra.h\r
69 >> \r
70 >> diff --git a/util/Makefile.local b/util/Makefile.local\r
71 >> index 29c0ce6..e2a5b65 100644\r
72 >> --- a/util/Makefile.local\r
73 >> +++ b/util/Makefile.local\r
74 >> @@ -4,7 +4,7 @@ dir := util\r
75 >>  extra_cflags += -I$(srcdir)/$(dir)\r
76 >>  \r
77 >>  libutil_c_srcs := $(dir)/xutil.c $(dir)/error_util.c $(dir)/hex-escape.c \\r
78 >> -              $(dir)/string-util.c $(dir)/talloc-extra.c\r
79 >> +              $(dir)/string-util.c $(dir)/talloc-extra.c $(dir)/zlib-extra.c\r
80 >>  \r
81 >>  libutil_modules := $(libutil_c_srcs:.c=.o)\r
82 >>  \r
83 >> diff --git a/util/util.h b/util/util.h\r
84 >> new file mode 100644\r
85 >> index 0000000..8663cfc\r
86 >> --- /dev/null\r
87 >> +++ b/util/util.h\r
88 >> @@ -0,0 +1,12 @@\r
89 >> +#ifndef _UTIL_H\r
90 >> +#define _UTIL_H\r
91 >> +\r
92 >> +typedef enum util_status {\r
93 >> +    UTIL_SUCCESS = 0,\r
94 >> +    UTIL_ERROR = 1,\r
95 >> +    UTIL_OUT_OF_MEMORY,\r
96 >> +    UTIL_EOF,\r
97 >> +    UTIL_FILE,\r
98 >> +} util_status_t;\r
99 >> +\r
100 >> +#endif\r
101 >> diff --git a/util/zlib-extra.c b/util/zlib-extra.c\r
102 >> new file mode 100644\r
103 >> index 0000000..cb1eba0\r
104 >> --- /dev/null\r
105 >> +++ b/util/zlib-extra.c\r
106 >> @@ -0,0 +1,76 @@\r
107 >> +/* zlib-extra.c -  Extra or enhanced routines for compressed I/O.\r
108 >> + *\r
109 >> + * Copyright (c) 2014 David Bremner\r
110 >> + *\r
111 >> + * This program is free software: you can redistribute it and/or modify\r
112 >> + * it under the terms of the GNU General Public License as published by\r
113 >> + * the Free Software Foundation, either version 3 of the License, or\r
114 >> + * (at your option) any later version.\r
115 >> + *\r
116 >> + * This program is distributed in the hope that it will be useful,\r
117 >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
118 >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
119 >> + * GNU General Public License for more details.\r
120 >> + *\r
121 >> + * You should have received a copy of the GNU General Public License\r
122 >> + * along with this program.  If not, see http://www.gnu.org/licenses/ .\r
123 >> + *\r
124 >> + * Author: David Bremner <david@tethera.net>\r
125 >> + */\r
126 >> +\r
127 >> +#include "zlib-extra.h"\r
128 >> +#include <talloc.h>\r
129 >> +#include <stdio.h>\r
130 >> +#include <string.h>\r
131 >> +\r
132 >> +/* mimic POSIX/glibc getline, but on a zlib gzFile stream, and using talloc */\r
133 >> +util_status_t\r
134 >> +gz_getline (void *talloc_ctx, char **bufptr, size_t *bufsiz, ssize_t *bytes_read,\r
135 >\r
136 > Talloc chunks know their size, so rather than taking bufsize, use\r
137 > talloc_get_size (or talloc_array_length if you switch to talloc array\r
138 > functions below).\r
139 \r
140 Now yoy David have a chance to drop the bufsiz argument altogether, as the\r
141 info is available in *bufptr:s talloc context...\r
142 \r
143 >\r
144 >> +        gzFile stream)\r
145 >> +{\r
146 >> +    size_t len = *bufsiz;\r
147 >> +    char *buf = *bufptr;\r
148 >> +    size_t offset = 0;\r
149 >> +\r
150 >> +    if (len == 0 || buf == NULL) {\r
151 >> +    /* same as getdelim from gnulib */\r
152 >> +    len = 120;\r
153 >\r
154 > This is presumably because glibc's malloc has an 8 byte header.  Fun\r
155 > fact: talloc has a 104 byte header (on 64-bit and including the malloc\r
156 > header).\r
157 \r
158 hmm, what should we choose here? 152 ? Some bikeshedding on IRC ?\r
159 \r
160 >> +    buf = talloc_size (talloc_ctx, len);\r
161 >> +    if (buf == NULL)\r
162 >> +        return UTIL_OUT_OF_MEMORY;\r
163 >> +    }\r
164 >> +\r
165 >> +    while (1) {\r
166 >> +    if (! gzgets (stream, buf + offset, len - offset)) {\r
167 >> +        int zlib_status = 0;\r
168 >> +        (void) gzerror (stream, &zlib_status);\r
169 >> +        switch (zlib_status) {\r
170 >> +        case Z_OK:\r
171 >> +            /* follow getline behaviour */\r
172 >> +            *bytes_read = -1;\r
173 >\r
174 > Is this really what getline does when the last line of a file isn't\r
175 > \n-terminated?\r
176 \r
177 Maybe the previous call returned non-\n -terminated string and\r
178 for this call there was 0 bytes left to return ???\r
179 \r
180 Tomi\r
181 \r
182 >> +            return UTIL_EOF;\r
183 >> +            break;\r
184 >> +        case Z_ERRNO:\r
185 >> +            return UTIL_FILE;\r
186 >> +            break;\r
187 >> +        default:\r
188 >> +            return UTIL_ERROR;\r
189 >> +        }\r
190 >> +    }\r
191 >> +\r
192 >> +    offset += strlen (buf + offset);\r
193 >> +\r
194 >> +    if ( buf[offset - 1] == '\n' )\r
195 >\r
196 > Too many spaces!\r
197 >\r
198 >> +        break;\r
199 >> +\r
200 >> +    len *= 2;\r
201 >> +    buf = talloc_realloc (talloc_ctx, buf, char, len);\r
202 >\r
203 > Or talloc_realloc_size, to match the initial talloc_size.\r
204 > Alternatively, the initial talloc_size could be a talloc_array.\r
205 >\r
206 >> +    if (buf == NULL)\r
207 >> +        return UTIL_OUT_OF_MEMORY;\r
208 >> +    }\r
209 >> +\r
210 >> +    *bufptr = buf;\r
211 >> +    *bufsiz = len;\r
212 >> +    *bytes_read = offset;\r
213 >> +    return UTIL_SUCCESS;\r
214 >> +}\r
215 >> diff --git a/util/zlib-extra.h b/util/zlib-extra.h\r
216 >> new file mode 100644\r
217 >> index 0000000..ed46ac1\r
218 >> --- /dev/null\r
219 >> +++ b/util/zlib-extra.h\r
220 >> @@ -0,0 +1,11 @@\r
221 >> +#ifndef _ZLIB_EXTRA_H\r
222 >> +#define _ZLIB_EXTRA_H\r
223 >> +\r
224 >> +#include <zlib.h>\r
225 >> +#include "util.h"\r
226 >\r
227 > I'd put "util.h" first so we're more likely to catch missing header\r
228 > dependencies (obviously util.h doesn't have any right now, but in the\r
229 > future).\r
230 >\r
231 > Also, I'd put a blank line after the #includes.\r
232 >\r
233 >> +/* Like getline, but read from a gzFile. Allocation is with talloc */\r
234 >> +util_status_t\r
235 >> +gz_getline (void *ctx, char **lineptr, size_t *line_size, ssize_t *bytes_read,\r
236 >> +        gzFile stream);\r
237 >> +\r
238 >> +#endif\r