]> git.seodisparate.com - UDPConnection/commitdiff
More work on Deque, UDPConnection
authorStephen Seo <seo.disparate@gmail.com>
Thu, 31 Jan 2019 03:16:01 +0000 (12:16 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Thu, 31 Jan 2019 03:16:01 +0000 (12:16 +0900)
src/UDPC_Deque.c
src/UDPC_Deque.h
src/UDPConnection.c
src/UDPConnection.h
src/test/UDPC_UnitTest.c

index 7675b8752cf4c1bdfe65328e6a802e169e35dc31..e1cee321df1bb01d5f03df85e8d9fddb4f23990d 100644 (file)
@@ -6,6 +6,10 @@
 UDPC_Deque* UDPC_Deque_init(uint32_t alloc_size)
 {
     UDPC_Deque *deque = malloc(sizeof(UDPC_Deque));
+    if(!deque)
+    {
+        return NULL;
+    }
     UDPC_Deque_clear(deque);
     deque->alloc_size = alloc_size;
     deque->buf = malloc(alloc_size);
@@ -163,7 +167,12 @@ int UDPC_Deque_get_back(UDPC_Deque *deque, void **data, uint32_t *size)
 
     *data = malloc(*size);
 
-    if(deque->tail < *size)
+    if(deque->tail == 0)
+    {
+        memcpy(*data, &deque->buf[deque->alloc_size - *size], *size);
+        return returnValue;
+    }
+    else if(deque->tail < *size)
     {
         memcpy(data[*size - deque->tail], deque->buf, deque->tail);
         memcpy(
@@ -172,9 +181,32 @@ int UDPC_Deque_get_back(UDPC_Deque *deque, void **data, uint32_t *size)
             *size - deque->tail);
         return returnValue;
     }
+    else
+    {
+        memcpy(*data, &deque->buf[deque->tail - *size], *size);
+        return returnValue;
+    }
+}
+
+void* UDPC_Deque_get_back_ptr(UDPC_Deque *deque, uint32_t unitSize)
+{
+    if(deque->size < unitSize)
+    {
+        return NULL;
+    }
 
-    memcpy(*data, &deque->buf[deque->tail - *size], *size);
-    return returnValue;
+    if(deque->tail == 0 && deque->size >= unitSize)
+    {
+        return &deque->buf[deque->alloc_size - unitSize];
+    }
+    else if(deque->tail < unitSize)
+    {
+        return NULL;
+    }
+    else
+    {
+        return &deque->buf[deque->tail - unitSize];
+    }
 }
 
 int UDPC_Deque_get_front(UDPC_Deque *deque, void **data, uint32_t *size)
@@ -203,9 +235,21 @@ int UDPC_Deque_get_front(UDPC_Deque *deque, void **data, uint32_t *size)
             *size - (deque->alloc_size - deque->head));
         return returnValue;
     }
+    else
+    {
+        memcpy(*data, &deque->buf[deque->head], *size);
+        return returnValue;
+    }
+}
+
+void* UDPC_Deque_get_front_ptr(UDPC_Deque *deque, uint32_t unitSize)
+{
+    if(deque->size < unitSize || deque->head + unitSize > deque->alloc_size)
+    {
+        return NULL;
+    }
 
-    memcpy(*data, &deque->buf[deque->head], *size);
-    return returnValue;
+    return &deque->buf[deque->head];
 }
 
 void UDPC_Deque_pop_back(UDPC_Deque *deque, uint32_t size)
@@ -294,6 +338,32 @@ int UDPC_Deque_index(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void
     return 1;
 }
 
