Commit 8d14165a authored by Rusty Russell's avatar Rusty Russell

tal: add tal_resizez for zero-padded expansion.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent daf621ae
......@@ -670,13 +670,13 @@ tal_t *tal_parent(const tal_t *ctx)
return from_tal_hdr(ignore_destroying_bit(t->parent_child)->parent);
}
bool tal_resize_(tal_t **ctxp, size_t size, size_t count)
bool tal_resize_(tal_t **ctxp, size_t size, size_t count, bool clear)
{
struct tal_hdr *old_t, *t;
struct children *child;
struct prop_hdr **lenp;
struct length len;
size_t extra = 0;
size_t extra = 0, elemsize = size;
old_t = debug_tal(to_tal_hdr(*ctxp));
......@@ -688,7 +688,8 @@ bool tal_resize_(tal_t **ctxp, size_t size, size_t count)
/* Copy here, in case we're shrinking! */
len = *(struct length *)*lenp;
extra = extra_for_length(size);
}
} else /* If we don't have an old length, we can't clear! */
assert(!clear);
t = resizefn(old_t, sizeof(struct tal_hdr) + size + extra);
if (!t) {
......@@ -700,6 +701,12 @@ bool tal_resize_(tal_t **ctxp, size_t size, size_t count)
if (lenp) {
struct length *new_len;
/* Clear between old end and new end. */
if (clear && count > len.count) {
char *old_end = (char *)(t + 1) + len.count * elemsize;
memset(old_end, 0, elemsize * (count - len.count));
}
new_len = (struct length *)((char *)(t + 1) + size);
len.count = count;
*new_len = len;
......@@ -753,7 +760,7 @@ bool tal_expand_(tal_t **ctxp, const void *src, size_t size, size_t count)
assert(src < *ctxp
|| (char *)src >= (char *)(*ctxp) + (size * old_count));
if (!tal_resize_(ctxp, size, old_count + count))
if (!tal_resize_(ctxp, size, old_count + count, false))
goto out;
memcpy((char *)*ctxp + size * old_count, src, count * size);
......@@ -789,7 +796,7 @@ void *tal_dup_(const tal_t *ctx, const void *p, size_t size,
if (taken(p)) {
if (unlikely(!p))
return NULL;
if (unlikely(!tal_resize_((void **)&p, size, n + extra)))
if (unlikely(!tal_resize_((void **)&p, size, n + extra, false)))
return tal_free(p);
if (unlikely(!tal_steal(ctx, p)))
return tal_free(p);
......
......@@ -110,7 +110,22 @@ void *tal_free(const tal_t *p);
* tal_resize(&p, 100);
*/
#define tal_resize(p, count) \
tal_resize_((void **)(p), sizeof**(p), (count))
tal_resize_((void **)(p), sizeof**(p), (count), false)
/**
* tal_resizez - enlarge or reduce a tal_arr[z]; zero out extra.
* @p: A pointer to the tal allocated array to resize.
* @count: the number to allocate.
*
* This returns true on success (and may move *@p), or false on failure.
* If @p has a length property, it is updated on success.
* On expand, new elements are memset to 0 bytes.
*
* Example:
* tal_resizez(&p, 200);
*/
#define tal_resizez(p, count) \
tal_resize_((void **)(p), sizeof**(p), (count), true)
/**
* tal_steal - change the parent of a tal-allocated pointer.
......@@ -406,7 +421,7 @@ void *tal_dup_(const tal_t *ctx, const void *p, size_t size,
tal_t *tal_steal_(const tal_t *new_parent, const tal_t *t);
bool tal_resize_(tal_t **ctxp, size_t size, size_t count);
bool tal_resize_(tal_t **ctxp, size_t size, size_t count, bool clear);
bool tal_expand_(tal_t **ctxp, const void *src, size_t size, size_t count);
bool tal_add_destructor_(const tal_t *ctx, void (*destroy)(void *me));
......
......@@ -40,6 +40,7 @@ int main(void)
strcpy(c[0], "hello");
tal_free(c[0]);
ok1(tal_first(parent) == NULL);
tal_free(parent);
tal_cleanup();
......
#include <ccan/tal/tal.h>
#include <ccan/tal/tal.c>
#include <ccan/tap/tap.h>
int main(void)
{
char *parent, *c;
int i;
plan_tests(1 + 3 * 100 + 98);
parent = tal(NULL, char);
ok1(parent);
for (i = 0; i < 100; i++) {
c = tal_arr(parent, char, 1);
ok1(tal_resizez(&c, i));
ok1(tal_count(c) == i);
ok1(tal_parent(c) == parent);
if (i > 1)
ok1(c[i-1] == '\0');
}
tal_free(parent);
tal_cleanup();
return exit_status();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment