object: add a range of string transformation functions
This commit is contained in:
@@ -5,10 +5,26 @@
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
printf("-------------\n");
|
||||||
b_string *str = b_string_create_from_cstr("Hello, world!\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);
|
b_string_insert_cstr(str, "WOW!", 4);
|
||||||
|
|
||||||
|
printf("-------------\n");
|
||||||
printf("%s\n", b_string_ptr(str));
|
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);
|
b_string_release(str);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <blue/core/status.h>
|
#include <blue/core/status.h>
|
||||||
#include <blue/object/object.h>
|
#include <blue/object/object.h>
|
||||||
#include <blue/object/type.h>
|
#include <blue/object/type.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
struct b_stream;
|
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 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_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_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 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);
|
BLUE_API void b_string_append_s(b_string *dest, const b_string *src);
|
||||||
|
|||||||
@@ -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;
|
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)
|
b_status b_string_replace_all(b_string *str, const char *new_data)
|
||||||
{
|
{
|
||||||
size_t new_len = strlen(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;
|
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)
|
static enum b_status stream_close(struct b_stream *stream)
|
||||||
{
|
{
|
||||||
struct b_string *str = stream->s_ptr;
|
struct b_string *str = stream->s_ptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user