commit bd847631dcf10e95b70d7a357818a20b4115ed97
parent 6f6e326b595d05867a539038266baf63d522b727
Author: Renev Pavel <an2qzavok@gmail.com>
Date: Wed, 17 May 2023 09:39:06 +0000
util: reinvent slices
Diffstat:
3 files changed, 135 insertions(+), 0 deletions(-)
diff --git a/src/util/mkfile b/src/util/mkfile
@@ -0,0 +1,11 @@
+</$objtype/mkfile
+
+LIB=libutil.a$O
+
+OFILES=\
+ slice.$O\
+
+HFILES=\
+ util.h\
+
+</sys/src/cmd/mklib
diff --git a/src/util/slice.c b/src/util/slice.c
@@ -0,0 +1,92 @@
+#include <u.h>
+#include <libc.h>
+#include "util.h"
+
+Type CharType = { .nbytes = 1, };
+Type PtrType = { .nbytes = sizeof(void *), };
+
+Array *
+allocarray(Type *type, int count)
+{
+ Array *a = malloc(sizeof(Array) + type->nbytes * count);
+ a->type = type;
+ a->count = count;
+ return a;
+}
+
+Slice *
+allocslice(Type *type, int len, int cap)
+{
+ Slice *s = malloc(sizeof(Slice));
+ if (cap < len) cap = len;
+ s->arr = allocarray(type, cap);
+ s->p = s->arr->p;
+ s->len = len;
+ s->cap = cap;
+ return s;
+}
+
+Slice *
+slicejoin(Slice *a, Slice *b)
+{
+ if (a->arr->type != b->arr->type) return nil;
+ Slice *c = allocslice(a->arr->type, a->len + b->len, 0);
+ char *cp = (char *)c->p;
+ memcpy(cp, a->p, a->arr->type->nbytes * a->len);
+ memcpy(cp + a->arr->type->nbytes * a->len,
+ b->p, a->arr->type->nbytes * b->len);
+ return c;
+}
+
+Slice *
+slicecopy(Slice *a)
+{
+ Slice *b = allocslice(a->arr->type, a->len, 0);
+ memcpy(b->p, a->p, a->arr->type->nbytes * a->len);
+ return b;
+}
+
+Slice *
+sliceappendp(Slice *s, int count, void *p)
+{
+ if (s->len + count < s->cap) {
+ s->len += count;
+ } else {
+ Slice *new = allocslice(s->arr->type, s->len + count, s->cap + count);
+ memcpy(new->p, s->p, s->len * s->arr->type->nbytes);
+ s = new;
+ }
+ void *np = slicegetp(s, s->len - count);
+ memcpy(np, p, count * s->arr->type->nbytes);
+ return s;
+}
+
+Slice *
+sliceappend(Slice *s, int count, ...)
+{
+ // TODO: test this!!!
+
+ va_list arg;
+ va_start(arg, count);
+
+ s = sliceappendp(s, count, arg);
+
+ va_end(arg);
+ return s;
+}
+
+void *
+slicegetp(Slice *s, int n)
+{
+ assert(n >= 0);
+ assert(n < s->len);
+ char *p = (char *)s->p + (n * s->arr->type->nbytes);
+ return p;
+}
+
+void
+freeslice(Slice *s)
+{
+ free(s->arr);
+ free(s);
+}
diff --git a/src/util/util.h b/src/util/util.h
@@ -0,0 +1,32 @@
+typedef struct Type Type;
+
+struct Type {
+ usize nbytes;
+};
+
+extern Type CharType;
+
+typedef struct Array Array;
+
+struct Array {
+ Type *type;
+ int count;
+ void p[1];
+};
+
+typedef struct Slice Slice;
+
+struct Slice {
+ Array *arr;
+ void *p;
+ int len, cap;
+};
+
+Array * allocarray(Type *, int);
+Slice * allocslice(Type *, int, int);
+Slice * sliceappendp(Slice *, int, void *);
+Slice * sliceappend(Slice *, int count, ...);
+Slice * slicecopy(Slice *);
+Slice * slicejoin(Slice *, Slice *);
+void *slicegetp(Slice *, int);
+void freeslice(Slice *);