#include "char.h" #include #include #include #include #include #include "utils.h" int is_valid(const Vec8_t* vec) { if (vec == nullptr) { LOGERROR(ERR_VECTOR_NULL); return ERR_VECTOR_NULL; } else if (vec->arr == nullptr) { LOGERROR(ERR_BUF_NULL); return ERR_BUF_NULL; } return SUCCESS; } Vec8_t create(const char* buf, const size_t len) { Vec8_t dst = { NULL, 0, CAPACITY, VEC_MAX }; if (len > VEC_MAX) { LOGERROR(ERR_MAX_PASSED); LOG("If you need more memory to start, create a blank and " "reserve."); return dst; } if (dst.capacity < len && len < dst.max_size) { if (dst.capacity * 2 > dst.max_size && len < dst.max_size) { dst.capacity = len; } while (dst.capacity < len && dst.capacity * 2 < dst.max_size) dst.capacity *= 2; } if (len > 0) { char* dst_buf = calloc(dst.capacity, sizeof(char)); if (!dst_buf) { LOGERROR(ERR_ALLOC_FAIL); return dst; } dst.arr = dst_buf; } if (buf) { for (size_t i = 0; i < len; i++) { dst.arr[i] = buf[i]; dst.size++; } } return dst; } Vec8_t push_back(Vec8_t* ptr, const char val) { if (is_valid(ptr) == ERR_VECTOR_NULL) { return create(nullptr, 0); } Vec8_t dst = { NULL, ptr->size, ptr->capacity, ptr->max_size }; if (is_valid(ptr) == ERR_BUF_NULL) { LOG("If you think this is wrong, reserve memory first"); return dst; } if (ptr->size + 1 > ptr->max_size) { LOGERROR(ERR_MAX_PASSED); dst = *ptr; return dst; } char* dst_buf; if (ptr->size + 1 > ptr->capacity) { if (ptr->capacity * 2 > ptr->max_size) { LOGERROR(ERR_MAX_PASSED); dst = *ptr; return dst; } dst.capacity = ptr->capacity * 2; dst_buf = realloc(ptr->arr, dst.capacity * sizeof(char)); if (!dst_buf) { LOGERROR(ERR_ALLOC_FAIL); dst = *ptr; return dst; } } else { dst_buf = ptr->arr; } dst.arr = dst_buf; dst.arr[dst.size] = val; dst.size++; return dst; } Vec8_t pop_back(Vec8_t* ptr) { Vec8_t err = create(nullptr, 0); if (is_valid(ptr) != SUCCESS) { return err; } if (ptr->size < 1) { LOGERROR(ERR_SIZE_ZERO); return err; } Vec8_t dst = { NULL, ptr->size - 1, ptr->capacity, ptr->max_size }; dst.arr = ptr->arr; dst.arr[dst.size] = 0; return dst; } Vec8_t reserve(const Vec8_t* ptr, const size_t max_size) { Vec8_t ret = create(nullptr, 0); if (max_size == 0) { LOGERROR(ERR_SIZE_ZERO); return ret; } if (is_valid(ptr) == ERR_VECTOR_NULL) { return ret; } ret.arr = ptr->arr; if (is_valid(&ret) == ERR_BUF_NULL) { ret.arr = calloc(max_size, sizeof(char)); if (!ret.arr) { LOGERROR(ERR_ALLOC_FAIL); ret = *ptr; return ret; } } else if (is_valid(ptr) == SUCCESS) { ret.arr = realloc(ret.arr, max_size * sizeof(char)); if (!ret.arr) { LOGERROR(ERR_ALLOC_FAIL); ret = *ptr; return ret; } ret.size = ptr->size; if (ret.size > max_size) { for (size_t i = max_size; i < ret.size; i++) { ret.arr[i] = 0; } ret.size = max_size; } } ret.capacity = max_size; ret.max_size = max_size; return ret; } Vec8_t shrink_to_fit(Vec8_t* ptr) { if (is_valid(ptr) != SUCCESS) return create(nullptr, 0); if (ptr->size == 0) { LOGERROR(ERR_SIZE_ZERO); return create(nullptr, 0); } return reserve(ptr, ptr->size); } int swap(Vec8_t* ptr1, Vec8_t* ptr2) { Vec8_t tmp = create(nullptr, 0); if (is_valid(ptr1) == ERR_VECTOR_NULL || is_valid(ptr2) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (is_valid(ptr1) == ERR_BUF_NULL || is_valid(ptr2) == ERR_BUF_NULL) { return ERR_BUF_NULL; } tmp.arr = ptr1->arr; ptr1->arr = ptr2->arr; ptr2->arr = tmp.arr; tmp.capacity = ptr1->capacity; tmp.size = ptr1->size; tmp.max_size = ptr1->max_size; ptr1->capacity = ptr2->capacity; ptr1->size = ptr2->size; ptr1->max_size = ptr2->max_size; ptr2->capacity = tmp.capacity; ptr2->size = tmp.size; ptr2->max_size = tmp.max_size; return SUCCESS; } char* data(const Vec8_t* ptr) { if (is_valid(ptr) == ERR_BUF_NULL || is_valid(ptr) == ERR_VECTOR_NULL) return nullptr; return &ptr->arr[0]; } size_t capacity(const Vec8_t* ptr) { if (is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } return ptr->capacity; } size_t max_size(const Vec8_t* ptr) { if (is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } return ptr->max_size; } void delete(const Vec8_t* ptr) { if (is_valid(ptr) == SUCCESS) { free((void*)ptr->arr); } } Vec8_t clear(const Vec8_t* ptr) { Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) { return dst; } dst = *ptr; if (dst.size > 0) { for (size_t i = 0; i < dst.size; i++) { dst.arr[i] = 0; } dst.size = 0; } return dst; } char at(const Vec8_t* ptr, const size_t idx) { if (is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (idx >= ptr->size) { fprintf(stderr, "At Index: [%zu] is out of bounds for size: [%zu]", idx, ptr->size); return ERR_OUT_OF_BOUNDS; } return ptr->arr[idx]; } void print_vec(const Vec8_t* ptr) { if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return; for (size_t i = 0; i < ptr->size; i++) printf("%c ", ptr->arr[i]); printf("\n"); } int begin(const Vec8_t* ptr) { if (is_valid(ptr) == SUCCESS) return 0; return FAILURE; } int end(const Vec8_t* ptr) { if (is_valid(ptr) == SUCCESS) { if (ptr->size != 0) return (int)(ptr->size - 1); else return FAILURE; } return FAILURE; } char front(const Vec8_t* ptr) { if (is_valid(ptr) == ERR_VECTOR_NULL) return FAILURE; if (ptr->size == 0) return FAILURE; return at(ptr, 0); } char back(const Vec8_t* ptr) { if (is_valid(ptr) == ERR_VECTOR_NULL) return FAILURE; if (ptr->size == 0) return FAILURE; return at(ptr, ptr->size - 1); } int empty(const Vec8_t* ptr) { if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return FAILURE; if (ptr->size == 0) return SUCCESS; return FAILURE; } __attribute__((overloadable)) Vec8_t erase(const Vec8_t* ptr, const size_t iter) { Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL) return dst; if (is_valid(ptr) == ERR_BUF_NULL) return dst; if (iter >= ptr->size) return dst; dst = *ptr; memmove(&dst.arr[iter], &dst.arr[iter + 1], (dst.size - iter - 1) * sizeof(char)); dst.arr[dst.size - 1] = 0; dst.size--; return dst; } __attribute__((overloadable)) Vec8_t erase(const Vec8_t* ptr, const size_t iter_start, const size_t iter_end) { Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL) return dst; if (is_valid(ptr) == ERR_BUF_NULL) return dst; if (iter_end > ptr->size) return dst; if (iter_start >= iter_end) return dst; dst = *ptr; size_t diff = iter_end - iter_start; memmove(&dst.arr[iter_start], &dst.arr[iter_end], (dst.size - iter_end) * sizeof(char)); for (size_t i = dst.size - diff; i < dst.size; i++) { dst.arr[i] = 0; } dst.size -= diff; return dst; } __attribute__((overloadable)) Vec8_t resize(const Vec8_t* ptr, const size_t size) { Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return dst; if (ptr->size == size) { LOG("ERR :- Ptr size and size are the same"); dst = *ptr; return dst; } else if (ptr->size == 0) { dst = reserve(&dst, size); } else if (size > ptr->max_size) { LOGERROR(ERR_MAX_PASSED); dst = *ptr; return dst; } else if (size > ptr->capacity) { size_t tmp = ptr->capacity; while (size > tmp) { tmp *= 2; } dst = reserve(ptr, tmp); if (!dst.arr) { LOGERROR(ERR_BUF_NULL); dst = *ptr; return dst; } } if (size < ptr->size) { dst = *ptr; for (size_t i = ptr->size; i > size; i--) { dst.arr[i] = '\0'; } } if (ptr->size < size && size <= ptr->capacity) { for (size_t i = ptr->size; i < size; i++) { dst.arr[i] = '\0'; } } dst.size = size; return dst; } __attribute__((overloadable)) Vec8_t resize(Vec8_t* ptr, const size_t size, const char val) { Vec8_t dst = create(nullptr, 0); dst = *ptr; if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return dst; if ((0 < size && size != dst.size && size < dst.size) || is_valid(ptr) == ERR_SIZE_ZERO) { LOGERROR(ERR_SIZE_ZERO); return dst; } if ((0 < size && size < dst.size) || is_valid(ptr) == ERR_SIZE_ZERO) { LOGERROR(ERR_SIZE_ZERO); return dst; } if (size >= dst.capacity) { dst = reserve(&dst, size); } dst.size = ptr->size + (size - ptr->size); for (size_t i = ptr->size; i < dst.size; i++) { if (at(&dst, i) >= 0) { dst.arr[i] = val; } } dst.size = size; return dst; } __attribute__((overloadable)) Vec8_t assign(const Vec8_t* ptr, const Vec8_t* iterator, const size_t iter_start, const size_t iter_end) { Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return dst; if (is_valid(iterator) == ERR_VECTOR_NULL || is_valid(iterator) == ERR_BUF_NULL) return dst; if (ptr->arr == iterator->arr) { LOGERROR(ERR_DOUBLE_BUF); dst = *ptr; return dst; } if (iterator->size < iter_end || iter_end <= iter_start) { LOGERROR(ERR_OUT_OF_BOUNDS); return dst; } dst = *ptr; dst = erase(ptr, begin(ptr), end(ptr) + 1); dst = reserve(&dst, (iter_end - iter_start)); for (size_t i = iter_start; i < iter_end; i++) { dst = push_back(&dst, at(iterator, i)); } return dst; } __attribute__((overloadable)) Vec8_t assign(const Vec8_t* ptr, const size_t amount, const char val) { Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return create(nullptr, 0); dst = *ptr; if (amount == 0) { LOGERROR(ERR_SIZE_ZERO); return dst; } dst = erase(&dst, begin(&dst), end(&dst) + 1); dst = reserve(&dst, amount); for (size_t i = 0; i < amount; i++) { dst = push_back(&dst, val); } return dst; } __attribute__((overloadable)) Vec8_t insert(const Vec8_t* ptr, const size_t iter, const char val) { Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) { return dst; } if (ptr->max_size < ptr->size + 1) { LOGERROR(ERR_MAX_PASSED); return dst; } if (iter > ptr->size) { LOGERROR(ERR_OUT_OF_BOUNDS); return dst; } dst = *ptr; dst = push_back(&dst, 0); for (size_t i = dst.size - 1; i > iter; i--) { dst.arr[i] = dst.arr[i - 1]; } dst.arr[iter] = val; return dst; } __attribute__((overloadable)) Vec8_t insert(const Vec8_t* ptr, const size_t iter, const size_t amount, const char val) { Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) != SUCCESS) { LOGERROR(ERR_NULL); return dst; } if (iter > ptr->size) { LOGERROR(ERR_OUT_OF_BOUNDS); return dst; } if (amount <= 0) { LOGERROR(ERR_SIZE_ZERO); return dst; } dst = *ptr; for (size_t i = iter; i < iter + amount; i++) { dst = insert(&dst, i, val); } return dst; } __attribute__((overloadable)) Vec8_t insert(const Vec8_t* dst_vec, const Vec8_t* src_vec, const size_t iter, const size_t iter_start, const size_t iter_end) { Vec8_t dst = create(nullptr, 0); if (is_valid(dst_vec) != SUCCESS || is_valid(src_vec) != SUCCESS) { LOGERROR(ERR_NULL); return dst; } if (iter_end > src_vec->size || iter > dst_vec->size) { LOGERROR(ERR_OUT_OF_BOUNDS); return dst; } if (dst_vec->arr == src_vec->arr) { LOGERROR(ERR_DOUBLE_BUF); return dst; } dst = *dst_vec; for (size_t i = iter_start; i < iter_end; i++) { dst = insert(&dst, iter + (i - iter_start), src_vec->arr[i]); } return dst; }