aboutsummaryrefslogtreecommitdiffstats
path: root/longbow/src/LongBow/private
diff options
context:
space:
mode:
Diffstat (limited to 'longbow/src/LongBow/private')
-rwxr-xr-xlongbow/src/LongBow/private/longBow_ArrayList.c277
-rw-r--r--longbow/src/LongBow/private/longBow_ArrayList.h225
-rw-r--r--longbow/src/LongBow/private/longBow_Memory.c95
-rwxr-xr-xlongbow/src/LongBow/private/longBow_Memory.h93
-rw-r--r--longbow/src/LongBow/private/longBow_OpenFile.c151
-rwxr-xr-xlongbow/src/LongBow/private/longBow_OpenFile.h70
-rw-r--r--longbow/src/LongBow/private/longBow_String.c180
-rwxr-xr-xlongbow/src/LongBow/private/longBow_String.h151
8 files changed, 1242 insertions, 0 deletions
diff --git a/longbow/src/LongBow/private/longBow_ArrayList.c b/longbow/src/LongBow/private/longBow_ArrayList.c
new file mode 100755
index 00000000..91cf02b9
--- /dev/null
+++ b/longbow/src/LongBow/private/longBow_ArrayList.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * 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 <config.h>
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include <LongBow/runtime.h>
+#include <LongBow/private/longBow_ArrayList.h>
+#include <LongBow/private/longBow_Memory.h>
+
+struct longbow_array_list {
+ void **array;
+ size_t numberOfElements;
+ size_t limit;
+ void (*destroyElement)(void **elementAddress);
+};
+
+static LongBowArrayList *_longBowArrayList_EnsureRemaining(LongBowArrayList *array, size_t remnant);
+static LongBowArrayList *_longBowArrayList_EnsureCapacity(LongBowArrayList *array, size_t newCapacity);
+
+void
+longBowArrayList_AssertValid(const LongBowArrayList *array)
+{
+ if (array == NULL) {
+ printf("Parameter must be a non-null pointer to a LongBowArrayList instance\n");
+ abort();
+ }
+}
+
+LongBowArrayList *
+longBowArrayList_Add(LongBowArrayList *array, const void *pointer)
+{
+ longBowArrayList_AssertValid(array);
+
+ if (_longBowArrayList_EnsureRemaining(array, 1) == NULL) {
+ return NULL;
+ }
+ array->array[array->numberOfElements++] = (void *) pointer;
+
+ return array;
+}
+
+static size_t
+_longBowArrayList_Remaining(const LongBowArrayList *array)
+{
+ longBowArrayList_AssertValid(array);
+
+ return array->limit - array->numberOfElements;
+}
+
+static LongBowArrayList *
+_longBowArrayList_EnsureCapacity(LongBowArrayList *array, size_t newCapacity)
+{
+ longBowArrayList_AssertValid(array);
+
+ void *newArray = longBowMemory_Reallocate(array->array, newCapacity * sizeof(void *));
+
+ if (newArray == NULL) {
+ return NULL;
+ }
+ array->array = newArray;
+ array->limit = newCapacity;
+
+ return array;
+}
+
+static LongBowArrayList *
+_longBowArrayList_EnsureRemaining(LongBowArrayList *array, size_t remnant)
+{
+ longBowArrayList_AssertValid(array);
+
+ if (_longBowArrayList_Remaining(array) < remnant) {
+ size_t newCapacity = longBowArrayList_Length(array) + remnant;
+ return _longBowArrayList_EnsureCapacity(array, newCapacity);
+ }
+ return array;
+}
+
+bool
+longBowArrayList_Equals(const LongBowArrayList *a, const LongBowArrayList *b)
+{
+ if (a != b) {
+ if (a == NULL || b == NULL) {
+ return false;
+ }
+ if (a->numberOfElements == b->numberOfElements) {
+ for (size_t i = 0; i < a->numberOfElements; i++) {
+ if (a->array[i] != b->array[i]) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+void *
+longBowArrayList_Get(const LongBowArrayList *array, size_t index)
+{
+ longBowArrayList_AssertValid(array);
+
+ assert(index < array->numberOfElements);
+
+ return array->array[index];
+}
+
+size_t
+longBowArrayList_Length(const LongBowArrayList *array)
+{
+ longBowArrayList_AssertValid(array);
+
+ return array->numberOfElements;
+}
+
+LongBowArrayList *
+longBowArrayList_Create(void (*destroyElement)(void **elementAddress))
+{
+ LongBowArrayList *result = longBowMemory_Allocate(sizeof(LongBowArrayList));
+
+ if (result != NULL) {
+ result->numberOfElements = 0;
+ result->limit = 0;
+ result->array = NULL;
+ result->destroyElement = destroyElement;
+ }
+
+ return result;
+}
+
+LongBowArrayList *
+longBowArrayList_Create_Capacity(void (*destroyElement)(void **elementAddress), size_t size)
+{
+ LongBowArrayList *result = longBowArrayList_Create(destroyElement);
+ if (result != NULL) {
+ _longBowArrayList_EnsureRemaining(result, size);
+ }
+
+ return result;
+}
+
+void
+longBowArrayList_Destroy(LongBowArrayList **arrayPtr)
+{
+ assertNotNull(arrayPtr, "Parameter must be a non-null pointer to a LongBow_ArrayList pointer.");
+
+ LongBowArrayList *array = *arrayPtr;
+
+ longBowArrayList_AssertValid(array);
+
+ assertTrue(array->numberOfElements == 0 ? true : array->array != NULL, "LongBow_ArrayList is inconsistent.");
+
+ if (array->destroyElement != NULL) {
+ for (size_t i = 0; i < array->numberOfElements; i++) {
+ array->destroyElement(&array->array[i]);
+ array->array[i] = NULL;
+ }
+ }
+
+ if (array->array != NULL) {
+ longBowMemory_Deallocate((void **) &array->array);
+ }
+
+ longBowMemory_Deallocate((void **) arrayPtr);
+}
+
+void **
+longBowArrayList_GetArray(const LongBowArrayList *array)
+{
+ longBowArrayList_AssertValid(array);
+ return array->array;
+}
+
+LongBowArrayList *
+longBowArrayList_Copy(const LongBowArrayList *original)
+{
+ longBowArrayList_AssertValid(original);
+
+ LongBowArrayList *result = longBowMemory_Allocate(sizeof(LongBowArrayList));
+
+ if (result != NULL) {
+ for (size_t i = 0; i < original->numberOfElements; i++) {
+ longBowArrayList_Add(result, original->array[i]);
+ }
+ }
+
+ return result;
+}
+
+void
+longBowArrayList_StdlibFreeFunction(void **elementPtr)
+{
+ if (elementPtr != NULL) {
+ free(*elementPtr);
+ *elementPtr = 0;
+ }
+}
+
+LongBowArrayList *
+longBowArrayList_RemoveAtIndex(LongBowArrayList *array, size_t index)
+{
+ longBowArrayList_AssertValid(array);
+
+ size_t length = longBowArrayList_Length(array);
+ assertTrue(index < length, "Index must be ( 0 <= index < %zd). Actual=%zd", length, index);
+
+ if (index < length) {
+ // Destroy the element at the given index.
+ if (array->destroyElement != NULL) {
+ array->destroyElement(&array->array[index]);
+ }
+
+ // Adjust the list to elide the element.
+ for (size_t i = index; i < length; i++) {
+ array->array[i] = array->array[i + 1];
+ }
+ array->numberOfElements--;
+ }
+
+ return array;
+}
+
+LongBowArrayList *
+longBowArrayList_Add_AtIndex(LongBowArrayList *array, const void *pointer, size_t index)
+{
+ longBowArrayList_AssertValid(array);
+ size_t length = longBowArrayList_Length(array);
+
+ if (index > array->limit) {
+ // We need to grow the array to fit this element.
+ _longBowArrayList_EnsureCapacity(array, index + 1);
+ array->numberOfElements = index + 1;
+ } else {
+ // Create space and grow the array if needed
+ _longBowArrayList_EnsureRemaining(array, length + 1);
+ for (size_t i = index; i < length; i++) {
+ array->array[i + 1] = array->array[i];
+ }
+ array->numberOfElements++;
+ }
+
+ array->array[index] = (void *) pointer;
+
+
+ return array;
+}
+
+bool
+longBowArrayList_Replace(LongBowArrayList *array, const void *old, void *new)
+{
+ for (size_t i = 0; i < longBowArrayList_Length(array); i++) {
+ if (array->array[i] == old) {
+ array->array[i] = new;
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/longbow/src/LongBow/private/longBow_ArrayList.h b/longbow/src/LongBow/private/longBow_ArrayList.h
new file mode 100644
index 00000000..71eeb2b9
--- /dev/null
+++ b/longbow/src/LongBow/private/longBow_ArrayList.h
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * 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.
+ */
+
+/**
+ * @file longBow_ArrayList.h
+ * @ingroup internals
+ * @brief A simple, list implementation using a dynamic array.
+ *
+ */
+#ifndef LongBow_ARRAYLIST_H
+#define LongBow_ARRAYLIST_H
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+/**
+ * @struct longbow_array_list
+ * @brief A LongBow_ArrayList is a (dynamic) array of <code>void *</code> pointers;
+ */
+struct longbow_array_list;
+
+/**
+ * @typedef LongBowArrayList
+ * @brief The struct longbow_array_list
+ */
+typedef struct longbow_array_list LongBowArrayList;
+
+/**
+ * Assert that a LongBowArrayList instance is valid.
+ *
+ * @param [in] array A pointer to a valid LongBowArrayList instance.
+ *
+ */
+void longBowArrayList_AssertValid(const LongBowArrayList *array);
+/**
+ * Add a pointer to an element to the given LongBowArrayList.
+ *
+ * If the list was constructed with a destroyer,
+ * the pointer will be destroyed when element is removed or the list is destroyed.
+ *
+ * @param [in] array A pointer to a LongBowArrayList instance.
+ * @param [in] pointer An arbitrary value to store.
+ *
+ * @return The input array pointer.
+ */
+LongBowArrayList *longBowArrayList_Add(LongBowArrayList *array, const void *pointer);
+
+/**
+ * Remove an element at a specific index from an Array List.
+ *
+ * The element is destroyed via the function provided when calling <code>longBowArrayList_Create</code>.
+ *
+ * @param [in] array A pointer to a LongBowArrayList instance.
+ * @param [in] index The index of the element to remove.
+ *
+ * @return A pointer to the modified LongBowArrayList.
+ */
+LongBowArrayList *longBowArrayList_RemoveAtIndex(LongBowArrayList *array, size_t index);
+
+/**
+ * Add an element at the index location. Elements will be moved up if required.
+ * If the index is higher than the current Length the Array will be grown to that size
+ *
+ * @param [in] array A pointer to a LongBowArrayList instance.
+ * @param [in] pointer An arbitrary value to store.
+ * @param [in] index The position that the value will be stored after.
+ * @return A pointer to the modified LongBowArrayList.
+ */
+LongBowArrayList *longBowArrayList_Add_AtIndex(LongBowArrayList *array, const void *pointer, size_t index);
+
+/**
+ * Create an instance of an empty LongBowArrayList.
+ *
+ * @param [in] destroyElement
+ * A pointer to a function that will destroy (or equivalent) the element pointed to by <code>element</code>
+ * @return A pointer to a LongBowArrayList instance, or NULL if no memory could be allocated.
+ */
+LongBowArrayList *longBowArrayList_Create(void (*destroyElement)(void **elementAddress));
+
+/**
+ * Create an instance of a LongBowArrayList pre-provisioned to contain the specified number of elements.
+ *
+ * @param [in] size
+ * The number of initial elements to provision for.
+ * @param [in] destroyElement
+ * A pointer to a function that will destroy (or equivalent) the element pointed to by <code>element</code>
+ * @return A pointer to a LongBowArrayList instance, or NULL if no memory could be allocated.
+ */
+LongBowArrayList *longBowArrayList_Create_Capacity(void (*destroyElement)(void **elementAddress), size_t size);
+
+/**
+ * Get an array of void * pointers.
+ * Return a pointer to an array of void * pointers contained in this Array List.
+ * The returned value may be the actual backing array for the Array List.
+ *
+ * @param [in] array The LongBow_ArrayList
+ * @return A pointer to an array of void * pointers contained in this Array List.
+ *
+ */
+void **longBowArrayList_GetArray(const LongBowArrayList *array);
+
+/**
+ * Copy a LongBowArrayList instance.
+ * Create a new LongBowArrayList instance with the same structure and content as the original.
+ *
+ * @param [in] array A pointer to a LongBowArrayList instance to copy.
+ * @return A pointer to a LongBowArrayList instance with a copy of the original, or NULL if no memory could be allocated.
+ */
+LongBowArrayList *longBowArrayList_Copy(const LongBowArrayList *array);
+
+/**
+ * Destroy a LongBowArrayList instance.
+ *
+ * Destroy the given LongBowArrayList by freeing all memory used by it.
+ *
+ * @param [in,out] arrayPtr A pointer to a LongBowArrayList pointer.
+ */
+void longBowArrayList_Destroy(LongBowArrayList **arrayPtr);
+
+/**
+ * Get an element from the given list at a specified index.
+ * The index must be 0 <= index < length.
+ *
+ * @return A pointer (void *) to the element in the list.
+ *
+ * @param [in] array A pointer to a LongBowArrayList instance.
+ * @param [in] index The index of the required element.
+ */
+void *longBowArrayList_Get(const LongBowArrayList *array, size_t index);
+
+/**
+ * Return the number of elements in the given LongBowArrayList.
+ *
+ * @param [in] array A pointer to a LongBowArrayList instance.
+ * @return A size_t of the number of elements in the given LongBowArrayList.
+ */
+size_t longBowArrayList_Length(const LongBowArrayList *array);
+
+
+/**
+ * Determine if two LongBowArrayList instances are equal.
+ *
+ * Two LongBowArrayList instances are equal if, and only if, they both contain the same pointers in the same order.
+ *
+ * The following equivalence relations on non-null `LongBowArrayList` instances are maintained:
+ *
+ * * It is reflexive: for any non-null reference value x, `LongBowArrayList_Equals(x, x)`
+ * must return true.
+ *
+ * * It is symmetric: for any non-null reference values x and y,
+ * `longBowArrayList_Equals(x, y)` must return true if and only if
+ * `longBowArrayList_Equals(y, x)` returns true.
+ *
+ * * It is transitive: for any non-null reference values x, y, and z, if
+ * `longBowArrayList_Equals(x, y)` returns true and
+ * `longBowArrayList_Equals(y, z)` returns true,
+ * then `longBowArrayList_Equals(x, z)` must return true.
+ *
+ * * It is consistent: for any non-null reference values x and y, multiple
+ * invocations of `longBowArrayList_Equals(x, y)` consistently return true or
+ * consistently return false.
+ *
+ * * For any non-null reference value x, `longBowArrayList_Equals(x, NULL)` must
+ * return false.
+ *
+ * @param a A pointer to a `LongBowArrayList` instance.
+ * @param b A pointer to a `LongBowArrayList` instance.
+ * @return true if the two `LongBowArrayList` instances are equal.
+ *
+ * Example:
+ * @code
+ * {
+ * LongBowArrayList *a = longBowArrayList_Create();
+ * LongBowArrayList *b = longBowArrayList_Create();
+ *
+ * if (longBowArrayList_Equals(a, b)) {
+ * // true
+ * } else {
+ * // false
+ * }
+ * }
+ * @endcode
+ */
+
+bool longBowArrayList_Equals(const LongBowArrayList *a, const LongBowArrayList *b);
+
+/**
+ * Standard library free(3) wrapper for use as a destructor function for elements of a LongBowArrayList.
+ *
+ * The create functions for LongBowArrayList have an input parameter that is a pointer to a function that
+ * will be called for each element when the Array List is destroyed, and when an element is removed via longBowArrayList_RemoveAtIndex.
+ * This destroy function has a different calling signature than the standard library's free(3) function.
+ * This function is a wrapper providing the correct facade for the standard library free(3) function.
+ *
+ * @param [in,out] element A pointer to the pointer to an element to be destroyed.
+ */
+void longBowArrayList_StdlibFreeFunction(void **element);
+
+/**
+ * Replace the first occurance of an existing element in the given LongBowArrayList.
+ *
+ * Paragraphs Of Explanation
+ *
+ * @param [in] array A pointer to a LongBowArrayList instance.
+ * @param [in] old A pointer to an element in the list to replace.
+ * @param [in] new A pointer to an element that will replace old.
+ *
+ * @return true If the element was found and replaced.
+ * @return false If the element was not found.
+ */
+bool longBowArrayList_Replace(LongBowArrayList *array, const void *old, void *new);
+#endif // LongBow_ARRAYLIST_H
diff --git a/longbow/src/LongBow/private/longBow_Memory.c b/longbow/src/LongBow/private/longBow_Memory.c
new file mode 100644
index 00000000..1c20101e
--- /dev/null
+++ b/longbow/src/LongBow/private/longBow_Memory.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * 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 <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <LongBow/private/longBow_Memory.h>
+
+#if HAVE_REALLOC == 0
+static void *
+_LongBow_rplRealloc(void *oldAlloc, size_t newSize)
+{
+ if (newSize == 0) {
+ newSize = 1;
+ }
+
+ char *newAlloc = malloc(newSize);
+
+ if (oldAlloc != NULL) {
+ memcpy(newAlloc, oldAlloc, newSize);
+ free(oldAlloc);
+ }
+ return newAlloc;
+}
+#endif
+
+static uint64_t _outstandingAllocations;
+
+void *
+longBowMemory_Allocate(const size_t size)
+{
+ _outstandingAllocations++;
+ return calloc(1, size);
+}
+
+void *
+longBowMemory_Reallocate(void *oldAllocation, const size_t newSize)
+{
+#if HAVE_REALLOC
+ void *result = realloc(oldAllocation, newSize);
+#else
+ void *result = _LongBow_rplRealloc(oldAllocation, newSize);
+#endif
+
+ if (oldAllocation == NULL) {
+ _outstandingAllocations++;
+ }
+
+ return result;
+}
+
+void
+longBowMemory_Deallocate(void **pointerPointer)
+{
+ free(*pointerPointer);
+ _outstandingAllocations--;
+ *pointerPointer = NULL;
+}
+
+uint64_t
+longBowMemory_OutstandingAllocations(void)
+{
+ return _outstandingAllocations;
+}
+
+char *
+longBowMemory_StringCopy(const char *string)
+{
+ char *result = NULL;
+
+ if (string != NULL) {
+ size_t length = strlen(string);
+ result = longBowMemory_Allocate(length + 1);
+ strcpy(result, string);
+ result[length] = 0;
+ }
+ return result;
+}
diff --git a/longbow/src/LongBow/private/longBow_Memory.h b/longbow/src/LongBow/private/longBow_Memory.h
new file mode 100755
index 00000000..173491dc
--- /dev/null
+++ b/longbow/src/LongBow/private/longBow_Memory.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * 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.
+ */
+
+/**
+ * @file longBow_Memory.c
+ * @ingroup internal
+ * @brief Memory allocation and deallocation support.
+ *
+ */
+#ifndef LongBow_longBow_Memory_h
+#define LongBow_longBow_Memory_h
+
+#include <stdint.h>
+
+/**
+ * Allocate `size` bytes of memory.
+ *
+ * @param [in] size The number of bytes to allocate
+ *
+ * @return non-NULL A pointer to allocated memory that must be deallocated via `longBowMemory_Deallocate`
+ * @return NULL Memory could not be allocated.
+ * @see longBowMemory_Deallocate
+ */
+void *longBowMemory_Allocate(const size_t size);
+
+/**
+ * Reallocate memory adjusting to a new size.
+ *
+ * @param [in] oldAllocation A pointer to memory previously allocated by `longBowMemory_Allocate` or `longBowMemory_Reallocate`
+ * @param [in] newSize The number of bytes to allocate
+ *
+ * @return non-NULL A pointer to allocated memory that must be deallocated via `longBowMemory_Deallocate`
+ * @return NULL Memory could not be allocated.
+ * @see longBowMemory_Allocate
+ */
+void *longBowMemory_Reallocate(void *oldAllocation, const size_t newSize);
+
+/**
+ * Deallocate previously allocated memory.
+ *
+ * @param [in,out] pointerPointer A pointer to a pointer to allocated memory that will set to NULL.
+ *
+ * @see longBowMemory_Allocate
+ */
+void longBowMemory_Deallocate(void **pointerPointer);
+
+/**
+ * Duplicate a nul-terminated C string in allocated memory.
+ *
+ * @param [in] string The nul-terminated string to duplicate
+ *
+ * @return non-NULL A pointer to allocated memory that must be deallocated via `longBowMemory_Deallocate`
+ * @return NULL Memory could not be allocated.
+ *
+ * Example:
+ * @code
+ * {
+ * char *copy = longBowMemory_StringCopy("Hello World");
+ *
+ * longBowMemory_Deallocate((void **) &copy);
+ * }
+ * @endcode
+ *
+ * @see longBowMemory_Deallocate
+ */
+char *longBowMemory_StringCopy(const char *string);
+
+/**
+ * Get the count of outstanding memory allocations.
+ *
+ * @return The number of outstanding memory allocations.
+ *
+ * Example:
+ * @code
+ * {
+ * <#example#>
+ * }
+ * @endcode
+ */
+uint64_t longBowMemory_OutstandingAllocations(void);
+#endif
diff --git a/longbow/src/LongBow/private/longBow_OpenFile.c b/longbow/src/LongBow/private/longBow_OpenFile.c
new file mode 100644
index 00000000..6b82069f
--- /dev/null
+++ b/longbow/src/LongBow/private/longBow_OpenFile.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * 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 <config.h>
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <poll.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/param.h>
+#include <sys/resource.h>
+#include <string.h>
+
+#include <LongBow/private/longBow_OpenFile.h>
+#include <LongBow/private/longBow_Memory.h>
+#include <LongBow/private/longBow_String.h>
+
+struct longbow_openfile {
+ char *fullPathName;
+ struct stat statbuf;
+ int fd;
+};
+
+#if defined(_WIN64)
+static char *
+_getFullPathNameFromFd(int fd)
+{
+ return strdup("./");
+}
+#elif defined(_WIN32)
+static char *
+_getFullPathNameFromFd(int fd)
+{
+ return strdup("./");
+}
+#elif defined(__APPLE__)
+static char *
+_getFullPathNameFromFd(int fd)
+{
+ char filePath[PATH_MAX];
+
+ if (fcntl(fd, F_GETPATH, filePath) != -1) {
+ return strdup(filePath);
+ }
+ return NULL;
+}
+#elif defined(__linux)
+static char *
+_getFullPathNameFromFd(int fd)
+{
+ return strdup("./");
+}
+#elif defined(__unix) // all unices not caught above
+static char *
+_getFullPathNameFromFd(int fd)
+{
+ return strdup("./");
+}
+#elif defined(__posix)
+static char *
+_getFullPathNameFromFd(int fd)
+{
+ return strdup("./");
+}
+#endif
+
+LongBowOpenFile *
+longBowOpenFile_Create(int fd)
+{
+ LongBowOpenFile *result = longBowMemory_Allocate(sizeof(LongBowOpenFile));
+ if (result != NULL) {
+ result->fd = fd;
+
+ if (fstat(fd, &result->statbuf) == 0) {
+ result->fullPathName = _getFullPathNameFromFd(fd);
+ }
+ }
+ return result;
+}
+
+void
+longBowOpenFile_Destroy(LongBowOpenFile **openFilePtr)
+{
+ longBowMemory_Deallocate((void **) openFilePtr);
+}
+
+char *
+longBowOpenFile_StructStatToString(const struct stat *statbuf)
+{
+ LongBowString *string = longBowString_CreateFormat("0x%" PRIx16 " %3ld %10d %10d %6lld",
+ statbuf->st_mode,
+ (long) statbuf->st_nlink,
+ statbuf->st_uid,
+ statbuf->st_gid,
+ (long long) statbuf->st_size);
+ char *result = longBowString_ToString(string);
+
+ return result;
+}
+
+char *
+longBowOpenFile_ToString(LongBowOpenFile *openFile)
+{
+ char *statString = longBowOpenFile_StructStatToString(&(openFile->statbuf));
+ LongBowString *string = longBowString_CreateFormat("%d %s %s", openFile->fd, statString, openFile->fullPathName);
+ free(statString);
+ char *result = longBowString_ToString(string);
+
+ return result;
+}
+
+LongBowArrayList *
+longBowOpenFile_CurrentlyOpen(void)
+{
+ struct rlimit rlimit;
+
+ bool success = getrlimit(RLIMIT_NOFILE, &rlimit) == 0;
+ if (!success) {
+ return NULL;
+ }
+ // Here is a potential problem: struct rlimit specifies rlim_cur as a 64 bit value (rlim_t), but poll only takes an
+ // unsigned int's worth of file descriptors.
+
+ LongBowArrayList *list = longBowArrayList_Create(longBowArrayList_StdlibFreeFunction);
+
+ for (nfds_t i = 0; i < (nfds_t) rlimit.rlim_cur; i++) {
+ int flags = fcntl((int) i, F_GETFD);
+ if (flags != -1) {
+ LongBowOpenFile *openFile = longBowOpenFile_Create((int) i);
+ longBowArrayList_Add(list, openFile);
+ }
+ }
+
+ return list;
+}
diff --git a/longbow/src/LongBow/private/longBow_OpenFile.h b/longbow/src/LongBow/private/longBow_OpenFile.h
new file mode 100755
index 00000000..10756ba5
--- /dev/null
+++ b/longbow/src/LongBow/private/longBow_OpenFile.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * 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.
+ */
+
+/**
+ * @file longBow_OpenFile.h
+ * @ingroup testing
+ * @brief LongBow support for files and file descriptors.
+ *
+ */
+#ifndef LongBow_longBow_Files_h
+#define LongBow_longBow_Files_h
+
+#include <sys/stat.h>
+
+#include <LongBow/private/longBow_ArrayList.h>
+
+struct longbow_openfile;
+/**
+ * @typedef LongBowOpenFile
+ * @brief A representation of an open file.
+ */
+typedef struct longbow_openfile LongBowOpenFile;
+
+/**
+ * @param [in] fd The file descriptor.
+ * @return An allocated LongBowOpenFile instance that must be destroyed via longBowOpenFile_Destroy().
+ */
+LongBowOpenFile *longBowOpenFile_Create(int fd);
+
+/**
+ *
+ * @param [in,out] openFilePtr A pointer to a pointer to a valid LongBowOpenFile instance.
+ */
+void longBowOpenFile_Destroy(LongBowOpenFile **openFilePtr);
+
+/**
+ *
+ * @param [in] openFile A pointer to a valid LongBowOpenFile instance.
+ * @return A nul-terminate C string that must be freed via free(3).
+ */
+char *longBowOpenFile_ToString(LongBowOpenFile *openFile);
+
+/**
+ * Create a list of the currently open files.
+ *
+ * @return A list of LongBowOpenFile instances for each open file.
+ */
+LongBowArrayList *longBowOpenFile_CurrentlyOpen(void);
+
+/**
+ * Return a nul-terminated C string representing the given `struct stat` pointed to by @p statbuf.
+ *
+ * @param [in] statbuf A pointer to a valid `struct stat` instance.
+ *
+ * @return non-NULL A nul-terminated C string that must be deallocated via longBowMemory_Deallocate.
+ */
+char *longBowOpenFile_StructStatToString(const struct stat *statbuf);
+#endif
diff --git a/longbow/src/LongBow/private/longBow_String.c b/longbow/src/LongBow/private/longBow_String.c
new file mode 100644
index 00000000..1def87a1
--- /dev/null
+++ b/longbow/src/LongBow/private/longBow_String.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * 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 "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include <LongBow/private/longBow_String.h>
+#include <LongBow/private/longBow_Memory.h>
+
+struct longbow_string {
+ char *buffer;
+ size_t cursor; // always the index of the nul terminating byte of the stored string.
+ size_t end; // always the index of the very last byte in buffer;
+};
+
+static size_t
+_longBowString_RemainingSpace(const LongBowString *string)
+{
+ size_t result = string->end - string->cursor;
+
+ return result;
+}
+
+LongBowString *
+longBowString_Create(const size_t initialSize)
+{
+ LongBowString *result = longBowMemory_Allocate(sizeof(LongBowString));
+ result->end = initialSize;
+ result->buffer = longBowMemory_Allocate(initialSize);
+ result->cursor = 0;
+
+ return result;
+}
+
+LongBowString *
+longBowString_CreateString(const char *string)
+{
+ LongBowString *result = longBowMemory_Allocate(sizeof(LongBowString));
+ result->end = strlen(string) + 1;
+ result->buffer = longBowMemory_StringCopy(string);
+ result->cursor = result->end - 1;
+ result->buffer[result->cursor] = 0;
+
+ return result;
+}
+
+LongBowString *
+longBowString_CreateFormat(const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ char *cString;
+ if (vasprintf(&cString, format, ap) == -1) {
+ return NULL;
+ }
+ va_end(ap);
+
+ LongBowString *string = longBowString_CreateString(cString);
+
+ free(cString);
+
+ return string;
+}
+
+void
+longBowString_Destroy(LongBowString **stringPtr)
+{
+ LongBowString *string = *stringPtr;
+ if (string != NULL) {
+ longBowMemory_Deallocate((void **) &string->buffer);
+ longBowMemory_Deallocate((void **) stringPtr);
+ }
+}
+
+LongBowString *
+longBowString_Append(LongBowString *string, const char *value)
+{
+ size_t length = strlen(value) + 1;
+
+ if (_longBowString_RemainingSpace(string) < length) {
+ size_t size = string->end + length;
+ string->buffer = longBowMemory_Reallocate(string->buffer, size);
+ string->end = size - 1;
+ }
+ strcpy(&string->buffer[string->cursor], value);
+ string->cursor += (length - 1);
+ string->buffer[string->cursor] = 0;
+
+ return string;
+}
+
+LongBowString *
+longBowString_Format(LongBowString *string, const char *format, ...)
+{
+ LongBowString *result = NULL;
+
+ va_list ap;
+ va_start(ap, format);
+
+ char *cString;
+ int status = vasprintf(&cString, format, ap);
+ va_end(ap);
+ if (status != -1) {
+ result = longBowString_Append(string, cString);
+ free(cString);
+ } else {
+ result = NULL;
+ }
+
+ return result;
+}
+
+char *
+longBowString_ToString(const LongBowString *string)
+{
+ char *result = strndup(string->buffer, string->end);
+ return result;
+}
+
+bool
+longBowString_StartsWith(const char *string, const char *prefix)
+{
+ bool result = strncmp(string, prefix, strlen(prefix)) == 0;
+ return result;
+}
+
+bool
+longBowString_Equals(const char *string, const char *other)
+{
+ return strcmp(string, other) == 0;
+}
+
+bool
+longBowString_Write(const LongBowString *string, FILE *fp)
+{
+ bool result = false;
+ size_t nwrite = string->end;
+
+ if (fwrite(string->buffer, sizeof(char), string->end, fp) == nwrite) {
+ result = true;
+ }
+
+ return result;
+}
+
+LongBowArrayList *
+longBowString_Tokenise(const char *string, const char *separators)
+{
+ LongBowArrayList *result = longBowArrayList_Create(longBowMemory_Deallocate);
+ if (string != NULL) {
+ char *workingCopy = longBowMemory_StringCopy(string);
+
+ char *p = strtok(workingCopy, separators);
+ while (p) {
+ longBowArrayList_Add(result, longBowMemory_StringCopy(p));
+ p = strtok(NULL, separators);
+ }
+
+ longBowMemory_Deallocate((void **) &workingCopy);
+ }
+
+ return result;
+}
diff --git a/longbow/src/LongBow/private/longBow_String.h b/longbow/src/LongBow/private/longBow_String.h
new file mode 100755
index 00000000..463dfbd8
--- /dev/null
+++ b/longbow/src/LongBow/private/longBow_String.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * 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.
+ */
+
+/**
+ * @file longBow_String.h
+ * @brief <#Brief Description#>
+ *
+ * <#Detailed Description#>
+ *
+ */
+#ifndef __LongBow__longBow_String__
+#define __LongBow__longBow_String__
+
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <LongBow/private/longBow_ArrayList.h>
+
+struct longbow_String;
+typedef struct longbow_string LongBowString;
+
+/**
+ * Create a LongBowString
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [in] initialSize The initial buffer size to allocate for the string.
+ *
+ * @return non-NULL A pointer to a valid LongBowString instance.
+ * @return NULL Memory could not be allocated.
+ *
+ */
+LongBowString *longBowString_Create(const size_t initialSize);
+
+/**
+ * Create a `LongBowString` instance containing the formatted result of the given format string and parameters.
+ *
+ * @param [in] format A pointer to a valid LongBowString instance.
+ *
+ * @return The a LongBowString instance that must be deallocated via longBowString_Deallocate.
+ */
+LongBowString *longBowString_CreateFormat(const char *format, ...) __attribute__((format(printf, 1, 2)));
+
+/**
+ * Destroy a LongBowString instance.
+ *
+ * The pointer will be set to zero on return.
+ *
+ * @param [in,out] stringPtr A pointer to a valid LongBowString instance.
+ */
+void longBowString_Destroy(LongBowString **stringPtr);
+
+/**
+ * Append to the given LongBowString instance the formatted result of the given format string and parameters.
+ *
+ * @param [in] string A pointer to a valid LongBowString instance.
+ *
+ * @return The value of @p string
+ */
+LongBowString *longBowString_Format(LongBowString *string, const char *format, ...) __attribute__((format(printf, 2, 3)));
+
+/**
+ * Determine if a string begins with a specific prefix.
+ *
+ * @param [in] string A nul-terminated C string.
+ * @param [in] prefix A nul-terminated C string.
+ *
+ * @return true The value of @p string starts with @p prefix.
+ * @return false The value of @p string does not start with @p prefix.
+ *
+ * Example:
+ * @code
+ * {
+ * bool result = longBowString_StartsWith("Hello World", "Hello");
+ * }
+ * @endcode
+ */
+bool longBowString_StartsWith(const char *string, const char *prefix);
+
+/**
+ * Determine if a nul-terminated C string is equal to another.
+ *
+ * @param [in] string A nul-terminated C string.
+ * @param [in] other A nul-terminated C string.
+ *
+ * @return true The value of @p string starts with @p prefix.
+ * @return false The value of @p string does not start with @p prefix.
+ *
+ * Example:
+ * @code
+ * {
+ * bool result = longBowString_StartsWith("Hello World", "Hello");
+ * }
+ * @endcode
+ */
+bool longBowString_Equals(const char *string, const char *other);
+
+/**
+ * Produce a LongBowArrayList containing the tokens for the given @p string
+ * where each token is separated by characters in the string @p separators.
+ *
+ * @param [in] string A nul-terminated C string.
+ * @param [in] separators A nul-terminated C string containing the characters that separate the tokens.
+ *
+ * @return non-NULL A valid LongBowArrayList containing the tokens of the string.
+ * @return NULL Memory could not be allocated.
+ *
+ * Example:
+ * @code
+ * {
+ * LongBowArrayList *result = longBowString_Tokenise("Hello World", " ");
+ * ....
+ * longBowArrayList_Destroy(&result);
+ * }
+ * @endcode
+ */
+LongBowArrayList *longBowString_Tokenise(const char *string, const char *separators);
+
+/**
+ * Produce a nul-terminated C string from the given LongBowString instance.
+ *
+ * @param [in] string A pointer to a valid LongBowString instance.
+ *
+ * @return non-NULL A pointer to a nul-terminated C string that must be deallocated via free(3).
+ */
+char *longBowString_ToString(const LongBowString *string);
+
+/**
+ * Write the contents of the given LongBowString instance to the specified FILE output stream.
+ *
+ * @param [in] string A pointer to a valid LongBowString instance.
+ * @param [in] fp A pointer to a valid FILE instance.
+ *
+ * @return true All of the string was successfully written.
+ * @return false All of the string was not successfully written.
+ */
+bool longBowString_Write(const LongBowString *string, FILE *fp);
+
+#endif /* defined(__LongBow__longBow_String__) */