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 }