blob: 378793e223dbe6ff02d0197542f7c4cceaf19b50 [file] [log] [blame]
Angel Ponsebda03e2020-04-02 23:48:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Aaron Durbin88b26b82017-03-24 17:10:51 -05002
3#include <commonlib/endian.h>
4#include <commonlib/iobuf.h>
5#include <string.h>
Elyes Haouas6a9ae292022-10-07 10:03:17 +02006#include <stdint.h>
Aaron Durbin88b26b82017-03-24 17:10:51 -05007
8static int ibuf_check_size(const struct ibuf *ib, size_t sz)
9{
10 if (ibuf_remaining(ib) < sz)
11 return -1;
12
13 return 0;
14}
15
16void ibuf_init(struct ibuf *ib, const void *b, size_t sz)
17{
18 ib->b = b;
19 ib->n_read = 0;
20 ib->capacity = sz;
21}
22
23void ibuf_from_obuf(struct ibuf *ib, const struct obuf *ob)
24{
25 ibuf_init(ib, ob->b, ob->n_written);
26}
27
28int ibuf_splice(const struct ibuf *src, struct ibuf *dst, size_t off, size_t sz)
29{
30 size_t end = off + sz;
31 size_t capacity = ibuf_capacity(src);
32 size_t nr_read = ibuf_nr_read(src);
33
34 if (end < off || end < sz || end > capacity)
35 return -1;
36
37 ibuf_init(dst, &src->b[off], sz);
38
39 /* Handle previously read data in src. */
40 if (off < nr_read)
41 dst->n_read = nr_read - off;
42
43 return 0;
44}
45
46int ibuf_splice_current(const struct ibuf *src, struct ibuf *dst, size_t sz)
47{
48 return ibuf_splice(src, dst, ibuf_nr_read(src), sz);
49}
50
51int ibuf_split(const struct ibuf *src, struct ibuf *a, struct ibuf *b,
52 size_t boundary)
53{
54 if (ibuf_splice(src, a, 0, boundary))
55 return -1;
56
57 return ibuf_splice(src, b, boundary, ibuf_capacity(src) - boundary);
58}
59
60const void *ibuf_oob_drain(struct ibuf *ib, size_t sz)
61{
62 const void *b;
63
64 if (ibuf_check_size(ib, sz))
65 return NULL;
66
67 b = &ib->b[ib->n_read];
68 ib->n_read += sz;
69
70 return b;
71}
72
73int ibuf_read(struct ibuf *ib, void *data, size_t sz)
74{
75 const void *b = ibuf_oob_drain(ib, sz);
76
77 if (b == NULL)
78 return -1;
79
80 memcpy(data, b, sz);
81
82 return 0;
83}
84
85int ibuf_read_be8(struct ibuf *ib, uint8_t *v)
86{
87 size_t sz = sizeof(*v);
88
89 if (ibuf_check_size(ib, sz))
90 return -1;
91
92 *v = read_at_be8(ib->b, ib->n_read);
93 ib->n_read += sz;
94
95 return 0;
96}
97
98int ibuf_read_be16(struct ibuf *ib, uint16_t *v)
99{
100 size_t sz = sizeof(*v);
101
102 if (ibuf_check_size(ib, sz))
103 return -1;
104
105 *v = read_at_be16(ib->b, ib->n_read);
106 ib->n_read += sz;
107
108 return 0;
109}
110
111int ibuf_read_be32(struct ibuf *ib, uint32_t *v)
112{
113 size_t sz = sizeof(*v);
114
115 if (ibuf_check_size(ib, sz))
116 return -1;
117
118 *v = read_at_be32(ib->b, ib->n_read);
119 ib->n_read += sz;
120
121 return 0;
122}
123
124int ibuf_read_be64(struct ibuf *ib, uint64_t *v)
125{
126 size_t sz = sizeof(*v);
127
128 if (ibuf_check_size(ib, sz))
129 return -1;
130
131 *v = read_at_be64(ib->b, ib->n_read);
132 ib->n_read += sz;
133
134 return 0;
135}
136
137int ibuf_read_le8(struct ibuf *ib, uint8_t *v)
138{
139 size_t sz = sizeof(*v);
140
141 if (ibuf_check_size(ib, sz))
142 return -1;
143
144 *v = read_at_le8(ib->b, ib->n_read);
145 ib->n_read += sz;
146
147 return 0;
148}
149
150int ibuf_read_le16(struct ibuf *ib, uint16_t *v)
151{
152 size_t sz = sizeof(*v);
153
154 if (ibuf_check_size(ib, sz))
155 return -1;
156
157 *v = read_at_le16(ib->b, ib->n_read);
158 ib->n_read += sz;
159
160 return 0;
161}
162
163int ibuf_read_le32(struct ibuf *ib, uint32_t *v)
164{
165 size_t sz = sizeof(*v);
166
167 if (ibuf_check_size(ib, sz))
168 return -1;
169
170 *v = read_at_le32(ib->b, ib->n_read);
171 ib->n_read += sz;
172
173 return 0;
174}
175
176int ibuf_read_le64(struct ibuf *ib, uint64_t *v)
177{
178 size_t sz = sizeof(*v);
179
180 if (ibuf_check_size(ib, sz))
181 return -1;
182
183 *v = read_at_le64(ib->b, ib->n_read);
184 ib->n_read += sz;
185
186 return 0;
187}
188
189int ibuf_read_n8(struct ibuf *ib, uint8_t *v)
190{
191 return ibuf_read(ib, v, sizeof(*v));
192}
193
194int ibuf_read_n16(struct ibuf *ib, uint16_t *v)
195{
196 return ibuf_read(ib, v, sizeof(*v));
197}
198
199int ibuf_read_n32(struct ibuf *ib, uint32_t *v)
200{
201 return ibuf_read(ib, v, sizeof(*v));
202}
203
204int ibuf_read_n64(struct ibuf *ib, uint64_t *v)
205{
206 return ibuf_read(ib, v, sizeof(*v));
207}
208
209static int obuf_check_size(const struct obuf *ob, size_t sz)
210{
211 if (obuf_remaining(ob) < sz)
212 return -1;
213
214 return 0;
215}
216
217void obuf_init(struct obuf *ob, void *b, size_t sz)
218{
219 ob->b = b;
220 ob->n_written = 0;
221 ob->capacity = sz;
222}
223
224int obuf_splice(const struct obuf *src, struct obuf *dst, size_t off, size_t sz)
225{
226 size_t end = off + sz;
227 size_t capacity = obuf_capacity(src);
228 size_t nr_written = obuf_nr_written(src);
229
230 if (end < off || end < sz || end > capacity)
231 return -1;
232
233 obuf_init(dst, &src->b[off], sz);
234
235 /* Handle previously written data in src. */
236 if (off < nr_written)
237 dst->n_written = nr_written - off;
238
239 return 0;
240}
241
242int obuf_splice_current(const struct obuf *src, struct obuf *dst, size_t sz)
243{
244 return obuf_splice(src, dst, obuf_nr_written(src), sz);
245}
246
247int obuf_split(const struct obuf *src, struct obuf *a, struct obuf *b,
248 size_t boundary)
249{
250 if (obuf_splice(src, a, 0, boundary))
251 return -1;
252
253 return obuf_splice(src, b, boundary, obuf_capacity(src) - boundary);
254}
255
256void *obuf_oob_fill(struct obuf *ob, size_t sz)
257{
258 void *b;
259
260 if (obuf_check_size(ob, sz))
261 return NULL;
262
263 b = &ob->b[ob->n_written];
264 ob->n_written += sz;
265
266 return b;
267}
268
269int obuf_write(struct obuf *ob, const void *data, size_t sz)
270{
271 void *b;
272
273 b = obuf_oob_fill(ob, sz);
274 if (b == NULL)
275 return -1;
276
277 memcpy(b, data, sz);
278
279 return 0;
280}
281
282int obuf_write_be8(struct obuf *ob, uint8_t v)
283{
284 size_t sz = sizeof(v);
285
286 if (obuf_check_size(ob, sz))
287 return -1;
288
289 write_at_be8(ob->b, v, ob->n_written);
290 ob->n_written += sz;
291
292 return 0;
293}
294
295int obuf_write_be16(struct obuf *ob, uint16_t v)
296{
297 size_t sz = sizeof(v);
298
299 if (obuf_check_size(ob, sz))
300 return -1;
301
302 write_at_be16(ob->b, v, ob->n_written);
303 ob->n_written += sz;
304
305 return 0;
306}
307
308int obuf_write_be32(struct obuf *ob, uint32_t v)
309{
310 size_t sz = sizeof(v);
311
312 if (obuf_check_size(ob, sz))
313 return -1;
314
315 write_at_be32(ob->b, v, ob->n_written);
316 ob->n_written += sz;
317
318 return 0;
319}
320
321int obuf_write_be64(struct obuf *ob, uint64_t v)
322{
323 size_t sz = sizeof(v);
324
325 if (obuf_check_size(ob, sz))
326 return -1;
327
328 write_at_be64(ob->b, v, ob->n_written);
329 ob->n_written += sz;
330
331 return 0;
332}
333
334int obuf_write_le8(struct obuf *ob, uint8_t v)
335{
336 size_t sz = sizeof(v);
337
338 if (obuf_check_size(ob, sz))
339 return -1;
340
341 write_at_le8(ob->b, v, ob->n_written);
342 ob->n_written += sz;
343
344 return 0;
345}
346
347int obuf_write_le16(struct obuf *ob, uint16_t v)
348{
349 size_t sz = sizeof(v);
350
351 if (obuf_check_size(ob, sz))
352 return -1;
353
354 write_at_le16(ob->b, v, ob->n_written);
355 ob->n_written += sz;
356
357 return 0;
358}
359
360int obuf_write_le32(struct obuf *ob, uint32_t v)
361{
362 size_t sz = sizeof(v);
363
364 if (obuf_check_size(ob, sz))
365 return -1;
366
367 write_at_le32(ob->b, v, ob->n_written);
368 ob->n_written += sz;
369
370 return 0;
371}
372
373int obuf_write_le64(struct obuf *ob, uint64_t v)
374{
375 size_t sz = sizeof(v);
376
377 if (obuf_check_size(ob, sz))
378 return -1;
379
380 write_at_le64(ob->b, v, ob->n_written);
381 ob->n_written += sz;
382
383 return 0;
384}
385
386int obuf_write_n8(struct obuf *ob, uint8_t v)
387{
388 return obuf_write(ob, &v, sizeof(v));
389}
390
391int obuf_write_n16(struct obuf *ob, uint16_t v)
392{
393 return obuf_write(ob, &v, sizeof(v));
394}
395
396int obuf_write_n32(struct obuf *ob, uint32_t v)
397{
398 return obuf_write(ob, &v, sizeof(v));
399}
400
401int obuf_write_n64(struct obuf *ob, uint64_t v)
402{
403 return obuf_write(ob, &v, sizeof(v));
404}
405
406const void *obuf_contents(const struct obuf *ob, size_t *sz)
407{
408 *sz = obuf_nr_written(ob);
409 return ob->b;
410}