From 205ee5b6b044a4db0af3d446e0d70cb23d193147 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 4 Apr 2025 11:02:02 +0200 Subject: [PATCH] dynamic: add _continue The continue functions takes a builder as the argument and makes a new builder that starts from the old builder memory. If the old builder was dynamic, the new one will also be dynamic. Because it's a separate builder, the memory of the old builder will not be reallocated when extended. This makes it possible to freely read the memory from the old builder while we construct the result in a new builder without having to worry about reallocating the memory of the old builder. When the new object is completed, it can then be copied into the old builder. --- spa/include/spa/pod/dynamic.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/spa/include/spa/pod/dynamic.h b/spa/include/spa/pod/dynamic.h index e9998cdb2..dad9c3d71 100644 --- a/spa/include/spa/pod/dynamic.h +++ b/spa/include/spa/pod/dynamic.h @@ -53,11 +53,21 @@ SPA_API_POD_DYNAMIC void spa_pod_dynamic_builder_init(struct spa_pod_dynamic_bui .overflow = spa_pod_dynamic_builder_overflow }; builder->b = SPA_POD_BUILDER_INIT(data, size); - spa_pod_builder_set_callbacks(&builder->b, &spa_pod_dynamic_builder_callbacks, builder); + if (extend > 0) + spa_pod_builder_set_callbacks(&builder->b, &spa_pod_dynamic_builder_callbacks, builder); builder->extend = extend; builder->data = data; } +SPA_API_POD_DYNAMIC void spa_pod_dynamic_builder_continue(struct spa_pod_dynamic_builder *builder, + struct spa_pod_builder *b) +{ + uint32_t remain = b->state.offset >= b->size ? 0 : b->size - b->state.offset; + spa_pod_dynamic_builder_init(builder, + remain ? SPA_PTROFF(b->data, b->state.offset, void) : NULL, + remain, b->callbacks.funcs == NULL ? 0 : 4096); +} + SPA_API_POD_DYNAMIC void spa_pod_dynamic_builder_clean(struct spa_pod_dynamic_builder *builder) { if (builder->data != builder->b.data)