commit a2ed7dd5873d2ac5113b21735688737fab330191
parent 421a152dfb5147bee67a07afcd5ab1d3c07b28e1
Author: Pavel Renev <an2qzavok@gmail.com>
Date: Tue, 24 Aug 2021 01:03:24 +0000
array: add arrayinsert, fix bug in arraygrow, rework some functions to copy memory from/to a pointer, if supplied
Diffstat:
M | array.c | | | 66 | +++++++++++++++++++++++++++++++++++++++++++++++++++--------------- |
M | array.h | | | 12 | ++++++------ |
2 files changed, 57 insertions(+), 21 deletions(-)
diff --git a/array.c b/array.c
@@ -3,6 +3,16 @@
#include "array.h"
+int
+_arraycheck(Array *ap, long n, char *s)
+{
+ if ((n < 0) || (n >= ap->count)) {
+ werrstr("%s: out of bounds", s);
+ return -1;
+ }
+ return 0;
+}
+
Array *
arraycreate(long size, long n, void (*free)(void *))
{
@@ -26,9 +36,10 @@ arrayfree(Array *ap)
qlock(ap->l);
if (ap->free != nil) {
for (i = 0; i < ap->count; i ++) {
- void **v;
- v = arrayget(ap, i);
- ap->free(*v);
+ void *v;
+ v = nil;
+ arrayget(ap, i, &v);
+ if (v != nil) ap->free(v);
}
}
qunlock(ap->l);
@@ -36,21 +47,25 @@ arrayfree(Array *ap)
}
void *
-arraygrow(Array *ap, long n)
+arraygrow(Array *ap, long n, void *v)
{
- void *v;
+ void *ve;
if (n < 0) {
werrstr("arraygrow: negative growth size");
return nil;
}
- v = arrayend(ap);
+ ve = arrayend(ap);
qlock(ap->l);
ap->count += n;
if (ap->count > ap->n) {
ap->n += ap->n;
+ if (ap->count > ap->n) ap->n = ap->count;
ap->p = realloc(ap->p, ap->size * ap->n);
}
- memset(v, 0, ap->size * n);
+ memset(ve, 0, ap->size * ap->n);
+ if (v != nil) {
+ memcpy(ve, v, n * ap->size);
+ }
qunlock(ap->l);
return (void *)(ap->p + ap->size * (ap->count - n));
}
@@ -59,10 +74,7 @@ int
arraydel(Array *ap, long n)
{
char *v;
- if ((n < 0) || (n >= ap->count)) {
- werrstr("arraydel: out of bounds");
- return -1;
- }
+ if (_arraycheck(ap, n, "arraydel") != 0) return -1;
qlock(ap->l);
v = ap->p + ap->size * n;
if (ap->free != nil) ap->free(v);
@@ -73,12 +85,14 @@ arraydel(Array *ap, long n)
}
void *
-arrayget(Array *ap, long n)
+arrayget(Array *ap, long n, void *v)
{
- if ((n < 0) || (n >= ap->count)) {
- werrstr("arrayget: out of bounds");
- return nil;
+ if (_arraycheck(ap, n, "arrayget") != 0) return nil;
+ qlock(ap->l);
+ if (v != nil) {
+ memcpy(v, ap->p + ap->size * n, ap->size);
}
+ qunlock(ap->l);
return (void *)(ap->p + ap->size * n);
}
@@ -87,3 +101,25 @@ arrayend(Array *ap)
{
return (void *)(ap->p + ap->size * ap->count);
}
+
+void *
+arrayinsert(Array *ap, long n, long m, void *v)
+{
+ void *vs, *vn;
+ if (n == ap->count) {
+ vs = arraygrow(ap, m, v);
+ return vs;
+ }
+ if (_arraycheck(ap, n, "arrayinsert") != 0) return nil;
+ arraygrow(ap, m, nil);
+ vs = arrayget(ap, n, nil);
+ vn = arrayget(ap, n + m, nil);
+ qlock(ap->l);
+ memcpy(vn, vs, (ap->count - n - m) * ap->size);
+ memset(vs, 0, m * ap->size);
+ if (v != nil) {
+ memcpy(vs, v, m * ap->size);
+ }
+ qunlock(ap->l);
+ return vs;
+}
diff --git a/array.h b/array.h
@@ -9,9 +9,10 @@ struct Array {
void (*free)(void *);
};
-Array * arraycreate(long, long, void (*free)(void *));
-void arrayfree(Array *);
-void * arraygrow(Array *, long);
+Array * arraycreate(long size, long n, void (*free)(void *));
int arraydel(Array *, long);
-void * arrayget(Array *, long);
-void * arrayend(Array *);
-\ No newline at end of file
+void arrayfree(Array *);
+void * arraygrow(Array *, long, void *);
+void * arrayget(Array *, long, void *);
+void * arrayend(Array *);
+void * arrayinsert(Array *, long, long, void *);