1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <commonlib/endian.h>
4 #include <commonlib/iobuf.h>
8 static int ibuf_check_size(const struct ibuf
*ib
, size_t sz
)
10 if (ibuf_remaining(ib
) < sz
)
16 void ibuf_init(struct ibuf
*ib
, const void *b
, size_t sz
)
23 void ibuf_from_obuf(struct ibuf
*ib
, const struct obuf
*ob
)
25 ibuf_init(ib
, ob
->b
, ob
->n_written
);
28 int ibuf_splice(const struct ibuf
*src
, struct ibuf
*dst
, size_t off
, size_t sz
)
30 size_t end
= off
+ sz
;
31 size_t capacity
= ibuf_capacity(src
);
32 size_t nr_read
= ibuf_nr_read(src
);
34 if (end
< off
|| end
< sz
|| end
> capacity
)
37 ibuf_init(dst
, &src
->b
[off
], sz
);
39 /* Handle previously read data in src. */
41 dst
->n_read
= nr_read
- off
;
46 int ibuf_splice_current(const struct ibuf
*src
, struct ibuf
*dst
, size_t sz
)
48 return ibuf_splice(src
, dst
, ibuf_nr_read(src
), sz
);
51 int ibuf_split(const struct ibuf
*src
, struct ibuf
*a
, struct ibuf
*b
,
54 if (ibuf_splice(src
, a
, 0, boundary
))
57 return ibuf_splice(src
, b
, boundary
, ibuf_capacity(src
) - boundary
);
60 const void *ibuf_oob_drain(struct ibuf
*ib
, size_t sz
)
64 if (ibuf_check_size(ib
, sz
))
67 b
= &ib
->b
[ib
->n_read
];
73 int ibuf_read(struct ibuf
*ib
, void *data
, size_t sz
)
75 const void *b
= ibuf_oob_drain(ib
, sz
);
85 int ibuf_read_be8(struct ibuf
*ib
, uint8_t *v
)
87 size_t sz
= sizeof(*v
);
89 if (ibuf_check_size(ib
, sz
))
92 *v
= read_at_be8(ib
->b
, ib
->n_read
);
98 int ibuf_read_be16(struct ibuf
*ib
, uint16_t *v
)
100 size_t sz
= sizeof(*v
);
102 if (ibuf_check_size(ib
, sz
))
105 *v
= read_at_be16(ib
->b
, ib
->n_read
);
111 int ibuf_read_be32(struct ibuf
*ib
, uint32_t *v
)
113 size_t sz
= sizeof(*v
);
115 if (ibuf_check_size(ib
, sz
))
118 *v
= read_at_be32(ib
->b
, ib
->n_read
);
124 int ibuf_read_be64(struct ibuf
*ib
, uint64_t *v
)
126 size_t sz
= sizeof(*v
);
128 if (ibuf_check_size(ib
, sz
))
131 *v
= read_at_be64(ib
->b
, ib
->n_read
);
137 int ibuf_read_le8(struct ibuf
*ib
, uint8_t *v
)
139 size_t sz
= sizeof(*v
);
141 if (ibuf_check_size(ib
, sz
))
144 *v
= read_at_le8(ib
->b
, ib
->n_read
);
150 int ibuf_read_le16(struct ibuf
*ib
, uint16_t *v
)
152 size_t sz
= sizeof(*v
);
154 if (ibuf_check_size(ib
, sz
))
157 *v
= read_at_le16(ib
->b
, ib
->n_read
);
163 int ibuf_read_le32(struct ibuf
*ib
, uint32_t *v
)
165 size_t sz
= sizeof(*v
);
167 if (ibuf_check_size(ib
, sz
))
170 *v
= read_at_le32(ib
->b
, ib
->n_read
);
176 int ibuf_read_le64(struct ibuf
*ib
, uint64_t *v
)
178 size_t sz
= sizeof(*v
);
180 if (ibuf_check_size(ib
, sz
))
183 *v
= read_at_le64(ib
->b
, ib
->n_read
);
189 int ibuf_read_n8(struct ibuf
*ib
, uint8_t *v
)
191 return ibuf_read(ib
, v
, sizeof(*v
));
194 int ibuf_read_n16(struct ibuf
*ib
, uint16_t *v
)
196 return ibuf_read(ib
, v
, sizeof(*v
));
199 int ibuf_read_n32(struct ibuf
*ib
, uint32_t *v
)
201 return ibuf_read(ib
, v
, sizeof(*v
));
204 int ibuf_read_n64(struct ibuf
*ib
, uint64_t *v
)
206 return ibuf_read(ib
, v
, sizeof(*v
));
209 static int obuf_check_size(const struct obuf
*ob
, size_t sz
)
211 if (obuf_remaining(ob
) < sz
)
217 void obuf_init(struct obuf
*ob
, void *b
, size_t sz
)
224 int obuf_splice(const struct obuf
*src
, struct obuf
*dst
, size_t off
, size_t sz
)
226 size_t end
= off
+ sz
;
227 size_t capacity
= obuf_capacity(src
);
228 size_t nr_written
= obuf_nr_written(src
);
230 if (end
< off
|| end
< sz
|| end
> capacity
)
233 obuf_init(dst
, &src
->b
[off
], sz
);
235 /* Handle previously written data in src. */
236 if (off
< nr_written
)
237 dst
->n_written
= nr_written
- off
;
242 int obuf_splice_current(const struct obuf
*src
, struct obuf
*dst
, size_t sz
)
244 return obuf_splice(src
, dst
, obuf_nr_written(src
), sz
);
247 int obuf_split(const struct obuf
*src
, struct obuf
*a
, struct obuf
*b
,
250 if (obuf_splice(src
, a
, 0, boundary
))
253 return obuf_splice(src
, b
, boundary
, obuf_capacity(src
) - boundary
);
256 void *obuf_oob_fill(struct obuf
*ob
, size_t sz
)
260 if (obuf_check_size(ob
, sz
))
263 b
= &ob
->b
[ob
->n_written
];
269 int obuf_write(struct obuf
*ob
, const void *data
, size_t sz
)
273 b
= obuf_oob_fill(ob
, sz
);
282 int obuf_write_be8(struct obuf
*ob
, uint8_t v
)
284 size_t sz
= sizeof(v
);
286 if (obuf_check_size(ob
, sz
))
289 write_at_be8(ob
->b
, v
, ob
->n_written
);
295 int obuf_write_be16(struct obuf
*ob
, uint16_t v
)
297 size_t sz
= sizeof(v
);
299 if (obuf_check_size(ob
, sz
))
302 write_at_be16(ob
->b
, v
, ob
->n_written
);
308 int obuf_write_be32(struct obuf
*ob
, uint32_t v
)
310 size_t sz
= sizeof(v
);
312 if (obuf_check_size(ob
, sz
))
315 write_at_be32(ob
->b
, v
, ob
->n_written
);
321 int obuf_write_be64(struct obuf
*ob
, uint64_t v
)
323 size_t sz
= sizeof(v
);
325 if (obuf_check_size(ob
, sz
))
328 write_at_be64(ob
->b
, v
, ob
->n_written
);
334 int obuf_write_le8(struct obuf
*ob
, uint8_t v
)
336 size_t sz
= sizeof(v
);
338 if (obuf_check_size(ob
, sz
))
341 write_at_le8(ob
->b
, v
, ob
->n_written
);
347 int obuf_write_le16(struct obuf
*ob
, uint16_t v
)
349 size_t sz
= sizeof(v
);
351 if (obuf_check_size(ob
, sz
))
354 write_at_le16(ob
->b
, v
, ob
->n_written
);
360 int obuf_write_le32(struct obuf
*ob
, uint32_t v
)
362 size_t sz
= sizeof(v
);
364 if (obuf_check_size(ob
, sz
))
367 write_at_le32(ob
->b
, v
, ob
->n_written
);
373 int obuf_write_le64(struct obuf
*ob
, uint64_t v
)
375 size_t sz
= sizeof(v
);
377 if (obuf_check_size(ob
, sz
))
380 write_at_le64(ob
->b
, v
, ob
->n_written
);
386 int obuf_write_n8(struct obuf
*ob
, uint8_t v
)
388 return obuf_write(ob
, &v
, sizeof(v
));
391 int obuf_write_n16(struct obuf
*ob
, uint16_t v
)
393 return obuf_write(ob
, &v
, sizeof(v
));
396 int obuf_write_n32(struct obuf
*ob
, uint32_t v
)
398 return obuf_write(ob
, &v
, sizeof(v
));
401 int obuf_write_n64(struct obuf
*ob
, uint64_t v
)
403 return obuf_write(ob
, &v
, sizeof(v
));
406 const void *obuf_contents(const struct obuf
*ob
, size_t *sz
)
408 *sz
= obuf_nr_written(ob
);