slice.c 3.83 KB
Newer Older
1
#include "dev/excit.h"
2
3
#include "slice.h"

4
static int slice_it_alloc(excit_t data)
5
{
6
7
8
9
10
	struct slice_it_s *it = (struct slice_it_s *)data->data;

	it->src = NULL;
	it->indexer = NULL;
	return EXCIT_SUCCESS;
11
12
}

13
static void slice_it_free(excit_t data)
14
{
15
16
17
18
	struct slice_it_s *it = (struct slice_it_s *)data->data;

	excit_free(it->src);
	excit_free(it->indexer);
19
20
}

21
static int slice_it_copy(excit_t dst, const excit_t src)
22
{
23
24
25
26
27
28
29
30
31
32
33
34
	const struct slice_it_s *it = (const struct slice_it_s *)src->data;
	struct slice_it_s *result = (struct slice_it_s *)dst->data;

	result->src = excit_dup(it->src);
	if (!result->src)
		return -EXCIT_ENOMEM;
	result->indexer = excit_dup(it->indexer);
	if (!result->indexer) {
		excit_free(it->src);
		return -EXCIT_ENOMEM;
	}
	return EXCIT_SUCCESS;
35
36
}

37
static int slice_it_next(excit_t data, ssize_t *indexes)
38
{
39
40
41
42
43
44
45
	struct slice_it_s *it = (struct slice_it_s *)data->data;
	ssize_t n;
	int err = excit_next(it->indexer, &n);

	if (err)
		return err;
	return excit_nth(it->src, n, indexes);
46
47
}

48
static int slice_it_peek(const excit_t data, ssize_t *indexes)
49
{
50
51
52
53
54
55
56
	const struct slice_it_s *it = (const struct slice_it_s *)data->data;
	ssize_t n;
	int err = excit_peek(it->indexer, &n);

	if (err)
		return err;
	return excit_nth(it->src, n, indexes);
57
58
}

59
static int slice_it_size(const excit_t data, ssize_t *size)
60
{
61
62
63
	const struct slice_it_s *it = (const struct slice_it_s *)data->data;

	return excit_size(it->indexer, size);
64
65
}

66
static int slice_it_rewind(excit_t data)
67
{
68
	struct slice_it_s *it = (struct slice_it_s *)data->data;
69

70
	return excit_rewind(it->indexer);
71
72
}

73
static int slice_it_nth(const excit_t data, ssize_t n, ssize_t *indexes)
74
{
75
76
77
78
79
80
81
	const struct slice_it_s *it = (const struct slice_it_s *)data->data;
	ssize_t p;
	int err = excit_nth(it->indexer, n, &p);

	if (err)
		return err;
	return excit_nth(it->src, p, indexes);
82
83
}

84
85
static int slice_it_rank(const excit_t data, const ssize_t *indexes,
			 ssize_t *n)
86
{
87
88
89
90
91
92
93
	const struct slice_it_s *it = (const struct slice_it_s *)data->data;
	ssize_t inner_n;
	int err = excit_rank(it->src, indexes, &inner_n);

	if (err)
		return err;
	return excit_rank(it->indexer, &inner_n, n);
94
95
}

96
static int slice_it_pos(const excit_t data, ssize_t *n)
97
{
98
99
100
	const struct slice_it_s *it = (const struct slice_it_s *)data->data;

	return excit_pos(it->indexer, n);
101
102
}

103
static int slice_it_split(const excit_t data, ssize_t n, excit_t *results)
104
{
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
	const struct slice_it_s *it = (const struct slice_it_s *)data->data;
	int err = excit_split(it->indexer, n, results);

	if (err)
		return err;
	if (!results)
		return EXCIT_SUCCESS;
	for (int i = 0; i < n; i++) {
		excit_t tmp;
		excit_t tmp2;

		tmp = results[i];
		results[i] = excit_alloc(EXCIT_SLICE);
		if (!results[i]) {
			excit_free(tmp);
			err = -EXCIT_ENOMEM;
			goto error;
		}
		tmp2 = excit_dup(it->src);
		if (!tmp2) {
			excit_free(tmp);
			err = -EXCIT_ENOMEM;
			goto error;
		}
Brice Videau's avatar
Brice Videau committed
129
		err = excit_slice_init(results[i], tmp2, tmp);
130
131
132
133
134
135
136
		if (err) {
			excit_free(tmp);
			excit_free(tmp2);
			goto error;
		}
	}
	return EXCIT_SUCCESS;
137
error:
138
139
140
	for (int i = 0; i < n; i++)
		excit_free(results[i]);
	return err;
141
142
}

143
144
145
146
147
148
149
150
151
152
153
154
155
156
struct excit_func_table_s excit_slice_func_table = {
	slice_it_alloc,
	slice_it_free,
	slice_it_copy,
	slice_it_next,
	slice_it_peek,
	slice_it_size,
	slice_it_rewind,
	slice_it_split,
	slice_it_nth,
	slice_it_rank,
	slice_it_pos
};

157
158
int excit_slice_init(excit_t it, excit_t src, excit_t indexer)
{
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
	if (!it || it->type != EXCIT_SLICE || !src || !indexer
	    || indexer->dimension != 1)
		return -EXCIT_EINVAL;
	struct slice_it_s *slice_it = (struct slice_it_s *)it->data;
	ssize_t size_src;
	ssize_t size_indexer;
	int err = excit_size(src, &size_src);

	if (err)
		return err;
	err = excit_size(indexer, &size_indexer);
	if (err)
		return err;
	if (size_indexer > size_src)
		return -EXCIT_EDOM;
	slice_it->src = src;
	slice_it->indexer = indexer;
	it->dimension = src->dimension;
	return EXCIT_SUCCESS;
178
179
}