#include #include #include #include #include #include #include #include "logerr.h" #include "math.h" #include "string.h" struct String { const size_t length; const u8 *const bytes; }; int string_new_with( const char *const string, const size_t length, const struct String **const out ) { int rc = -1; const struct String *ret = NULL; const u8 *bytes = NULL; ret = malloc(sizeof(*ret)); if (ret == NULL) { logerr("malloc(): %s", strerror(errno)); goto out; } bytes = malloc(length + NULL_TERMINATOR); if (bytes == NULL) { logerr("malloc(): %s", strerror(errno)); goto out; } memcpy((u8 *)bytes, string, length); memcpy((u8 *)(bytes + length), "", NULL_TERMINATOR); memcpy((u8 *)ret, &(struct String) { .length = length, .bytes = bytes, }, sizeof(*ret)); *out = ret; rc = 0; out: if (rc) { if (bytes != NULL) { free((u8 *)bytes); bytes = NULL; } if (ret != NULL) { free((struct String *)ret); ret = NULL; } } return rc; } int string_new(const char *const string, const struct String **const out) { return string_new_with(string, strlen(string), out); } struct String S(const char *const string) { return (struct String) { .length = strlen(string) + NULL_TERMINATOR, .bytes = (const u8 *)string, }; } void string_free(const struct String **const s) { const u8 *bytes = (*s)->bytes; free((u8 *)bytes); bytes = NULL; free((struct String *)*s); *s = NULL; } const char * cstr(const struct String *s) { return (const char *)s->bytes; } enum Comparison string_compare(const struct String *const s1, const struct String *const s2) { if (s1->length < s2->length) { return Comparison_LT; } else if (s1->length > s2->length) { return Comparison_GT; } else { const int ret = strcmp( (const char *)s1->bytes, (const char *)s2->bytes ); if (ret < 0) { return Comparison_LT; } else if (ret > 0) { return Comparison_GT; } else { return Comparison_EQ; } } } bool string_equals(const struct String *const s1, const struct String *const s2) { return string_compare(s1, s2) == Comparison_EQ; } int string_append( const struct String *const s1, const struct String *const s2, const struct String **const out ) { int rc = -1; const struct String *ret = NULL; const u8 *bytes = NULL; size_t length; if (add_size(s1->length, s2->length, &length)) { logerr("add_size()"); goto out; } ret = malloc(sizeof(*ret)); if (ret == NULL) { logerr("malloc(): %s", strerror(errno)); goto out; } bytes = malloc(length + NULL_TERMINATOR); if (bytes == NULL) { logerr("malloc(): %s", strerror(errno)); goto out; } memcpy((u8 *)bytes, s1->bytes, s1->length); memcpy((u8 *)(bytes + s1->length), s2->bytes, s2->length); memcpy((u8 *)(bytes + length), "", NULL_TERMINATOR); memcpy((u8 *)ret, &(struct String) { .length = length, .bytes = bytes, }, sizeof(*ret)); *out = ret; rc = 0; out: if (rc) { if (bytes != NULL) { free((u8 *)bytes); bytes = NULL; } if (ret != NULL) { free((struct String *)ret); ret = NULL; } } return rc; }