diff options
Diffstat (limited to 'src/util.c')
-rw-r--r-- | src/util.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..47bf7a7 --- /dev/null +++ b/src/util.c @@ -0,0 +1,65 @@ +#include <errno.h> +#include "defs.h" +#include "util.h" +#include "cache.h" +#include "stream.h" + +int stream_rewind(struct stream * const restrict in) +{ + int ret = 0; + + in->cnode = in->cnode ? in->cache_l : NULL; + in->index = 0; + + return ret; +} + +int split(struct stream * const src, struct stream * const A, struct stream * const B) +{ + int ret = 0; + struct settings tmp_settings[2]; + + try(src->n < 2, err, EINVAL, "cannot split single element stream."); + + /* setting up minimal stream basics */ + A->n = src->n / 2; + B->n = src->n / 2 + (src->n & 1ul); + A->index = B->index = 0; + /* we only care about these three functions for these temporary streams */ + A->get = B->get = src->get; + A->put = B->put = src->put; + A->copy = B->copy = src->copy; + + tmp_settings[0] = *src->settings; + tmp_settings[1] = *src->settings; + A->settings = tmp_settings; + B->settings = tmp_settings + 1; + + /* setting up A */ + tmp_settings[0].ss = 0; + tmp_settings[0].to = A->n; + /* setting up B */ + tmp_settings[1].ss = A->n; + tmp_settings[1].to = src->n; + + if (src->settings->access == cached) { + A->fd = B->fd = -1; /* if we're splitting, these are for holding cache only */ + A->type = B->type = stream_cache; + try_s((ret = cache_create(A)), err); + try_s((ret = src->copy(src, A)), err); + try_s((ret = cache_create(B)), err); + try_s((ret = src->copy(src, B)), err); + } else { + A->name = B->name = src->name; + A->type = B->type = stream_lite; + try_s((ret = stream_open(A)), err); + try_s((ret = src->copy(src, A)), err); + try_s((ret = stream_open(B)), err); + try_s((ret = src->copy(src, B)), err); + } + + A->settings = B->settings = src->settings; + +err: + return ret; +} |