about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorRen Kararou <[email protected]>2025-02-03 21:28:08 -0600
committerRen Kararou <[email protected]>2025-02-03 21:28:08 -0600
commit8eaabcd22bcad13ccbf9f1ee3979f26adcf2ca2f (patch)
tree6418d9327843a7f98e6563200912572052ee050c
parente9b6b43b72eb25a13287467262a956bd0eaa563f (diff)
downloadlibspicy-8eaabcd22bcad13ccbf9f1ee3979f26adcf2ca2f.tar.gz
libspicy-8eaabcd22bcad13ccbf9f1ee3979f26adcf2ca2f.tar.bz2
libspicy-8eaabcd22bcad13ccbf9f1ee3979f26adcf2ca2f.zip
completed impl of resarr
-rw-r--r--inc/resarr.h1
-rw-r--r--src/resarr.c73
2 files changed, 69 insertions, 5 deletions
diff --git a/inc/resarr.h b/inc/resarr.h
index 0a4ed23..84c5c72 100644
--- a/inc/resarr.h
+++ b/inc/resarr.h
@@ -15,6 +15,7 @@ typedef struct ResArr {
 stype_resarr resarr_create(size_t elemsize);
 int resarr_reserve(stype_resarr *arr, size_t elemcount);
 int resarr_reserve_exact(stype_resarr *arr, size_t elemcount);
+int resarr_truncate(stype_resarr *arr);
 int resarr_push(stype_resarr *arr, void *elem);
 int resarr_pop(stype_resarr *arr);
 size_t resarr_size(stype_resarr arr);
diff --git a/src/resarr.c b/src/resarr.c
index a359d71..4996a90 100644
--- a/src/resarr.c
+++ b/src/resarr.c
@@ -4,16 +4,19 @@
 #include <stdint.h>
 #include <string.h>
 
+size_t get_res_count(size_t count) {
+	size_t ec = 1;
+	while (ec < count) ec *= 2;
+	return ec;
+}
+
 stype_resarr resarr_create(size_t elemsize) {
 	return (stype_resarr) { .elemsize = elemsize, .elemcount = 0, .allocsize = 0, .array = NULL };
 }
 
 int resarr_reserve(stype_resarr *arr, size_t elemcount) {
 	if (arr == NULL) return -1;
-	size_t ec = 1;
-	while (ec < elemcount) {
-		ec *= 2;
-	}
+	size_t ec = get_res_count(elemcount);
 	if (ec * arr->elemsize < arr->allocsize) return -1;
 	arr->array = realloc(arr->array, (ec * arr->elemsize));
 	if (arr->array == NULL) return -1;
@@ -30,6 +33,17 @@ int resarr_reserve_exact(stype_resarr *arr, size_t elemcount) {
 	return 0;
 }
 
+int resarr_truncate(stype_resarr *arr) {
+	if (arr == NULL) return -1;
+	void *narray = malloc(arr->elemcount * arr->elemsize);
+	if (narray == NULL) return -1;
+	memcpy(narray, arr->array, arr->elemcount * arr->elemsize);
+	free(arr->array);
+	arr->array = narray;
+	arr->allocsize = arr->elemcount * arr->elemsize;
+	return 0;
+}
+
 int resarr_push(stype_resarr *arr, void *elem) {
 	if (arr == NULL) return -1;
 	if (arr->elemsize * arr->elemcount == arr->allocsize) {
@@ -60,7 +74,56 @@ size_t resarr_size(stype_resarr arr) {
 	return arr.elemcount;
 }
 
-// TODO: insert{,_single}, delete
+int resarr_insert(stype_resarr *arr, void *elem, size_t before, size_t count) {
+	if (arr == NULL) return -1;
+	if (before > arr->elemcount) return -1;
+	size_t esize = arr->elemsize;
+	size_t newcount = arr->elemcount + count;
+	size_t alloc = get_res_count(newcount) * esize;
+	void *narray = malloc(alloc);
+	if (narray == NULL) return -1;
+	memcpy(
+		narray,
+		arr->array,
+		before * esize
+	);
+	memcpy(
+		((uint8_t *)narray + (before * esize)),
+		elem,
+		count * esize
+	);
+	memcpy(
+		((uint8_t *)narray + (before * esize) + (count * esize)),
+		((uint8_t *)arr->array + (before * esize)),
+		(arr->elemcount - before) * esize
+	);
+	free(arr->array);
+	arr->array = narray;
+	arr->elemcount = newcount;
+	arr->allocsize = alloc;
+	return 0;
+}
+
+int resarr_insert_single(stype_resarr *arr, void *elem, size_t before) {
+	return resarr_insert(arr, elem, before, 1);
+}
+
+int resarr_delete(stype_resarr *arr, size_t start, size_t end) {
+	if (arr == NULL) return -1;
+	if ((start > end) || (start > arr->elemcount) || (end > arr->elemcount))
+		return -1;
+	size_t rmcount = end - start;
+	memset(((uint8_t *)arr->array + (start * arr->elemsize)), 0, rmcount * arr->elemsize);
+	if (end != arr->elemcount) {
+		memmove(
+			((uint8_t *)arr->array + (start * arr->elemsize)),
+			((uint8_t *)arr->array + (end * arr->elemsize)),
+			(arr->elemcount - end) * arr->elemsize
+		);
+	}
+	arr->elemcount -= rmcount;
+	return 0;
+}
 
 int resarr_swap(stype_resarr *first, stype_resarr *second) {
 	if (first == NULL || second == NULL) return -1;