chiark / gitweb /
disorder.h: more consistent approach to function attributes
[disorder] / lib / hreader.c
index 9bcc808d9203041a68dab85db73ff180ced1dc3c..bdf3c074c7ed5a741070c03721040ee7a4e4281c 100644 (file)
 /** @file lib/hreader.c
  * @brief Hands-off reader - read files without keeping them open
  */
+#include <config.h>
 #include "hreader.h"
 #include "mem.h"
 #include <string.h>
 #include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
 
 static int hreader_fill(struct hreader *h, off_t offset);
 
-void hreader_init(const char *path, struct hreader *h) {
+int hreader_init(const char *path, struct hreader *h) {
+  struct stat sb;
+  if(stat(path, &sb) < 0)
+    return -1;
   memset(h, 0, sizeof *h);
   h->path = xstrdup(path);
+  h->size = sb.st_size;
   h->bufsize = 65536;
   h->buffer = xmalloc_noptr(h->bufsize);
+  return 0;
+}
+
+void hreader_close(struct hreader *h) {
+  xfree(h->path);
+  xfree(h->buffer);
 }
 
 int hreader_read(struct hreader *h, void *buffer, size_t n) {
@@ -78,6 +92,18 @@ static int hreader_fill(struct hreader *h, off_t offset) {
   return n;
 }
 
+off_t hreader_seek(struct hreader *h, off_t offset, int whence) {
+  switch(whence) {
+  case SEEK_SET: break;
+  case SEEK_CUR: offset += h->read_offset; break;
+  case SEEK_END: offset += h->size; break;
+  default: einval: errno = EINVAL; return -1;
+  }
+  if(offset < 0) goto einval;
+  h->read_offset = offset;
+  return offset;
+}
+
 /*
 Local Variables:
 c-basic-offset:2