summaryrefslogtreecommitdiff
path: root/source4/lib/appweb/ejs-2.0/mpr/mprArray.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/appweb/ejs-2.0/mpr/mprArray.c')
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprArray.c385
1 files changed, 385 insertions, 0 deletions
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprArray.c b/source4/lib/appweb/ejs-2.0/mpr/mprArray.c
new file mode 100644
index 0000000000..95b0a14450
--- /dev/null
+++ b/source4/lib/appweb/ejs-2.0/mpr/mprArray.c
@@ -0,0 +1,385 @@
+/**
+ * @file mprArray.c
+ * @brief Growable array structure
+ * @overview Simple growable array structure.
+ * @remarks Most routines in this file are not thread-safe. It is the callers
+ * responsibility to perform all thread synchronization.
+ */
+
+/*
+ * @copy default
+ *
+ * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
+ *
+ * This software is distributed under commercial and open source licenses.
+ * You may use the GPL open source license described below or you may acquire
+ * a commercial license from Mbedthis Software. You agree to be fully bound
+ * by the terms of either license. Consult the LICENSE.TXT distributed with
+ * this software for full details.
+ *
+ * This software is open source; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See the GNU General Public License for more
+ * details at: http://www.mbedthis.com/downloads/gplLicense.html
+ *
+ * This program is distributed WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * This GPL license does NOT permit incorporating this software into
+ * proprietary programs. If you are unable to comply with the GPL, you must
+ * acquire a commercial license to use this software. Commercial licenses
+ * for this software and support services are available from Mbedthis
+ * Software at http://www.mbedthis.com
+ *
+ * @end
+ */
+
+/********************************** Includes **********************************/
+
+#include "mpr.h"
+
+/******************************************************************************/
+/*
+ * Create a general growable array structure. Use mprFree to destroy.
+ */
+
+MprArray *mprCreateItemArrayInternal(MPR_LOC_DEC(ctx, loc), int initialSize,
+ int maxSize)
+{
+ MprArray *array;
+ int size;
+
+ mprAssert(initialSize <= maxSize);
+
+ array = (MprArray*) mprSlabAllocZeroedBlock(MPR_LOC_PASS(ctx, loc),
+ sizeof(MprArray), 0);
+ if (array == 0) {
+ return 0;
+ }
+
+ if (initialSize == 0) {
+ initialSize = MPR_ARRAY_INCR;
+ }
+ if (maxSize == 0) {
+ maxSize = MAXINT;
+ }
+ size = initialSize * sizeof(void*);
+
+ array->items = (void**) mprSlabAllocBlock(MPR_LOC_PASS(array, loc),
+ size, 0);
+
+ if (array->items == 0) {
+ mprFree(array);
+ return 0;
+ }
+
+ array->capacity = initialSize;
+ array->maxSize = maxSize;
+ array->incr = min(initialSize * 2, (array->maxSize - array->length));
+ array->length = 0;
+
+ return array;
+}
+
+/******************************************************************************/
+/*
+ * Add an item to the array
+ */
+
+int mprAddItem(MprArray *array, void *item)
+{
+ int memsize, index, len;
+
+ mprAssert(array);
+ mprAssert(array->capacity >= 0);
+ mprAssert(array->length >= 0);
+
+ if (array->length < array->capacity) {
+ /*
+ * Room to fit in the current capacity
+ */
+ index = array->length++;
+ array->items[index] = item;
+ return index;
+ }
+ mprAssert(array->length == array->capacity);
+
+ /*
+ * Need to grow the array
+ */
+ if (array->capacity >= array->maxSize) {
+ mprAssert(array->capacity < array->maxSize);
+ return MPR_ERR_TOO_MANY;
+ }
+
+ len = array->capacity + array->incr;
+ memsize = len * sizeof(void*);
+
+ /*
+ * Grow the array of items
+ */
+
+ array->items = (void**) mprRealloc(array, array->items, memsize);
+
+ /*
+ * Zero the new portion
+ */
+ memset(&array->items[array->capacity], 0, sizeof(void*) * array->incr);
+ array->capacity = len;
+
+ array->incr = min(array->incr * 2, (array->maxSize - array->length));
+
+ index = array->length++;
+ array->items[index] = item;
+
+ return index;
+}
+
+/******************************************************************************/
+/*
+ * Remove an item from the array
+ */
+
+int mprRemoveItem(MprArray *array, void *item)
+{
+ int index;
+
+ mprAssert(array);
+ mprAssert(array->capacity > 0);
+ mprAssert(array->length > 0);
+
+ index = mprFindItem(array, item);
+ if (index < 0) {
+ return index;
+ }
+
+ return mprRemoveItemByIndex(array, index);
+}
+
+/******************************************************************************/
+/*
+ * Remove an index from the array
+ */
+
+int mprRemoveItemByIndex(MprArray *array, int index)
+{
+ void **items;
+ int i;
+
+ mprAssert(array);
+ mprAssert(array->capacity > 0);
+ mprAssert(index >= 0 && index < array->capacity);
+ mprAssert(array->items[index] != 0);
+ mprAssert(array->length > 0);
+
+ if (index < 0 || index >= array->length) {
+ return MPR_ERR_NOT_FOUND;
+ }
+
+ /*
+ * Copy down to compress
+ */
+ items = array->items;
+ for (i = index; i < (array->length - 1); i++) {
+ items[i] = items[i + 1];
+ }
+ array->length--;
+
+#if BLD_DEBUG
+ if (array->length < array->capacity) {
+ items[array->length] = 0;
+ }
+#endif
+ return 0;
+}
+
+/******************************************************************************/
+
+int mprRemoveRangeOfItems(MprArray *array, int start, int end)
+{
+ void **items;
+ int i, count;
+
+ mprAssert(array);
+ mprAssert(array->capacity > 0);
+ mprAssert(array->length > 0);
+ mprAssert(start > end);
+
+ if (start < 0 || start >= array->length) {
+ return MPR_ERR_NOT_FOUND;
+ }
+ if (end < 0 || end >= array->length) {
+ return MPR_ERR_NOT_FOUND;
+ }
+ if (start > end) {
+ return MPR_ERR_BAD_ARGS;
+ }
+
+ /*
+ * Copy down to compress
+ */
+ items = array->items;
+ count = end - start;
+ for (i = start; i < (array->length - count); i++) {
+ items[i] = items[i + count];
+ }
+ array->length -= count;
+
+#if BLD_DEBUG
+ if (array->length < array->capacity) {
+ for (i = array->length; i < array->capacity; i++) {
+ items[i] = 0;
+ }
+ }
+#endif
+ return 0;
+}
+
+/******************************************************************************/
+
+void *mprGetItem(MprArray *array, int index)
+{
+ mprAssert(array);
+
+ if (index < 0 || index >= array->length) {
+ return 0;
+ }
+ return array->items[index];
+}
+
+/******************************************************************************/
+
+void *mprGetFirstItem(MprArray *array, int *last)
+{
+ mprAssert(array);
+ mprAssert(last);
+
+ if (array == 0) {
+ return 0;
+ }
+
+ *last = 0;
+
+ if (array->length == 0) {
+ return 0;
+ }
+ return array->items[0];
+}
+
+/******************************************************************************/
+
+void *mprGetNextItem(MprArray *array, int *last)
+{
+ int index;
+
+ mprAssert(array);
+ mprAssert(last);
+ mprAssert(*last >= 0);
+
+ index = *last;
+
+ if (++index < array->length) {
+ *last = index;
+ return array->items[index];
+ }
+ return 0;
+}
+
+/******************************************************************************/
+
+void *mprGetPrevItem(MprArray *array, int *last)
+{
+ int index;
+
+ mprAssert(array);
+ mprAssert(last);
+ mprAssert(*last >= 0);
+
+ if (array == 0) {
+ return 0;
+ }
+
+ index = *last;
+
+ if (--index < array->length && index >= 0) {
+ *last = index;
+ return array->items[index];
+ }
+ return 0;
+}
+
+/******************************************************************************/
+
+int mprGetItemCount(MprArray *array)
+{
+ mprAssert(array);
+
+ if (array == 0) {
+ return 0;
+ }
+
+ return array->length;
+}
+
+/******************************************************************************/
+
+int mprGetItemCapacity(MprArray *array)
+{
+ mprAssert(array);
+
+ if (array == 0) {
+ return 0;
+ }
+
+ return array->capacity;
+}
+
+/******************************************************************************/
+
+void mprClearAndFreeItems(MprArray *array)
+{
+ int i;
+
+ mprAssert(array);
+
+ for (i = 0; i < array->length; i++) {
+ mprFree(array->items[i]);
+ }
+}
+
+/******************************************************************************/
+
+void mprClearItems(MprArray *array)
+{
+ mprAssert(array);
+
+ array->length = 0;
+}
+
+/******************************************************************************/
+
+int mprFindItem(MprArray *array, void *item)
+{
+ int i;
+
+ mprAssert(array);
+
+ for (i = 0; i < array->length; i++) {
+ if (array->items[i] == item) {
+ return i;
+ }
+ }
+ return MPR_ERR_NOT_FOUND;
+}
+
+/******************************************************************************/
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim:tw=78
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */