From 780384484cf58939f9413d644ccdd8c40cb82ae5 Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Mon, 21 Jul 2025 14:37:12 +0200 Subject: feat(string): Arena base allocation for copy --- json.c | 10 +++++----- string.c | 11 ++++++----- string.h | 2 +- test_json.c | 10 ++++++---- test_string.c | 6 +++--- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/json.c b/json.c index 0ef03a2..f170e3f 100644 --- a/json.c +++ b/json.c @@ -69,7 +69,7 @@ parse_array_result parse_array(Arena *a, char *src, uintptr_t pos) { } typedef struct { - Str string; + Str *string; uintptr_t pos; } parse_string_result; @@ -81,7 +81,7 @@ parse_string_result parse_string(Arena *a, char *src, uintptr_t pos) { i++; } assert(src[pos + i] == '"'); - Str s = Str_copy(a, &src[pos + 1], i - 1); + Str* s = Str_copy(a, &src[pos + 1], i - 1); return (parse_string_result){s, pos + i + 1}; } @@ -104,13 +104,13 @@ parse_object_result parse_object(Arena *a, char *src, uintptr_t pos) { for (;;) { assert(src[pos] == '"'); parse_string_result str_result = parse_string(a, src, pos); - Str key = str_result.string; + Str *key = str_result.string; pos = absorb_whitespaces(src, str_result.pos); assert(src[pos] == ':'); pos = absorb_whitespaces(src, pos+1); parse_any_result any_result = parse_any(a, src, pos); object->len++; - Vec_push(a, &object->keys, &key); + Vec_push(a, &object->keys, key); Vec_push(a, &object->values, any_result.value); pos = absorb_whitespaces(src, any_result.pos); if (src[pos] != ',') {break;} @@ -132,7 +132,7 @@ parse_any_result parse_any(Arena *a, char *src, uintptr_t pos) { pos = result.pos; } else if (src[pos] == '"') { parse_string_result result = parse_string(a, src, pos); - value->string = &result.string; + value->string = result.string; pos = result.pos; } else if (src[pos] == '{') { parse_object_result result = parse_object(a, src, pos); diff --git a/string.c b/string.c index 191059e..0fc8341 100644 --- a/string.c +++ b/string.c @@ -20,11 +20,12 @@ uint64_t Str_hash64(Str s) { return h; } -Str Str_copy(Arena *a, char *data, uintptr_t len) { - Str str = {.data = NULL, .len = len}; - str.data = new (a, char, len); - if (str.len) - memcpy(str.data, data, len); +Str* Str_copy(Arena *a, char *data, uintptr_t len) { + Str *str = new(a, Str, 1); + str->len = len; + str->data = new (a, char, len); + if (str->len) + memcpy(str->data, data, len); return str; } diff --git a/string.h b/string.h index d8835f4..10b3869 100644 --- a/string.h +++ b/string.h @@ -12,6 +12,6 @@ typedef struct { } Str; int Str_equals(Str a, Str b); uint64_t Str_hash64(Str s); -Str Str_copy(Arena *a, char *data, uintptr_t len); +Str* Str_copy(Arena *a, char *data, uintptr_t len); void Str_print(Str s); #endif diff --git a/test_json.c b/test_json.c index e187b62..d2a4595 100644 --- a/test_json.c +++ b/test_json.c @@ -40,6 +40,7 @@ char test_json_nested_array() { JSON doc = JSON_parse(&perm, "[[1,\"abc\"]]"); + t_assert_equal(Arena_get_used(perm), 283); JSON sub_array = *Vec_get(doc.array, JSON, 0); JSON val_1 = *Vec_get(sub_array.array, JSON, 0); t_assert(*val_1.integer == 1); @@ -47,7 +48,7 @@ char test_json_nested_array() { Str str = *val_2.string; Str expected = S("abc"); t_assert(Str_equals(str, expected)); - t_assert_equal(Arena_get_used(perm), 267); + t_assert_equal(Arena_get_used(perm), 283); return 0; } @@ -57,8 +58,9 @@ char test_json_string() { JSON js = JSON_parse(&perm, "\"abc\""); + t_assert_equal(Arena_get_used(perm), 51); t_assert(Str_equals(*js.string, S("abc"))); - t_assert_equal(Arena_get_used(perm), 35); + t_assert_equal(Arena_get_used(perm), 51); return 0; } @@ -79,11 +81,11 @@ char test_json_object() { JSON doc = JSON_parse(&perm, "{\"key\": \"value\"}"); - t_assert_equal(Arena_get_used(perm), 261); + t_assert_equal(Arena_get_used(perm), 293); t_assert_equal(doc.object->len, 1); t_assert(Str_equals(*Vec_get(&doc.object->keys, Str, 0), S("key"))); t_assert(Str_equals(*JSONObject_get(doc.object, S("key"))->string, S("value"))) - t_assert_equal(Arena_get_used(perm), 261); + t_assert_equal(Arena_get_used(perm), 293); return 0; } diff --git a/test_string.c b/test_string.c index 590a30f..f62f4ab 100644 --- a/test_string.c +++ b/test_string.c @@ -10,10 +10,10 @@ char test_string_copy() { Arena perm = Arena_new(128e3); Str src = S("Hello"); - Str cpy = Str_copy(&perm, src.data, src.len); + Str *cpy = Str_copy(&perm, src.data, src.len); - t_assert(Str_equals(src, cpy)); - t_assert(Arena_get_used(perm) == 5); + t_assert(Str_equals(src, *cpy)); + t_assert_equal(Arena_get_used(perm), 21); return 0; } -- cgit v1.3