2 * This file is part of the coreboot project.
4 * Copyright 2017 Google Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <commonlib/endian.h>
17 #include <commonlib/iobuf.h>
20 static int ibuf_check_size(const struct ibuf
*ib
, size_t sz
)
22 if (ibuf_remaining(ib
) < sz
)
28 void ibuf_init(struct ibuf
*ib
, const void *b
, size_t sz
)
35 void ibuf_from_obuf(struct ibuf
*ib
, const struct obuf
*ob
)
37 ibuf_init(ib
, ob
->b
, ob
->n_written
);
40 int ibuf_splice(const struct ibuf
*src
, struct ibuf
*dst
, size_t off
, size_t sz
)
42 size_t end
= off
+ sz
;
43 size_t capacity
= ibuf_capacity(src
);
44 size_t nr_read
= ibuf_nr_read(src
);
46 if (end
< off
|| end
< sz
|| end
> capacity
)
49 ibuf_init(dst
, &src
->b
[off
], sz
);
51 /* Handle previously read data in src. */
53 dst
->n_read
= nr_read
- off
;
58 int ibuf_splice_current(const struct ibuf
*src
, struct ibuf
*dst
, size_t sz
)
60 return ibuf_splice(src
, dst
, ibuf_nr_read(src
), sz
);
63 int ibuf_split(const struct ibuf
*src
, struct ibuf
*a
, struct ibuf
*b
,
66 if (ibuf_splice(src
, a
, 0, boundary
))
69 return ibuf_splice(src
, b
, boundary
, ibuf_capacity(src
) - boundary
);
72 const void *ibuf_oob_drain(struct ibuf
*ib
, size_t sz
)
76 if (ibuf_check_size(ib
, sz
))
79 b
= &ib
->b
[ib
->n_read
];
85 int ibuf_read(struct ibuf
*ib
, void *data
, size_t sz
)
87 const void *b
= ibuf_oob_drain(ib
, sz
);
97 int ibuf_read_be8(struct ibuf
*ib
, uint8_t *v
)
99 size_t sz
= sizeof(*v
);
101 if (ibuf_check_size(ib
, sz
))
104 *v
= read_at_be8(ib
->b
, ib
->n_read
);
110 int ibuf_read_be16(struct ibuf
*ib
, uint16_t *v
)
112 size_t sz
= sizeof(*v
);
114 if (ibuf_check_size(ib
, sz
))
117 *v
= read_at_be16(ib
->b
, ib
->n_read
);
123 int ibuf_read_be32(struct ibuf
*ib
, uint32_t *v
)
125 size_t sz
= sizeof(*v
);
127 if (ibuf_check_size(ib
, sz
))
130 *v
= read_at_be32(ib
->b
, ib
->n_read
);
136 int ibuf_read_be64(struct ibuf
*ib
, uint64_t *v
)
138 size_t sz
= sizeof(*v
);
140 if (ibuf_check_size(ib
, sz
))
143 *v
= read_at_be64(ib
->b
, ib
->n_read
);
149 int ibuf_read_le8(struct ibuf
*ib
, uint8_t *v
)
151 size_t sz
= sizeof(*v
);
153 if (ibuf_check_size(ib
, sz
))
156 *v
= read_at_le8(ib
->b
, ib
->n_read
);
162 int ibuf_read_le16(struct ibuf
*ib
, uint16_t *v
)
164 size_t sz
= sizeof(*v
);
166 if (ibuf_check_size(ib
, sz
))
169 *v
= read_at_le16(ib
->b
, ib
->n_read
);
175 int ibuf_read_le32(struct ibuf
*ib
, uint32_t *v
)
177 size_t sz
= sizeof(*v
);
179 if (ibuf_check_size(ib
, sz
))
182 *v
= read_at_le32(ib
->b
, ib
->n_read
);
188 int ibuf_read_le64(struct ibuf
*ib
, uint64_t *v
)
190 size_t sz
= sizeof(*v
);
192 if (ibuf_check_size(ib
, sz
))
195 *v
= read_at_le64(ib
->b
, ib
->n_read
);
201 int ibuf_read_n8(struct ibuf
*ib
, uint8_t *v
)
203 return ibuf_read(ib
, v
, sizeof(*v
));
206 int ibuf_read_n16(struct ibuf
*ib
, uint16_t *v
)
208 return ibuf_read(ib
, v
, sizeof(*v
));
211 int ibuf_read_n32(struct ibuf
*ib
, uint32_t *v
)
213 return ibuf_read(ib
, v
, sizeof(*v
));
216 int ibuf_read_n64(struct ibuf
*ib
, uint64_t *v
)
218 return ibuf_read(ib
, v
, sizeof(*v
));
221 static int obuf_check_size(const struct obuf
*ob
, size_t sz
)
223 if (obuf_remaining(ob
) < sz
)
229 void obuf_init(struct obuf
*ob
, void *b
, size_t sz
)
236 int obuf_splice(const struct obuf
*src
, struct obuf
*dst
, size_t off
, size_t sz
)
238 size_t end
= off
+ sz
;
239 size_t capacity
= obuf_capacity(src
);
240 size_t nr_written
= obuf_nr_written(src
);
242 if (end
< off
|| end
< sz
|| end
> capacity
)
245 obuf_init(dst
, &src
->b
[off
], sz
);
247 /* Handle previously written data in src. */
248 if (off
< nr_written
)
249 dst
->n_written
= nr_written
- off
;
254 int obuf_splice_current(const struct obuf
*src
, struct obuf
*dst
, size_t sz
)
256 return obuf_splice(src
, dst
, obuf_nr_written(src
), sz
);
259 int obuf_split(const struct obuf
*src
, struct obuf
*a
, struct obuf
*b
,
262 if (obuf_splice(src
, a
, 0, boundary
))
265 return obuf_splice(src
, b
, boundary
, obuf_capacity(src
) - boundary
);
268 void *obuf_oob_fill(struct obuf
*ob
, size_t sz
)
272 if (obuf_check_size(ob
, sz
))
275 b
= &ob
->b
[ob
->n_written
];
281 int obuf_write(struct obuf
*ob
, const void *data
, size_t sz
)
285 b
= obuf_oob_fill(ob
, sz
);
294 int obuf_write_be8(struct obuf
*ob
, uint8_t v
)
296 size_t sz
= sizeof(v
);
298 if (obuf_check_size(ob
, sz
))
301 write_at_be8(ob
->b
, v
, ob
->n_written
);
307 int obuf_write_be16(struct obuf
*ob
, uint16_t v
)
309 size_t sz
= sizeof(v
);
311 if (obuf_check_size(ob
, sz
))
314 write_at_be16(ob
->b
, v
, ob
->n_written
);
320 int obuf_write_be32(struct obuf
*ob
, uint32_t v
)
322 size_t sz
= sizeof(v
);
324 if (obuf_check_size(ob
, sz
))
327 write_at_be32(ob
->b
, v
, ob
->n_written
);
333 int obuf_write_be64(struct obuf
*ob
, uint64_t v
)
335 size_t sz
= sizeof(v
);
337 if (obuf_check_size(ob
, sz
))
340 write_at_be64(ob
->b
, v
, ob
->n_written
);
346 int obuf_write_le8(struct obuf
*ob
, uint8_t v
)
348 size_t sz
= sizeof(v
);
350 if (obuf_check_size(ob
, sz
))
353 write_at_le8(ob
->b
, v
, ob
->n_written
);
359 int obuf_write_le16(struct obuf
*ob
, uint16_t v
)
361 size_t sz
= sizeof(v
);
363 if (obuf_check_size(ob
, sz
))
366 write_at_le16(ob
->b
, v
, ob
->n_written
);
372 int obuf_write_le32(struct obuf
*ob
, uint32_t v
)
374 size_t sz
= sizeof(v
);
376 if (obuf_check_size(ob
, sz
))
379 write_at_le32(ob
->b
, v
, ob
->n_written
);
385 int obuf_write_le64(struct obuf
*ob
, uint64_t v
)
387 size_t sz
= sizeof(v
);
389 if (obuf_check_size(ob
, sz
))
392 write_at_le64(ob
->b
, v
, ob
->n_written
);
398 int obuf_write_n8(struct obuf
*ob
, uint8_t v
)
400 return obuf_write(ob
, &v
, sizeof(v
));
403 int obuf_write_n16(struct obuf
*ob
, uint16_t v
)
405 return obuf_write(ob
, &v
, sizeof(v
));
408 int obuf_write_n32(struct obuf
*ob
, uint32_t v
)
410 return obuf_write(ob
, &v
, sizeof(v
));
413 int obuf_write_n64(struct obuf
*ob
, uint64_t v
)
415 return obuf_write(ob
, &v
, sizeof(v
));
418 const void *obuf_contents(const struct obuf
*ob
, size_t *sz
)
420 *sz
= obuf_nr_written(ob
);