diff options
-rw-r--r-- | dynstr.c | 13 | ||||
-rw-r--r-- | dynstr.h | 6 | ||||
-rw-r--r-- | unittests.c | 16 |
3 files changed, 35 insertions, 0 deletions
@@ -197,6 +197,19 @@ size_t dynstr_memcpy(void *mem, Dynstr *dynstr, size_t offset, size_t size) } +char *dynstr_strdup(Dynstr *dynstr) +{ + char *mem; + + mem = alloc(dynstr->size + 1); + if (mem == NULL) + return NULL; + memcpy(mem, dynstr->mem, dynstr->size); + mem[dynstr->size] = '\0'; + return mem; +} + + Dynstr *dynstr_substr(Dynstr *dynstr, size_t offset, size_t size) { if (offset >= dynstr->size) { @@ -136,6 +136,12 @@ int dynstr_byte_at(Dynstr *dynstr, size_t offset); * actually copied, which may be less than requested, and may be zero. */ size_t dynstr_memcpy(void *mem, Dynstr *dynstr, size_t offset, size_t size); +/* Create a dynamically allocated C string copy of the dynamic string. + * This is like strdup. If the dynamic string contains NUL bytes, then + * that is the caller's problem. Return pointer to the C string. The + * caller is responsible for freeing it. Return NULL on error. */ +char *dynstr_strdup(Dynstr *dynstr); + /* Search for first or last byte with a given value in a string, * starting at a given offset and until the end of the string. Return offset * of matching byte, or DYNSTR_NOT_FOUND if not found. Offset is from diff --git a/unittests.c b/unittests.c index fc6b663..61a59bb 100644 --- a/unittests.c +++ b/unittests.c @@ -515,6 +515,21 @@ static int test_copies_partial_substring_when_length_too_big(void) } +static int test_strdup_duplicates_string(void) +{ + Dynstr *dynstr; + char *cstring; + char data[] = "hello, world"; + + dynstr = dynstr_new_from_constant_cstring(data); + cstring = dynstr_strdup(dynstr); + FAIL_UNLESS_EQUAL(memcmp(data, cstring, sizeof(data)), 0); + free(cstring); + dynstr_free(dynstr); + return true; +} + + static int test_cats_ok(void) { Dynstr *a; @@ -1233,6 +1248,7 @@ static const struct test tests[] = { TEST(test_memcpy_truncates_if_copying_too_much), TEST(test_memcpy_copies_whole_string_ok), TEST(test_memcpy_copies_substring_ok), + TEST(test_strdup_duplicates_string), TEST(test_copies_empty_substring_ok), TEST(test_copies_single_byte_substring_ok), TEST(test_copies_middle_substring_ok), |