Commit df3cdeea authored by Greg Williams's avatar Greg Williams
Browse files

Nearing completion of transision to using client allocated ByteBuffers for...

Nearing completion of transision to using client allocated ByteBuffers for variable length protobuf byte arrays
parent 8deee4dd
Loading
Loading
Loading
Loading
+3 −17
Original line number Diff line number Diff line
@@ -51,20 +51,6 @@ KineticStatus KineticClient_Connect(const KineticSession* config,
 */
KineticStatus KineticClient_Disconnect(KineticSessionHandle* const handle);

/**
 * @brief Creates a new key/value entry with preallocated ByteArrays for
 *        pertinent metadata fields. 'value' and its memory are owned by
 *        the caller.
 *
 * @param handle    KineticSessionHandle for a connected session.
 * @param value     Payload ByteArray w/ caller-allocated buffer to embed in
 *                  entry.
 *
 * @return          Returns the resulting KineticStatus
 */
KineticStatus KineticClient_CreateEntry(KineticSessionHandle handle,
    ByteArray value);

/**
 * @brief Executes a NOOP command to test whether the Kinetic Device is operational.
 *
@@ -84,7 +70,7 @@ KineticStatus KineticClient_NoOp(KineticSessionHandle handle);
 * @return              Returns the resulting KineticStatus
 */
KineticStatus KineticClient_Put(KineticSessionHandle handle,
    KineticKeyValue* const metadata);
    KineticEntry* const metadata);

/**
 * @brief Executes a GET command to retrieve and entry from the Kinetic Device.
@@ -96,7 +82,7 @@ KineticStatus KineticClient_Put(KineticSessionHandle handle,
 * @return              Returns the resulting KineticStatus
 */
KineticStatus KineticClient_Get(KineticSessionHandle handle,
    KineticKeyValue* const metadata);
    KineticEntry* const metadata);

/**
 * @brief Executes a DELETE command to delete an entry from the Kinetic Device
@@ -108,6 +94,6 @@ KineticStatus KineticClient_Get(KineticSessionHandle handle,
 * @return              Returns the resulting KineticStatus
 */
KineticStatus KineticClient_Delete(KineticSessionHandle handle,
    KineticKeyValue* const metadata);
    KineticEntry* const metadata);

#endif // _KINETIC_CLIENT_H
+7 −97
Original line number Diff line number Diff line
@@ -32,9 +32,7 @@
#include <stdio.h>
#include <assert.h>
#include <limits.h>

// #include <netinet/in.h>
// #include <ifaddrs.h>
#include "byte_array.h"


#define KINETIC_HANDLE_INVALID  (0)
@@ -60,55 +58,6 @@
#ifndef LOG_FILE_NAME_MAX
#define LOG_FILE_NAME_MAX (HOST_NAME_MAX)
#endif

/**
 * @brief Structure for handling generic arrays of bytes
 *
 * The data contained in a `ByteArray` is an arbitrary sequence of
 * bytes. It may contain embedded `NULL` characters and is not required to be
 * `NULL`-terminated.
 */
typedef struct _ByteArray {
    size_t  len;    /**< Number of bytes in the `data` field. */
    uint8_t *data;  /**< Pointer to an allocated array of data bytes. */
} ByteArray;

#define BYTE_ARRAY_NONE \
    (ByteArray){.len = 0, .data = NULL}
#define BYTE_ARRAY_INIT(_data) (ByteArray) \
    {.data = (uint8_t*)(_data), .len = sizeof(_data)};
#define BYTE_ARRAY_INIT_WITH_LEN(_data, _len) \
    (ByteArray){.data = (uint8_t*)(_data), .len = (_len)};
