chiark / gitweb /
Hands-off reader type
authorRichard Kettlewell <richard@kakajou.wlan.anjou.terraraq.org.uk>
Sun, 6 Jun 2010 18:00:38 +0000 (19:00 +0100)
committerRichard Kettlewell <richard@kakajou.wlan.anjou.terraraq.org.uk>
Sun, 6 Jun 2010 18:00:38 +0000 (19:00 +0100)
lib/Makefile.am
lib/hreader.c [new file with mode: 0644]
lib/hreader.h [new file with mode: 0644]

index be12f1c..ff0eb8b 100644 (file)
@@ -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 (file)
index 0000000..6390d69
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+ */
+/** @file lib/hreader.c
+ * @brief Hands-off reader - read files without keeping them open
+ */
+#include "hreader.h"
+#include "mem.h"
+#include <string.h>
+#include <fcntl.h>
+
+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 (file)
index 0000000..ac56b2c
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+ */
+/** @file lib/hreader.h
+ * @brief Hands-off reader - read files without keeping them open
+ */
+#ifndef HREADER_H
+#define HREADER_H
+
+#include <unistd.h>
+
+/** @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:
+*/