| /* | 
 |  * 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; | 
 | } |