1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
#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;
if (in->cnode) {
if (in->cache) {
in->cnode = in->cache_l;
} else {
in->cnode_f.file_offset = 0;
}
}
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;
}
|