#include "char.h" #include #include #include #include #include #include "utils/utils.h" size_t _vec_char_is_valid(const _VecCharInternal* ptr) { if (ptr == nullptr) { LOGERROR(ERR_VECTOR_NULL); return ERR_VECTOR_NULL; } else if (ptr->_internal_arr == nullptr) { LOGERROR(ERR_BUF_NULL); return ERR_BUF_NULL; } return SUCCESS; } _VecCharInternal _vec_char_create(const char* src, const size_t size) { _VecCharInternal self = { ._internal_arr = NULL, ._internal_size = 0, ._internal_capacity = CAPACITY, ._internal_max_size = VEC_MAX, }; if (size > self._internal_max_size) { LOGERROR(ERR_MAX_PASSED); LOG("If you need more memory to start, create a blank and " "selferve."); return self; } if (self._internal_capacity < size && size < self._internal_max_size) { while (self._internal_capacity < size && self._internal_capacity * 2 < self._internal_max_size) self._internal_capacity *= 2; } if (self._internal_capacity * 2 > self._internal_max_size && size < self._internal_max_size) { self._internal_capacity = size; } if (size > 0) { char* dst_buf = calloc(self._internal_capacity, sizeof(char)); if (!dst_buf) { LOGERROR(ERR_ALLOC_FAIL); return self; } self._internal_arr = dst_buf; } if (src) { for (size_t i = 0; i < size; i++) { self._internal_arr[i] = src[i]; self._internal_size++; } } return self; } size_t _vec_char_push_back(_VecCharInternal* ptr, const char val) { char* res; size_t status = _vec_char_is_valid(ptr); if (status == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (ptr->_internal_size + 1 > ptr->_internal_max_size) { LOGERROR(ERR_MAX_PASSED); return ERR_MAX_PASSED; } if (status == ERR_BUF_NULL && ptr->_internal_size == 0) { res = calloc(1, sizeof(char)); if (!res) { LOGERROR(ERR_ALLOC_FAIL); return ERR_ALLOC_FAIL; } ptr->_internal_arr = res; ptr->_internal_arr[0] = val; ptr->_internal_size++; return SUCCESS; } else if (ptr->_internal_size + 1 > ptr->_internal_capacity) { size_t dst_cap = ptr->_internal_capacity * 2; if (dst_cap > ptr->_internal_max_size) { ptr->_internal_capacity = ptr->_internal_max_size; res = realloc(ptr->_internal_arr, ptr->_internal_capacity * sizeof(char)); LOG("DEBUG: Capacity cannot be grown any further due " "to hitting max size"); } else { res = realloc(ptr->_internal_arr, dst_cap * sizeof(char)); ptr->_internal_capacity = dst_cap; } if (!res) { LOGERROR(ERR_ALLOC_FAIL); return ERR_ALLOC_FAIL; } } else { res = ptr->_internal_arr; } ptr->_internal_arr = res; ptr->_internal_arr[ptr->_internal_size] = val; ptr->_internal_size++; return SUCCESS; } size_t _vec_char_pop_back(_VecCharInternal* ptr) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (ptr->_internal_size < 1) { LOGERROR(ERR_SIZE_ZERO); return ERR_SIZE_ZERO; } ptr->_internal_arr[ptr->_internal_size - 1] = 0; ptr->_internal_size--; return SUCCESS; } size_t _vec_char_reserve(_VecCharInternal* ptr, const size_t capacity) { char* res; size_t status = _vec_char_is_valid(ptr); if (capacity == 0) { LOGERROR(ERR_SIZE_ZERO); return ERR_SIZE_ZERO; } if (status == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (status == ERR_BUF_NULL) { res = calloc(ptr->_internal_capacity, sizeof(char)); if (!res) { LOGERROR(ERR_ALLOC_FAIL); return ERR_ALLOC_FAIL; } } else if (status == SUCCESS) { res = realloc(ptr->_internal_arr, capacity * sizeof(char)); if (!res) { LOGERROR(ERR_ALLOC_FAIL); return ERR_ALLOC_FAIL; } if (ptr->_internal_size > capacity) { for (size_t i = capacity; i < ptr->_internal_size; i++) { ptr->_internal_arr[i] = '\0'; } ptr->_internal_size = capacity; } } ptr->_internal_arr = res; ptr->_internal_capacity = capacity; ptr->_internal_max_size = capacity; return SUCCESS; } size_t _vec_char_shrink_to_fit(_VecCharInternal* ptr) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (ptr->_internal_size == 0) { LOGERROR(ERR_SIZE_ZERO); return ERR_SIZE_ZERO; } return _vec_char_reserve(ptr, ptr->_internal_size); } size_t _vec_char_swap(_VecCharInternal* ptr1, _VecCharInternal* ptr2) { _VecCharInternal self = _vec_char_create(nullptr, 0); if (_vec_char_is_valid(ptr1) == ERR_VECTOR_NULL || _vec_char_is_valid(ptr2) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr1) == ERR_BUF_NULL || _vec_char_is_valid(ptr2) == ERR_BUF_NULL) { return ERR_BUF_NULL; } self._internal_arr = ptr1->_internal_arr; ptr1->_internal_arr = ptr2->_internal_arr; ptr2->_internal_arr = self._internal_arr; self._internal_capacity = ptr1->_internal_capacity; self._internal_size = ptr1->_internal_size; self._internal_max_size = ptr1->_internal_max_size; ptr1->_internal_capacity = ptr2->_internal_capacity; ptr1->_internal_size = ptr2->_internal_size; ptr1->_internal_max_size = ptr2->_internal_max_size; ptr2->_internal_capacity = self._internal_capacity; ptr2->_internal_size = self._internal_size; ptr2->_internal_max_size = self._internal_max_size; return SUCCESS; } char* _vec_char_data(const _VecCharInternal* ptr) { if (_vec_char_is_valid(ptr) == ERR_BUF_NULL || _vec_char_is_valid(ptr) == ERR_VECTOR_NULL) return nullptr; return &ptr->_internal_arr[0]; } size_t _vec_char_capacity(const _VecCharInternal* ptr) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } return ptr->_internal_capacity; } size_t _vec_char_max_size(const _VecCharInternal* ptr) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } return ptr->_internal_max_size; } void _vec_char_delete(const _VecCharInternal* ptr) { if (_vec_char_is_valid(ptr) == SUCCESS) { free((void*)ptr->_internal_arr); } } size_t _vec_char_clear(_VecCharInternal* ptr) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (ptr->_internal_size > 0) { for (size_t i = 0; i < ptr->_internal_size; i++) { ptr->_internal_arr[i] = 0; } ptr->_internal_size = 0; } return SUCCESS; } char _vec_char_at(const _VecCharInternal* ptr, const size_t idx) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (idx >= ptr->_internal_size) { fprintf(stderr, "At Index: [%zu] is out of bounds for size: [%zu]\n", idx, ptr->_internal_size); return ERR_OUT_OF_BOUNDS; } return ptr->_internal_arr[idx]; } void _vec_char_print_vec(const _VecCharInternal* ptr) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL || _vec_char_is_valid(ptr) == ERR_BUF_NULL) return; for (size_t i = 0; i < ptr->_internal_size; i++) printf("%c ", ptr->_internal_arr[i]); printf("\n"); } size_t _vec_char_begin(const _VecCharInternal* ptr) { if (_vec_char_is_valid(ptr) == SUCCESS) return 0; return FAILURE; } size_t _vec_char_end(const _VecCharInternal* ptr) { if (_vec_char_is_valid(ptr) == SUCCESS) { if (ptr->_internal_size != 0) return (int)(ptr->_internal_size - 1); else return FAILURE; } return FAILURE; } char _vec_char_front(const _VecCharInternal* ptr) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) return FAILURE; if (ptr->_internal_size == 0) return FAILURE; return _vec_char_at(ptr, 0); } char _vec_char_back(const _VecCharInternal* ptr) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) return FAILURE; if (ptr->_internal_size == 0) return FAILURE; return _vec_char_at(ptr, ptr->_internal_size - 1); } size_t _vec_char_empty(const _VecCharInternal* ptr) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL || _vec_char_is_valid(ptr) == ERR_BUF_NULL) return FAILURE; if (ptr->_internal_size == 0) return SUCCESS; return FAILURE; } // TODO: Fix return value __attribute__((overloadable)) size_t _vec_char_erase(_VecCharInternal* ptr, const size_t iter) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) return ERR_VECTOR_NULL; if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) return ERR_BUF_NULL; if (iter >= ptr->_internal_size) return ERR_OUT_OF_BOUNDS; memmove(&ptr->_internal_arr[iter], &ptr->_internal_arr[iter + 1], (ptr->_internal_size - iter - 1) * sizeof(char)); ptr->_internal_arr[ptr->_internal_size - 1] = 0; ptr->_internal_size--; return SUCCESS; } // TODO: Fix return value __attribute__((overloadable)) size_t _vec_char_erase(_VecCharInternal* ptr, const size_t iter_start, const size_t iter_end) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) return ERR_VECTOR_NULL; if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) return ERR_BUF_NULL; if (iter_end > ptr->_internal_size) return ERR_OUT_OF_BOUNDS; if (iter_start >= iter_end) return ERR_OUT_OF_BOUNDS; size_t diff = iter_end - iter_start; memmove(&ptr->_internal_arr[iter_start], &ptr->_internal_arr[iter_end], (ptr->_internal_size - iter_end) * sizeof(char)); for (size_t i = ptr->_internal_size - diff; i < ptr->_internal_size; i++) { ptr->_internal_arr[i] = 0; } ptr->_internal_size -= diff; return SUCCESS; } __attribute__((overloadable)) size_t _vec_char_resize(_VecCharInternal* ptr, const size_t size) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (ptr->_internal_size == size) { LOG("ERR :- Ptr size and size are the same"); return ERR_OUT_OF_BOUNDS; } else if (size > ptr->_internal_max_size) { LOGERROR(ERR_MAX_PASSED); return ERR_MAX_PASSED; } else if (ptr->_internal_size == 0) { size_t max = ptr->_internal_max_size; size_t status = _vec_char_reserve(ptr, size); if (status != SUCCESS) { return status; } if (ptr->_internal_capacity != size) { LOGERROR(ERR_ALLOC_FAIL); return ERR_ALLOC_FAIL; } for (size_t i = 0; i < size; i++) { ptr->_internal_arr[i] = '\0'; } ptr->_internal_max_size = max; ptr->_internal_size = size; return SUCCESS; } else if (size > ptr->_internal_capacity) { size_t tmpcp = ptr->_internal_capacity; size_t tmpmx = ptr->_internal_max_size; while (size > tmpcp) { tmpcp *= 2; } if (tmpcp > ptr->_internal_max_size) { tmpcp = size; } size_t status = _vec_char_reserve(ptr, tmpcp); if (status != SUCCESS) { return status; } if (ptr->_internal_capacity != tmpcp) { LOGERROR(ERR_ALLOC_FAIL); return ERR_ALLOC_FAIL; } ptr->_internal_max_size = tmpmx; } if (size < ptr->_internal_size) { for (size_t i = size; i < ptr->_internal_size; i++) { ptr->_internal_arr[i] = '\0'; } } if (ptr->_internal_size < size && size <= ptr->_internal_capacity) { for (size_t i = ptr->_internal_size; i < size; i++) { ptr->_internal_arr[i] = '\0'; } } ptr->_internal_size = size; return SUCCESS; } __attribute__((overloadable)) size_t _vec_char_resize(_VecCharInternal* ptr, const size_t size, const char val) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (ptr->_internal_size == size) { LOG("ERR :- Ptr size and size are the same"); return ERR_OUT_OF_BOUNDS; } else if (size > ptr->_internal_max_size) { LOGERROR(ERR_MAX_PASSED); return ERR_MAX_PASSED; } else if (ptr->_internal_size == 0) { size_t max = ptr->_internal_max_size; size_t status = _vec_char_reserve(ptr, size); if (status != SUCCESS) { return status; } if (ptr->_internal_capacity != size) { LOGERROR(ERR_ALLOC_FAIL); return ERR_ALLOC_FAIL; } for (size_t i = 0; i < size; i++) { ptr->_internal_arr[i] = val; } ptr->_internal_max_size = max; ptr->_internal_size = size; return SUCCESS; } else if (size > ptr->_internal_capacity) { size_t tmpcp = ptr->_internal_capacity; size_t tmpmx = ptr->_internal_max_size; while (size > tmpcp) { tmpcp *= 2; } if (tmpcp > ptr->_internal_max_size) { tmpcp = size; } size_t status = _vec_char_reserve(ptr, tmpcp); if (status != SUCCESS) { LOGERROR(ERR_ALLOC_FAIL); return ERR_ALLOC_FAIL; } ptr->_internal_max_size = tmpmx; } if (size < ptr->_internal_size) { for (size_t i = size; i < ptr->_internal_size; i++) { ptr->_internal_arr[i] = val; } } if (ptr->_internal_size < size && size <= ptr->_internal_capacity) { for (size_t i = ptr->_internal_size; i < size; i++) { ptr->_internal_arr[i] = val; } } ptr->_internal_size = size; return SUCCESS; } __attribute__((overloadable)) size_t _vec_char_assign(_VecCharInternal* ptr, const _VecCharInternal* iterator, const size_t iter_start, const size_t iter_end) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (_vec_char_is_valid(iterator) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(iterator) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (ptr->_internal_arr == iterator->_internal_arr) { LOGERROR(ERR_DOUBLE_BUF); return ERR_DOUBLE_BUF; } if (iterator->_internal_size < iter_end || iter_end <= iter_start) { LOGERROR(ERR_OUT_OF_BOUNDS); return ERR_OUT_OF_BOUNDS; } size_t status = _vec_char_erase(ptr, _vec_char_begin(ptr), _vec_char_end(ptr) + 1); if (status != SUCCESS) { return status; } status = _vec_char_reserve(ptr, (iter_end - iter_start)); if (status != SUCCESS) { return status; } for (size_t i = iter_start; i < iter_end; i++) { status = _vec_char_push_back(ptr, _vec_char_at(iterator, i)); if (status != SUCCESS) { return status; } } return SUCCESS; } __attribute__((overloadable)) size_t _vec_char_assign(_VecCharInternal* ptr, const size_t amount, const char val) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (amount == 0) { LOGERROR(ERR_SIZE_ZERO); return ERR_SIZE_ZERO; } size_t status = _vec_char_erase(ptr, _vec_char_begin(ptr), _vec_char_end(ptr) + 1); if (status != SUCCESS) { return status; } status = _vec_char_reserve(ptr, amount); if (status != SUCCESS) { return status; } for (size_t i = 0; i < amount; i++) { status = _vec_char_push_back(ptr, val); if (status != SUCCESS) { return status; } } return SUCCESS; } __attribute__((overloadable)) size_t _vec_char_insert(_VecCharInternal* ptr, const size_t iter, const char val) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (ptr->_internal_max_size < ptr->_internal_size + 1) { LOGERROR(ERR_MAX_PASSED); return ERR_MAX_PASSED; } if (iter > ptr->_internal_size) { LOGERROR(ERR_OUT_OF_BOUNDS); return ERR_OUT_OF_BOUNDS; } size_t status = _vec_char_push_back(ptr, 0); if (status != SUCCESS) { return status; } for (size_t i = ptr->_internal_size - 1; i > iter; i--) { ptr->_internal_arr[i] = ptr->_internal_arr[i - 1]; } ptr->_internal_arr[iter] = val; return SUCCESS; } __attribute__((overloadable)) size_t _vec_char_insert(_VecCharInternal* ptr, const size_t iter, const size_t amount, const char val) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (iter > ptr->_internal_size) { LOGERROR(ERR_OUT_OF_BOUNDS); return ERR_OUT_OF_BOUNDS; } if (amount <= 0) { LOGERROR(ERR_SIZE_ZERO); return ERR_SIZE_ZERO; } for (size_t i = iter; i < iter + amount; i++) { size_t status = _vec_char_insert(ptr, i, val); if (status != SUCCESS) { return status; } } return SUCCESS; } __attribute__((overloadable)) size_t _vec_char_insert(_VecCharInternal* ptr, const _VecCharInternal* iterator, const size_t iter, const size_t iter_start, const size_t iter_end) { if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (_vec_char_is_valid(iterator) == ERR_VECTOR_NULL) { return ERR_VECTOR_NULL; } if (_vec_char_is_valid(iterator) == ERR_BUF_NULL) { return ERR_BUF_NULL; } if (iter_end > iter_start || iter_end > iterator->_internal_size || iter > ptr->_internal_size) { LOGERROR(ERR_OUT_OF_BOUNDS); return ERR_OUT_OF_BOUNDS; } if (ptr->_internal_arr == iterator->_internal_arr) { LOGERROR(ERR_DOUBLE_BUF); return ERR_DOUBLE_BUF; } for (size_t i = iter_start; i < iter_end; i++) { size_t status = _vec_char_insert(ptr, iter + (i - iter_start), iterator->_internal_arr[i]); if (status != SUCCESS) { return status; } } return SUCCESS; }