summaryrefslogtreecommitdiff
path: root/ckcapi-util.c
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2007-04-27 03:19:46 +0000
committerStef Walter <stef@memberwebs.com>2007-04-27 03:19:46 +0000
commit3d8ed01d2653c45e52821ba00ac72099a12600e1 (patch)
treead13d6df465ef1a4f143109f04c35991ddb1efba /ckcapi-util.c
Diffstat (limited to 'ckcapi-util.c')
-rw-r--r--ckcapi-util.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/ckcapi-util.c b/ckcapi-util.c
new file mode 100644
index 0000000..d8d182b
--- /dev/null
+++ b/ckcapi-util.c
@@ -0,0 +1,167 @@
+
+#include "cryptoki-capi-util.h"
+
+#include <string.h>
+
+
+
+
+
+#define MIN_ARRAY_SIZE 16
+
+typedef struct _RealArray
+{
+ Array pub;
+ size_t alloc;
+ size_t elt_size;
+ int zero_terminated : 1;
+ int clear : 1;
+}
+RealArray;
+
+#define array_elt_len(array, i) ((array)->elt_size * (i))
+#define array_elt_pos(array, i) (((char*)(array)->pub.data) + array_elt_len((array),(i)))
+#define array_elt_zero(array, pos, len) \
+ (memset(array_elt_pos((array), pos), 0, array_elt_len((array), len)))
+#define array_zero_terminate(array) \
+ { if ((array)->zero_terminated) \
+ array_elt_zero((array), (array)->pub.len, 1); }
+
+static unsigned int
+nearest_pow(unsigned int num)
+{
+ unsigned int n = 1;
+ while(n < num)
+ n <<= 1;
+ return n;
+}
+
+static int
+maybe_expand(RealArray *array, size_t len)
+{
+ void* mem;
+ size_t want_alloc = array_elt_len(array, array->pub.len + len +
+ array->zero_terminated);
+
+ if(want_alloc > array->alloc)
+ {
+ want_alloc = nearest_pow(want_alloc);
+ want_alloc = want_alloc > MIN_ARRAY_SIZE ? want_alloc : MIN_ARRAY_SIZE;
+
+ mem = realloc(array->pub.data, want_alloc);
+ if(!mem)
+ return 0;
+ array->pub.data = mem;
+
+ memset((char*)array->pub.data + array->alloc, 0, want_alloc - array->alloc);
+ array->alloc = want_alloc;
+ }
+
+ return 1;
+}
+
+Array*
+ckcapi_util_array_new(int zero_terminated, int clear, size_t elt_size)
+{
+ return ckcapi_util_array_sized_new(zero_terminated, clear, elt_size, 0);
+}
+
+Array*
+ckcapi_util_array_sized_new(int zero_terminated, int clear, size_t elt_size,
+ size_t reserved_size)
+{
+ RealArray *array = malloc(sizeof(RealArray));
+ if(!array)
+ return NULL;
+
+ array->pub.data = NULL;
+ array->pub.len = 0;
+ array->alloc = 0;
+ array->zero_terminated = (zero_terminated ? 1 : 0);
+ array->clear = (clear ? 1 : 0);
+ array->elt_size = elt_size;
+
+ if(array->zero_terminated || reserved_size != 0)
+ {
+ maybe_expand(array, reserved_size);
+ array_zero_terminate(array);
+ }
+
+ return (Array*)array;
+}
+
+void*
+ckcapi_util_array_free(Array* array, int free_segment)
+{
+ void* segment;
+
+ if(array == NULL)
+ return NULL;
+
+ if(free_segment)
+ {
+ free(array->data);
+ segment = NULL;
+ }
+ else
+ segment = array->data;
+
+ free(array);
+ return segment;
+}
+
+int
+ckcapi_util_array_append_vals(Array* parray, const void* data, size_t len)
+{
+ RealArray* array = (RealArray*)parray;
+ if(!maybe_expand(array, len))
+ return 0;
+
+ memcpy(array_elt_pos(array, array->pub.len), data,
+ array_elt_len(array, len));
+
+ array->pub.len += len;
+ array_zero_terminate(array);
+
+ return 1;
+}
+
+void
+ckcapi_util_array_remove_index(Array* parray, unsigned int index)
+{
+ RealArray* array = (RealArray*)parray;
+
+ if(index >= array->pub.len)
+ return;
+
+ if(index != array->pub.len - 1)
+ memmove(array_elt_pos (array, index),
+ array_elt_pos (array, index + 1),
+ array_elt_len (array, array->pub.len - index - 1));
+
+ array->pub.len -= 1;
+
+ array_elt_zero (array, array->pub.len, 1);
+}
+
+void
+ckcapi_util_array_remove_range(Array* parray, unsigned int index, size_t length)
+{
+ RealArray *array = (RealArray*)parray;
+
+ if(index >= array->pub.len)
+ return;
+ if(index + length > array->pub.len);
+ length = array->pub.len - index;
+ if(length == 0)
+ return;
+
+ if(index + length != array->pub.len)
+ memmove(array_elt_pos (array, index),
+ array_elt_pos (array, index + length),
+ (array->pub.len - (index + length)) * array->elt_size);
+
+ array->pub.len -= length;
+ array_elt_zero(array, array->pub.len, length);
+}
+