]> git.seodisparate.com - UDPConnection/commitdiff
Finish impl of Deque, testing required
authorStephen Seo <seo.disparate@gmail.com>
Sat, 26 Jan 2019 11:44:31 +0000 (20:44 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Sat, 26 Jan 2019 11:44:31 +0000 (20:44 +0900)
CMakeLists.txt
src/Deque.c
src/Deque.h

index 9fed4fac1ee6cab584f00e6c5e7854249fe217df..a53356c287d8b3835d68eec1c4d97b5c459a2d5c 100644 (file)
@@ -3,6 +3,7 @@ project(UDPConnection)
 
 set(UDPConnection_SOURCES
     src/UDPConnection.c
+    src/Deque.c
 )
 
 set(CMAKE_C_FLAGS "-Wall -Wno-missing-braces")
index 622d65a0c6d4963088aa1937d1deafd2e1525e34..ea8dbbafc21b8b3f7ccc76f0f516b57a90a271de 100644 (file)
@@ -3,13 +3,60 @@
 #include <stdlib.h>
 #include <string.h>
 
-void UDPC_Deque_init(UDPC_Deque *deque, uint32_t alloc_size)
+int UDPC_Deque_init(UDPC_Deque *deque, uint32_t alloc_size)
 {
-    deque->head = 0;
-    deque->tail = 0;
-    deque->size = 0;
+    UDPC_Deque_clear(deque);
     deque->alloc_size = alloc_size;
     deque->buf = malloc(alloc_size);
+    if(deque->buf)
+    {
+        return 1;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+void UDPC_Deque_destroy(UDPC_Deque *deque)
+{
+    free(deque->buf);
+    deque->buf = NULL;
+}
+
+int UDPC_Deque_realloc(UDPC_Deque *deque, uint32_t new_size)
+{
+    if(new_size < deque->size)
+    {
+        return 0;
+    }
+    else if(deque->size != 0 && deque->tail <= deque->head)
+    {
+        char *buf = malloc(new_size);
+        memcpy(buf, &deque->buf[deque->head], deque->alloc_size - deque->head);
+        if(deque->tail != 0)
+        {
+            memcpy(&buf[deque->alloc_size - deque->head], deque->buf, deque->tail);
+        }
+        free(deque->buf);
+        deque->buf = buf;
+        deque->alloc_size = new_size;
+        return 1;
+    }
+    else
+    {
+        void *buf = realloc(deque->buf, new_size);
+        if(buf)
+        {
+            deque->buf = buf;
+            deque->alloc_size = new_size;
+            return 1;
+        }
+        else
+        {
+            return 0;
+        }
+    }
 }
 
 int UDPC_Deque_push_back(UDPC_Deque *deque, const char *data, uint32_t size)
@@ -86,12 +133,18 @@ uint32_t UDPC_Deque_get_available(UDPC_Deque *deque)
     return deque->alloc_size - deque->size;
 }
 
+uint32_t UDPC_Deque_get_used(UDPC_Deque *deque)
+{
+    return deque->size;
+}
+
 int UDPC_Deque_get_back(UDPC_Deque *deque, char **data, uint32_t *size)
 {
     int returnValue = 1;
     if(deque->size == 0)
     {
         *size = 0;
+        *data = NULL;
         return 0;
     }
     else if(*size > deque->size)
@@ -122,6 +175,7 @@ int UDPC_Deque_get_front(UDPC_Deque *deque, char **data, uint32_t *size)
     if(deque->size == 0)
     {
         *size = 0;
+        *data = NULL;
         return 0;
     }
     else if(*size > deque->size)
@@ -154,9 +208,7 @@ void UDPC_Deque_pop_back(UDPC_Deque *deque, uint32_t size)
     }
     else if(deque->size <= size)
     {
-        deque->head = 0;
-        deque->tail = 0;
-        deque->size = 0;
+        UDPC_Deque_clear(deque);
         return;
     }
 
@@ -180,9 +232,7 @@ void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size)
     }
     else if(deque->size <= size)
     {
-        deque->head = 0;
-        deque->tail = 0;
-        deque->size = 0;
+        UDPC_Deque_clear(deque);
         return;
     }
 
@@ -201,3 +251,78 @@ void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size)
         }
     }
 }
