summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fischer <joeljfischer@gmail.com>2019-08-27 17:52:26 -0400
committerJoel Fischer <joeljfischer@gmail.com>2019-08-27 17:52:26 -0400
commit2acc41302578bd2e90a08dafd920a7678c532bf9 (patch)
tree6854ead5d4ae9f2c621357d0ee79761acf1f4c2f
parentce4ef80cffcc9b508f523b710cef54e81d306cf1 (diff)
downloadsdl_ios-bugfix/issue-1387-swift-package-manager-installation.tar.gz
Remove submodule, add BSON code into the librarybugfix/issue-1387-swift-package-manager-installation
-rw-r--r--.gitmodules3
-rw-r--r--BSON-lib/bson_array.c481
-rw-r--r--BSON-lib/bson_array.h245
-rw-r--r--BSON-lib/bson_object.c500
-rw-r--r--BSON-lib/bson_object.h306
-rw-r--r--BSON-lib/bson_util.c157
-rw-r--r--BSON-lib/bson_util.h201
-rwxr-xr-xBSON-lib/emhashmap.c156
-rwxr-xr-xBSON-lib/emhashmap.h144
-rw-r--r--DEPENDENCIES.md32
-rw-r--r--SmartDeviceLink-iOS.podspec1
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.pbxproj78
-rw-r--r--SmartDeviceLink.podspec1
m---------bson_c_lib0
14 files changed, 2253 insertions, 52 deletions
diff --git a/.gitmodules b/.gitmodules
index 684da2889..e69de29bb 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "bson_c_lib"]
- path = bson_c_lib
- url = https://github.com/smartdevicelink/bson_c_lib.git
diff --git a/BSON-lib/bson_array.c b/BSON-lib/bson_array.c
new file mode 100644
index 000000000..756744157
--- /dev/null
+++ b/BSON-lib/bson_array.c
@@ -0,0 +1,481 @@
+#include "bson_array.h"
+
+bool bson_array_initialize(BsonArray *array, size_t initialCapacity) {
+ array->count = 0;
+ array->maxCount = initialCapacity;
+ array->elements = malloc(sizeof(BsonElement *) * initialCapacity);
+ return true;
+}
+
+void bson_array_deinitialize(BsonArray *array) {
+ size_t i = 0;
+ for (i = 0; i < array->count; i++) {
+ BsonElement *element = array->elements[i];
+ if (element->type == TYPE_DOCUMENT) {
+ bson_object_deinitialize((BsonObject *)element->value);
+ }
+ else if (element->type == TYPE_ARRAY) {
+ bson_array_deinitialize((BsonArray *)element->value);
+ }
+ free(element->value);
+ free(element);
+ }
+
+ free(array->elements);
+}
+
+size_t bson_array_size(BsonArray *array) {
+ size_t arraySize = ARRAY_OVERHEAD_BYTES;
+ size_t i = 0;
+ for (i = 0; i < array->count; i++) {
+ BsonElement *element = array->elements[i];
+ arraySize += array_key_size(i) + ELEMENT_OVERHEAD_BYTES;
+ if (element->type == TYPE_DOCUMENT) {
+ arraySize += bson_object_size((BsonObject *)element->value);
+ }
+ else if (element->type == TYPE_ARRAY) {
+ arraySize += bson_array_size((BsonArray *)element->value);
+ }
+ else {
+ arraySize += element->size;
+ }
+ }
+ return arraySize;
+}
+
+uint8_t *bson_array_to_bytes(BsonArray *array) {
+ size_t arraySize = bson_array_size(array);
+ uint8_t *bytes = malloc(arraySize);
+ size_t position = 0;
+ write_int32_le(bytes, (int32_t)arraySize, &position);
+ size_t i = 0;
+ for (i = 0; i < array->count; i++) {
+ BsonElement *element = array->elements[i];
+
+ bytes[position++] = element->type;
+
+ uint8_t *keyBytes = index_to_key(i);
+ memcpy(&bytes[position], keyBytes, digits(i));
+ free(keyBytes);
+ position += digits(i);
+
+ //Null-terminate
+ bytes[position++] = 0x00;
+
+ switch (element->type) {
+ case TYPE_DOCUMENT: {
+ BsonObject *obj = (BsonObject *)element->value;
+ uint8_t *objBytes = bson_object_to_bytes(obj);
+ if (objBytes == NULL) {
+ printf("An error occured while parsing the object with index \"%i\"\n", (int)i);
+ free(bytes);
+ return NULL;
+ }
+ size_t objSize = bson_object_size(obj);
+ memcpy(&bytes[position], objBytes, objSize);
+ free(objBytes);
+ position += objSize;
+ break;
+ }
+ case TYPE_ARRAY: {
+ BsonArray *subArray = (BsonArray *)element->value;
+ uint8_t *subArrayBytes = bson_array_to_bytes(subArray);
+ if (subArrayBytes == NULL) {
+ printf("An error occured while parsing the object with index \"%i\"\n", (int)i);
+ free(bytes);
+ return NULL;
+ }
+ size_t subArraySize = bson_array_size(subArray);
+ memset(&bytes[position], 0, subArraySize);
+ memcpy(&bytes[position], subArrayBytes, subArraySize);
+ free(subArrayBytes);
+ position += subArraySize;
+ break;
+ }
+ case TYPE_INT32: {
+ write_int32_le(bytes, *(int32_t *)element->value, &position);
+ break;
+ }
+ case TYPE_INT64: {
+ write_int64_le(bytes, *(int64_t *)element->value, &position);
+ break;
+ }
+ case TYPE_STRING: {
+ char *stringVal = (char *)element->value;
+ //String length is written first
+ write_int32_le(bytes, (int32_t)(strlen(stringVal) + 1), &position);
+
+ uint8_t *stringBytes = string_to_byte_array(stringVal);
+ memcpy(&bytes[position], stringBytes, strlen(stringVal));
+ free(stringBytes);
+ position += strlen(stringVal);
+
+ //Null-terminate
+ bytes[position++] = 0x00;
+ break;
+ }
+ case TYPE_DOUBLE: {
+ write_double_le(bytes, *(double *)element->value, &position);
+ break;
+ }
+ case TYPE_BOOLEAN: {
+ bytes[position++] = (uint8_t)(*(bson_boolean *)element->value);
+ break;
+ }
+ default: {
+ printf("Unrecognized BSON type: %i\n", element->type);
+ position += sizeof(*element->value);
+ }
+ }
+ }
+
+ bytes[position++] = DOCUMENT_END;
+ if (position != arraySize) {
+ printf("Something went horribly wrong. Unexpected size of array in bytes: %i, expected size: %i\n", (int)position, (int)arraySize);
+ free(bytes);
+ return NULL;
+ }
+ return bytes;
+}
+
+// DEPRECATED: use bson_array_from_bytes_len() instead
+BsonArray bson_array_from_bytes(uint8_t *data) {
+ uint8_t *p = data;
+ int32_t size = read_int32_le(&p);
+
+ BsonArray array;
+ bson_array_from_bytes_len(&array, data, size);
+ return array;
+}
+
+size_t bson_array_from_bytes_len(BsonArray *output, const uint8_t *data, size_t dataSize) {
+ const uint8_t *current = data;
+ size_t remainBytes = dataSize;
+ int32_t size = 0;
+ bool parseError = false;
+ size_t ret;
+
+ if (output == NULL || data == NULL || dataSize < SIZE_INT32) {
+ return 0;
+ }
+ size = read_int32_le((uint8_t **)&current);
+ remainBytes -= SIZE_INT32;
+ if (size > dataSize) {
+ printf("Unexpected array length %i, data is only %i bytes\n", (int)size, (int)dataSize);
+ return 0;
+ }
+
+ if (remainBytes < 1) {
+ return 0;
+ }
+ uint8_t type = *current;
+ current += 1;
+ remainBytes -= 1;
+
+ BsonArray array;
+ bson_array_initialize(&array, 10);
+
+ while (type != DOCUMENT_END) {
+ char *key = NULL;
+ ret = read_string_len(&key, &current, &remainBytes);
+ if (ret == 0) {
+ parseError = true;
+ break;
+ }
+
+ switch ((element_type)type) {
+ case TYPE_DOCUMENT: {
+ BsonObject obj;
+ ret = bson_object_from_bytes_len(&obj, current, remainBytes);
+ if (ret > 0) {
+ bson_array_add_object(&array, &obj);
+ current += ret;
+ remainBytes -= ret;
+ } else {
+ parseError = true;
+ }
+ break;
+ }
+ case TYPE_ARRAY: {
+ BsonArray subArray;
+ ret = bson_array_from_bytes_len(&subArray, current, remainBytes);
+ if (ret > 0) {
+ bson_array_add_array(&array, &subArray);
+ current += ret;
+ remainBytes -= ret;
+ } else {
+ parseError = true;
+ }
+ break;
+ }
+ case TYPE_INT32:
+ if (remainBytes >= SIZE_INT32) {
+ int32_t value = read_int32_le((uint8_t **)&current);
+ bson_array_add_int32(&array, value);
+ remainBytes -= SIZE_INT32;
+ } else {
+ parseError = true;
+ }
+ break;
+ case TYPE_INT64:
+ if (remainBytes >= SIZE_INT64) {
+ int64_t value = read_int64_le((uint8_t **)&current);
+ bson_array_add_int64(&array, value);
+ remainBytes -= SIZE_INT64;
+ } else {
+ parseError = true;
+ }
+ break;
+ case TYPE_STRING:
+ // Buffer length is read first
+ if (remainBytes >= SIZE_INT32) {
+ int32_t bufferLength = read_int32_le((uint8_t **)&current);
+ remainBytes -= SIZE_INT32;
+
+ if (bufferLength <= remainBytes) {
+ char *stringVal = byte_array_to_bson_string((uint8_t*)current, (size_t)bufferLength - 1);
+ bson_array_add_string(&array, stringVal);
+ free(stringVal);
+ current += bufferLength;
+ remainBytes -= bufferLength;
+ } else {
+ parseError = true;
+ }
+ } else {
+ parseError = true;
+ }
+ break;
+ case TYPE_DOUBLE:
+ if (remainBytes >= SIZE_DOUBLE) {
+ double value = read_double_le((uint8_t **)&current);
+ bson_array_add_double(&array, value);
+ remainBytes -= SIZE_DOUBLE;
+ } else {
+ parseError = true;
+ }
+ break;
+ case TYPE_BOOLEAN:
+ if (remainBytes >= 1) {
+ uint8_t value = *current;
+ bson_array_add_bool(&array, value);
+ current += 1;
+ remainBytes -= 1;
+ } else {
+ parseError = true;
+ }
+ break;
+ default: {
+ printf("Unrecognized BSON type: %i\n", type);
+ parseError = true;
+ }
+ }
+ free(key);
+
+ if (parseError) {
+ break;
+ }
+
+ if (remainBytes >= 1) {
+ type = *current;
+ current += 1;
+ remainBytes -= 1;
+ } else {
+ parseError = true;
+ break;
+ }
+ }
+
+ if (parseError) {
+ bson_array_deinitialize(&array);
+ return 0;
+ }
+
+ if (data + size != current) {
+ printf("Unexpected parsed array size. Expected %i, got %i\n", (int)size, (int)(current - data));
+ }
+ *output = array;
+ return dataSize - remainBytes;
+}
+
+char *bson_array_to_string(BsonArray *array, char *out) {
+ //TODO just move the pointer rather than keep a position variable
+ int position = 0;
+ position += sprintf(out, "[ ");
+ size_t i = 0;
+ for (i = 0; i < array->count; i++) {
+ BsonElement *element = array->elements[i];
+ switch (element->type) {
+ case TYPE_DOCUMENT: {
+ char docString[512];
+ position += sprintf(&out[position], "%s", bson_object_to_string(bson_array_get_object(array, i), docString));
+ break;
+ }
+ case TYPE_ARRAY: {
+ char docString[512];
+ position += sprintf(&out[position], "%s", bson_array_to_string(bson_array_get_array(array, i), docString));
+ break;
+ }
+ case TYPE_INT32: {
+ position += sprintf(&out[position], "%i", (int)bson_array_get_int32(array, i));
+ break;
+ }
+ case TYPE_INT64: {
+ position += sprintf(&out[position], "%li", (long)bson_array_get_int64(array, i));
+ break;
+ }
+ case TYPE_STRING: {
+ position += sprintf(&out[position], "\"%s\"", bson_array_get_string(array, i));
+ break;
+ }
+ case TYPE_DOUBLE: {
+ position += sprintf(&out[position], "%f", bson_array_get_double(array, i));
+ break;
+ }
+ case TYPE_BOOLEAN: {
+ position += sprintf(&out[position], "%s", (bson_array_get_bool(array, i) == BOOLEAN_TRUE) ? "true" : "false");
+ break;
+ }
+ default: {
+ printf("Unrecognized BSON type: %i\n", element->type);
+ position += sprintf(&out[position], "UNKNOWN_TYPE");
+ }
+ }
+ if (i != (array->count - 1)) {
+ position += sprintf(&out[position], ", ");
+ }
+ }
+ sprintf(&out[position], " ]");
+
+ return out;
+}
+
+bool bson_array_resize(BsonArray *array, size_t newSize) {
+ if (array->count > newSize) {
+ printf("Attempted to resize an array smaller than the number of elements it contains\n");
+ return false;
+ }
+ int i = 0;
+ BsonElement **newArray = malloc(sizeof(BsonElement *) * newSize);
+ BsonElement **oldArray = array->elements;
+ for (i = 0; i < array->maxCount; i++) {
+ newArray[i] = oldArray[i];
+ }
+ free(oldArray);
+ array->elements = newArray;
+ array->maxCount = newSize;
+ return true;
+}
+
+bool bson_array_add_element(BsonArray *array, BsonElement *element, size_t allocSize) {
+ if (array->count == array->maxCount) {
+ if (!bson_array_resize(array, array->maxCount * 2)) {
+ return false;
+ }
+ }
+ BsonElement *allocElement = malloc(sizeof(BsonElement));
+ allocElement->type = element->type;
+ allocElement->size = element->size;
+ allocElement->value = malloc(allocSize);
+ memcpy(allocElement->value, element->value, allocSize);
+ array->elements[array->count] = allocElement;
+ array->count++;
+ return true;
+}
+
+/*
+ @brief Add a new element to the end of a given array
+
+ @param array - The array to be modified
+ @param type - The type of the element to be added
+ @param value - The value of the element to be added
+ @param allocSize - The size, in bytes, to be allocated for the element
+ @param elementSize - The size, in bytes, of the element when converted to BSON format
+
+ @return - true if the addition was successful, false if not
+*/
+bool bson_array_add(BsonArray *array, element_type type, void *value, size_t allocSize, size_t elementSize) {
+ BsonElement element;
+ element.type = type;
+ element.value = value;
+ element.size = elementSize;
+ return bson_array_add_element(array, &element, allocSize);
+}
+
+bool bson_array_add_object(BsonArray *array, BsonObject *value) {
+ return bson_array_add(array, TYPE_DOCUMENT, value, sizeof(BsonObject), 0);
+}
+
+bool bson_array_add_array(BsonArray *array, BsonArray *value) {
+ return bson_array_add(array, TYPE_ARRAY, value, sizeof(BsonArray), 0);
+}
+
+bool bson_array_add_int32(BsonArray *array, int32_t value) {
+ return bson_array_add(array, TYPE_INT32, &value, sizeof(int32_t),
+ SIZE_INT32);
+}
+
+bool bson_array_add_int64(BsonArray *array, int64_t value) {
+ return bson_array_add(array, TYPE_INT64, &value, sizeof(int64_t),
+ SIZE_INT64);
+}
+
+bool bson_array_add_string(BsonArray *array, char *value) {
+ return bson_array_add(array, TYPE_STRING, value, (strlen(value) + 1) * sizeof(char),
+ strlen(value) + STRING_OVERHEAD_BYTES);
+}
+
+bool bson_array_add_bool(BsonArray *array, bson_boolean value) {
+ return bson_array_add(array, TYPE_BOOLEAN, &value, sizeof(bson_boolean),
+ SIZE_BOOLEAN);
+}
+
+bool bson_array_add_double(BsonArray *array, double value) {
+ return bson_array_add(array, TYPE_DOUBLE, &value, sizeof(double),
+ SIZE_DOUBLE);
+}
+
+BsonElement *bson_array_get(BsonArray *array, size_t index) {
+ return (index >= array->count) ? NULL : array->elements[index];
+}
+
+BsonObject *bson_array_get_object(BsonArray *array, size_t index) {
+ BsonElement *element = bson_array_get(array, index);
+ return (element == NULL || element->type != TYPE_DOCUMENT) ?
+ NULL : (BsonObject *)element->value;
+}
+
+BsonArray *bson_array_get_array(BsonArray *array, size_t index) {
+ BsonElement *element = bson_array_get(array, index);
+ return (element == NULL || element->type != TYPE_ARRAY) ?
+ NULL : (BsonArray *)element->value;
+}
+
+int32_t bson_array_get_int32(BsonArray *array, size_t index) {
+ BsonElement *element = bson_array_get(array, index);
+ return (element == NULL || element->type != TYPE_INT32) ?
+ -1 : *(int32_t *)element->value;
+}
+
+int64_t bson_array_get_int64(BsonArray *array, size_t index) {
+ BsonElement *element = bson_array_get(array, index);
+ return (element == NULL || element->type != TYPE_INT64) ?
+ -1 : *(int64_t *)element->value;
+}
+
+char *bson_array_get_string(BsonArray *array, size_t index) {
+ BsonElement *element = bson_array_get(array, index);
+ return (element == NULL || element->type != TYPE_STRING) ?
+ NULL : (char *)element->value;
+}
+
+bson_boolean bson_array_get_bool(BsonArray *array, size_t index) {
+ BsonElement *element = bson_array_get(array, index);
+ return (element == NULL || element->type != TYPE_BOOLEAN) ?
+ BOOLEAN_INVALID : *(bson_boolean *)element->value;
+}
+
+double bson_array_get_double(BsonArray *array, size_t index) {
+ BsonElement *element = bson_array_get(array, index);
+ return (element == NULL || element->type != TYPE_DOUBLE) ?
+ -1 : *(double *)element->value;
+}
diff --git a/BSON-lib/bson_array.h b/BSON-lib/bson_array.h
new file mode 100644
index 000000000..581447c54
--- /dev/null
+++ b/BSON-lib/bson_array.h
@@ -0,0 +1,245 @@
+#ifndef BSON_ARRAY_H
+#define BSON_ARRAY_H
+
+#include "bson_object.h"
+
+typedef struct BsonElement BsonElement;
+typedef struct BsonObject BsonObject;
+
+typedef enum bson_boolean bson_boolean;
+typedef enum element_type element_type;
+
+//Object representing a BSON array
+struct BsonArray {
+ //Array of BSON elements
+ BsonElement **elements;
+ //Number of elements currently in the array
+ size_t count;
+ //The current maximum number of elements in the array
+ size_t maxCount;
+};
+typedef struct BsonArray BsonArray;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ @brief Initalize BSON Array
+
+ @param array - The uninitialized BSON Array
+ @param initialSize - The initial maximum size of the array
+
+ @return - true if the array was initialized successfully, false if not
+*/
+bool bson_array_initialize(BsonArray *array, size_t initialCapacity);
+/*
+ @brief Deinitalize BSON Array, free all associated memory,
+ and recursively clean up all sub-objects
+
+ @param array - The BSON Array to be deinitalized
+*/
+void bson_array_deinitialize(BsonArray *array);
+
+/*
+ @brief Calculate the size, in bytes, of a given array when converted to a BSON document
+
+ @param obj - The BSON array from which the size is calculated
+
+ @return - The calculated size
+*/
+size_t bson_array_size(BsonArray *array);
+
+/*
+ @brief Get the BSON represention of an array
+
+ @param array - The array to be converted to BSON
+
+ @return - A byte array containing the BSON representation of the array,
+ this data must be freed by the caller after use
+*/
+uint8_t *bson_array_to_bytes(BsonArray *array);
+/*
+ @brief Parse BSON data into an array
+
+ @param data - The BSON data to be parsed
+
+ @return - The BSON array created from the BSON data
+
+ @note DEPRECATED: use bson_array_from_bytes_len() instead
+*/
+BsonArray bson_array_from_bytes(uint8_t *data);
+
+/*
+ @brief Parse BSON data into an array
+
+ @param output - Pointer to an uninitialized BsonArray. On success, it is
+ initialized and stores converted data.
+ @param data - Byte buffer that contains BSON data to be parsed
+ @param dataSize - Number of bytes of the data stored in the byte buffer
+
+ @return - On success, a positive number indicating number of bytes consumed
+ is returned. On error, 0 is returned.
+*/
+size_t bson_array_from_bytes_len(BsonArray *output, const uint8_t *data, size_t dataSize);
+
+/*
+ @brief Get a JSON string representation of a BSON array
+
+ @param array - The array to be converted to a JSON string
+ @param out - The output string of the function
+
+ @return - The value of out
+*/
+char *bson_array_to_string(BsonArray *array, char *out);
+
+/*
+ @brief Add a BSON object to the end of a given array
+
+ @param array - The array to be modified
+ @param value - The pointer to the BSON object to be added
+
+ @return - true if the addition was successful, false if not
+*/
+bool bson_array_add_object(BsonArray *array, BsonObject *value);
+/*
+ @brief Add a BSON array to the end of a given array
+
+ @param array - The array to be modified
+ @param value - The pointer to the BSON array to be added
+
+ @return - true if the addition was successful, false if not
+*/
+bool bson_array_add_array(BsonArray *array, BsonArray *value);
+/*
+ @brief Add a 32-bit integer value to the end of a given array
+
+ @param array - The array to be modified
+ @param value - The integer value to be added
+
+ @return - true if the addition was successful, false if not
+*/
+bool bson_array_add_int32(BsonArray *array, int32_t value);
+/*
+ @brief Add a 64-bit integer value to the end of a given array
+
+ @param array - The array to be modified
+ @param value - The integer value to be added
+
+ @return - true if the addition was successful, false if not
+*/
+bool bson_array_add_int64(BsonArray *array, int64_t value);
+/*
+ @brief Add a string value to the end of a given array
+
+ @param array - The array to be modified
+ @param value - The string value to be added
+
+ @return - true if the addition was successful, false if not
+*/
+bool bson_array_add_string(BsonArray *array, char *value);
+/*
+ @brief Add a boolean value to the end of a given array
+
+ @param array - The array to be modified
+ @param value - The boolean value to be added
+
+ @return - true if the addition was successful, false if not
+*/
+bool bson_array_add_bool(BsonArray *array, bson_boolean value);
+/*
+ @brief Add a floating-point value to the end of a given array
+
+ @param array - The array to be modified
+ @param value - The floating-point value to be added
+
+ @return - true if the addition was successful, false if not
+*/
+bool bson_array_add_double(BsonArray *array, double value);
+
+/*
+ @brief Retrieve the object at a specified index
+
+ @param array - The array to be accessed
+ @param index - The index of the object within the array
+
+ @return - The BSON element at the given index if it exists,
+ NULL if the index is out of bounds
+*/
+BsonElement *bson_array_get(BsonArray *array, size_t index);
+/*
+ @brief Retrieve the BSON object at a specified index in an array
+
+ @param array - The array to be accessed
+ @param index - The index of the BSON object within the array
+
+ @return - The pointer to the BSON object at the given index if it exists,
+ NULL if the index is out of bounds or the value is not a BSON object
+*/
+BsonObject *bson_array_get_object(BsonArray *array, size_t index);
+/*
+ @brief Retrieve the BSON array at a specified index in an array
+
+ @param array - The array to be accessed
+ @param index - The index of the BSON array within the array
+
+ @return - The pointer to the BSON array at the given index if it exists,
+ NULL if the index is out of bounds or the value is not a BSON array
+*/
+BsonArray *bson_array_get_array(BsonArray *array, size_t index);
+/*
+ @brief Retrieve the 32-bit integer value at a specified index in an array
+
+ @param array - The array to be accessed
+ @param index - The index of the integer value within the array
+
+ @return - The integer value at the given index if it exists,
+ NULL if the index is out of bounds or the value is not a 32-bit integer
+*/
+int32_t bson_array_get_int32(BsonArray *array, size_t index);
+/*
+ @brief Retrieve the 64-bit integer value at a specified index in an array
+
+ @param array - The array to be accessed
+ @param index - The index of the integer value within the array
+
+ @return - The integer value at the given index if it exists,
+ NULL if the index is out of bounds or the value is not a 64-bit integer
+*/
+int64_t bson_array_get_int64(BsonArray *array, size_t index);
+/*
+ @brief Retrieve the string value at a specified index in an array
+
+ @param array - The array to be accessed
+ @param index - The index of the string value within the array
+
+ @return - The string value at the given index if it exists,
+ NULL if the index is out of bounds or the value is not a string
+*/
+char *bson_array_get_string(BsonArray *array, size_t index);
+/*
+ @brief Retrieve the boolean value at a specified index in an array
+
+ @param array - The array to be accessed
+ @param index - The index of the string value within the array
+
+ @return - The boolean value at the given index if it exists,
+ NULL if the index is out of bounds or the value is not a boolean
+*/
+bson_boolean bson_array_get_bool(BsonArray *array, size_t index);
+/*
+ @brief Retrieve the floating-point value at a specified index in an array
+
+ @param array - The array to be accessed
+ @param index - The index of the floating-point value within the array
+
+ @return - The floating-point value at the given index if it exists,
+ NULL if the index is out of bounds or the value is not a floating-point number
+*/
+double bson_array_get_double(BsonArray *array, size_t index);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/BSON-lib/bson_object.c b/BSON-lib/bson_object.c
new file mode 100644
index 000000000..d1fa21d9f
--- /dev/null
+++ b/BSON-lib/bson_object.c
@@ -0,0 +1,500 @@
+#include "bson_object.h"
+#define DEFAULT_MAP_SIZE 32
+
+size_t hash_function(const char* key, size_t maxValue) {
+ size_t keyLength = strlen(key);
+ size_t hash = 0;
+ int i;
+ for (i = 0; i < keyLength; i++) {
+ hash += (size_t)key[i];
+ hash %= maxValue;
+ }
+ return hash;
+}
+
+bool bson_object_initialize(BsonObject *obj, size_t capacity, float loadFactor) {
+ return emhashmap_initialize(&obj->data, (int)capacity, loadFactor, &hash_function);
+}
+
+bool bson_object_initialize_default(BsonObject *obj) {
+ return bson_object_initialize(obj, DEFAULT_MAP_SIZE, 0.5f);
+}
+
+void bson_object_deinitialize(BsonObject *obj) {
+ MapIterator iterator = emhashmap_iterator(&obj->data);
+ MapEntry *current = emhashmap_iterator_next(&iterator);
+ while (current != NULL) {
+ BsonElement *element = (BsonElement *)current->value;
+ if (element->type == TYPE_DOCUMENT) {
+ bson_object_deinitialize((BsonObject *)element->value);
+ }
+ else if (element->type == TYPE_ARRAY) {
+ bson_array_deinitialize((BsonArray *)element->value);
+ }
+ free(element->value);
+ free(element);
+ current = emhashmap_iterator_next(&iterator);
+ }
+
+ emhashmap_deinitialize(&obj->data);
+}
+
+size_t bson_object_size(BsonObject *obj) {
+ size_t objSize = OBJECT_OVERHEAD_BYTES;
+ MapIterator iterator = emhashmap_iterator(&obj->data);
+ MapEntry *current = emhashmap_iterator_next(&iterator);
+ while (current != NULL) {
+ BsonElement *element = (BsonElement *)current->value;
+ objSize += object_key_size(current->key) + ELEMENT_OVERHEAD_BYTES;
+ if (element->type == TYPE_DOCUMENT) {
+ objSize += bson_object_size((BsonObject *)element->value);
+ }
+ else if (element->type == TYPE_ARRAY) {
+ objSize += bson_array_size((BsonArray *)element->value);
+ }
+ else {
+ objSize += element->size;
+ }
+ current = emhashmap_iterator_next(&iterator);
+ }
+ return objSize;
+}
+
+uint8_t *bson_object_to_bytes(BsonObject *obj) {
+ //TODO just move the pointer rather than keep a position variable
+ MapIterator iterator = emhashmap_iterator(&obj->data);
+ MapEntry *current = emhashmap_iterator_next(&iterator);
+ size_t objSize = bson_object_size(obj);
+ uint8_t *bytes = malloc(objSize);
+ size_t position = 0;
+ write_int32_le(bytes, (int32_t)objSize, &position);
+
+ while (current != NULL) {
+ BsonElement *element = (BsonElement *)current->value;
+
+ bytes[position++] = element->type;
+
+ uint8_t *keyBytes = string_to_byte_array(current->key);
+ memcpy(&bytes[position], keyBytes, strlen(current->key));
+ free(keyBytes);
+ position += strlen(current->key);
+
+ //Null-terminate
+ bytes[position++] = 0x00;
+
+ switch (element->type) {
+ case TYPE_DOCUMENT: {
+ BsonObject *subObject = (BsonObject *)element->value;
+ uint8_t *subObjectBytes = bson_object_to_bytes(subObject);
+ if (subObjectBytes == NULL) {
+ printf("An error occured while parsing the object with key \"%s\"\n", current->key);
+ free(bytes);
+ return NULL;
+ }
+ size_t subObjectSize = bson_object_size(subObject);
+ memcpy(&bytes[position], subObjectBytes, subObjectSize);
+ free(subObjectBytes);
+ position += subObjectSize;
+ break;
+ }
+ case TYPE_ARRAY: {
+ BsonArray *array = (BsonArray *)element->value;
+ uint8_t *arrayBytes = bson_array_to_bytes(array);
+ if (arrayBytes == NULL) {
+ printf("An error occured while parsing the object with key \"%s\"\n", current->key);
+ free(bytes);
+ return NULL;
+ }
+ size_t arraySize = bson_array_size(array);
+ memset(&bytes[position], 0, arraySize);
+ memcpy(&bytes[position], arrayBytes, arraySize);
+ free(arrayBytes);
+ position += arraySize;
+ break;
+ }
+ case TYPE_INT32: {
+ write_int32_le(bytes, *(int32_t *)element->value, &position);
+ break;
+ }
+ case TYPE_INT64: {
+ write_int64_le(bytes, *(int64_t *)element->value, &position);
+ break;
+ }
+ case TYPE_STRING: {
+ char *stringVal = (char *)element->value;
+ //String length is written first
+ write_int32_le(bytes, (int32_t)(strlen(stringVal) + 1), &position);
+
+ uint8_t *stringBytes = string_to_byte_array(stringVal);
+ memcpy(&bytes[position], stringBytes, strlen(stringVal));
+ free(stringBytes);
+ position += strlen(stringVal);
+
+ //Null-terminate
+ bytes[position++] = 0x00;
+ break;
+ }
+ case TYPE_DOUBLE: {
+ write_double_le(bytes, *(double *)element->value, &position);
+ break;
+ }
+ case TYPE_BOOLEAN: {
+ bytes[position++] = (uint8_t)(*(bson_boolean *)element->value);
+ break;
+ }
+ default: {
+ printf("Unrecognized BSON type: %i\n", element->type);
+ position += sizeof(element->value);
+ }
+ }
+ current = emhashmap_iterator_next(&iterator);
+ }
+
+ bytes[position++] = DOCUMENT_END;
+ if (position != objSize) {
+ printf("Something went horribly wrong. Unexpected size of map in bytes: %i, expected size: %i\n", (int)position, (int)objSize);
+ free(bytes);
+ return NULL;
+ }
+ return bytes;
+}
+
+// DEPRECATED: use bson_object_from_bytes_len() instead
+BsonObject bson_object_from_bytes(uint8_t *data) {
+ uint8_t *p = data;
+ int32_t size = read_int32_le(&p);
+
+ BsonObject obj;
+ bson_object_from_bytes_len(&obj, data, size);
+ return obj;
+}
+
+size_t bson_object_from_bytes_len(BsonObject *output, const uint8_t *data, size_t dataSize) {
+ const uint8_t *current = data;
+ size_t remainBytes = dataSize;
+ int32_t size = 0;
+ bool parseError = false;
+ size_t ret;
+
+ if (output == NULL || data == NULL || dataSize < SIZE_INT32) {
+ return 0;
+ }
+ size = read_int32_le((uint8_t **)&current);
+ remainBytes -= SIZE_INT32;
+ if (size > dataSize) {
+ printf("Unexpected object length %i, data is only %i bytes\n", (int)size, (int)dataSize);
+ return 0;
+ }
+
+ if (remainBytes < 1) {
+ return 0;
+ }
+ uint8_t type = *current;
+ current += 1;
+ remainBytes -= 1;
+
+ BsonObject obj;
+ bson_object_initialize_default(&obj);
+
+ while (type != DOCUMENT_END) {
+ char *key = NULL;
+ ret = read_string_len(&key, &current, &remainBytes);
+ if (ret == 0) {
+ parseError = true;
+ break;
+ }
+
+ switch ((element_type)type) {
+ case TYPE_DOCUMENT: {
+ BsonObject subObject;
+ ret = bson_object_from_bytes_len(&subObject, current, remainBytes);
+ if (ret > 0) {
+ bson_object_put_object(&obj, key, &subObject);
+ current += ret;
+ remainBytes -= ret;
+ } else {
+ parseError = true;
+ }
+ break;
+ }
+ case TYPE_ARRAY: {
+ BsonArray array;
+ ret = bson_array_from_bytes_len(&array, current, remainBytes);
+ if (ret > 0) {
+ bson_object_put_array(&obj, key, &array);
+ current += ret;
+ remainBytes -= ret;
+ } else {
+ parseError = true;
+ }
+ break;
+ }
+ case TYPE_INT32:
+ if (remainBytes >= SIZE_INT32) {
+ int32_t value = read_int32_le((uint8_t **)&current);
+ bson_object_put_int32(&obj, key, value);
+ remainBytes -= SIZE_INT32;
+ } else {
+ parseError = true;
+ }
+ break;
+ case TYPE_INT64:
+ if (remainBytes >= SIZE_INT64) {
+ int64_t value = read_int64_le((uint8_t **)&current);
+ bson_object_put_int64(&obj, key, value);
+ remainBytes -= SIZE_INT64;
+ } else {
+ parseError = true;
+ }
+ break;
+ case TYPE_STRING:
+ // Buffer length is read first
+ if (remainBytes >= SIZE_INT32) {
+ int32_t bufferLength = read_int32_le((uint8_t **)&current);
+ remainBytes -= SIZE_INT32;
+
+ if (bufferLength <= remainBytes) {
+ char *stringVal = byte_array_to_bson_string((uint8_t*)current, (size_t)bufferLength - 1);
+ bson_object_put_string(&obj, key, stringVal);
+ free(stringVal);
+ current += bufferLength;
+ remainBytes -= bufferLength;
+ } else {
+ parseError = true;
+ }
+ } else {
+ parseError = true;
+ }
+ break;
+ case TYPE_DOUBLE:
+ if (remainBytes >= SIZE_DOUBLE) {
+ double value = read_double_le((uint8_t **)&current);
+ bson_object_put_double(&obj, key, value);
+ remainBytes -= SIZE_DOUBLE;
+ } else {
+ parseError = true;
+ }
+ break;
+ case TYPE_BOOLEAN:
+ if (remainBytes >= 1) {
+ uint8_t value = *current;
+ bson_object_put_bool(&obj, key, value);
+ current += 1;
+ remainBytes -= 1;
+ } else {
+ parseError = true;
+ }
+ break;
+ default: {
+ printf("Unrecognized BSON type: %i\n", type);
+ parseError = true;
+ }
+ }
+ free(key);
+
+ if (parseError) {
+ break;
+ }
+
+ if (remainBytes >= 1) {
+ type = *current;
+ current += 1;
+ remainBytes -= 1;
+ } else {
+ parseError = true;
+ break;
+ }
+ }
+
+ if (parseError) {
+ bson_object_deinitialize(&obj);
+ return 0;
+ }
+
+ if (data + size != current) {
+ printf("Unexpected parsed object size. Expected %i, got %i\n", (int)size, (int)(current - data));
+ }
+ *output = obj;
+ return dataSize - remainBytes;
+}
+
+char *bson_object_to_string(BsonObject *obj, char *out) {
+ //TODO just move the pointer rather than keep a position variable
+ int position = 0;
+ MapIterator iterator = emhashmap_iterator(&obj->data);
+ MapEntry *current = emhashmap_iterator_next(&iterator);
+ position += sprintf(out, "{ ");
+ while (current != NULL) {
+ BsonElement *element = (BsonElement *)current->value;
+ position += sprintf(&out[position], "\"%s\":", current->key);
+ switch (element->type) {
+ case TYPE_DOCUMENT: {
+ char docString[512];
+ position += sprintf(&out[position], "%s", bson_object_to_string(bson_object_get_object(obj, current->key), docString));
+ break;
+ }
+ case TYPE_ARRAY: {
+ char docString[512];
+ position += sprintf(&out[position], "%s", bson_array_to_string(bson_object_get_array(obj, current->key), docString));
+ break;
+ }
+ case TYPE_INT32: {
+ position += sprintf(&out[position], "%i", (int)bson_object_get_int32(obj, current->key));
+ break;
+ }
+ case TYPE_INT64: {
+ position += sprintf(&out[position], "%li", (long)bson_object_get_int64(obj, current->key));
+ break;
+ }
+ case TYPE_STRING: {
+ position += sprintf(&out[position], "\"%s\"", bson_object_get_string(obj, current->key));
+ break;
+ }
+ case TYPE_DOUBLE: {
+ position += sprintf(&out[position], "%f", bson_object_get_double(obj, current->key));
+ break;
+ }
+ case TYPE_BOOLEAN: {
+ position += sprintf(&out[position], "%s", (bson_object_get_bool(obj, current->key) == BOOLEAN_TRUE) ? "true" : "false");
+ break;
+ }
+ default: {
+ printf("Unrecognized BSON type: %i\n", element->type);
+ position += sprintf(&out[position], "UNKNOWN_TYPE");
+ }
+ }
+ current = emhashmap_iterator_next(&iterator);
+ if (current != NULL) {
+ position += sprintf(&out[position], ", ");
+ }
+ }
+ sprintf(&out[position], " }");
+
+ return out;
+}
+
+bool bson_object_put_element(BsonObject *obj, const char *key, BsonElement *element, size_t allocSize) {
+ BsonElement *allocElement = malloc(sizeof(BsonElement));
+ allocElement->type = element->type;
+ allocElement->size = element->size;
+ allocElement->value = malloc(allocSize);
+ memcpy(allocElement->value, element->value, allocSize);
+ BsonElement *existingElement = emhashmap_remove(&obj->data, key);
+ if (existingElement != NULL) {
+ if (existingElement->type == TYPE_DOCUMENT) {
+ bson_object_deinitialize((BsonObject *)existingElement->value);
+ }
+ else if (existingElement->type == TYPE_ARRAY) {
+ bson_array_deinitialize((BsonArray *)existingElement->value);
+ }
+ free(existingElement->value);
+ free(existingElement);
+ }
+ return emhashmap_put(&obj->data, key, (void *)allocElement);
+}
+
+bool bson_object_put(BsonObject *obj, const char *key, element_type type, void *value, size_t allocSize, size_t elementSize) {
+ BsonElement element;
+ element.type = type;
+ element.value = value;
+ element.size = elementSize;
+ return bson_object_put_element(obj, key, &element, allocSize);
+}
+
+bool bson_object_put_object(BsonObject *obj, const char *key, BsonObject *value) {
+ return bson_object_put(obj, key, TYPE_DOCUMENT, value, sizeof(BsonObject), 0);
+}
+
+bool bson_object_put_array(BsonObject *obj, const char *key, BsonArray *value) {
+ return bson_object_put(obj, key, TYPE_ARRAY, value, sizeof(BsonArray), 0);
+}
+
+bool bson_object_put_int32(BsonObject *obj, const char *key, int32_t value) {
+ return bson_object_put(obj, key, TYPE_INT32, &value, sizeof(int32_t),
+ SIZE_INT32);
+}
+
+bool bson_object_put_int64(BsonObject *obj, const char *key, int64_t value) {
+ return bson_object_put(obj, key, TYPE_INT64, &value, sizeof(int64_t),
+ SIZE_INT64);
+}
+
+bool bson_object_put_string(BsonObject *obj, const char *key, char *value) {
+ return bson_object_put(obj, key, TYPE_STRING, value, (strlen(value) + 1) * sizeof(char),
+ strlen(value) + STRING_OVERHEAD_BYTES);
+}
+
+bool bson_object_put_bool(BsonObject *obj, const char *key, bson_boolean value) {
+ return bson_object_put(obj, key, TYPE_BOOLEAN, &value, sizeof(bson_boolean),
+ SIZE_BOOLEAN);
+}
+
+bool bson_object_put_double(BsonObject *obj, const char *key, double value) {
+ return bson_object_put(obj, key, TYPE_DOUBLE, &value, sizeof(double),
+ SIZE_DOUBLE);
+}
+
+BsonElement *bson_object_get(BsonObject *obj, const char *key) {
+ MapEntry *entry = emhashmap_get(&obj->data, key);
+ return (entry == NULL) ? NULL : entry->value;
+}
+
+BsonObject *bson_object_get_object(BsonObject *obj, const char *key) {
+ BsonElement *element = bson_object_get(obj, key);
+ return (element == NULL || element->type != TYPE_DOCUMENT) ?
+ NULL : (BsonObject *)element->value;
+}
+
+BsonArray *bson_object_get_array(BsonObject *obj, const char *key) {
+ BsonElement *element = bson_object_get(obj, key);
+ return (element == NULL || element->type != TYPE_ARRAY) ?
+ NULL : (BsonArray *)element->value;
+}
+
+int32_t bson_object_get_int32(BsonObject *obj, const char *key) {
+ BsonElement *element = bson_object_get(obj, key);
+ return (element == NULL || element->type != TYPE_INT32) ?
+ -1 : *(int32_t *)element->value;
+}
+
+int64_t bson_object_get_int64(BsonObject *obj, const char *key) {
+ BsonElement *element = bson_object_get(obj, key);
+ return (element == NULL || element->type != TYPE_INT64) ?
+ -1 : *(int64_t *)element->value;
+}
+
+char *bson_object_get_string(BsonObject *obj, const char *key) {
+ BsonElement *element = bson_object_get(obj, key);
+ return (element == NULL || element->type != TYPE_STRING) ?
+ NULL : (char *)element->value;
+}
+
+bson_boolean bson_object_get_bool(BsonObject *obj, const char *key) {
+ BsonElement *element = bson_object_get(obj, key);
+ return (element == NULL || element->type != TYPE_BOOLEAN) ?
+ BOOLEAN_INVALID : *(bson_boolean *)element->value;
+}
+
+double bson_object_get_double(BsonObject *obj, const char *key) {
+ BsonElement *element = bson_object_get(obj, key);
+ return (element == NULL || element->type != TYPE_DOUBLE) ?
+ -1 : *(double *)element->value;
+}
+
+MapIterator bson_object_iterator(BsonObject *obj) {
+ return emhashmap_iterator(&obj->data);
+}
+
+BsonObjectEntry bson_object_iterator_next(MapIterator *iterator) {
+ MapEntry *entry = emhashmap_iterator_next(iterator);
+ BsonObjectEntry bsonEntry;
+ if(entry == NULL) {
+ bsonEntry.key[0] = 0x00; //Assign empty string
+ bsonEntry.element = NULL;
+ }
+ else {
+ strncpy(bsonEntry.key, entry->key, 255);
+ bsonEntry.element = (BsonElement *)entry->value;
+ }
+ return bsonEntry;
+}
diff --git a/BSON-lib/bson_object.h b/BSON-lib/bson_object.h
new file mode 100644
index 000000000..803b8aeb7
--- /dev/null
+++ b/BSON-lib/bson_object.h
@@ -0,0 +1,306 @@
+#ifndef BSON_OBJECT_H
+#define BSON_OBJECT_H
+
+#include <stdbool.h>
+#include <stdio.h>
+
+#include "bson_util.h"
+#include "bson_array.h"
+#include "emhashmap.h"
+
+typedef struct BsonArray BsonArray;
+
+typedef enum element_type element_type;
+typedef enum bson_boolean bson_boolean;
+
+struct BsonObject {
+ //Internal map implementation
+ HashMap data;
+};
+typedef struct BsonObject BsonObject;
+
+struct BsonElement {
+ //The value of this element
+ void *value;
+ //The data type of this element
+ element_type type;
+ //Size of the element in bytes when converted to BSON
+ //Unused for TYPE_DOCUMENT and TYPE_ARRAY
+ size_t size;
+};
+typedef struct BsonElement BsonElement;
+
+struct BsonObjectEntry {
+ char key[255];
+ BsonElement *element;
+};
+typedef struct BsonObjectEntry BsonObjectEntry;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ @brief Initalize BSON Object
+
+ @param obj - The uninitialized BSON Object
+ @param size - The maximum capacity of the map used to store object data
+ @param loadFactor - The load factor of the map used to store object data
+
+ @return - true if the object was initialized successfully, false if not
+*/
+bool bson_object_initialize(BsonObject *obj, size_t capacity, float loadFactor);
+/*
+ @brief Initalize BSON object with default map size (64) and load factor (0.5)
+
+ @param obj - The uninitialized BSON Object
+
+ @return - true if the object was initialized successfully, false if not
+*/
+bool bson_object_initialize_default(BsonObject *obj);
+/*
+ @brief Deinitalize BSON object, free all associated memory,
+ and recursively clean up all sub-objects
+
+ @param obj - The BSON object to be deinitalized
+*/
+void bson_object_deinitialize(BsonObject *obj);
+
+/*
+ @brief Calculate the size, in bytes, of a given object when converted to a BSON document
+
+ @param obj - The BSON object from which the size is calculated
+
+ @return - The calculated size
+*/
+size_t bson_object_size(BsonObject *obj);
+
+/*
+ @brief Get the BSON represention of an object
+
+ @param obj - The array to be converted to BSON
+
+ @return - A byte array containing the BSON representation of the object,
+ this data must be freed by the caller after use
+*/
+uint8_t *bson_object_to_bytes(BsonObject *obj);
+/*
+ @brief Parse BSON data into an object
+
+ @param data - The BSON data to be parsed
+
+ @return - The BSON object created from the BSON data
+
+ @note DEPRECATED: use bson_object_from_bytes_len() instead
+*/
+BsonObject bson_object_from_bytes(uint8_t *data);
+
+/*
+ @brief Parse BSON data into an object
+
+ @param output - Pointer to an uninitialized BsonObject. On success, it is
+ initialized and stores converted data.
+ @param data - Byte buffer that contains BSON data to be parsed
+ @param dataSize - Number of bytes of the data stored in the byte buffer
+
+ @return - On success, a positive number indicating number of bytes consumed
+ is returned. On error, 0 is returned.
+*/
+size_t bson_object_from_bytes_len(BsonObject *output, const uint8_t *data, size_t dataSize);
+
+/*
+ @brief Get a JSON string representation of a BSON object
+
+ @param obj - The object to be converted to a JSON string
+ @param out - The output string of the function
+
+ @return - The value of out
+*/
+char *bson_object_to_string(BsonObject *obj, char *out);
+
+/*
+ @brief Put a new BSON object into a given object
+
+ @param obj - The object to be modified
+ @param key - The key used to reference the new object
+ (if it matches an existing key,
+ the associated value will be overwritten)
+ @param value - The pointer to the BSON object to be added to the object
+
+ @return - true if the value was set successfully, false if not
+*/
+bool bson_object_put_object(BsonObject *obj, const char *key, BsonObject *value);
+/*
+ @brief Put a new BSON array into a given object
+
+ @param obj - The object to be modified
+ @param key - The key used to reference the new array
+ (if it matches an existing key,
+ the associated value will be overwritten)
+ @param value - The pointer to the BSON array to be added to the object
+
+ @return - true if the value was set successfully, false if not
+*/
+bool bson_object_put_array(BsonObject *obj, const char *key, BsonArray *value);
+/*
+ @brief Put a new 32-bit integer value into a given object
+
+ @param obj - The object to be modified
+ @param key - The key used to reference the new integer value
+ (if it matches an existing key,
+ the associated value will be overwritten)
+ @param value - The integer value to be added to the object
+
+ @return - true if the value was set successfully, false if not
+*/
+bool bson_object_put_int32(BsonObject *obj, const char *key, int32_t value);
+/*
+ @brief Put a new 64-bit integer value into a given object
+
+ @param obj - The object to be modified
+ @param key - The key used to reference the new integer value
+ (if it matches an existing key,
+ the associated value will be overwritten)
+ @param value - The integer value to be added to the object
+
+ @return - true if the value was set successfully, false if not
+*/
+bool bson_object_put_int64(BsonObject *obj, const char *key, int64_t value);
+/*
+ @brief Put a new string value into a given object
+
+ @param obj - The object to be modified
+ @param key - The key used to reference the new string value
+ (if it matches an existing key,
+ the associated value will be overwritten)
+ @param value - The string value to be added to the object
+
+ @return - true if the value was set successfully, false if not
+*/
+bool bson_object_put_string(BsonObject *obj, const char *key, char *value);
+/*
+ @brief Put a new boolean value into a given object
+
+ @param obj - The object to be modified
+ @param key - The key used to reference the new boolean value
+ (if it matches an existing key,
+ the associated value will be overwritten)
+ @param value - The boolean value to be added to the object
+
+ @return - true if the value was set successfully, false if not
+*/
+bool bson_object_put_bool(BsonObject *obj, const char *key, bson_boolean value);
+/*
+ @brief Put a new floating-point value into a given object
+
+ @param obj - The object to be modified
+ @param key - The key used to reference the new floating-point value
+ (if it matches an existing key,
+ the associated value will be overwritten)
+ @param value - The floating-point value to be added to the object
+
+ @return - true if the value was set successfully, false if not
+*/
+bool bson_object_put_double(BsonObject *obj, const char *key, double value);
+
+/*
+ @brief Put a new element into a given object
+
+ @param obj - The object to be modified
+ @param key - The key used to reference the new element
+ @param type - The type of the element to be added
+ @param value - The value of the element to be added
+ @param allocSize - The size, in bytes, to be allocated for the element
+ @param elementSize - The size, in bytes, of the element when converted to BSON format
+
+ @return - true if the addition was successful, false if not
+*/
+BsonElement *bson_object_get(BsonObject *obj, const char *key);
+/*
+ @brief Retrieve the BSON object to which the specified key is mapped in an object
+
+ @param obj - The object to be accessed
+ @param key - The key associated with the object to be retrieved
+
+ @return - The pointer to the BSON object mapped to the given key if it exists, NULL otherwise
+*/
+BsonObject *bson_object_get_object(BsonObject *obj, const char *key);
+/*
+ @brief Retrieve the BSON array to which the specified key is mapped in an object
+
+ @param obj - The object to be accessed
+ @param key - The key associated with the array to be retrieved
+
+ @return - The pointer to the BSON array mapped to the given key if it exists, NULL otherwise
+*/
+BsonArray *bson_object_get_array(BsonObject *obj, const char *key);
+/*
+ @brief Retrieve the 32-bit integer value to which the specified key is mapped in an object
+
+ @param obj - The object to be accessed
+ @param key - The key associated with the integer value to be retrieved
+
+ @return - The 32-bit integer value mapped to the given key if it exists, NULL otherwise
+*/
+int32_t bson_object_get_int32(BsonObject *obj, const char *key);
+/*
+ @brief Retrieve the 64-bit integer value to which the specified key is mapped in an object
+
+ @param obj - The object to be accessed
+ @param key - The key associated with the integer value to be retrieved
+
+ @return - The 64-bit integer value mapped to the given key if it exists, NULL otherwise
+*/
+int64_t bson_object_get_int64(BsonObject *obj, const char *key);
+/*
+ @brief Retrieve the string value to which the specified key is mapped in an object
+
+ @param obj - The object to be accessed
+ @param key - The key associated with the string value to be retrieved
+
+ @return - The string value mapped to the given key if it exists, NULL otherwise
+*/
+char *bson_object_get_string(BsonObject *obj, const char *key);
+/*
+ @brief Retrieve the boolean value to which the specified key is mapped in an object
+
+ @param obj - The object to be accessed
+ @param key - The key associated with the boolean value to be retrieved
+
+ @return - The boolean value mapped to the given key if it exists, NULL otherwise
+*/
+bson_boolean bson_object_get_bool(BsonObject *obj, const char *key);
+/*
+ @brief Retrieve the floating-point value to which the specified key is mapped in an object
+
+ @param obj - The object to be accessed
+ @param key - The key associated with the floating-point value to be retrieved
+
+ @return - The floating-point value mapped to the given key if it exists, NULL otherwise
+*/
+double bson_object_get_double(BsonObject *obj, const char *key);
+
+/*
+ @brief Get an iterator for a given BSON object
+
+ @param obj - The object from which the iterator is created
+
+ @return - The iterator
+*/
+MapIterator bson_object_iterator(BsonObject *obj);
+/*
+ @brief Get the next value from an object iterator
+
+ @param iterator - The iterator to be advanced
+
+ @return - The next BSON object entry in the object if it exists,
+ an entry with a NULL element if the iterator has moved past the end
+ of the entry list
+*/
+BsonObjectEntry bson_object_iterator_next(MapIterator *iterator);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/BSON-lib/bson_util.c b/BSON-lib/bson_util.c
new file mode 100644
index 000000000..6734b29ef
--- /dev/null
+++ b/BSON-lib/bson_util.c
@@ -0,0 +1,157 @@
+#include "bson_util.h"
+
+void write_int32_le(uint8_t *bytes, int32_t value, size_t *position) {
+ int i = 0;
+ for (i = 0; i < SIZE_INT32; i++) {
+ bytes[(*position)++] = (uint8_t)value & 0x000000FF;
+ value >>= 8;
+ }
+}
+
+void write_int64_le(uint8_t *bytes, int64_t value, size_t *position) {
+ int i = 0;
+ for (i = 0; i < SIZE_INT64; i++) {
+ bytes[(*position)++] = (uint8_t)value & 0x000000FFull;
+ value >>= 8;
+ }
+}
+
+void write_double_le(uint8_t *bytes, double value, size_t *position) {
+ union doubleUnion_t {
+ double value;
+ uint64_t intValue;
+ };
+ union doubleUnion_t unionVal;
+ unionVal.value = value;
+ int i = 0;
+ for (i = 0; i < SIZE_DOUBLE; i++) {
+ bytes[(*position)++] = (uint8_t)unionVal.intValue & 0x000000FFull;
+ unionVal.intValue >>= 8;
+ }
+}
+
+int32_t read_int32_le(uint8_t **bytes) {
+ int32_t value = 0;
+ int i = 0;
+ for (i = SIZE_INT32 - 1; i >= 0; i--) {
+ value <<= 8;
+ value += (*bytes)[i];
+ }
+ (*bytes) += SIZE_INT32;
+ return value;
+}
+
+int64_t read_int64_le(uint8_t **bytes) {
+ int64_t value = 0;
+ int i = 0;
+ for (i = SIZE_INT64 - 1; i >= 0; i--) {
+ value <<= 8;
+ value += (*bytes)[i];
+ }
+ (*bytes) += SIZE_INT64;
+ return value;
+}
+
+double read_double_le(uint8_t **bytes) {
+ union doubleUnion_t {
+ double value;
+ uint64_t intValue;
+ };
+ union doubleUnion_t unionVal;
+ unionVal.intValue = 0;
+ int i = 0;
+ for (i = SIZE_DOUBLE - 1; i >= 0; i--) {
+ unionVal.intValue <<= 8;
+ unionVal.intValue += (*bytes)[i];
+ }
+ (*bytes) += SIZE_DOUBLE;
+ return unionVal.value;
+}
+
+size_t read_string_len(char **output, const uint8_t **data, size_t *dataSize) {
+ size_t i = 0;
+ for (i = 0; i < *dataSize; i++) {
+ if ((*data)[i] == 0x00) {
+ break;
+ }
+ }
+ if (i == *dataSize) {
+ // '\0' is not found
+ return 0;
+ }
+
+ *output = byte_array_to_bson_string((uint8_t *)*data, i);
+
+ // add 1 since we also consumed '\0' at the end
+ size_t bytesRead = i + 1;
+ (*data) += bytesRead;
+ *dataSize -= bytesRead;
+ return bytesRead;
+}
+
+uint8_t *string_to_byte_array(char *stringVal) {
+ size_t length = strlen(stringVal);
+ uint8_t *bytes = malloc(length + 1);
+ int i = 0;
+ for (i = 0; i < length; i++) {
+ bytes[i] = (uint8_t)stringVal[i];
+ }
+ bytes[length] = 0x00;
+ return bytes;
+}
+
+size_t c_string_length(uint8_t *value) {
+ size_t length = 0;
+ while (value[length] != 0x00) {
+ length++;
+ }
+ return length;
+}
+
+char *byte_array_to_string(uint8_t *bytes) {
+ size_t length = c_string_length(bytes);
+ return byte_array_to_bson_string(bytes, length);
+}
+
+char *byte_array_to_bson_string(uint8_t *bytes, size_t length) {
+ char *stringVal = malloc(sizeof(char) * (length + 1));
+
+ int i = 0;
+ for (i = 0; i < length; i++) {
+ stringVal[i] = (char)(bytes[i] & 0xFF);
+ }
+ stringVal[length] = 0x00;
+ return stringVal;
+}
+
+uint8_t *index_to_key(size_t index) {
+ size_t length = digits(index);
+ uint8_t *bytes = malloc(length);
+ size_t modValue = index;
+ int i = 0;
+ for (i = (int)length - 1; i >= 0; i--) {
+ //Convert digit to UTF-8
+ bytes[i] = 0x30 + (modValue % 10);
+ modValue /= 10;
+ }
+ return bytes;
+}
+
+size_t object_key_size(char *key) {
+ return strlen(key) + 1;
+}
+
+size_t array_key_size(size_t index) {
+ //One byte for each decimal digit in index plus null character
+ return digits(index) + 1;
+}
+
+size_t digits(size_t value) {
+ size_t modValue = value;
+ size_t numDigits = 1;
+ while (modValue >= 10) {
+ numDigits++;
+ modValue /= 10;
+ }
+ return numDigits;
+}
diff --git a/BSON-lib/bson_util.h b/BSON-lib/bson_util.h
new file mode 100644
index 000000000..012898ba6
--- /dev/null
+++ b/BSON-lib/bson_util.h
@@ -0,0 +1,201 @@
+#ifndef BSON_UTIL_H
+#define BSON_UTIL_H
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+
+//4 bytes for length, one for ending null character
+#define OBJECT_OVERHEAD_BYTES 5
+//Same as object
+#define ARRAY_OVERHEAD_BYTES 5
+//1 byte for element type
+#define ELEMENT_OVERHEAD_BYTES 1
+//4 bytes for length, one for ending null character
+#define STRING_OVERHEAD_BYTES 5
+
+//Sizes in bytes of each primitive type, as defined by the BSON spec
+#define SIZE_INT32 4
+#define SIZE_INT64 8
+#define SIZE_DOUBLE 8
+#define SIZE_BOOLEAN 1
+
+//Last byte in a BSON document
+#define DOCUMENT_END 0x00
+
+//Byte which defines the type of a value as defined in the BSON spec
+enum element_type {
+ TYPE_DOUBLE = 0x01,
+ TYPE_STRING = 0x02,
+ TYPE_DOCUMENT = 0x03,
+ TYPE_ARRAY = 0x04,
+ TYPE_BINARY = 0x05, //unused
+ TYPE_UNDEFINED = 0x06, //deprecated
+ TYPE_OBJECT_ID = 0x07, //unused
+ TYPE_BOOLEAN = 0x08,
+ TYPE_DATE_TIME = 0x09, //unused
+ TYPE_NULL = 0x0A, //unused
+ TYPE_REGEX = 0x0B, //unused
+ TYPE_DB_POINTER = 0x0C, //deprecated
+ TYPE_JS_CODE = 0x0D, //unused
+ TYPE_SYMBOL = 0x0E, //deprecated
+ TYPE_JS_CODE_WITH_SCOPE = 0x0F, //unused
+ TYPE_INT32 = 0x10,
+ TYPE_TIMESTAMP = 0x11, //unused
+ TYPE_INT64 = 0x12,
+ TYPE_DEC128 = 0x13, //unused
+ TYPE_MIN_KEY = 0xFF, //unused
+ TYPE_MAX_KEY = 0x7F //unused
+};
+typedef enum element_type element_type;
+
+//Definition of each boolean value according to the BSON spec
+enum bson_boolean {
+ BOOLEAN_INVALID = -1,
+ BOOLEAN_FALSE = 0x00,
+ BOOLEAN_TRUE = 0x01
+};
+typedef enum bson_boolean bson_boolean;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ @brief Write a little endian 32-bit integer value to a given buffer
+
+ @param bytes - The byte buffer to be written to
+ @param value - The integer value to be written to the buffer
+ @param position - Pointer to the current position in the buffer, will be advanced past the written value
+*/
+void write_int32_le(uint8_t *bytes, int32_t value, size_t *position);
+/*
+ @brief Write a little endian 64-bit integer value to a given buffer
+
+ @param bytes - The byte buffer to be written to
+ @param value - The integer value to be written to the buffer
+ @param position - Pointer to the current position in the buffer, will be advanced past the written value
+*/
+void write_int64_le(uint8_t *bytes, int64_t value, size_t *position);
+/*
+ @brief Write a little endian 64-bit floating-point value to a given buffer
+
+ @param bytes - The byte buffer to be written to
+ @param value - The integer value to be written to the buffer
+ @param position - Pointer to the current position in the buffer, will be advanced past the written value
+*/
+void write_double_le(uint8_t *bytes, double value, size_t *position);
+
+/*
+ @brief Read a little endian 32-bit integer value from a given buffer
+
+ @param bytes - Pointer to the byte buffer from which to read,
+ this value will be advanced past the value that was read
+
+ @return - The value that was read from the buffer
+*/
+int32_t read_int32_le(uint8_t **bytes);
+/*
+ @brief Read a little endian 64-bit integer value from a given buffer
+
+ @param bytes - Pointer to the byte buffer from which to read,
+ this value will be advanced past the value that was read
+
+ @return - The value that was read from the buffer
+*/
+int64_t read_int64_le(uint8_t **bytes);
+/*
+ @brief Read a little endian 64-bit floating point value from a given buffer
+
+ @param bytes - Pointer to the byte buffer from which to read,
+ this value will be advanced past the value that was read
+
+ @return - The value that was read from the buffer
+*/
+double read_double_le(uint8_t **bytes);
+
+/*
+ @brief Read a string from given buffer and return number of bytes read.
+ Update "data" and "dataSize" parameters on success.
+
+ @param output - Pointer to a char* value. On success, the value is updated to
+ point to a malloc()-ed buffer that stores the output.
+ Caller must call free() to release the buffer after use.
+ @param data - Pointer to the byte buffer from which to read. On success, this
+ value will be advanced past the value that was read.
+ @param dataSize - Pointer to a value that indicates the size of data in the
+ byte buffer. On success, this value will be decreased to
+ indicate the remaining data size in the buffer.
+
+ @return - On success, a positive number of bytes read (including last '\0')
+ is returned. On failure, 0 is returned.
+*/
+size_t read_string_len(char **output, const uint8_t **data, size_t *dataSize);
+
+/*
+ @brief Convert the give UTF-8 string into a byte array
+
+ @param stringVal - the string value to be converted
+
+ @return - The byte array representation of the string, must be freed by the caller after use
+*/
+uint8_t *string_to_byte_array(char *stringVal);
+/*
+ @brief Convert the given byte array to a UTF-8 string
+
+ @param bytes - The byte array to be converted
+
+ @return The converted string
+*/
+char *byte_array_to_string(uint8_t *bytes);
+/*
+ @brief Convert the given byte array to a UTF-8 BSON string
+
+ @param bytes - The byte array to be converted
+ @param length - The length of the array to be converted
+
+ @return The converted string (may include null characters)
+*/
+char *byte_array_to_bson_string(uint8_t *bytes, size_t length);
+
+/*
+ @brief Convert the given a array index into a BSON key
+
+ @param index - The index to be converted
+
+ @return - A byte array containing the BSON key representation of index, must be freed by the caller after use
+*/
+uint8_t *index_to_key(size_t index);
+
+/*
+ @brief Calculate the size, in bytes, of a BSON object key
+
+ @param key - The object key used for calculations
+
+ @return - The size of the BSON object key, in bytes
+*/
+size_t object_key_size(char *key);
+/*
+ @brief Calculate the size, in bytes, of a BSON array key
+
+ @param index - The array key (index) used for calculations
+
+ @return - The size of the BSON array key, in bytes
+*/
+size_t array_key_size(size_t index);
+
+/*
+ @brief Calculate the number of decimal digits in a given integer value
+
+ @param value - The value on which calculations are done
+
+ @return The number of decimal digits in value
+*/
+size_t digits(size_t value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/BSON-lib/emhashmap.c b/BSON-lib/emhashmap.c
new file mode 100755
index 000000000..5c9a55d9a
--- /dev/null
+++ b/BSON-lib/emhashmap.c
@@ -0,0 +1,156 @@
+#include "emhashmap.h"
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+static MapBucketList* find_bucket(HashMap* map, const char* key) {
+ MapBucketList* bucket = NULL;
+
+ if(map != NULL && map->buckets != NULL) {
+ bucket = &map->buckets[(*map->hash)(key, (size_t)map->bucket_count)];
+ }
+ return bucket;
+}
+
+void emhashmap_deinitialize(HashMap* map) {
+ if(map->entries != NULL) {
+ free(map->entries);
+ map->entries = NULL;
+ }
+
+ if(map->buckets != NULL) {
+ free(map->buckets);
+ map->buckets = NULL;
+ }
+}
+
+bool emhashmap_initialize(HashMap* map, int capacity, float load_factor, size_t (*hash_function)(const char*, size_t)) {
+ map->bucket_count = ((int)(capacity / load_factor) + 1);
+ map->capacity = capacity;
+ map->entries = (MapEntry*) malloc(sizeof(MapEntry) * (uint32_t)map->capacity);
+ memset(map->entries, 0, sizeof(MapEntry) * (uint32_t)map->capacity);
+ map->buckets = (MapBucketList*) malloc(sizeof(MapBucketList) * (uint32_t)map->bucket_count);
+ memset(map->buckets, 0, sizeof(MapBucketList) * (uint32_t)map->bucket_count);
+ map->hash = hash_function;
+ int i;
+ for(i = 0; i < map->bucket_count; i++) {
+ LIST_INIT(&map->buckets[i]);
+ }
+
+ LIST_INIT(&map->free_list);
+ for(i = 0; i < map->capacity; i++) {
+ LIST_INSERT_HEAD(&map->free_list, &map->entries[i], entries);
+ }
+ return map->buckets != NULL;
+}
+
+MapEntry* emhashmap_get(HashMap* map, const char* key) {
+ MapBucketList* bucket = find_bucket(map, key);
+
+ MapEntry* entry;
+ LIST_FOREACH(entry, bucket, entries) {
+ if(strcmp(entry->key, key) == 0) {
+ return entry;
+ }
+ }
+ return NULL;
+}
+
+bool emhashmap_contains(HashMap* map, const char* key) {
+ return emhashmap_get(map, key) != NULL;
+}
+
+bool emhashmap_put(HashMap* map, const char* key, void* value) {
+ MapBucketList* bucket = find_bucket(map, key);
+
+ MapEntry* entry, *matching_entry = NULL;
+ LIST_FOREACH(entry, bucket, entries) {
+ if(strcmp(entry->key, key) == 0) {
+ matching_entry = entry;
+ }
+ }
+
+ bool result = true;
+ if(matching_entry != NULL) {
+ matching_entry->value = value;
+ } else {
+ MapEntry* new_entry = LIST_FIRST(&map->free_list);
+ if(new_entry == NULL) {
+ result = false;
+ } else {
+ strncpy(new_entry->key, key, 255);
+ new_entry->value = value;
+ LIST_REMOVE(new_entry, entries);
+ LIST_INSERT_HEAD(bucket, new_entry, entries);
+ }
+ }
+ return result;
+}
+
+void* emhashmap_remove(HashMap* map, const char* key) {
+ MapBucketList* bucket = find_bucket(map, key);
+
+ MapEntry* entry, *matching_entry = NULL;
+ LIST_FOREACH(entry, bucket, entries) {
+ if(strcmp(entry->key, key) == 0) {
+ matching_entry = entry;
+ }
+ }
+
+ void* value = NULL;
+ if(matching_entry != NULL) {
+ value = matching_entry->value;
+ LIST_REMOVE(matching_entry, entries);
+ }
+ return value;
+}
+
+int emhashmap_size(HashMap* map) {
+ int size = 0;
+ int i;
+ for(i = 0; i < map->bucket_count; i++) {
+ MapEntry* entry = NULL;
+ LIST_FOREACH(entry, &map->buckets[i], entries) {
+ ++size;
+ }
+ }
+ return size;
+}
+
+bool emhashmap_is_empty(HashMap* map) {
+ return emhashmap_size(map) == 0;
+}
+
+float emhashmap_load_factor(HashMap* map) {
+ return emhashmap_size(map) / map->capacity;
+}
+
+MapIterator emhashmap_iterator(HashMap* map) {
+ MapIterator iterator;
+ iterator.current_bucket = 0;
+ iterator.current_entry = NULL;
+ iterator.map = map;
+ return iterator;
+}
+
+MapEntry* emhashmap_iterator_next(MapIterator* iterator) {
+ if(iterator != NULL) {
+ if(iterator->current_entry != NULL) {
+ iterator->current_entry = LIST_NEXT(iterator->current_entry, entries);
+ }
+
+ if(iterator->current_entry == NULL) {
+ while (iterator->current_entry == NULL &&
+ iterator->current_bucket < iterator->map->bucket_count) {
+ iterator->current_entry = LIST_FIRST(&iterator->map->buckets[iterator->current_bucket++]);
+ }
+ }
+ return iterator->current_entry;
+ }
+ else {
+ return NULL;
+ }
+}
diff --git a/BSON-lib/emhashmap.h b/BSON-lib/emhashmap.h
new file mode 100755
index 000000000..7d7f28721
--- /dev/null
+++ b/BSON-lib/emhashmap.h
@@ -0,0 +1,144 @@
+#ifndef _EMHASHMAP_H_
+#define _EMHASHMAP_H_
+
+#include <sys/queue.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Public: An entry in the map.
+ *
+ * key - the entry key, currently supports only integers.
+ * value - a pointer to the value. this must be allocated with malloc or
+ * be in global scope, and the map entry does not take ownership of its
+ * memory.
+ */
+struct MapEntry {
+ char key[255];
+ void* value;
+ LIST_ENTRY(MapEntry) entries;
+};
+typedef struct MapEntry MapEntry;
+
+LIST_HEAD(MapBucketList, MapEntry);
+typedef struct MapBucketList MapBucketList;
+
+/* Public: A struct encapsulating a map's state. All of the fields are private
+ * - use the emhashmap_ functions to interact with the map.
+ *
+ * bucket_count - The fixed count of buckets for elements in the map.
+ * capacity - The total, fixed capacity of the map.
+ * buckets - An array of MapBucketList lists, each a bucket in the map.
+ * entries - An array of all entry slots, to be used in each bucket.
+ * free_list - An array of all entries when not actively in a bucket.
+ */
+struct HashMap {
+ int bucket_count;
+ int capacity;
+ MapBucketList* buckets;
+ MapEntry* entries;
+ MapBucketList free_list;
+ size_t (*hash)(const char*, size_t);
+};
+typedef struct HashMap HashMap;
+
+struct MapIterator {
+ HashMap* map;
+ int current_bucket;
+ MapEntry* current_entry;
+};
+typedef struct MapIterator MapIterator;
+
+/* Public: Initialize a map with the given capacity and load factor (determines
+ * the number of buckets).
+ *
+ * This allocates memory for the buckets and entries, so make sure to call
+ * emhashmap_destroy(HashMap*) after done with this map.
+ *
+ * map - a pointer to the map to initialize. It must already be allocated on the
+ * stack or heap.
+ * capacity - the initial capacity for the map.
+ * load_factor - The desired load factor when the map is at capacity.
+ *
+ * Returns true if the map was initialized, successfully, false if space could
+ * not be allocated for the buckets or entries.
+ */
+bool emhashmap_initialize(HashMap* map, int capacity, float load_factor, size_t (*hash_function)(const char*, size_t));
+
+/* Public: De-initialize a map, freeing memory for the buckets and entries.
+ *
+ * This will *not* free the memory associated with any values stored in the map
+ * - only the buckets and map entry objects.
+ *
+ * map - a pointer to the map to deinitialize. It must already be allocated on
+ * the stack or heap.
+ */
+void emhashmap_deinitialize(HashMap* map);
+
+/* Public: Retrive the entry for a given key from the map.
+ *
+ * map - the map to retrive the value.
+ * key - the key for this value.
+ *
+ * Returns the MapEntry if found, otherwise NULL.
+ */
+MapEntry* emhashmap_get(HashMap* map, const char* key);
+
+/* Public: Check if the given key is in the map.
+ *
+ * map - the map to query.
+ * key - the key to check for membership.
+ *
+ * Returns true if the key is in the map.
+ */
+bool emhashmap_contains(HashMap* map, const char* key);
+
+/* Public: Put the value in the map with the given key.
+ *
+ * If the key already exists in the map, its value will be overridden (so make
+ * sure you've freed the memory associated with the existing value).
+ *
+ * Returns true if there was space in the map and the key-value pair was added
+ * successfully. Returns false if the map is full.
+ */
+bool emhashmap_put(HashMap* map, const char* key, void* value);
+
+/* Public: Remove a value with the given key from the map.
+ *
+ * map - the map to query.
+ * key - the key to remove.
+ *
+ * Returns the value pointer if found in the map and removed - the map user is
+ * responsible for freeing any memory associated with that pointer.
+ * Returns NULL if the key was not in the map.
+ */
+void* emhashmap_remove(HashMap* map, const char* key);
+
+/* Public: Get the number of keys in the map.
+ *
+ * map - the map to query.
+ *
+ * Returns the total number of keys in the map.
+ */
+int emhashmap_size(HashMap* map);
+
+/* Public: Check if a map is empty.
+ *
+ * map - the map to query.
+ *
+ * Returns true if there are no entries in the map.
+ */
+bool emhashmap_is_empty(HashMap* map);
+
+MapIterator emhashmap_iterator(HashMap* map);
+
+MapEntry* emhashmap_iterator_next(MapIterator* iterator);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _EMHASHMAP_H_
diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md
index 0ab2739ed..1970c5424 100644
--- a/DEPENDENCIES.md
+++ b/DEPENDENCIES.md
@@ -1,3 +1,33 @@
+## Library Dependencies
+### bson_c_lib (https://github.com/smartdevicelink/bson_c_lib)
+Copyright (c) 2017 SmartDeviceLink Consortium, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+* Neither the name of SmartDeviceLink Consortium, Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
## Test Dependencies
### Quick
@@ -566,4 +596,4 @@ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec
index 1f9316962..7d9694d7f 100644
--- a/SmartDeviceLink-iOS.podspec
+++ b/SmartDeviceLink-iOS.podspec
@@ -7,7 +7,6 @@ s.homepage = "https://github.com/smartdevicelink/SmartDeviceLink-iOS"
s.license = { :type => "New BSD", :file => "LICENSE" }
s.author = { "SmartDeviceLink Team" => "developer@smartdevicelink.com" }
s.platform = :ios, "8.0"
-s.dependency 'BiSON', '~> 1.2.0'
s.source = { :git => "https://github.com/smartdevicelink/sdl_ios.git", :tag => s.version.to_s }
s.requires_arc = true
s.resource_bundles = { 'SmartDeviceLink' => ['SmartDeviceLink/Assets/**/*'] }
diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
index 77acb13a2..de9acd5f8 100644
--- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
+++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
@@ -1079,15 +1079,6 @@
5D9FC2A31FD8814A00ACA5C2 /* SDLAudioFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9FC2A11FD8814A00ACA5C2 /* SDLAudioFile.h */; settings = {ATTRIBUTES = (Public, ); }; };
5D9FC2A61FD8815800ACA5C2 /* SDLPCMAudioConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9FC2A41FD8815800ACA5C2 /* SDLPCMAudioConverter.h */; };
5D9FC2A71FD8815800ACA5C2 /* SDLPCMAudioConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9FC2A51FD8815800ACA5C2 /* SDLPCMAudioConverter.m */; };
- 5D9FDA8F1F2A7D3400A495C8 /* bson_array.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D9FDA891F2A7D3400A495C8 /* bson_array.c */; };
- 5D9FDA901F2A7D3400A495C8 /* bson_array.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9FDA8A1F2A7D3400A495C8 /* bson_array.h */; };
- 5D9FDA911F2A7D3400A495C8 /* bson_object.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D9FDA8B1F2A7D3400A495C8 /* bson_object.c */; };
- 5D9FDA921F2A7D3400A495C8 /* bson_object.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9FDA8C1F2A7D3400A495C8 /* bson_object.h */; };
- 5D9FDA931F2A7D3400A495C8 /* bson_util.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D9FDA8D1F2A7D3400A495C8 /* bson_util.c */; };
- 5D9FDA941F2A7D3400A495C8 /* bson_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9FDA8E1F2A7D3400A495C8 /* bson_util.h */; };
- 5D9FDA981F2A7D3F00A495C8 /* emhashmap.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D9FDA951F2A7D3F00A495C8 /* emhashmap.c */; };
- 5D9FDA991F2A7D3F00A495C8 /* emhashmap.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9FDA961F2A7D3F00A495C8 /* emhashmap.h */; };
- 5D9FDA9A1F2A7D3F00A495C8 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 5D9FDA971F2A7D3F00A495C8 /* LICENSE */; };
5DA026901AD44EE700019F86 /* SDLDialNumberResponseSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA0268F1AD44EE700019F86 /* SDLDialNumberResponseSpec.m */; };
5DA102A41D4122C700C15826 /* NSMutableDictionary+SafeRemove.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA102A21D4122C700C15826 /* NSMutableDictionary+SafeRemove.h */; };
5DA102A51D4122C700C15826 /* NSMutableDictionary+SafeRemove.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA102A31D4122C700C15826 /* NSMutableDictionary+SafeRemove.m */; };
@@ -1165,6 +1156,14 @@
5DB996611F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB9965F1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.m */; };
5DBAE0AB1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */; };
5DBAE0AD1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */; };
+ 5DBD73D22315D82900744C40 /* bson_array.c in Sources */ = {isa = PBXBuildFile; fileRef = 5DBD73CA2315D82800744C40 /* bson_array.c */; };
+ 5DBD73D32315D82900744C40 /* bson_array.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBD73CB2315D82800744C40 /* bson_array.h */; };
+ 5DBD73D42315D82900744C40 /* bson_util.c in Sources */ = {isa = PBXBuildFile; fileRef = 5DBD73CC2315D82800744C40 /* bson_util.c */; };
+ 5DBD73D52315D82900744C40 /* bson_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBD73CD2315D82800744C40 /* bson_util.h */; };
+ 5DBD73D62315D82900744C40 /* bson_object.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBD73CE2315D82900744C40 /* bson_object.h */; };
+ 5DBD73D72315D82900744C40 /* emhashmap.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBD73CF2315D82900744C40 /* emhashmap.h */; };
+ 5DBD73D92315D82900744C40 /* emhashmap.c in Sources */ = {isa = PBXBuildFile; fileRef = 5DBD73D12315D82900744C40 /* emhashmap.c */; };
+ 5DBD73DB2315DA3200744C40 /* bson_object.c in Sources */ = {isa = PBXBuildFile; fileRef = 5DBD73DA2315DA3200744C40 /* bson_object.c */; };
5DBEFA541F434B9E009EE295 /* SDLStreamingMediaConfigurationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBEFA531F434B9E009EE295 /* SDLStreamingMediaConfigurationSpec.m */; };
5DBEFA581F436132009EE295 /* SDLFakeSecurityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBEFA571F436132009EE295 /* SDLFakeSecurityManager.m */; };
5DBF06231E64A83F00A5CF03 /* SDLLogManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBF06211E64A83F00A5CF03 /* SDLLogManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -1325,7 +1324,6 @@
8877F5EF1F34A72200DC128A /* SDLSendHapticDataResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 8877F5ED1F34A72200DC128A /* SDLSendHapticDataResponse.m */; };
8877F5F11F34AA2D00DC128A /* SDLSendHapticDataResponseSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8877F5F01F34AA2D00DC128A /* SDLSendHapticDataResponseSpec.m */; };
887BE4D422272B2200B397C2 /* SDLControlFramePayloadConstantsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 887BE4D322272B2200B397C2 /* SDLControlFramePayloadConstantsSpec.m */; };
- 88802FE920853AE600E9EBC6 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 5D9FDA971F2A7D3F00A495C8 /* LICENSE */; };
88802FEA20853AE600E9EBC6 /* SDLAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5D6F7A3D1BC811FC0070BF37 /* SDLAssets.xcassets */; };
88802FEB20853AE600E9EBC6 /* SDLLockScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5D616B481D552F7A00553F6B /* SDLLockScreen.storyboard */; };
88802FF120853BB700E9EBC6 /* SDLLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D4346851E771B5700B639C6 /* SDLLog.swift */; };
@@ -2752,15 +2750,6 @@
5D9FC2A11FD8814A00ACA5C2 /* SDLAudioFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDLAudioFile.h; path = SmartDeviceLink/SDLAudioFile.h; sourceTree = SOURCE_ROOT; };
5D9FC2A41FD8815800ACA5C2 /* SDLPCMAudioConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDLPCMAudioConverter.h; path = SmartDeviceLink/SDLPCMAudioConverter.h; sourceTree = SOURCE_ROOT; };
5D9FC2A51FD8815800ACA5C2 /* SDLPCMAudioConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLPCMAudioConverter.m; path = SmartDeviceLink/SDLPCMAudioConverter.m; sourceTree = SOURCE_ROOT; };
- 5D9FDA891F2A7D3400A495C8 /* bson_array.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bson_array.c; path = bson_c_lib/src/bson_array.c; sourceTree = SOURCE_ROOT; };
- 5D9FDA8A1F2A7D3400A495C8 /* bson_array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bson_array.h; path = bson_c_lib/src/bson_array.h; sourceTree = SOURCE_ROOT; };
- 5D9FDA8B1F2A7D3400A495C8 /* bson_object.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bson_object.c; path = bson_c_lib/src/bson_object.c; sourceTree = SOURCE_ROOT; };
- 5D9FDA8C1F2A7D3400A495C8 /* bson_object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bson_object.h; path = bson_c_lib/src/bson_object.h; sourceTree = SOURCE_ROOT; };
- 5D9FDA8D1F2A7D3400A495C8 /* bson_util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bson_util.c; path = bson_c_lib/src/bson_util.c; sourceTree = SOURCE_ROOT; };
- 5D9FDA8E1F2A7D3400A495C8 /* bson_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bson_util.h; path = bson_c_lib/src/bson_util.h; sourceTree = SOURCE_ROOT; };
- 5D9FDA951F2A7D3F00A495C8 /* emhashmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = emhashmap.c; path = bson_c_lib/src/emhashmap/emhashmap.c; sourceTree = SOURCE_ROOT; };
- 5D9FDA961F2A7D3F00A495C8 /* emhashmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = emhashmap.h; path = bson_c_lib/src/emhashmap/emhashmap.h; sourceTree = SOURCE_ROOT; };
- 5D9FDA971F2A7D3F00A495C8 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = bson_c_lib/src/emhashmap/LICENSE; sourceTree = SOURCE_ROOT; };
5DA0268F1AD44EE700019F86 /* SDLDialNumberResponseSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLDialNumberResponseSpec.m; sourceTree = "<group>"; };
5DA102A21D4122C700C15826 /* NSMutableDictionary+SafeRemove.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableDictionary+SafeRemove.h"; sourceTree = "<group>"; };
5DA102A31D4122C700C15826 /* NSMutableDictionary+SafeRemove.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableDictionary+SafeRemove.m"; sourceTree = "<group>"; };
@@ -2834,6 +2823,14 @@
5DB9965F1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadVideoStartServiceAck.m; sourceTree = "<group>"; };
5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLNotificationDispatcherSpec.m; sourceTree = "<group>"; };
5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLResponseDispatcherSpec.m; sourceTree = "<group>"; };
+ 5DBD73CA2315D82800744C40 /* bson_array.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bson_array.c; path = "BSON-lib/bson_array.c"; sourceTree = SOURCE_ROOT; };
+ 5DBD73CB2315D82800744C40 /* bson_array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bson_array.h; path = "BSON-lib/bson_array.h"; sourceTree = SOURCE_ROOT; };
+ 5DBD73CC2315D82800744C40 /* bson_util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bson_util.c; path = "BSON-lib/bson_util.c"; sourceTree = SOURCE_ROOT; };
+ 5DBD73CD2315D82800744C40 /* bson_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bson_util.h; path = "BSON-lib/bson_util.h"; sourceTree = SOURCE_ROOT; };
+ 5DBD73CE2315D82900744C40 /* bson_object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bson_object.h; path = "BSON-lib/bson_object.h"; sourceTree = SOURCE_ROOT; };
+ 5DBD73CF2315D82900744C40 /* emhashmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = emhashmap.h; path = "BSON-lib/emhashmap.h"; sourceTree = SOURCE_ROOT; };
+ 5DBD73D12315D82900744C40 /* emhashmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = emhashmap.c; path = "BSON-lib/emhashmap.c"; sourceTree = SOURCE_ROOT; };
+ 5DBD73DA2315DA3200744C40 /* bson_object.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bson_object.c; path = "BSON-lib/bson_object.c"; sourceTree = SOURCE_ROOT; };
5DBEFA531F434B9E009EE295 /* SDLStreamingMediaConfigurationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLStreamingMediaConfigurationSpec.m; path = DevAPISpecs/SDLStreamingMediaConfigurationSpec.m; sourceTree = "<group>"; };
5DBEFA561F436132009EE295 /* SDLFakeSecurityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDLFakeSecurityManager.h; path = DevAPISpecs/SDLFakeSecurityManager.h; sourceTree = "<group>"; };
5DBEFA571F436132009EE295 /* SDLFakeSecurityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLFakeSecurityManager.m; path = DevAPISpecs/SDLFakeSecurityManager.m; sourceTree = "<group>"; };
@@ -5450,27 +5447,18 @@
5DA49C8C1F1E549000E65FC5 /* BSON library */ = {
isa = PBXGroup;
children = (
- 5D9FDA891F2A7D3400A495C8 /* bson_array.c */,
- 5D9FDA8A1F2A7D3400A495C8 /* bson_array.h */,
- 5D9FDA8B1F2A7D3400A495C8 /* bson_object.c */,
- 5D9FDA8C1F2A7D3400A495C8 /* bson_object.h */,
- 5D9FDA8D1F2A7D3400A495C8 /* bson_util.c */,
- 5D9FDA8E1F2A7D3400A495C8 /* bson_util.h */,
- 5DA49CB51F1E64BB00E65FC5 /* emhashmap */,
+ 5DBD73CE2315D82900744C40 /* bson_object.h */,
+ 5DBD73DA2315DA3200744C40 /* bson_object.c */,
+ 5DBD73CB2315D82800744C40 /* bson_array.h */,
+ 5DBD73CA2315D82800744C40 /* bson_array.c */,
+ 5DBD73CD2315D82800744C40 /* bson_util.h */,
+ 5DBD73CC2315D82800744C40 /* bson_util.c */,
+ 5DBD73CF2315D82900744C40 /* emhashmap.h */,
+ 5DBD73D12315D82900744C40 /* emhashmap.c */,
);
name = "BSON library";
sourceTree = "<group>";
};
- 5DA49CB51F1E64BB00E65FC5 /* emhashmap */ = {
- isa = PBXGroup;
- children = (
- 5D9FDA951F2A7D3F00A495C8 /* emhashmap.c */,
- 5D9FDA961F2A7D3F00A495C8 /* emhashmap.h */,
- 5D9FDA971F2A7D3F00A495C8 /* LICENSE */,
- );
- name = emhashmap;
- sourceTree = "<group>";
- };
5DA49CE21F1EA77900E65FC5 /* Control Frame Payloads */ = {
isa = PBXGroup;
children = (
@@ -6331,6 +6319,7 @@
5DB9965C1F268F97002D8795 /* SDLControlFramePayloadVideoStartService.h in Headers */,
5D1665C81CF8CA3D00CC4CA1 /* SDLPermissionFilter.h in Headers */,
E9C32B911AB20BA200F283AF /* SDLIAPSession.h in Headers */,
+ 5DBD73D52315D82900744C40 /* bson_util.h in Headers */,
5D61FCD71A84238C00846EE7 /* SDLInteractionMode.h in Headers */,
8881AFBE2225E9BB00EA870B /* SDLGetCloudAppPropertiesResponse.h in Headers */,
880FE6272267AE5300723732 /* SDLIAPConstants.h in Headers */,
@@ -6347,11 +6336,9 @@
5D61FC7A1A84238C00846EE7 /* SDLDeleteInteractionChoiceSet.h in Headers */,
5D61FC3B1A84238C00846EE7 /* SDLAlertManeuverResponse.h in Headers */,
5DB9964E1F26886C002D8795 /* SDLControlFramePayloadEndService.h in Headers */,
- 5D9FDA991F2A7D3F00A495C8 /* emhashmap.h in Headers */,
5D61FDB71A84238C00846EE7 /* SDLSyncPData.h in Headers */,
5D61FD011A84238C00846EE7 /* SDLOnAudioPassThru.h in Headers */,
8854682F2225BDAE00994D8D /* SDLHybridAppPreference.h in Headers */,
- 5D9FDA901F2A7D3400A495C8 /* bson_array.h in Headers */,
5D61FDCB1A84238C00846EE7 /* SDLTextFieldName.h in Headers */,
5D61FD8B1A84238C00846EE7 /* SDLSetMediaClockTimer.h in Headers */,
DA6223BD1E7B088200878689 /* CVPixelBufferRef+SDLUtil.h in Headers */,
@@ -6452,6 +6439,7 @@
5D61FD871A84238C00846EE7 /* SDLSetGlobalProperties.h in Headers */,
5D92936120B354BE00FCC775 /* SDLChoiceSetDelegate.h in Headers */,
5D61FC741A84238C00846EE7 /* SDLDeleteCommandResponse.h in Headers */,
+ 5DBD73D62315D82900744C40 /* bson_object.h in Headers */,
5D61FDF11A84238C00846EE7 /* SDLUpdateTurnList.h in Headers */,
5DB996571F268ECB002D8795 /* SDLControlFramePayloadAudioStartServiceAck.h in Headers */,
5D61FD671A84238C00846EE7 /* SDLResult.h in Headers */,
@@ -6497,7 +6485,6 @@
5D61FCFA1A84238C00846EE7 /* SDLMyKey.h in Headers */,
8B7B31A61F2F875200BDC38D /* SDLVideoStreamingCapability.h in Headers */,
5D61FC981A84238C00846EE7 /* SDLECallInfo.h in Headers */,
- 5D9FDA921F2A7D3400A495C8 /* bson_object.h in Headers */,
5D61FD7B1A84238C00846EE7 /* SDLScrollableMessage.h in Headers */,
DA9F7E931DCC04E400ACAE48 /* SDLUnsubscribeWayPoints.h in Headers */,
5D61FD3D1A84238C00846EE7 /* SDLPrimaryAudioSource.h in Headers */,
@@ -6688,6 +6675,7 @@
5D61FDEF1A84238C00846EE7 /* SDLUpdateMode.h in Headers */,
EED5CA001F4D18DC00F04000 /* SDLRAWH264Packetizer.h in Headers */,
5D293AFE1FE078A9000CBD7E /* SDLCarWindowViewController.h in Headers */,
+ 5DBD73D72315D82900744C40 /* emhashmap.h in Headers */,
8818ADD82100FC18007D6F19 /* SDLTurnSignal.h in Headers */,
5D61FDDB1A84238C00846EE7 /* SDLTriggerSource.h in Headers */,
5D61FD8F1A84238C00846EE7 /* SDLShow.h in Headers */,
@@ -6704,7 +6692,6 @@
332A91501CED9CF10043824C /* SDLAppInfo.h in Headers */,
5D61FDA71A84238C00846EE7 /* SDLSpeakResponse.h in Headers */,
5D1665CB1CF8CA6700CC4CA1 /* NSNumber+NumberType.h in Headers */,
- 5D9FDA941F2A7D3400A495C8 /* bson_util.h in Headers */,
5D61FD771A84238C00846EE7 /* SDLSamplingRate.h in Headers */,
5DF40B22208E761A00DD6FDA /* SDLVoiceCommandManager.h in Headers */,
5D61FCBB1A84238C00846EE7 /* SDLGPSData.h in Headers */,
@@ -6728,6 +6715,7 @@
5DBF06351E64A9FE00A5CF03 /* SDLLogConstants.h in Headers */,
75FF2E3B22E0DD5400D0C13B /* SDLMsgVersion.h in Headers */,
DAC572671D10C5640004288B /* CGPoint_Util.h in Headers */,
+ 5DBD73D32315D82900744C40 /* bson_array.h in Headers */,
5D61FDF91A84238C00846EE7 /* SDLV2ProtocolHeader.h in Headers */,
884E702B21FBB151008D53BA /* SDLAppServiceRecord.h in Headers */,
5DBF06231E64A83F00A5CF03 /* SDLLogManager.h in Headers */,
@@ -6949,7 +6937,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 5D9FDA9A1F2A7D3F00A495C8 /* LICENSE in Resources */,
5D6F7A3E1BC811FC0070BF37 /* SDLAssets.xcassets in Resources */,
5D616B451D552F7A00553F6B /* SDLLockScreen.storyboard in Resources */,
);
@@ -6988,7 +6975,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 88802FE920853AE600E9EBC6 /* LICENSE in Resources */,
88802FEA20853AE600E9EBC6 /* SDLAssets.xcassets in Resources */,
88802FEB20853AE600E9EBC6 /* SDLLockScreen.storyboard in Resources */,
);
@@ -7138,6 +7124,7 @@
DA9F7E741DCC004C00ACAE48 /* SDLGetWayPointsResponse.m in Sources */,
5D61FD4D1A84238C00846EE7 /* SDLProtocolMessageDisassembler.m in Sources */,
5D61FD4B1A84238C00846EE7 /* SDLProtocolMessageAssembler.m in Sources */,
+ 5DBD73D42315D82900744C40 /* bson_util.c in Sources */,
5D61FCC41A84238C00846EE7 /* SDLHMIPermissions.m in Sources */,
5D61FE141A84238C00846EE7 /* SDLWiperStatus.m in Sources */,
5D61FC8B1A84238C00846EE7 /* SDLDiagnosticMessageResponse.m in Sources */,
@@ -7234,9 +7221,9 @@
5D61FD9C1A84238C00846EE7 /* SDLSlider.m in Sources */,
5D0A7383203F23F30001595D /* SDLSoftButtonManager.m in Sources */,
5DCF76FA1ACDD7CD00BB647B /* SDLSendLocationResponse.m in Sources */,
- 5D9FDA8F1F2A7D3400A495C8 /* bson_array.c in Sources */,
5D61FD661A84238C00846EE7 /* SDLResetGlobalPropertiesResponse.m in Sources */,
5D61FCFE1A84238C00846EE7 /* SDLObjectWithPriority.m in Sources */,
+ 5DBD73D22315D82900744C40 /* bson_array.c in Sources */,
5D92937D20B70A3E00FCC775 /* SDLPresentKeyboardOperation.m in Sources */,
5DBF06241E64A83F00A5CF03 /* SDLLogManager.m in Sources */,
5D61FC401A84238C00846EE7 /* SDLAmbientLightStatus.m in Sources */,
@@ -7249,7 +7236,6 @@
5D61FD981A84238C00846EE7 /* SDLSingleTireStatus.m in Sources */,
1EB59CA8202D946500343A61 /* SDLMassageModeData.m in Sources */,
8881AFB32225DED900EA870B /* SDLSetCloudAppPropertiesResponse.m in Sources */,
- 5D9FDA931F2A7D3400A495C8 /* bson_util.c in Sources */,
5D61FD511A84238C00846EE7 /* SDLProxy.m in Sources */,
5D61FD461A84238C00846EE7 /* SDLProtocolHeader.m in Sources */,
5DD8406320FCD6C10082CE04 /* SDLElectronicParkBrakeStatus.m in Sources */,
@@ -7370,10 +7356,10 @@
EED5CA021F4D18EC00F04000 /* SDLRAWH264Packetizer.m in Sources */,
5D61FC851A84238C00846EE7 /* SDLDeviceLevelStatus.m in Sources */,
EE38C0C3211C440400E170AD /* SDLSecondaryTransportPrimaryProtocolHandler.m in Sources */,
- 5D9FDA981F2A7D3F00A495C8 /* emhashmap.c in Sources */,
5D61FD1E1A84238C00846EE7 /* SDLOnTBTClientState.m in Sources */,
5D0C29FD20D93D8C008B56CD /* SDLVideoStreamingState.m in Sources */,
5DD67CBD1E661C84009CD394 /* SDLLogTargetOSLog.m in Sources */,
+ 5DBD73D92315D82900744C40 /* emhashmap.c in Sources */,
DA9F7E641DCBFAC800ACAE48 /* SDLDateTime.m in Sources */,
5D61FD581A84238C00846EE7 /* SDLPutFileResponse.m in Sources */,
5D61FCB21A84238C00846EE7 /* SDLGetDTCs.m in Sources */,
@@ -7472,7 +7458,6 @@
5DAD5F80204DEDEB0025624C /* SDLScreenManager.m in Sources */,
1EAA4732203442C0000FE74B /* SDLLightName.m in Sources */,
5D61FDC21A84238C00846EE7 /* SDLSystemRequestResponse.m in Sources */,
- 5D9FDA911F2A7D3400A495C8 /* bson_object.c in Sources */,
5D61FD001A84238C00846EE7 /* SDLOnAppInterfaceUnregistered.m in Sources */,
5D61FC6C1A84238C00846EE7 /* SDLCreateInteractionChoiceSet.m in Sources */,
5DCD7AF71FCCA8E400A0FC7F /* SDLScreenshotViewController.m in Sources */,
@@ -7493,6 +7478,7 @@
5D61FC931A84238C00846EE7 /* SDLDisplayType.m in Sources */,
5D61FCE31A84238C00846EE7 /* SDLKeyboardLayout.m in Sources */,
5D61FE0C1A84238C00846EE7 /* SDLVehicleType.m in Sources */,
+ 5DBD73DB2315DA3200744C40 /* bson_object.c in Sources */,
880E35B42088F75A00181259 /* SDLSystemCapabilityManager.m in Sources */,
1EAA474A203567FA000FE74B /* SDLHMISettingsControlCapabilities.m in Sources */,
DA9F7E941DCC04E400ACAE48 /* SDLUnsubscribeWayPoints.m in Sources */,
diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec
index 5e1f6be76..313b73b5d 100644
--- a/SmartDeviceLink.podspec
+++ b/SmartDeviceLink.podspec
@@ -7,7 +7,6 @@ s.homepage = "https://github.com/smartdevicelink/SmartDeviceLink-iOS"
s.license = { :type => "New BSD", :file => "LICENSE" }
s.author = { "SmartDeviceLink Team" => "developer@smartdevicelink.com" }
s.platform = :ios, "8.0"
-s.dependency 'BiSON', '~> 1.2.0'
s.source = { :git => "https://github.com/smartdevicelink/sdl_ios.git", :tag => s.version.to_s }
s.requires_arc = true
s.swift_version = '4.2'
diff --git a/bson_c_lib b/bson_c_lib
deleted file mode 160000
-Subproject 5e79ef239b88246504ca8efa017479bf417c516