strbuf: Add strbuf_used()

So users don't feel tempted to look at inside the strbuf. Just add a
function for it and proper tests.

Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Link: https://github.com/kmod-project/kmod/pull/239
This commit is contained in:
Lucas De Marchi 2024-11-13 22:49:52 -06:00
parent 68c0b9fb8c
commit 5706fb7d61
4 changed files with 42 additions and 5 deletions

View File

@ -139,10 +139,10 @@ static char **strbuf_to_vector(struct strbuf *buf, size_t count)
char *s;
size_t n;
/* (string vector + NULL) * sizeof(char *) + buf->used */
/* (string vector + NULL) * sizeof(char *) + strbuf_used() */
if (uaddsz_overflow(count, 1, &n) ||
umulsz_overflow(sizeof(char *), n, &vec_size) ||
uaddsz_overflow(buf->used, vec_size, &total_size)) {
uaddsz_overflow(strbuf_used(buf), vec_size, &total_size)) {
errno = ENOMEM;
return NULL;
}
@ -151,7 +151,7 @@ static char **strbuf_to_vector(struct strbuf *buf, size_t count)
if (vector == NULL)
return NULL;
buf->bytes = NULL;
memmove(vector + count + 1, vector, buf->used);
memmove(vector + count + 1, vector, strbuf_used(buf));
s = (char *)(vector + count + 1);
for (n = 0; n < count; n++) {

View File

@ -369,7 +369,7 @@ static void index_dump_node(struct index_node_f *node, struct strbuf *buf, int f
pushed = strbuf_pushchars(buf, node->prefix);
for (v = node->values; v != NULL; v = v->next) {
write_str_safe(fd, buf->bytes, buf->used);
write_str_safe(fd, buf->bytes, strbuf_used(buf));
write_str_safe(fd, " ", 1);
write_str_safe(fd, v->value, strlen(v->value));
write_str_safe(fd, "\n", 1);
@ -833,7 +833,7 @@ static void index_mm_dump_node(struct index_mm_node *node, struct strbuf *buf, i
struct index_mm_value v;
read_value_mm(&p, &v);
write_str_safe(fd, buf->bytes, buf->used);
write_str_safe(fd, buf->bytes, strbuf_used(buf));
write_str_safe(fd, " ", 1);
write_str_safe(fd, v.value, v.len);
write_str_safe(fd, "\n", 1);

View File

@ -101,3 +101,16 @@ void strbuf_popchar(struct strbuf *buf);
* guaranteed to have (at least) 5 chars available without needing to reallocate.
*/
void strbuf_popchars(struct strbuf *buf, size_t n);
/*
* Return number of used chars. This may different than calling strlen() in a C string
* since '\0' is considered a valid char - this only keeps track of how many slots are
* used in the underlying storage.
*
* If used knows '\0' has not been added (e.g. when calling just strbuf_pushchars() and
* similar), then the result matches the output of strlen().
*/
static inline size_t strbuf_used(struct strbuf *buf)
{
return buf->used;
}

View File

@ -203,4 +203,28 @@ static int test_strbuf_pushmem(const struct test *t)
}
DEFINE_TEST(test_strbuf_pushmem, .description = "test strbuf_reserve");
static int test_strbuf_used(const struct test *t)
{
_cleanup_strbuf_ struct strbuf buf;
strbuf_init(&buf);
assert_return(strbuf_used(&buf) == 0, EXIT_FAILURE);
strbuf_pushchars(&buf, TEXT);
assert_return(strbuf_used(&buf) == strlen(TEXT), EXIT_FAILURE);
strbuf_reserve_extra(&buf, 1);
assert_return(strbuf_used(&buf) == strlen(TEXT), EXIT_FAILURE);
assert_return(streq(TEXT, strbuf_str(&buf)), EXIT_FAILURE);
assert_return(strbuf_used(&buf) == strlen(TEXT), EXIT_FAILURE);
strbuf_pushchar(&buf, '\0');
assert_return(streq(TEXT, strbuf_str(&buf)), EXIT_FAILURE);
assert_return(strbuf_used(&buf) == strlen(TEXT) + 1, EXIT_FAILURE);
return 0;
}
DEFINE_TEST(test_strbuf_used, .description = "test strbuf_used");
TESTSUITE_MAIN();