+void* UDPC_Deque_index_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index)
+{
+    uint32_t pos = unitSize * index;
+    uint32_t abspos;
+    if(pos >= deque->size)
+    {
+        return NULL;
+    }
+
+    if(pos + deque->head >= deque->alloc_size)
+    {
+        abspos = pos + deque->head - deque->alloc_size;
+    }
+    else
+    {
+        abspos = pos + deque->head;
+    }
+
+    if(abspos + unitSize > deque->alloc_size)
+    {
+        return NULL;
+    }
+
+    return &deque->buf[abspos];
+}
+
 int UDPC_Deque_index_rev(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void **out)
 {
     uint32_t pos = unitSize * (index + 1);
@@ -328,6 +398,32 @@ int UDPC_Deque_index_rev(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, v
     return 1;
 }
 
+void* UDPC_Deque_index_rev_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index)
+{
+    uint32_t pos = unitSize * (index + 1);
+    uint32_t abspos;
+    if(pos >= deque->size + unitSize)
+    {
+        return NULL;
+    }
+
+    if(pos > deque->tail)
+    {
+        abspos = deque->alloc_size - (pos - deque->tail);
+    }
+    else
+    {
+        abspos = deque->tail - pos;
+    }
+
+    if(abspos + unitSize > deque->alloc_size)
+    {
+        return NULL;
+    }
+
+    return &deque->buf[abspos];
+}
+
 int UDPC_Deque_remove(UDPC_Deque *deque, uint32_t unitSize, uint32_t index)
 {
     uint32_t pos = unitSize * index;
index 54590a1d92e3362622300449646508d801fafd2a..567ac78d372ac42065a6cc639f41784eec9a6e82 100644 (file)
@@ -60,6 +60,14 @@ uint32_t UDPC_Deque_get_used(UDPC_Deque *deque);
  */
 int UDPC_Deque_get_back(UDPC_Deque *deque, void **data, uint32_t *size);
 
+/*!
+ * \brief Get data ptr from back of deque
+ * The returned ptr is part of the Deque's internal buffer and must not be
+ * manually free'd; it will be free'd when the Deque itself is destroyed.
+ * \return non-null if tail of deque has contiguous data of size unitSize
+ */
+void* UDPC_Deque_get_back_ptr(UDPC_Deque *deque, uint32_t unitSize);
+
 /*!
  * \brief Get data from front of deque
  * Data must be free'd after use as it was allocated with malloc.
@@ -69,6 +77,14 @@ int UDPC_Deque_get_back(UDPC_Deque *deque, void **data, uint32_t *size);
  */
 int UDPC_Deque_get_front(UDPC_Deque *deque, void **data, uint32_t *size);
 
+/*!
+ * \brief Get data ptr from front of deque
+ * The returned ptr is part of the Deque's internal buffer and must not be
+ * manually free'd; it will be free'd when the Deque itself is destroyed.
+ * \return non-null if head of deque has contiguous data of size unitSize
+ */
+void* UDPC_Deque_get_front_ptr(UDPC_Deque *deque, uint32_t unitSize);
+
 /*!
  * \brief "free" data from the back of the deque
  * If size is greater than data used, then all data will be "free"d.
@@ -98,6 +114,15 @@ void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size);
  */
 int UDPC_Deque_index(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void **out);
 
+/*!
+ * \brief Get a ptr to the indexed data at position unitSize * index
+ * The ptr will be indexed relative to the head of the Deque.
+ * The returned ptr is part of the Deque's internal buffer and will be free'd
+ * when the Deque is destroyed, so it should not be free'd directly.
+ * \return non-null if indexed data is a valid contiguous part of the buffer
+ */
+void* UDPC_Deque_index_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index);
+
 /*!
  * \brief Get a unitSize sized chunk of data at position relative to tail
  * The out pointer will be malloc'd with size unitSize and will have a copy of
@@ -109,6 +134,15 @@ int UDPC_Deque_index(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void
  */
 int UDPC_Deque_index_rev(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void **out);
 
