From 4690738af15f1292f984eea7704d5e3524ec8f16 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Thu, 17 Jul 2025 17:55:13 +0100 Subject: [PATCH] object: add a range of string transformation functions --- object-test/strings.c | 16 ++++++ object/include/blue/object/string.h | 13 +++++ object/string.c | 81 +++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) diff --git a/object-test/strings.c b/object-test/strings.c index 12f9fd7..62d1a66 100644 --- a/object-test/strings.c +++ b/object-test/strings.c @@ -5,10 +5,26 @@ int main(void) { + printf("-------------\n"); b_string *str = b_string_create_from_cstr("Hello, world!\n"); + printf("%s\n", b_string_ptr(str)); + printf("len:%zu, max:%zu\n", b_string_get_size(str, B_STRLEN_NORMAL), + b_string_get_capacity(str)); + b_string_insert_cstr(str, "WOW!", 4); + printf("-------------\n"); printf("%s\n", b_string_ptr(str)); + printf("len:%zu, max:%zu\n", b_string_get_size(str, B_STRLEN_NORMAL), + b_string_get_capacity(str)); + + b_string_replace(str, 4, 4, "+"); + + printf("-------------\n"); + printf("%s\n", b_string_ptr(str)); + printf("len:%zu, max:%zu\n", b_string_get_size(str, B_STRLEN_NORMAL), + b_string_get_capacity(str)); + printf("-------------\n"); b_string_release(str); diff --git a/object/include/blue/object/string.h b/object/include/blue/object/string.h index fe83bda..836d305 100644 --- a/object/include/blue/object/string.h +++ b/object/include/blue/object/string.h @@ -4,6 +4,7 @@ #include #include #include +#include struct b_stream; @@ -34,7 +35,19 @@ static inline void b_string_release(b_string *str) } BLUE_API char *b_string_steal(b_string *str); BLUE_API b_status b_string_reserve(b_string *str, size_t capacity); +BLUE_API b_status b_string_replace( + b_string *str, size_t start, size_t length, const char *new_data); BLUE_API b_status b_string_replace_all(b_string *str, const char *new_data); +BLUE_API b_status b_string_remove(b_string *str, size_t start, size_t length); +BLUE_API b_status b_string_transform(b_string *str, int (*transformer)(int)); +static inline b_status b_string_toupper(b_string *str) +{ + return b_string_transform(str, toupper); +} +static inline b_status b_string_tolower(b_string *str) +{ + return b_string_transform(str, tolower); +} BLUE_API b_status b_string_open_stream(b_string *str, struct b_stream **out); BLUE_API void b_string_append_s(b_string *dest, const b_string *src); diff --git a/object/string.c b/object/string.c index 893911a..a75c313 100644 --- a/object/string.c +++ b/object/string.c @@ -199,6 +199,45 @@ b_status b_string_reserve(struct b_string *str, size_t capacity) return err == 0 ? B_SUCCESS : B_ERR_NO_MEMORY; } +b_status b_string_replace( + struct b_string *str, size_t start, size_t length, const char *new_data) +{ + b_status status = B_SUCCESS; + size_t new_data_len = strlen(new_data); + + if (start >= str->s_len) { + return B_ERR_INVALID_ARGUMENT; + } + + if (start + length >= str->s_len) { + length = str->s_len - start; + } + + size_t new_str_len = str->s_len - length + new_data_len; + if (new_str_len > str->s_max) { + status = b_string_reserve(str, new_str_len); + } + + if (!B_OK(status)) { + return status; + } + + char *s = string_ptr(str); + + char *substitution_start = s + start; + char *excess_src = s + start + length; + size_t excess_length = str->s_len - start - length; + char *excess_dest = substitution_start + new_data_len; + + memmove(excess_dest, excess_src, excess_length); + memmove(substitution_start, new_data, new_data_len); + s[new_str_len] = '\0'; + + str->s_len = new_str_len; + + return B_SUCCESS; +} + b_status b_string_replace_all(b_string *str, const char *new_data) { size_t new_len = strlen(new_data); @@ -211,6 +250,48 @@ b_status b_string_replace_all(b_string *str, const char *new_data) return B_SUCCESS; } +b_status b_string_remove(b_string *str, size_t start, size_t length) +{ + b_status status = B_SUCCESS; + + if (start >= str->s_len) { + return B_ERR_INVALID_ARGUMENT; + } + + if (start + length >= str->s_len) { + length = str->s_len - start; + } + + size_t new_str_len = str->s_len - length; + + char *s = string_ptr(str); + + char *removal_start = s + start; + char *excess_src = s + start + length; + size_t excess_length = str->s_len - start - length; + + memmove(removal_start, excess_src, excess_length); + s[new_str_len] = '\0'; + + str->s_len = new_str_len; + + return B_SUCCESS; +} + +b_status b_string_transform(b_string *str, int (*transformer)(int)) +{ + char *s = string_ptr(str); + for (size_t i = 0; i < str->s_len; i++) { + int c = transformer(s[i]); + + if (c != 0) { + s[i] = c; + } + } + + return B_SUCCESS; +} + static enum b_status stream_close(struct b_stream *stream) { struct b_string *str = stream->s_ptr;