#define BYTE_ARRAY_CREATE(name, len) \
    uint8_t ( name ## _buf )[(len)]; ByteArray (name) = BYTE_ARRAY_INIT(( name ## _buf ));
#define BYTE_ARRAY_CREATE_WITH_DATA(_name, _data) \
    uint8_t ( _name ## _data )[sizeof(_data)]; ByteArray (_name) = {.data = (uint8_t*(_data)), .len = sizeof(data)};
#define BYTE_ARRAY_CREATE_WITH_BUFFER(_name, _buf) \
    ByteArray (_name) = {.data = (uint8_t*(_buf)), .len = 0};
#define BYTE_ARRAY_INIT_FROM_CSTRING(str) \
    (ByteArray){.data = (uint8_t*)(str), .len = strlen(str)}
#define BYTE_ARRAY_FILL_WITH_DUMMY_DATA(_array) \
    {size_t i=0; for(;i<(_array).len;++i){(_array).data[i] = (uint8_t)(i & 0xFFu);} }


/**
 * @brief Structure for an embedded ByteArray as a buffer
 *
 * The `bytesUsed` field is initialized to zero, and is to incremented as each
 * byte is consumed, but shall not exceed the `array` length
 */
typedef struct
{
    ByteArray   array;
    size_t      bytesUsed;
} ByteBuffer;
#define BYTE_BUFFER_INIT(_array) (ByteBuffer) { \
    .array = (ByteArray) { \
        .data = (_array).data, \
        .len = (_array).len }, \
    .bytesUsed = 0, \
}

/**
 * @brief Enumeration of encryption/checksum key algorithms
 */
@@ -210,57 +159,18 @@ typedef enum
extern const char* KineticStatusDescriptor[];


// KeyValue data
typedef struct _KineticKeyValue
{
    ByteArray key;
    ByteArray newVersion;
    ByteArray dbVersion;
    ByteArray tag;
    bool force;
    KineticAlgorithm algorithm;
    bool metadataOnly;
    KineticSynchronization synchronization;
    ByteArray value;
} KineticKeyValue;
#define KINETIC_KEY_VALUE_INIT(_keyValue) \
    memset((_keyValue), 0, sizeof(KineticKeyValue));

// KineticEntry - byte arrays need to be preallocated by the client
typedef struct _KineticEntry {
    KineticKeyValue keyValue;
    KineticSessionHandle sessionHandle;
    uint8_t keyData[KINETIC_MAX_KEY_LEN];
    uint8_t newVersionData[KINETIC_MAX_VERSION_LEN];
    uint8_t dbVersionData[KINETIC_MAX_VERSION_LEN];
    uint8_t tagData[KINETIC_MAX_VERSION_LEN];
    ByteBuffer key;
    ByteBuffer newVersion;
    ByteBuffer dbVersion;
    ByteBuffer tag;
    bool force;
    KineticAlgorithm algorithm;
    bool metadataOnly;
    KineticSynchronization synchronization;
    uint8_t valueData[PDU_VALUE_MAX_LEN];
    ByteBuffer value;
} KineticEntry;
#define KINTEIC_ENTRY_INIT(_entry, _sessionHandle) \
{ \
    KINETIC_KEY_VALUE_INIT(&(_entry)->keyValue); \
    (_entry)->sessionHandle = (_sessionHandle); \
    (_entry)->keyValue.key = (ByteArray){ \
        .data = (_entry)->keyData, .len = sizeof((_entry)->keyData) }; \
    (_entry)->keyValue.newVersion = (ByteArray){ \
        .data = (_entry)->newVersionData, .len = sizeof((_entry)->newVersionData) }; \
    (_entry)->keyValue.dbVersion = (ByteArray){ \
        .data = (_entry)->dbVersionData, .len = sizeof((_entry)->dbVersionData) }; \
    (_entry)->keyValue.tag = (ByteArray){ \
        .data = (_entry)->tagData, .len = sizeof((_entry)->tagData) }; \
    (_entry)->keyValue.value = (ByteArray){ \
        .data = (_entry)->valueData, .len = sizeof((_entry)->valueData) }; \
}

// Expose normally private data for test builds to allow inspection
#ifdef TEST
#define STATIC
#else
#define STATIC static
#endif


#endif // _KINETIC_TYPES_H

src/lib/byte_array.c

0 → 100644
+117 −0
Original line number Diff line number Diff line
#include "byte_array.h"
#include <assert.h>
#include <string.h>

ByteArray ByteArray_Create(uint8_t* data, size_t len)
{
    return (ByteArray) {.data = (uint8_t*)(data), .len = len};
}

ByteArray ByteArray_CreateWithCString(char* str)
{
    return (ByteArray) {.data = (uint8_t*)str, .len = strlen(str)};
}

void ByteArray_FillWithDummyData(ByteArray array)
{
    for(size_t i = 0; i < array.len; i++) {
        array.data[i] = (uint8_t)(i & 0x0FFu);
    }
}

ByteArray ByteArray_GetSlice(ByteArray array, size_t start, size_t len)
{
    assert(array.data != NULL);
    assert(start < array.len);
    assert(start + len <= array.len);
    return (ByteArray){.data = &array.data[start], .len = len};
}



ByteBuffer ByteBuffer_Create(uint8_t* data, size_t max_len)
{
    return (ByteBuffer) {
        .array = (ByteArray) {.data = data, .len = max_len},
        .bytesUsed = 0,
    };
}

ByteBuffer ByteBuffer_CreateWithArray(ByteArray array)
{
    return (ByteBuffer) {.array = array, .bytesUsed = 0};
}

long ByteBuffer_BytesRemaining(const ByteBuffer buffer)
{
    assert(buffer.array.data != NULL);
    return ((long)buffer.array.len - (long)buffer.bytesUsed);
}

ByteArray ByteBuffer_Consume(ByteBuffer* buffer, size_t len)
{
    assert(buffer != NULL);
    assert(buffer->array.data != NULL);
    if (buffer->bytesUsed + len > buffer->array.len) {
        return BYTE_ARRAY_NONE;
    }
    ByteArray slice = {
        .data = &buffer->array.data[buffer->bytesUsed],
        .len = len,
    };
    buffer->bytesUsed += len;
    return slice;
}

bool ByteBuffer_Append(ByteBuffer* buffer,
    const uint8_t* data, size_t len)
{
    assert(buffer->array.data != NULL);
    assert(data != NULL);
    if (len == 0 || ((buffer->bytesUsed + len) > buffer->array.len)) {
        return false;
    }
    memcpy(&buffer->array.data[buffer->bytesUsed], data, len);
    buffer->bytesUsed += len;
    return true;
}

bool ByteBuffer_AppendArray(ByteBuffer* buffer, const ByteArray array)
{
    assert(buffer->array.data != NULL);
    assert(array.data != NULL);
    if (array.len == 0 || ((buffer->bytesUsed + array.len) > buffer->array.len)) {
        return false;
    }
    memcpy(&buffer->array.data[buffer->bytesUsed], array.data, array.len);
    buffer->bytesUsed += array.len;
    return true;
}

bool ByteBuffer_AppendCString(ByteBuffer* buffer, const char* str)
{
    assert(buffer->array.data != NULL);
    assert(str != NULL);
    int len = strlen(str);
    if (len == 0 || ((buffer->bytesUsed + len) > buffer->array.len)) {
        return false;
    }
    memcpy(&buffer->array.data[buffer->bytesUsed], str, len);
    buffer->bytesUsed += len;
    return true;
}

#include <stdio.h>

bool ByteBuffer_AppendDummyData(ByteBuffer* buffer, size_t len)
{
    assert(buffer->array.data != NULL);
    if (len == 0 || ((buffer->bytesUsed + len) > buffer->array.len)) {
        return false;
    }
    for(size_t i = 0; i < len; i++) {
        buffer->array.data[buffer->bytesUsed + i] = (uint8_t)(i & 0x0FFu);
    }
    buffer->bytesUsed += len;
    return true;
}

src/lib/byte_array.h

0 → 100644
+49 −0
Original line number Diff line number Diff line
#ifndef _BYTE_ARRAY_H
#define _BYTE_ARRAY_H

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

/**
 * @brief Structure for handling generic arrays of bytes
 *
 * The data contained in a `ByteArray` is an arbitrary sequence of
 * bytes. It may contain embedded `NULL` characters and is not required to be
 * `NULL`-terminated.
 */
typedef struct _ByteArray {
    size_t  len;    /**< Number of bytes in the `data` field. */
    uint8_t *data;  /**< Pointer to an allocated array of data bytes. */
} ByteArray;

/** @brief Convenience macro to represent an empty array with no data */
#define BYTE_ARRAY_NONE (ByteArray){.len = 0, .data = NULL}

ByteArray ByteArray_Create(uint8_t* data, size_t len);
ByteArray ByteArray_CreateWithCString(char* str);
void ByteArray_FillWithDummyData(ByteArray array);
ByteArray ByteArray_GetSlice(ByteArray array, size_t start, size_t len);

/**
 * @brief Structure for an embedded ByteArray as a buffer
 *
 * The `bytesUsed` field is initialized to zero, and is to incremented as each
 * byte is consumed, but shall not exceed the `array` length
 */
typedef struct
{
    ByteArray   array;     /**< ByteArray holding allocated array w/length = allocated size */
    size_t      bytesUsed; /**< Reflects the number of bytes used from the `array` */
} ByteBuffer;

ByteBuffer ByteBuffer_Create(uint8_t* data, size_t max_len);
ByteBuffer ByteBuffer_CreateWithArray(ByteArray array);
long ByteBuffer_BytesRemaining(const ByteBuffer buffer);
ByteArray ByteBuffer_Consume(ByteBuffer* buffer, size_t len);
bool ByteBuffer_Append(ByteBuffer* buffer, const uint8_t* data, size_t len);
bool ByteBuffer_AppendArray(ByteBuffer* buffer, const ByteArray array);
bool ByteBuffer_AppendCString(ByteBuffer* buffer, const char* data);
bool ByteBuffer_AppendDummyData(ByteBuffer* buffer, size_t len);

#endif // _BYTE_ARRAY_H
+0 −20
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@
#include <stdlib.h>

STATIC KineticList PDUList = {.start = NULL, .last = NULL};
STATIC KineticList EntryList = {.start = NULL, .last = NULL};

void* KineticAllocator_NewItem(KineticList* list, size_t size)
{
@@ -179,8 +178,6 @@ void KineticAllocator_FreePDU(KineticPDU** pdu)
    KineticAllocator_FreeItem(&PDUList, (void**)pdu);
}



void KineticAllocator_FreeAllPDUs(void)
{
    LOG_LOCATION;
@@ -202,23 +199,6 @@ void KineticAllocator_FreeAllPDUs(void)
    }
}


KineticEntry* KineticAllocator_NewEntry(KineticConnection* connection)
{
    return NULL;
}

void KineticAllocator_FreeEntry(KineticConnection* connection, KineticEntry* entry)
{
}

void KineticAllocator_FreeAllEntries(KineticConnection* connection)
{
}




bool KineticAllocator_ValidateAllMemoryFreed(void)
{
    bool empty = (PDUList.start == NULL);
Loading