It is useful to be able to copy an abuf, to allow changes while preserving the original. Add a function for this.
Signed-off-by: Simon Glass <s...@chromium.org> --- include/abuf.h | 11 +++++++++++ lib/abuf.c | 14 ++++++++++++++ test/lib/abuf.c | 23 +++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/include/abuf.h b/include/abuf.h index 62ff6499a0c..64189a4e32c 100644 --- a/include/abuf.h +++ b/include/abuf.h @@ -111,6 +111,17 @@ bool abuf_realloc(struct abuf *abuf, size_t new_size); */ bool abuf_realloc_inc(struct abuf *abuf, size_t inc); +/** + * abuf_copy() - Make a copy of an abuf + * + * Creates an allocated copy of @old in @new + * + * @old: abuf to copy + * @new: new abuf to hold the copy (inited by this function) + * Return: true if OK, false if out of memory + */ +bool abuf_copy(const struct abuf *old, struct abuf *new); + /** * abuf_uninit_move() - Return the allocated contents and uninit the abuf * diff --git a/lib/abuf.c b/lib/abuf.c index 61adf7fc6b1..503f5004ff8 100644 --- a/lib/abuf.c +++ b/lib/abuf.c @@ -119,6 +119,20 @@ void abuf_init_set(struct abuf *abuf, void *data, size_t size) abuf_set(abuf, data, size); } +bool abuf_copy(const struct abuf *old, struct abuf *copy) +{ + char *data; + + data = malloc(old->size); + if (!data) + return false; + memcpy(data, old->data, old->size); + abuf_init_set(copy, data, old->size); + copy->alloced = true; + + return true; +} + void abuf_init_const(struct abuf *abuf, const void *data, size_t size) { /* for now there is no flag indicating that the abuf data is constant */ diff --git a/test/lib/abuf.c b/test/lib/abuf.c index b38690fe1a9..fa6b007248c 100644 --- a/test/lib/abuf.c +++ b/test/lib/abuf.c @@ -419,3 +419,26 @@ static int lib_test_abuf_init(struct unit_test_state *uts) return 0; } LIB_TEST(lib_test_abuf_init, 0); + +/* Test abuf_copy() */ +static int lib_test_abuf_copy(struct unit_test_state *uts) +{ + struct abuf buf, copy; + ulong start; + + start = ut_check_free(); + + abuf_init_set(&buf, test_data, TEST_DATA_LEN); + ut_assert(abuf_copy(&buf, ©)); + ut_asserteq(buf.size, copy.size); + ut_assert(buf.data != copy.data); + ut_assert(copy.alloced); + abuf_uninit(©); + abuf_uninit(&buf); + + /* Check for memory leaks */ + ut_assertok(ut_check_delta(start)); + + return 0; +} +LIB_TEST(lib_test_abuf_copy, 0); -- 2.43.0