stew

a monorepo of some sort
git clone git://git.nsmpr.xyz/stew.git
Log | Files | Refs

slice.c (1838B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include "util.h"
      4 
      5 Type CharType = { .nbytes = 1, };
      6 Type PtrType = { .nbytes = sizeof(void *), };
      7 
      8 Array *
      9 allocarray(Type *type, int count)
     10 {
     11 	Array *a = malloc(sizeof(Array) + type->nbytes * count);
     12 	a->type = type;
     13 	a->count = count;
     14 	return a;
     15 }
     16 
     17 void
     18 freearray(Array *a)
     19 {
     20 	free(a);
     21 }
     22 
     23 Slice *
     24 allocslice(Type *type, int len, int cap)
     25 {
     26 	Slice *s = malloc(sizeof(Slice));
     27 	if (cap < len) cap = len;
     28 	s->arr = allocarray(type, cap);
     29 	s->p = s->arr->p;
     30 	s->len = len;
     31 	s->cap = cap;
     32 	return s;
     33 }
     34 
     35 Slice *
     36 slicejoin(Slice *a, Slice *b)
     37 {
     38 	if (a->arr->type != b->arr->type) return nil;
     39 	Slice *c = allocslice(a->arr->type, a->len + b->len, 0);
     40 	char *cp = (char *)c->p;
     41 	memcpy(cp, a->p, a->arr->type->nbytes * a->len);
     42 	memcpy(cp + a->arr->type->nbytes * a->len,
     43 	  b->p, a->arr->type->nbytes * b->len);
     44 	return c;
     45 }
     46 
     47 Slice *
     48 slicecopy(Slice *a)
     49 {
     50 	Slice *b = allocslice(a->arr->type, a->len, 0);
     51 	memcpy(b->p, a->p, a->arr->type->nbytes * a->len);
     52 	return b;
     53 }
     54 
     55 Slice *
     56 sliceappendp(Slice *s, int count, void *p)
     57 {
     58 	assert(s != nil);
     59 	assert(p != nil);
     60 	if (s->len + count < s->cap) {
     61 		s->len += count;
     62 	} else {
     63 		Array *arr = allocarray(s->arr->type, s->len + count);
     64 		memcpy(arr->p, s->p, s->len * s->arr->type->nbytes);
     65 		freearray(s->arr);
     66 		s->arr = arr;
     67 		s->len += count;
     68 		s->cap = arr->count;
     69 		s->p = arr->p;
     70 	}
     71 	void *np = slicegetp(s, s->len - count);
     72 	memcpy(np, p, count * s->arr->type->nbytes);
     73 	return s;
     74 }
     75 
     76 Slice *
     77 sliceappend(Slice *s, int count, ...)
     78 {
     79 	// TODO: test this!!!
     80 
     81 	va_list arg;
     82 	va_start(arg, count);
     83 
     84 	s = sliceappendp(s, count, arg);
     85 
     86 	va_end(arg);
     87 	return s;
     88 }
     89 
     90 void *
     91 slicegetp(Slice *s, int n)
     92 {
     93 	assert(n >= 0);
     94 	assert(n < s->len);
     95 	char *p = (char *)s->p + (n * s->arr->type->nbytes);
     96 	return p;
     97 }
     98 
     99 void
    100 freeslice(Slice *s)
    101 {
    102 	freearray(s->arr);
    103 	free(s);
    104 }