]> git.seodisparate.com - UDPConnection/commitdiff
Some more work on UDPC, WIP Deque
authorStephen Seo <seo.disparate@gmail.com>
Sat, 26 Jan 2019 10:11:12 +0000 (19:11 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Sat, 26 Jan 2019 10:11:12 +0000 (19:11 +0900)
src/Deque.c [new file with mode: 0644]
src/Deque.h [new file with mode: 0644]
src/UDPConnection.c
src/UDPConnection.h

diff --git a/src/Deque.c b/src/Deque.c
new file mode 100644 (file)
index 0000000..622d65a
--- /dev/null
@@ -0,0 +1,203 @@
+#include "Deque.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+void UDPC_Deque_init(UDPC_Deque *deque, uint32_t alloc_size)
+{
+    deque->head = 0;
+    deque->tail = 0;
+    deque->size = 0;
+    deque->alloc_size = alloc_size;
+    deque->buf = malloc(alloc_size);
+}
+
+int UDPC_Deque_push_back(UDPC_Deque *deque, const char *data, uint32_t size)
+{
+    if(deque->size + size > deque->alloc_size)
+    {
+        return 0;
+    }
+    else if(deque->tail + size <= deque->alloc_size)
+    {
+        memcpy(&deque->buf[deque->tail], data, size);
+        deque->tail += size;
+        if(deque->tail == deque->alloc_size)
+        {
+            deque->tail = 0;
+        }
+        deque->size += size;
+
+        return 1;
+    }
+
+    uint32_t temp;
+
+    if(deque->tail < deque->alloc_size)
+    {
+        memcpy(&deque->buf[deque->tail], data, deque->alloc_size - deque->tail);
+        temp = deque->alloc_size - deque->tail;
+        deque->size += temp;
+        size -= temp;
+        deque->tail = 0;
+    }
+    if(size > 0)
+    {
+        memcpy(&deque->buf[deque->tail], &data[temp], size);
+        deque->tail += size;
+        deque->size += size;
+    }
+    return 1;
+}
+
+int UDPC_Deque_push_front(UDPC_Deque *deque, const char *data, uint32_t size)
+{
+    if(deque->size + size > deque->alloc_size)
+    {
+        return 0;
+    }
+    else if(size <= deque->head)
+    {
+        memcpy(&deque->buf[deque->head - size], data, size);
+        deque->head -= size;
+        deque->size += size;
+
+        return 1;
+    }
+
+    if(deque->head > 0)
+    {
+        memcpy(deque->buf, &data[size - deque->head], deque->head);
+        deque->size += deque->head;
+        size -= deque->head;
+        deque->head = 0;
+    }
+    if(size > 0)
+    {
+        memcpy(&deque->buf[deque->alloc_size - size], data, size);
+        deque->head = deque->alloc_size - size;
+        deque->size += size;
+    }
+    return 1;
+}
+
+uint32_t UDPC_Deque_get_available(UDPC_Deque *deque)
+{
+    return deque->alloc_size - deque->size;
+}
+
+int UDPC_Deque_get_back(UDPC_Deque *deque, char **data, uint32_t *size)
+{
+    int returnValue = 1;
+    if(deque->size == 0)
+    {
+        *size = 0;
+        return 0;
+    }
+    else if(*size > deque->size)
+    {
+        *size = deque->size;
+        returnValue = 0;
+    }
+
+    *data = malloc(*size);
+
+    if(deque->tail < *size)
+    {
+        memcpy(data[*size - deque->tail], deque->buf, deque->tail);
+        memcpy(
+            *data,
+            &deque->buf[deque->alloc_size - (*size - deque->tail)],
+            *size - deque->tail);
+        return returnValue;
+    }
+
+    memcpy(*data, &deque->buf[deque->tail - *size], *size);
+    return returnValue;
+}
+
+int UDPC_Deque_get_front(UDPC_Deque *deque, char **data, uint32_t *size)
+{
+    int returnValue = 1;
+    if(deque->size == 0)
+    {
+        *size = 0;
+        return 0;
+    }
+    else if(*size > deque->size)
+    {
+        *size = deque->size;
+        returnValue = 0;
+    }
+
+    *data = malloc(*size);
+
+    if(deque->head + *size > deque->alloc_size)
+    {
+        memcpy(*data, &deque->buf[deque->head], deque->alloc_size - deque->head);
+        memcpy(
+            data[deque->alloc_size - deque->head],
+            deque->buf,
+            *size - (deque->alloc_size - deque->head));
+        return returnValue;
+    }
+
+    memcpy(*data, &deque->buf[deque->head], *size);
+    return returnValue;
+}
+
+void UDPC_Deque_pop_back(UDPC_Deque *deque, uint32_t size)
+{
+    if(deque->size == 0)
+    {
+        return;
+    }
+    else if(deque->size <= size)
+    {
+        deque->head = 0;
+        deque->tail = 0;
+        deque->size = 0;
+        return;
+    }
+
+    deque->size -= size;
+
+    if(deque->tail < size)
+    {
+        deque->tail = deque->alloc_size - (size - deque->tail);
+    }
+    else
+    {
+        deque->tail -= size;
+    }
+}
+
+void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size)
+{
+    if(deque->size == 0)
+    {
+        return;
+    }
+    else if(deque->size <= size)
+    {
+        deque->head = 0;
+        deque->tail = 0;
+        deque->size = 0;
+        return;
+    }
+
+    deque->size -= size;
+
+    if(deque->head + size > deque->alloc_size)
+    {
+        deque->head = deque->head + size - deque->alloc_size;
+    }
+    else
+    {
+        deque->head += size;
+        if(deque->head == deque->alloc_size)
+        {
+            deque->head = 0;
+        }
+    }
+}
diff --git a/src/Deque.h b/src/Deque.h
new file mode 100644 (file)
index 0000000..dccc6f6
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef UDPC_DEQUE_H
+#define UDPC_DEQUE_H
+
+#include <stdint.h>
+
+typedef struct
+{
+    uint32_t head;
+    uint32_t tail;
+    uint32_t size;
+    uint32_t alloc_size;
+    char *buf;
+} UDPC_Deque;
+
+void UDPC_Deque_init(UDPC_Deque *deque, uint32_t alloc_size);
+
+/*!
+ * If there was not enough space in the Deque, then no data is inserted at all.
+ * \return non-zero on success (there was enough size to insert data)
+ */
+int UDPC_Deque_push_back(UDPC_Deque *deque, const char *data, uint32_t size);
+
+/*!
+ * If there was not enough space in the Deque, then no data is inserted at all.
+ * \return non-zero on success (there was enough size to insert data)
+ */
+int UDPC_Deque_push_front(UDPC_Deque *deque, const char *data, uint32_t size);
+
+uint32_t UDPC_Deque_get_available(UDPC_Deque *deque);
+
+/*!
+ * \brief Get data from back of deque
+ * Data must be free'd after use as it was allocated with malloc.
+ * When size is greater than deque size, partial data is allocated, size is
+ * updated to allocated amount. If deque is empty, no data is allocated.
+ * \return non-zero if full requested size was returned
+ */
+int UDPC_Deque_get_back(UDPC_Deque *deque, char **data, uint32_t *size);
+
+/*!
+ * \brief Get data from front of deque
+ * Data must be free'd after use as it was allocated with malloc.
+ * When size is greater than deque size, partial data is allocated, size is
+ * updated to allocated amount. If deque is empty, no data is allocated.
+ * \return non-zero if full requested size was returned
+ */
+int UDPC_Deque_get_front(UDPC_Deque *deque, char **data, uint32_t *size);
+
+/*!
+ * \brief "free" data from the back of the deque
+ * If size is greater than data used, then all data will be "free"d.
+ * Note that this doesn't actually deallocate data, but changes internal values
+ * that keep track of data positions in the internal buffer. The data will only
+ * actually be removed when it is overwritten or the Deque is free'd.
+ */
+void UDPC_Deque_pop_back(UDPC_Deque *deque, uint32_t size);
+
+/*!
+ * \brief "free" data from the front of the deque
+ * If size is greater than data used, then all data will be "free"d.
+ * Note that this doesn't actually deallocate data, but changes internal values
+ * that keep track of data positions in the internal buffer. The data will only
+ * actually be removed when it is overwritten or the Deque is free'd.
+ */
+void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size);
+
+#endif
index df402740d86a5bf480a06f3a50770a7af75fe053..0b6d33a25aed3a6695b62237c6203842f6bc307d 100644 (file)
@@ -1,8 +1,6 @@
 #include "UDPConnection.h"
 
