From 993424547df0d253d546dbe7adee9b2448294b08 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 15 Jun 2024 11:42:29 -0700 Subject: Add dynamically-sized strings. --- cstring/src/cstring.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 cstring/src/cstring.c (limited to 'cstring/src') diff --git a/cstring/src/cstring.c b/cstring/src/cstring.c new file mode 100644 index 0000000..832cb85 --- /dev/null +++ b/cstring/src/cstring.c @@ -0,0 +1,103 @@ +#include + +#include +#include +#include + +string string_new(const char* cstr) { + const size_t length = strlen(cstr); + const size_t size = length + 1; + + char* data = calloc(size, sizeof(char)); + ASSERT(data); + if (length > 0) { + memcpy(data, cstr, length); + } + + return (string){ + .data = data, + .length = length, + }; +} + +void string_del(string* str) { + if (str->data) { + free((void*)str->data); + str->data = 0; + str->length = 0; + } +} + +string string_concat(string left, string right) { + const size_t length = left.length + right.length; + const size_t size = length + 1; + + char* data = calloc(size, sizeof(char)); + ASSERT(data); + if (length > 0) { + memcpy(data, left.data, left.length); + memcpy(data + left.length, right.data, right.length); + } + + return (string){ + .data = data, + .length = length, + }; +} + +string string_from_size(size_t size) { + const size_t length = snprintf(NULL, 0, "%zu", size) + 1; + char* data = calloc(length, sizeof(char)); + ASSERT(data); + snprintf(data, length, "%zu", size); + return (string){ + .data = data, + .length = length, + }; +} + +string string_format_size(size_t size) { + const size_t multiples[] = {1073741824, 1048576, 1024, 1}; + const char* units[] = {"G", "M", "K", "B"}; + + size_t integer = 0; + size_t fractional = 0; + + int i; + for (i = 0; i < 4; ++i) { + const size_t m = multiples[i]; + if (size >= m) { + integer = size / m; + fractional = size % m; + break; + } + } + + double s; + const char* unit; + const char* format; + if (i == 4) { // 0 + s = (double)size; + unit = ""; + format = "%f%s"; + } else if (i == 3) { // Bytes + s = (double)integer + (double)fractional / (double)multiples[i]; + unit = units[i]; + format = "%.0f%s"; + } else { // KB, MB, GB + assert(i >= 0); + assert(i < 3); + s = (double)integer + (double)fractional / (double)multiples[i]; + unit = units[i]; + format = "%.2f%s"; + } + + const size_t length = snprintf(NULL, 0, format, s, unit) + 1; + char* data = calloc(length, sizeof(char)); + ASSERT(data); + snprintf(data, length, format, s, unit); + return (string){ + .data = data, + .length = length, + }; +} -- cgit v1.2.3