summaryrefslogtreecommitdiffstats
path: root/src/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cache.c')
-rw-r--r--src/cache.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/src/cache.c b/src/cache.c
index e0852f4..f158e44 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -2,6 +2,7 @@
/* Copyright (C) 2020-2021 Gediminas Jakutis */
+#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -11,6 +12,8 @@
#include "stream.h"
#include "cache.h"
+static int cache_readfile(struct stream * const in);
+
int cache_create(struct stream * const in)
{
int ret = 0;
@@ -48,7 +51,7 @@ int cache_populate(struct stream * const in)
}
}
} else if (in->type == stream_in) {
- try_s((ret == stream_readfile(in)), err);
+ try_s((ret == cache_readfile(in)), err);
} else {
try(1, err, EINVAL, "cannot populate a non-reading stream cache");
}
@@ -247,3 +250,36 @@ int cache_rewind(struct stream * const in)
return ret;
}
+
+static int cache_readfile(struct stream * const in)
+{
+ ssize_t ret = 0;
+ size_t remaining = in->n * in->settings->stride;
+ ssize_t bytesread = 0;
+ size_t i;
+
+ try(in->fd < 3, err, EINVAL, "no file open for reading");
+
+ do {
+ ret = read(in->fd, in->cache + bytesread, remaining);
+ if (ret < 0) {
+ try(errno != EAGAIN, err, errno, "Writing to stream failed with %zi", ret);
+ } else {
+ bytesread += ret;
+ remaining -= ret;
+ }
+ } while (ret);
+
+ /* if this is a list, we need to adjust the link pointers from file offsets
+ * to buffer addresses. 'Cept for the last one, which needs to be NULL.
+ */
+ if (in->settings->format == list) {
+ for (i = 0; i < (in->n - 1); ++i) {
+ in->cache_l[i].nextaddr = in->cache + in->cache_l[i].offset;
+ }
+ in->cnode = in->cache_l;
+ }
+
+err:
+ return ret;
+}