+/*!
+ * \brief Get a ptr to the indexed data at position unitSize * index
+ * The ptr will be indexed relative to the tail of the Deque.
+ * The returned ptr is part of the Deque's internal buffer and will be free'd
+ * when the Deque is destroyed, so it should not be free'd directly.
+ * \return non-null if indexed data is a valid contiguous part of the buffer
+ */
+void* UDPC_Deque_index_rev_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index);
+
 /*!
  * \brief Replaces the data at index with data at the end (if exists)
  * Note this will reduce the size of the Deque by unitSize amount.
index a763e456a4acf3dc47497fe9ef8159d1e39c142e..6f239a1a5abace6f72034ab13aa0659c947bdeae 100644 (file)
@@ -62,6 +62,8 @@ UDPC_Context* UDPC_init(uint16_t listenPort, int isClient)
     context->connected = UDPC_Deque_init(sizeof(UDPC_INTERNAL_ConnectionData)
             * (isClient != 0 ? 1 : UDPC_CD_AMOUNT));
 
+    timespec_get(&context->lastUpdated, TIME_UTC);
+
     return context;
 }
 
@@ -166,6 +168,70 @@ const char* UDPC_get_error_str(uint32_t error)
     }
 }
 
+void UDPC_update(UDPC_Context *ctx)
+{
+    // get dt
+    struct timespec ts;
+    timespec_get(&ts, TIME_UTC);
+    float dt = UDPC_ts_diff_to_seconds(&ts, &ctx->lastUpdated);
+    ctx->lastUpdated = ts;
+
+    // check rtt
+    for(int x = 0; x * sizeof(UDPC_INTERNAL_ConnectionData) < ctx->connected->size; ++x)
+    {
+        // TODO after fixing Deque
+    }
+}
+
+float UDPC_ts_diff_to_seconds(struct timespec *ts0, struct timespec *ts1)
+{
+    float sec = 0.0f;
+    if(!ts0 || !ts1)
+    {
+        return sec;
+    }
+
+    if(ts0->tv_sec > ts1->tv_sec)
+    {
+        sec = ts0->tv_sec - ts1->tv_sec;
+        if(ts0->tv_nsec > ts1->tv_nsec)
+        {
+            sec += ((float)(ts0->tv_nsec - ts1->tv_nsec)) / 1000000000.0f;
+        }
+        else if(ts0->tv_nsec < ts1->tv_nsec)
+        {
+            sec -= 1.0f;
+            sec += ((float)(1000000000 + ts0->tv_nsec - ts1->tv_nsec)) / 1000000000.0f;
+        }
+    }
+    else if(ts0->tv_sec < ts1->tv_sec)
+    {
+        sec = ts1->tv_sec - ts0->tv_sec;
+        if(ts0->tv_nsec < ts1->tv_nsec)
+        {
+            sec += ((float)(ts1->tv_nsec - ts0->tv_nsec)) / 1000000000.0f;
+        }
+        else if(ts0->tv_nsec > ts1->tv_nsec)
+        {
+            sec -= 1.0f;
+            sec += ((float)(1000000000 + ts1->tv_nsec - ts0->tv_nsec)) / 1000000000.0f;
+        }
+    }
+    else
+    {
+        if(ts0->tv_nsec > ts1->tv_nsec)
+        {
+            sec += ((float)(ts0->tv_nsec - ts1->tv_nsec)) / 1000000000.0f;
+        }
+        else
+        {
+            sec += ((float)(ts1->tv_nsec - ts0->tv_nsec)) / 1000000000.0f;
+        }
+    }
+
+    return sec;
+}
+
 int UDPC_INTERNAL_threadfn(void *context)
 {
     UDPC_Context *ctx = (UDPC_Context*)context;
index 27f459e8c563dcb959d921b9aa2322387123fac4..d1ce97757f6b986b1d28bc12dbc18797436104fb 100644 (file)
   #include <unistd.h>
 
   #define CleanupSocket(x) close(x)
+#else
+  #define CleanupSocket(x) ((void)0)
 #endif
 
 #define UDPC_CD_AMOUNT 32
 
-// This struct should not be used outside of this library
+/// This struct should not be used outside of this library
 typedef struct
 {
     uint32_t addr;
@@ -39,7 +41,7 @@ typedef struct
     struct timespec sent;
 } UDPC_INTERNAL_PacketInfo;
 
-// This struct should not be used outside of this library
+/// This struct should not be used outside of this library
 typedef struct
 {
     /*
@@ -64,7 +66,7 @@ typedef struct
     struct timespec rtt;
 } UDPC_INTERNAL_ConnectionData;
 
-// This struct should not be modified, only passed to functions that require it
+/// This struct should not be modified, only passed to functions that require it
 typedef struct
 {
     /*
@@ -84,6 +86,7 @@ typedef struct
     mtx_t tflagsMtx;
     cnd_t threadCV;
     UDPC_Deque *connected;
+    struct timespec lastUpdated;
 } UDPC_Context;
 
 UDPC_Context* UDPC_init(uint16_t listenPort, int isClient);
@@ -96,6 +99,11 @@ uint32_t UDPC_get_error(UDPC_Context *ctx);
 
 const char* UDPC_get_error_str(uint32_t error);
 
+/// If threaded, this function is called automatically
+void UDPC_update(UDPC_Context *ctx);
+
+float UDPC_ts_diff_to_seconds(struct timespec *ts0, struct timespec *ts1);
+
 int UDPC_INTERNAL_threadfn(void *context); // internal usage only
 
 #endif
index 01d5f8992877841222976572c52a26d1050f531a..83115ee3b655c15b75666558e353e159f2ceac3f 100644 (file)
@@ -36,11 +36,27 @@ int main()
     // push back success
     ASSERT_TRUE(UDPC_Deque_push_back(deque, arr, sizeof(int) * 4));
     ASSERT_EQ_MEM(arr, deque->buf, sizeof(int) * 4);
+    ASSERT_EQ_MEM(arr, UDPC_Deque_get_back_ptr(deque, sizeof(int) * 4), sizeof(int) * 4);
+    ASSERT_EQ_MEM(arr, UDPC_Deque_get_front_ptr(deque, sizeof(int) * 4), sizeof(int) * 4);
+    for(int x = 0; x < 4; ++x)
+    {
+        ASSERT_EQ_MEM(&arr[x], UDPC_Deque_index_ptr(deque, sizeof(int), x), sizeof(int));
+        ASSERT_EQ_MEM(&arr[3 - x], UDPC_Deque_index_rev_ptr(deque, sizeof(int), x), sizeof(int));
+    }
     ASSERT_EQ(deque->size, sizeof(int) * 4);
 
     // push front success
     ASSERT_TRUE(UDPC_Deque_push_front(deque, &arr[4], sizeof(int) * 4));
     ASSERT_EQ_MEM(&arr[4], &deque->buf[sizeof(int) * 12], sizeof(int) * 4);
+    ASSERT_EQ_MEM(arr, UDPC_Deque_get_back_ptr(deque, sizeof(int) * 4), sizeof(int) * 4);
+    ASSERT_EQ_MEM(&arr[4], UDPC_Deque_get_front_ptr(deque, sizeof(int) * 4), sizeof(int) * 4);
+    for(int x = 0; x < 4; ++x)
+    {
+        ASSERT_EQ_MEM(&arr[x + 4], UDPC_Deque_index_ptr(deque, sizeof(int), x), sizeof(int));
+        ASSERT_EQ_MEM(&arr[x], UDPC_Deque_index_ptr(deque, sizeof(int), x + 4), sizeof(int));
+        ASSERT_EQ_MEM(&arr[3 - x], UDPC_Deque_index_rev_ptr(deque, sizeof(int), x), sizeof(int));
+        ASSERT_EQ_MEM(&arr[7 - x], UDPC_Deque_index_rev_ptr(deque, sizeof(int), x + 4), sizeof(int));
+    }
     ASSERT_EQ(deque->size, sizeof(int) * 8);
 
     // realloc bigger success