From ec688b4723a041044226358bcd4dd6e2da39da49 Mon Sep 17 00:00:00 2001 From: Luca Muscariello Date: Thu, 23 Feb 2017 17:01:02 +0100 Subject: Initial commit: cframework. Longbow and Libparc Change-Id: I90378dbd30da6033b20fb1f829b3b822cf366c59 Signed-off-by: Luca Muscariello --- longbow/src/LongBow/private/longBow_ArrayList.c | 277 ++++++++++++++++++++++++ longbow/src/LongBow/private/longBow_ArrayList.h | 225 +++++++++++++++++++ longbow/src/LongBow/private/longBow_Memory.c | 95 ++++++++ longbow/src/LongBow/private/longBow_Memory.h | 93 ++++++++ longbow/src/LongBow/private/longBow_OpenFile.c | 151 +++++++++++++ longbow/src/LongBow/private/longBow_OpenFile.h | 70 ++++++ longbow/src/LongBow/private/longBow_String.c | 180 +++++++++++++++ longbow/src/LongBow/private/longBow_String.h | 151 +++++++++++++ 8 files changed, 1242 insertions(+) create mode 100755 longbow/src/LongBow/private/longBow_ArrayList.c create mode 100644 longbow/src/LongBow/private/longBow_ArrayList.h create mode 100644 longbow/src/LongBow/private/longBow_Memory.c create mode 100755 longbow/src/LongBow/private/longBow_Memory.h create mode 100644 longbow/src/LongBow/private/longBow_OpenFile.c create mode 100755 longbow/src/LongBow/private/longBow_OpenFile.h create mode 100644 longbow/src/LongBow/private/longBow_String.c create mode 100755 longbow/src/LongBow/private/longBow_String.h (limited to 'longbow/src/LongBow/private') 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 + +#include +#include +#include +#include +#include + +#include +#include +#include + +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 +#include +#include + +/** + * @struct longbow_array_list + * @brief A LongBow_ArrayList is a (dynamic) array of void * 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 longBowArrayList_Create. + * + * @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 element + * @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 element + * @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 + +#include +#include +#include + +#include + +#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 + +/** + * 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 **) ©); + * } + * @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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +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 + +#include + +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 +#include +#include + +#include +#include + +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 +#include + +#include + +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__) */ -- cgit 1.2.3-korg