stew

a monorepo of some sort
Log | Files | Refs

commit bd847631dcf10e95b70d7a357818a20b4115ed97
parent 6f6e326b595d05867a539038266baf63d522b727
Author: Renev Pavel <an2qzavok@gmail.com>
Date:   Wed, 17 May 2023 09:39:06 +0000

util: reinvent slices

Diffstat:
Asrc/util/mkfile | 11+++++++++++
Asrc/util/slice.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/util/util.h | 32++++++++++++++++++++++++++++++++
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 *);