| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- #include <errno.h>
- #include <stdbool.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "scufcont/scufcont.h"
- #include "scufcont/DString.h"
- ScufContResult SCDString_alloc(SCDString *const dstr, const char *str, const size_t len) {
- dstr->data = (char *) malloc(sizeof(char) * (len + 1));
- dstr->len = len;
- dstr->capacity = len + 1;
- if (dstr->data == NULL) {
- return SCUFCONT_OUT_OF_MEMORY;
- }
- dstr->data = memcpy(dstr->data, str, len);
- dstr->data[len] = '\0';
- return SCUFCONT_SUCCESS;
- }
- ScufContResult SCDString_alloc_copy(SCDString *const dstr, const SCDString *const o) {
- return SCDString_alloc(dstr, SCDString_c_str(o), o->len);
- }
- ScufContResult SCDString_reserve(SCDString *const dstr, const size_t new_capacity) {
- if (dstr->capacity < new_capacity) {
- errno = 0;
- dstr->data = (char *) realloc(dstr->data, sizeof(char) * new_capacity);
- if (errno != 0) {
- return SCUFCONT_OUT_OF_MEMORY;
- }
- dstr->capacity = new_capacity;
- }
- return SCUFCONT_SUCCESS;
- }
- void SCDString_free(SCDString *const dstr) {
- if (dstr->data != NULL) {
- free(dstr->data);
- dstr->data = NULL;
- }
- dstr->len = 0;
- dstr->capacity = 0;
- }
- void SCDString_shrink_to_fit(SCDString *const dstr) {
- if (dstr->capacity > dstr->len + 1) {
- dstr->capacity = dstr->len + 1;
- dstr->data = (char *) realloc(dstr->data, dstr->capacity);
- }
- }
- ScufContResult SCDString_copy(const SCDString *const src, SCDString *const dst) {
- ScufContResult res = SCDString_reserve(dst, src->len + 1);
- if (res != SCUFCONT_SUCCESS) {
- return res;
- }
- dst->len = src->len;
- memcpy(dst->data, src->data, dst->len);
- dst->data[dst->len] = '\0';
- return SCUFCONT_SUCCESS;
- }
- ScufContResult SCDString_at(const SCDString *const dstr, const size_t i) {
- if (i > dstr->len - 1) {
- return SCUFCONT_OUT_OF_BOUNDS;
- }
- return dstr->data[i];
- }
- bool SCDString_equal(const SCDString *const s1, const SCDString *const s2) {
- if (s1->data == NULL || s2->data == NULL) {
- return false;
- }
- if (s1->len != s2->len) {
- return false;
- }
- for (size_t i = 0; i < s1->len; i++) {
- if (s1->data[i] != s2->data[i]) {
- return false;
- }
- }
- return true;
- }
- bool SCDString_equal_c_str(const SCDString *const s1, const char *s2) {
- if (s1->data == NULL || s2 == NULL) {
- return false;
- }
- if (s1->len != strlen(s2)) {
- return false;
- }
- for (size_t i = 0; i < s1->len; i++) {
- if (s1->data[i] != s2[i]) {
- return false;
- }
- }
- return true;
- }
- bool SCDString_equal_next_chars_c_str(
- const SCDString *const dstr,
- const char *str,
- const size_t str_len,
- size_t s
- ) {
- if (dstr->len < s || dstr->len < s + str_len) {
- return false;
- }
- const size_t e = s + str_len;
- for (size_t i = 0; s < e; s++, i++) {
- if (dstr->data[s] != str[i]) {
- return false;
- }
- }
- return true;
- }
- ScufContResult SCDString_concat_char(SCDString *const dstr, const char ch) {
- const size_t new_len = dstr->len + 1;
- if (new_len > dstr->capacity) {
- ScufContResult res = SCDString_reserve(dstr, new_len + 1);
- if (res != SCUFCONT_SUCCESS) {
- return res;
- }
- }
- dstr->data[new_len - 1] = ch;
- dstr->data[new_len] = '\0';
- dstr->len = new_len;
- return SCUFCONT_SUCCESS;
- }
- ScufContResult SCDString_concat_c_str(
- SCDString *const dstr,
- const char *str,
- const size_t str_len
- ) {
- const size_t new_len = dstr->len + str_len;
- if (new_len > dstr->capacity) {
- ScufContResult res = SCDString_reserve(dstr, new_len + 1);
- if (res != SCUFCONT_SUCCESS) {
- return res;
- }
- }
- strncpy(dstr->data + dstr->len, str, str_len);
- dstr->data[new_len] = '\0';
- dstr->len = new_len;
- return SCUFCONT_SUCCESS;
- }
- ScufContResult SCDString_alloc_concat_c_strs(
- SCDString *const dstr,
- const char *s1,
- const size_t s1_len,
- const char *s2,
- const size_t s2_len
- ) {
- ScufContResult res = SCDString_alloc(dstr, s1, s1_len);
- if (res != SCUFCONT_SUCCESS) {
- return res;
- }
- res = SCDString_concat_c_str(dstr, s2, s2_len);
- if (res != SCUFCONT_SUCCESS) {
- return res;
- }
- return SCUFCONT_SUCCESS;
- }
- ScufContResult SCDString_split(
- const SCDString *const dstr,
- const char *delim,
- SCDString **const split_arr,
- size_t *arr_len
- ) {
- ScufContResult ret = SCUFCONT_SUCCESS;
- *arr_len = 0;
- SCDString elem;
- ScufContResult res = SCDString_alloc(&elem, "", 0);
- if (res != SCUFCONT_SUCCESS) {
- return res;
- }
- const size_t delim_len = strlen(delim);
- for (size_t i = 0; i < dstr->len; i++) {
- if (SCDString_equal_next_chars_c_str(dstr, delim, delim_len, i)) {
- *arr_len += 1;
- *split_arr = realloc(*split_arr, sizeof(SCDString) * (*arr_len));
- if (split_arr == NULL) {
- ret = SCUFCONT_OUT_OF_MEMORY;
- break;
- }
- (*split_arr)[(*arr_len) - 1] = elem;
- res = SCDString_alloc(&elem, "", 0);
- if (res != SCUFCONT_SUCCESS) {
- ret = res;
- break;
- }
- i += delim_len - 1;
- } else {
- SCDString_concat_c_str(&elem, dstr->data + i, 1);
- }
- }
- if (ret == SCUFCONT_SUCCESS) {
- *split_arr = realloc(*split_arr, sizeof(SCDString) * (*arr_len + 1));
- if (split_arr != NULL) {
- (*split_arr)[*arr_len] = elem;
- *arr_len += 1;
- return ret;
- }
- ret = SCUFCONT_OUT_OF_MEMORY;
- }
- for (size_t i = 0; i < *arr_len; i++) {
- SCDString_free((*split_arr) + i);
- }
- free(*split_arr);
- *split_arr = NULL;
- SCDString_free(&elem);
- return ret;
- }
- void SCDString_split_arr_free(SCDString **const arr, const size_t arr_len) {
- for (size_t i = 0; i < arr_len; i++) {
- SCDString_free((*arr) + i);
- }
- free(*arr);
- *arr = NULL;
- }
- ScufContResult SCDString_char_mod(SCDString *const dstr, const size_t at, const char ch) {
- if (at > dstr->len - 1) {
- return SCUFCONT_OUT_OF_BOUNDS;
- }
- dstr->data[at] = ch;
- return SCUFCONT_SUCCESS;
- }
- ScufContResult SCDString_char_remove_no_shrink(SCDString *const dstr, const size_t at) {
- if (at > dstr->len - 1) {
- return SCUFCONT_OUT_OF_BOUNDS;
- }
- memmove(&dstr->data[at], &dstr->data[at] + 1, dstr->len - at);
- dstr->len--;
- return SCUFCONT_SUCCESS;
- }
- ScufContResult SCDString_char_remove(SCDString *const dstr, const size_t at) {
- const ScufContResult res = SCDString_char_remove_no_shrink(dstr, at);
- if (res != SCUFCONT_SUCCESS) {
- return res;
- }
- SCDString_shrink_to_fit(dstr);
- return SCUFCONT_SUCCESS;
- }
- ScufContResult SCDString_char_insert(SCDString *const dstr, const size_t at, const char ch) {
- if (at > dstr->len) {
- return SCUFCONT_OUT_OF_BOUNDS;
- }
- ScufContResult res = SCDString_reserve(dstr, dstr->len + 2);
- if (res != SCUFCONT_SUCCESS) {
- return res;
- }
- const size_t move_block_size = at == dstr->len ? 1 : dstr->len - at;
- memmove(&dstr->data[at] + 1, &dstr->data[at], move_block_size);
- dstr->data[at] = ch;
- dstr->len++;
- return SCUFCONT_SUCCESS;
- }
- ScufContResult SCDString_replace_c_str_no_shrink(SCDString *const dstr, const char *str, const size_t str_len) {
- if (dstr->capacity < str_len + 1) {
- const ScufContResult res = SCDString_reserve(dstr, str_len + 1);
- if (res != SCUFCONT_SUCCESS) {
- return res;
- }
- }
- memcpy(dstr->data, str, str_len);
- dstr->len = str_len;
- return SCUFCONT_SUCCESS;
- }
- ScufContResult SCDString_replace_c_str(SCDString *const dstr, const char *str, const size_t str_len) {
- const ScufContResult res = SCDString_replace_c_str_no_shrink(dstr, str, str_len);
- if (res != SCUFCONT_SUCCESS) {
- return res;
- }
- SCDString_shrink_to_fit(dstr);
- return SCUFCONT_SUCCESS;
- }
- void SCDString_trim_whitespace_leading(SCDString *const dstr) {
- while (isspace(dstr->data[0])) {
- SCDString_char_remove_no_shrink(dstr, 0);
- }
- SCDString_shrink_to_fit(dstr);
- }
- void SCDString_trim_whitespace_trailing(SCDString *const dstr) {
- while (isspace(dstr->data[dstr->len - 1])) {
- SCDString_char_remove_no_shrink(dstr, dstr->len - 1);
- }
- SCDString_shrink_to_fit(dstr);
- }
- void SCDString_trim_whitespace(SCDString *const dstr) {
- SCDString_trim_whitespace_leading(dstr);
- SCDString_trim_whitespace_trailing(dstr);
- }
|