-#include <time.h>
-
-UDPC_Context UDPC_init(unsigned short listenPort)
+UDPC_Context UDPC_init(uint16_t listenPort)
 {
     UDPC_Context context;
     context.error = 0;
@@ -45,6 +43,8 @@ UDPC_Context UDPC_init(unsigned short listenPort)
     DWORD nonblocking = 1;
     if(ioctlsocket(context.socketHandle, FIONBIO, &nonblocking) != 0)
     {
+#else
+    {
 #endif
         context.error = UDPCON_ERR_SOCKETNONBF;
         CleanupSocket(context.socketHandle);
@@ -56,7 +56,7 @@ UDPC_Context UDPC_init(unsigned short listenPort)
     return context;
 }
 
-UDPC_Context UDPC_init_threaded_update(unsigned short listenPort)
+UDPC_Context UDPC_init_threaded_update(uint16_t listenPort)
 {
     UDPC_Context context = UDPC_init(listenPort);
 
index 036a4f5758c5725b3f33b96fca488d64f681ad07..bccf6b0002d6156980cfe4a98b1287bee9c54eb4 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <stdio.h>
 #include <threads.h>
+#include <time.h>
+#include <stdint.h>
 
 #define UDPC_PLATFORM_WINDOWS 1
 #define UDPC_PLATFORM_MAC 2
 #define UDPCON_ERR_CVFAIL 5 // failed to create condition variable
 #define UDPCON_ERR_THREADFAIL 6 // failed to create thread
 
+// This struct should not be used outside of this library
+typedef struct
+{
+    uint32_t addr;
+    uint32_t id;
+    /*
+     * 0x1 - is resending
+     * 0x2 - is not received checked
+     * 0x4 - has been re-sent
+     */
+    uint32_t flags;
+    char *data;
+    struct timespec sent;
+} UDPC_INTERNAL_PacketInfo;
+
+// This struct should not be used outside of this library
+typedef struct
+{
+    /*
+     * 0x1 - trigger send
+     * 0x2 - is good mode
+     * 0x4 - is good rtt
+     */
+    uint32_t flags;
+    uint32_t id;
+    uint32_t lseq;
+    uint32_t rseq;
+    uint32_t ack;
+    float timer;
+    float toggleT;
+    float toggleTimer;
+    float toggledTimer;
+    uint16_t port;
+    UDPC_INTERNAL_PacketInfo *sentPkts;
+    UDPC_INTERNAL_PacketInfo *sendPktQueue;
+    struct timespec received;
+    struct timespec sent;
+    struct timespec rtt;
+} UDPC_INTERNAL_ConnectionData;
+
 // This struct should not be modified, only passed to functions that require it
 typedef struct
 {
-    int error;
-    int socketHandle;
-    struct sockaddr_in socketInfo;
-    thrd_t threadHandle;
-    mtx_t tCVMtx;
-    mtx_t tflagsMtx;
-    cnd_t threadCV;
     /*
      * 0x1 - is threaded
      */
-    int flags;
+    uint32_t flags;
     /*
      * 0x1 - thread should stop
      */
-    int threadFlags;
+    uint32_t threadFlags;
+    uint32_t error;
+    int socketHandle;
+    struct sockaddr_in socketInfo;
+    thrd_t threadHandle;
+    mtx_t tCVMtx;
+    mtx_t tflagsMtx;
+    cnd_t threadCV;
 } UDPC_Context;
 
-UDPC_Context UDPC_init(unsigned short listenPort);
+UDPC_Context UDPC_init(uint16_t listenPort);
 
-UDPC_Context UDPC_init_threaded_update(unsigned short listenPort);
+UDPC_Context UDPC_init_threaded_update(uint16_t listenPort);
 
 void UDPC_destroy(UDPC_Context *ctx);