1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <commonlib/endian.h>
4 #include <commonlib/iobuf.h>
7 static int ibuf_check_size(const struct ibuf
*ib
, size_t sz
)
9 if (ibuf_remaining(ib
) < sz
)
15 void ibuf_init(struct ibuf
*ib
, const void *b
, size_t sz
)
22 void ibuf_from_obuf(struct ibuf
*ib
, const struct obuf
*ob
)
24 ibuf_init(ib
, ob
->b
, ob
->n_written
);
27 int ibuf_splice(const struct ibuf
*src
, struct ibuf
*dst
, size_t off
, size_t sz
)
29 size_t end
= off
+ sz
;
30 size_t capacity
= ibuf_capacity(src
);
31 size_t nr_read
= ibuf_nr_read(src
);
33 if (end
< off
|| end
< sz
|| end
> capacity
)
36 ibuf_init(dst
, &src
->b
[off
], sz
);
38 /* Handle previously read data in src. */
40 dst
->n_read
= nr_read
- off
;
45 int ibuf_splice_current(const struct ibuf
*src
, struct ibuf
*dst
, size_t sz
)
47 return ibuf_splice(src
, dst
, ibuf_nr_read(src
), sz
);
50 int ibuf_split(const struct ibuf
*src
, struct ibuf
*a
, struct ibuf
*b
,
53 if (ibuf_splice(src
, a
, 0, boundary
))
56 return ibuf_splice(src
, b
, boundary
, ibuf_capacity(src
) - boundary
);
59 const void *ibuf_oob_drain(struct ibuf
*ib
, size_t sz
)
63 if (ibuf_check_size(ib
, sz
))
66 b
= &ib
->b
[ib
->n_read
];
72 int ibuf_read(struct ibuf
*ib
, void *data
, size_t sz
)
74 const void *b
= ibuf_oob_drain(ib
, sz
);
84 int ibuf_read_be8(struct ibuf
*ib
, uint8_t *v
)
86 size_t sz
= sizeof(*v
);
88 if (ibuf_check_size(ib
, sz
))
91 *v
= read_at_be8(ib
->b
, ib
->n_read
);
97 int ibuf_read_be16(struct ibuf
*ib
, uint16_t *v
)
99 size_t sz
= sizeof(*v
);
101 if (ibuf_check_size(ib
, sz
))
104 *v
= read_at_be16(ib
->b
, ib
->n_read
);
110 int ibuf_read_be32(struct ibuf
*ib
, uint32_t *v
)
112 size_t sz
= sizeof(*v
);
114 if (ibuf_check_size(ib
, sz
))
117 *v
= read_at_be32(ib
->b
, ib
->n_read
);
123 int ibuf_read_be64(struct ibuf
*ib
, uint64_t *v
)
125 size_t sz
= sizeof(*v
);
127 if (ibuf_check_size(ib
, sz
))
130 *v
= read_at_be64(ib
->b
, ib
->n_read
);
136 int ibuf_read_le8(struct ibuf
*ib
, uint8_t *v
)
138 size_t sz
= sizeof(*v
);
140 if (ibuf_check_size(ib
, sz
))
143 *v
= read_at_le8(ib
->b
, ib
->n_read
);
149 int ibuf_read_le16(struct ibuf
*ib
, uint16_t *v
)
151 size_t sz
= sizeof(*v
);
153 if (ibuf_check_size(ib
, sz
))
156 *v
= read_at_le16(ib
->b
, ib
->n_read
);
162 int ibuf_read_le32(struct ibuf
*ib
, uint32_t *v
)
164 size_t sz
= sizeof(*v
);
166 if (ibuf_check_size(ib
, sz
))
169 *v
= read_at_le32(ib
->b
, ib
->n_read
);
175 int ibuf_read_le64(struct ibuf
*ib
, uint64_t *v
)
177 size_t sz
= sizeof(*v
);
179 if (ibuf_check_size(ib
, sz
))
182 *v
= read_at_le64(ib
->b
, ib
->n_read
);
188 int ibuf_read_n8(struct ibuf
*ib
, uint8_t *v
)
190 return ibuf_read(ib
, v
, sizeof(*v
));
193 int ibuf_read_n16(struct ibuf
*ib
, uint16_t *v
)
195 return ibuf_read(ib
, v
, sizeof(*v
));
198 int ibuf_read_n32(struct ibuf
*ib
, uint32_t *v
)
200 return ibuf_read(ib
, v
, sizeof(*v
));
203 int ibuf_read_n64(struct ibuf
*ib
, uint64_t *v
)
205 return ibuf_read(ib
, v
, sizeof(*v
));
208 static int obuf_check_size(const struct obuf
*ob
, size_t sz
)
210 if (obuf_remaining(ob
) < sz
)
216 void obuf_init(struct obuf
*ob
, void *b
, size_t sz
)
223 int obuf_splice(const struct obuf
*src
, struct obuf
*dst
, size_t off
, size_t sz
)
225 size_t end
= off
+ sz
;
226 size_t capacity
= obuf_capacity(src
);
227 size_t nr_written
= obuf_nr_written(src
);
229 if (end
< off
|| end
< sz
|| end
> capacity
)
232 obuf_init(dst
, &src
->b
[off
], sz
);
234 /* Handle previously written data in src. */
235 if (off
< nr_written
)
236 dst
->n_written
= nr_written
- off
;
241 int obuf_splice_current(const struct obuf
*src
, struct obuf
*dst
, size_t sz
)
243 return obuf_splice(src
, dst
, obuf_nr_written(src
), sz
);
246 int obuf_split(const struct obuf
*src
, struct obuf
*a
, struct obuf
*b
,
249 if (obuf_splice(src
, a
, 0, boundary
))
252 return obuf_splice(src
, b
, boundary
, obuf_capacity(src
) - boundary
);
255 void *obuf_oob_fill(struct obuf
*ob
, size_t sz
)
259 if (obuf_check_size(ob
, sz
))
262 b
= &ob
->b
[ob
->n_written
];
268 int obuf_write(struct obuf
*ob
, const void *data
, size_t sz
)
272 b
= obuf_oob_fill(ob
, sz
);
281 int obuf_write_be8(struct obuf
*ob
, uint8_t v
)
283 size_t sz
= sizeof(v
);
285 if (obuf_check_size(ob
, sz
))
288 write_at_be8(ob
->b
, v
, ob
->n_written
);
294 int obuf_write_be16(struct obuf
*ob
, uint16_t v
)
296 size_t sz
= sizeof(v
);
298 if (obuf_check_size(ob
, sz
))
301 write_at_be16(ob
->b
, v
, ob
->n_written
);
307 int obuf_write_be32(struct obuf
*ob
, uint32_t v
)
309 size_t sz
= sizeof(v
);
311 if (obuf_check_size(ob
, sz
))
314 write_at_be32(ob
->b
, v
, ob
->n_written
);
320 int obuf_write_be64(struct obuf
*ob
, uint64_t v
)
322 size_t sz
= sizeof(v
);
324 if (obuf_check_size(ob
, sz
))
327 write_at_be64(ob
->b
, v
, ob
->n_written
);
333 int obuf_write_le8(struct obuf
*ob
, uint8_t v
)
335 size_t sz
= sizeof(v
);
337 if (obuf_check_size(ob
, sz
))
340 write_at_le8(ob
->b
, v
, ob
->n_written
);
346 int obuf_write_le16(struct obuf
*ob
, uint16_t v
)
348 size_t sz
= sizeof(v
);
350 if (obuf_check_size(ob
, sz
))
353 write_at_le16(ob
->b
, v
, ob
->n_written
);
359 int obuf_write_le32(struct obuf
*ob
, uint32_t v
)
361 size_t sz
= sizeof(v
);
363 if (obuf_check_size(ob
, sz
))
366 write_at_le32(ob
->b
, v
, ob
->n_written
);
372 int obuf_write_le64(struct obuf
*ob
, uint64_t v
)
374 size_t sz
= sizeof(v
);
376 if (obuf_check_size(ob
, sz
))
379 write_at_le64(ob
->b
, v
, ob
->n_written
);
385 int obuf_write_n8(struct obuf
*ob
, uint8_t v
)
387 return obuf_write(ob
, &v
, sizeof(v
));
390 int obuf_write_n16(struct obuf
*ob
, uint16_t v
)
392 return obuf_write(ob
, &v
, sizeof(v
));
395 int obuf_write_n32(struct obuf
*ob
, uint32_t v
)
397 return obuf_write(ob
, &v
, sizeof(v
));
400 int obuf_write_n64(struct obuf
*ob
, uint64_t v
)
402 return obuf_write(ob
, &v
, sizeof(v
));
405 const void *obuf_contents(const struct obuf
*ob
, size_t *sz
)
407 *sz
= obuf_nr_written(ob
);