From: Richard Kettlewell Date: Sun, 6 Jun 2010 18:00:38 +0000 (+0100) Subject: Hands-off reader type X-Git-Tag: branchpoint-5.1~77^2~9 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/commitdiff_plain/5e57438cb616e2da147c5365330872c424cca02e Hands-off reader type --- diff --git a/lib/Makefile.am b/lib/Makefile.am index be12f1c..ff0eb8b 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -52,6 +52,7 @@ libdisorder_a_SOURCES=charset.c charset.h \ heap.h \ hex.c hex.h \ hostname.c hostname.h \ + hreader.c hreader.h \ ifreq.c ifreq.h \ inputline.c inputline.h \ kvp.c kvp.h \ diff --git a/lib/hreader.c b/lib/hreader.c new file mode 100644 index 0000000..6390d69 --- /dev/null +++ b/lib/hreader.c @@ -0,0 +1,77 @@ +/* + * This file is part of DisOrder + * Copyright (C) 2010 Richard Kettlewell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +/** @file lib/hreader.c + * @brief Hands-off reader - read files without keeping them open + */ +#include "hreader.h" +#include "mem.h" +#include +#include + +void hreader_init(const char *path, struct hreader *h) { + memset(h, 0, sizeof *h); + h->path = xstrdup(path); + h->bufsize = 65536; + h->buffer = xmalloc_noptr(h->bufsize); +} + +int hreader_read(struct hreader *h, void *buffer, size_t n) { + if(h->consumed == h->bytes) { + int r; + + if((r = hreader_fill(h)) <= 0) + return r; + } + if(n > h->bytes - h->consumed) + n = h->bytes - h->consumed; + memcpy(buffer, h->buffer + h->consumed, n); + h->consumed += n; + return n; +} + +int hreader_fill(struct hreader *h) { + if(h->consumed < h->bytes) + return h->bytes - h->consumed; + h->bytes = h->consumed = 0; + int fd = open(h->path, O_RDONLY); + if(fd < 0) + return -1; + if(lseek(fd, h->offset, SEEK_SET) < 0) { + close(fd); + return -1; + } + int n = read(fd, h->buffer, h->bufsize); + close(fd); + if(n < 0) + return -1; + h->bytes = n; + return n; +} + +void hreader_consume(struct hreader *h, size_t n) { + h->consumed += n; +} + +/* +Local Variables: +c-basic-offset:2 +comment-column:40 +fill-column:79 +indent-tabs-mode:nil +End: +*/ diff --git a/lib/hreader.h b/lib/hreader.h new file mode 100644 index 0000000..ac56b2c --- /dev/null +++ b/lib/hreader.h @@ -0,0 +1,78 @@ +/* + * This file is part of DisOrder + * Copyright (C) 2010 Richard Kettlewell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +/** @file lib/hreader.h + * @brief Hands-off reader - read files without keeping them open + */ +#ifndef HREADER_H +#define HREADER_H + +#include + +/** @brief A hands-off reader + * + * Allows files to be read without holding them open. + */ +struct hreader { + const char *path; /* file to read */ + off_t offset; /* how far we've read so far */ + char *buffer; /* input buffer */ + size_t bufsize; /* buffer size */ + size_t bytes; /* size of last read */ + size_t consumed; /* bytes consumed by caller from last read */ +}; + +/** @brief Initialize a hands-off reader + * @param path File to read + * @param h Reader to initialize + */ +void hreader_init(const char *path, struct hreader *h); + +/** @brief Read some bytes + * @param h Reader to read from + * @param buffer Where to store bytes + * @param n Maximum bytes to read + * @return Bytes read, or 0 at EOF, or -1 on error + */ +int hreader_read(struct hreader *h, void *buffer, size_t n); + +/** @brief Read more bytes + * @param h Reader to update + * @return Bytes available to read + * + * If not all bytes were consumed so far then just returns the number + * of bytes left to consume. + */ +int hreader_fill(struct hreader *h); + +/** @brief Consume some bytes + * @param h Reader to update + * @param n Bytes to consume + */ +void hreader_consume(struct hreader *h, size_t n); + +#endif /* HREADER_H */ + + +/* +Local Variables: +c-basic-offset:2 +comment-column:40 +fill-column:79 +indent-tabs-mode:nil +End: +*/