| /* |
| * Copyright (C) 2016 Google Inc. |
| * Dan Cross <crossd@gmail.com> |
| * See LICENSE for license details. |
| */ |
| |
| #include <kmalloc.h> |
| #include <assert.h> |
| #include <error.h> |
| #include <slice.h> |
| |
| void slice_init(struct slice *slice) |
| { |
| memset(slice, 0, sizeof(*slice)); |
| } |
| |
| void slice_clear(struct slice *slice) |
| { |
| slice->len = 0; |
| memset(slice->ptrs, 0, sizeof(*slice->ptrs) * slice->capacity); |
| } |
| |
| void *slice_get(struct slice *slice, size_t i) |
| { |
| if (i >= slice->len) |
| return NULL; |
| return slice->ptrs[i]; |
| } |
| |
| bool slice_put(struct slice *slice, size_t i, void *p) |
| { |
| if (i >= slice->len) |
| return FALSE; |
| slice->ptrs[i] = p; |
| return TRUE; |
| } |
| |
| bool slice_del(struct slice *slice, size_t i) |
| { |
| if (i >= slice->len) |
| return FALSE; |
| memmove(slice->ptrs + i, slice->ptrs + i + 1, |
| (slice->len - (i + 1)) * sizeof(void *)); |
| slice->len--; |
| return TRUE; |
| } |
| |
| void slice_append(struct slice *s, void *p) |
| { |
| void **ps; |
| |
| assert(p != NULL); |
| if (s->len == s->capacity) { |
| if (s->capacity == 0) |
| s->capacity = 4; |
| s->capacity *= 2; |
| ps = kreallocarray(s->ptrs, s->capacity, sizeof(void *), |
| MEM_WAIT); |
| assert(ps != NULL); /* XXX: if size*sizeof(void*) overflows. */ |
| s->ptrs = ps; |
| } |
| s->ptrs[s->len] = p; |
| s->len++; |
| } |
| |
| size_t slice_len(struct slice *slice) |
| { |
| return slice->len; |
| } |
| |
| void **slice_finalize(struct slice *slice) |
| { |
| void **ps; |
| |
| ps = kreallocarray(slice->ptrs, slice->len, sizeof(void *), MEM_WAIT); |
| assert(ps != NULL); |
| slice->len = 0; |
| slice->capacity = 0; |
| slice->ptrs = NULL; |
| |
| return ps; |
| } |
| |
| void slice_destroy(struct slice *slice) |
| { |
| kfree(slice->ptrs); |
| slice->ptrs = NULL; |
| slice->capacity = 0; |
| slice->len = 0; |
| } |