+
+int UDPC_Deque_index(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, char **out)
+{
+    uint32_t pos = unitSize * index;
+    uint32_t abspos;
+    if(pos >= deque->alloc_size)
+    {
+        *out = NULL;
+        return 0;
+    }
+
+    *out = malloc(unitSize);
+
+    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)
+    {
+        memcpy(*out, &deque->buf[abspos], deque->alloc_size - abspos);
+        memcpy(*out, deque->buf, unitSize - (deque->alloc_size - abspos));
+    }
+    else
+    {
+        memcpy(*out, &deque->buf[abspos], unitSize);
+    }
+
+    return 1;
+}
+
+int UDPC_Deque_index_rev(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, char **out)
+{
+    uint32_t pos = unitSize * (index + 1);
+    uint32_t abspos;
+    if(pos >= deque->alloc_size)
+    {
+        *out = NULL;
+        return 0;
+    }
+
+    *out = malloc(unitSize);
+
+    if(pos > deque->tail)
+    {
+        abspos = deque->alloc_size - (pos - deque->tail);
+    }
+    else
+    {
+        abspos = deque->tail - pos;
+    }
+
+    if(abspos + unitSize >= deque->alloc_size)
+    {
+        memcpy(*out, &deque->buf[abspos], deque->alloc_size - abspos);
+        memcpy(*out, deque->buf, unitSize - (deque->alloc_size - abspos));
+    }
+    else
+    {
+        memcpy(*out, &deque->buf[abspos], unitSize);
+    }
+
+    return 1;
+}
+
+void UDPC_Deque_clear(UDPC_Deque *deque)
+{
+    deque->head = 0;
+    deque->tail = 0;
+    deque->size = 0;
+}
index dccc6f6ffc975c1bcfaa005cdc239bc3bb113b61..a67b7c38c83b414b99b6607c1e120f1d178a581d 100644 (file)
@@ -12,7 +12,22 @@ typedef struct
     char *buf;
 } UDPC_Deque;
 
-void UDPC_Deque_init(UDPC_Deque *deque, uint32_t alloc_size);
+/*!
+ * \return non-zero on success
+ */
+int UDPC_Deque_init(UDPC_Deque *deque, uint32_t alloc_size);
+
+/*!
+ * Frees resources used by a UDPC_Deque
+ */
+void UDPC_Deque_destroy(UDPC_Deque *deque);
+
+/*!
+ * Fails if new_size is smaller than current size of Deque.
+ * On failure, deque remains unchanged.
+ * \return non-zero on success
+ */
+int UDPC_Deque_realloc(UDPC_Deque *deque, uint32_t new_size);
 
 /*!
  * If there was not enough space in the Deque, then no data is inserted at all.
@@ -26,8 +41,16 @@ int UDPC_Deque_push_back(UDPC_Deque *deque, const char *data, uint32_t size);
  */
 int UDPC_Deque_push_front(UDPC_Deque *deque, const char *data, uint32_t size);
 
+/*!
+ * \return size in bytes of available data
+ */
 uint32_t UDPC_Deque_get_available(UDPC_Deque *deque);
 
+/*!
+ * \return size in bytes of used data
+ */
+uint32_t UDPC_Deque_get_used(UDPC_Deque *deque);
+
 /*!
  * \brief Get data from back of deque
  * Data must be free'd after use as it was allocated with malloc.
@@ -64,4 +87,28 @@ void UDPC_Deque_pop_back(UDPC_Deque *deque, uint32_t size);
  */
 void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size);
 
+/*!
+ * \brief Get a unitSize sized chunk of data at position unitSize * index
+ * The data will be indexed relative to the head of the Deque.
+ * The out pointer will be malloc'd with size unitSize and will have a copy of
+ * the data at the specified unitSize * index.
+ * Note that the out data must be free'd, but nothing will be malloc'd on fail
+ * and *out will be set to NULL.
+ * \return non-zero if unitSize * index < allocated_size_of_Deque
+ */
+int UDPC_Deque_index(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, char **out);
+
+/*!
+ * \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
+ * the data at the specified unitSize * (index + 1) relative to tail in reverse
+ * direction.
+ * Note that the out data must be free'd, but nothing will be malloc'd on fail
+ * and *out will be set to NULL.
+ * \return non-zero if unitSize * (index + 1) < allocated_size_of_Deque
+ */
+int UDPC_Deque_index_rev(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, char **out);
+
+void UDPC_Deque_clear(UDPC_Deque *deque);
+
 #endif