diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:32:55 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:32:55 -0800 |
commit | dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0 (patch) | |
tree | 2ba8d1a0846d69b18f623515e8d9b5d9fe38b590 /libcutils/array.c | |
parent | e54eebbf1a908d65ee8cf80bab62821c05666d70 (diff) | |
download | system_core-dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0.zip system_core-dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0.tar.gz system_core-dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'libcutils/array.c')
-rw-r--r-- | libcutils/array.c | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/libcutils/array.c b/libcutils/array.c new file mode 100644 index 0000000..ff2c8ff --- /dev/null +++ b/libcutils/array.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cutils/array.h> +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#define INITIAL_CAPACITY (4) + +struct Array { + void** contents; + int size; + int capacity; +}; + +Array* arrayCreate() { + return calloc(1, sizeof(struct Array)); +} + +void arrayFree(Array* array) { + assert(array != NULL); + + // Free internal array. + free(array->contents); + + // Free the Array itself. + free(array); +} + +/** Returns 0 if successful, < 0 otherwise.. */ +static int ensureCapacity(Array* array, int capacity) { + int oldCapacity = array->capacity; + if (capacity > oldCapacity) { + int newCapacity = (oldCapacity == 0) ? INITIAL_CAPACITY : oldCapacity * 2; + + // Keep doubling capacity until we surpass necessary capacity. + while (newCapacity < capacity) { + newCapacity *= 2; + } + + void** newContents; + if (array->contents == NULL) { + // Allocate new array. + newContents = malloc(newCapacity * sizeof(void*)); + if (newContents == NULL) { + return -1; + } + } else { + // Expand existing array. + newContents = realloc(array->contents, sizeof(void*) * newCapacity); + if (newContents == NULL) { + return -1; + } + } + + array->capacity = newCapacity; + array->contents = newContents; + } + + return 0; +} + +int arrayAdd(Array* array, void* pointer) { + assert(array != NULL); + int size = array->size; + int result = ensureCapacity(array, size + 1); + if (result < 0) { + return result; + } + array->contents[size] = pointer; + array->size++; + return 0; +} + +static inline void checkBounds(Array* array, int index) { + assert(array != NULL); + assert(index < array->size); + assert(index >= 0); +} + +void* arrayGet(Array* array, int index) { + checkBounds(array, index); + return array->contents[index]; +} + +void* arrayRemove(Array* array, int index) { + checkBounds(array, index); + + void* pointer = array->contents[index]; + + int newSize = array->size - 1; + + // Shift entries left. + if (index != newSize) { + memmove(array->contents + index, array->contents + index + 1, + (sizeof(void*)) * (newSize - index)); + } + + array->size = newSize; + + return pointer; +} + +void* arraySet(Array* array, int index, void* pointer) { + checkBounds(array, index); + void* old = array->contents[index]; + array->contents[index] = pointer; + return old; +} + +int arraySetSize(Array* array, int newSize) { + assert(array != NULL); + assert(newSize >= 0); + + int oldSize = array->size; + + if (newSize > oldSize) { + // Expand. + int result = ensureCapacity(array, newSize); + if (result < 0) { + return result; + } + + // Zero out new entries. + memset(array->contents + sizeof(void*) * oldSize, 0, + sizeof(void*) * (newSize - oldSize)); + } + + array->size = newSize; + + return 0; +} + +int arraySize(Array* array) { + assert(array != NULL); + return array->size; +} + +const void** arrayUnwrap(Array* array) { + return array->contents; +} |