Azure IoT common library

Fork of azure_c_shared_utility by Azure IoT

Revision:
27:8656a313842b
Parent:
21:b92006c5b9ff
Child:
30:ce3813c5a692
--- a/buffer.c	Mon May 08 10:51:21 2017 -0700
+++ b/buffer.c	Mon May 22 10:35:55 2017 -0700
@@ -4,6 +4,7 @@
 #include <stdlib.h>
 #include <stddef.h>
 #include <string.h>
+#include <stdbool.h>
 #include "azure_c_shared_utility/gballoc.h"
 #include "azure_c_shared_utility/buffer_.h"
 #include "azure_c_shared_utility/optimize_size.h"
@@ -13,7 +14,7 @@
 {
     unsigned char* buffer;
     size_t size;
-}BUFFER;
+} BUFFER;
 
 /* Codes_SRS_BUFFER_07_001: [BUFFER_new shall allocate a BUFFER_HANDLE that will contain a NULL unsigned char*.] */
 BUFFER_HANDLE BUFFER_new(void)
@@ -40,6 +41,7 @@
     if (handleptr->buffer == NULL)
     {
         /*Codes_SRS_BUFFER_02_003: [If allocating memory fails, then BUFFER_create shall return NULL.]*/
+        LogError("Failure allocating data");
         result = __FAILURE__;
     }
     else
@@ -57,6 +59,7 @@
     /*Codes_SRS_BUFFER_02_001: [If source is NULL then BUFFER_create shall return NULL.]*/
     if (source == NULL)
     {
+        LogError("invalid parameter source: %p", source);
         result = NULL;
     }
     else
@@ -67,6 +70,7 @@
         {
             /*Codes_SRS_BUFFER_02_003: [If allocating memory fails, then BUFFER_create shall return NULL.] */
             /*fallthrough*/
+            LogError("Failure allocating BUFFER structure");
         }
         else
         {
@@ -140,6 +144,7 @@
             if (newBuffer == NULL)
             {
                 /* Codes_SRS_BUFFER_07_010: [BUFFER_build shall return nonzero if any error is encountered.] */
+                LogError("Failure reallocating buffer");
                 result = __FAILURE__;
             }
             else
@@ -157,6 +162,59 @@
     return result;
 }
 
+int BUFFER_append_build(BUFFER_HANDLE handle, const unsigned char* source, size_t size)
+{
+    int result;
+    if (handle == NULL || source == NULL || size == 0)
+    {
+        /* Codes_SRS_BUFFER_07_029: [ BUFFER_append_build shall return nonzero if handle or source are NULL or if size is 0. ] */
+        LogError("BUFFER_append_build failed invalid parameter handle: %p, source: %p, size: %uz", handle, source, size);
+        result = __FAILURE__;
+    }
+    else
+    {
+        if (handle->buffer == NULL)
+        {
+            /* Codes_SRS_BUFFER_07_030: [ if handle->buffer is NULL BUFFER_append_build shall allocate the a buffer of size bytes... ] */
+            if (BUFFER_safemalloc(handle, size) != 0)
+            {
+                /* Codes_SRS_BUFFER_07_035: [ If any error is encountered BUFFER_append_build shall return a non-null value. ] */
+                LogError("Failure with BUFFER_safemalloc");
+                result = __FAILURE__;
+            }
+            else
+            {
+                /* Codes_SRS_BUFFER_07_031: [ ... and copy the contents of source to handle->buffer. ] */
+                (void)memcpy(handle->buffer, source, size);
+                /* Codes_SRS_BUFFER_07_034: [ On success BUFFER_append_build shall return 0 ] */
+                result = 0;
+            }
+        }
+        else
+        {
+            /* Codes_SRS_BUFFER_07_032: [ if handle->buffer is not NULL BUFFER_append_build shall realloc the buffer to be the handle->size + size ] */
+            unsigned char* temp = (unsigned char*)realloc(handle->buffer, handle->size + size);
+            if (temp == NULL)
+            {
+                /* Codes_SRS_BUFFER_07_035: [ If any error is encountered BUFFER_append_build shall return a non-null value. ] */
+                LogError("Failure reallocating temporary buffer");
+                result = __FAILURE__;
+            }
+            else
+            {
+                /* Codes_SRS_BUFFER_07_033: [ ... and copy the contents of source to the end of the buffer. ] */
+                handle->buffer = temp;
+                // Append the BUFFER
+                (void)memcpy(&handle->buffer[handle->size], source, size);
+                handle->size += size;
+                /* Codes_SRS_BUFFER_07_034: [ On success BUFFER_append_build shall return 0 ] */
+                result = 0;
+            }
+        }
+    }
+    return result;
+}
+
 /*return 0 if the buffer was pre-build(that is, had its space allocated)*/
 /*else return different than zero*/
 /* Codes_SRS_BUFFER_07_005: [BUFFER_pre_build allocates size_t bytes of BUFFER_HANDLE and returns zero on success.] */
@@ -179,6 +237,7 @@
         if (b->buffer != NULL)
         {
             /* Codes_SRS_BUFFER_07_007: [BUFFER_pre_build shall return nonzero if the buffer has been previously allocated and is not NULL.] */
+            LogError("Failure buffer data is NULL");
             result = __FAILURE__;
         }
         else
@@ -186,6 +245,7 @@
             if ((b->buffer = (unsigned char*)malloc(size)) == NULL)
             {
                 /* Codes_SRS_BUFFER_07_013: [BUFFER_pre_build shall return nonzero if any error is encountered.] */
+                LogError("Failure allocating buffer");
                 result = __FAILURE__;
             }
             else
@@ -231,6 +291,7 @@
         BUFFER* b = (BUFFER*)handle;
         if (b->buffer != NULL)
         {
+            LogError("Failure buffer data is NULL");
             free(b->buffer);
             b->buffer = NULL;
             b->size = 0;
@@ -252,11 +313,13 @@
     if (handle == NULL)
     {
         /* Codes_SRS_BUFFER_07_017: [BUFFER_enlarge shall return a nonzero result if any parameters are NULL or zero.] */
+        LogError("Failure: handle is invalid.");
         result = __FAILURE__;
     }
     else if (enlargeSize == 0)
     {
         /* Codes_SRS_BUFFER_07_017: [BUFFER_enlarge shall return a nonzero result if any parameters are NULL or zero.] */
+        LogError("Failure: enlargeSize size is 0.");
         result = __FAILURE__;
     }
     else
@@ -266,6 +329,7 @@
         if (temp == NULL)
         {
             /* Codes_SRS_BUFFER_07_018: [BUFFER_enlarge shall return a nonzero result if any error is encountered.] */
+            LogError("Failure: allocating temp buffer.");
             result = __FAILURE__;
         }
         else
@@ -278,6 +342,74 @@
     return result;
 }
 
+int BUFFER_shrink(BUFFER_HANDLE handle, size_t decreaseSize, bool fromEnd)
+{
+    int result;
+    if (handle == NULL)
+    {
+        /* Codes_SRS_BUFFER_07_036: [ if handle is NULL, BUFFER_shrink shall return a non-null value ]*/
+        LogError("Failure: handle is invalid.");
+        result = __FAILURE__;
+    }
+    else if (decreaseSize == 0)
+    {
+        /* Codes_SRS_BUFFER_07_037: [ If decreaseSize is equal zero, BUFFER_shrink shall return a non-null value ] */
+        LogError("Failure: decrease size is 0.");
+        result = __FAILURE__;
+    }
+    else if (decreaseSize > handle->size)
+    {
+        /* Codes_SRS_BUFFER_07_038: [ If decreaseSize is less than the size of the buffer, BUFFER_shrink shall return a non-null value ] */
+        LogError("Failure: decrease size is less than buffer size.");
+        result = __FAILURE__;
+    }
+    else
+    {
+        /* Codes_SRS_BUFFER_07_039: [ BUFFER_shrink shall allocate a temporary buffer of existing buffer size minus decreaseSize. ] */
+        size_t alloc_size = handle->size - decreaseSize;
+        if (alloc_size == 0)
+        {
+            /* Codes_SRS_BUFFER_07_043: [ If the decreaseSize is equal the buffer size , BUFFER_shrink shall deallocate the buffer and set the size to zero. ] */
+            free(handle->buffer);
+            handle->buffer = NULL;
+            handle->size = 0;
+            result = 0;
+        }
+        else
+        {
+            unsigned char* tmp = malloc(alloc_size);
+            if (tmp == NULL)
+            {
+                /* Codes_SRS_BUFFER_07_042: [ If a failure is encountered, BUFFER_shrink shall return a non-null value ] */
+                LogError("Failure: allocating temp buffer.");
+                result = __FAILURE__;
+            }
+            else
+            {
+                if (fromEnd)
+                {
+                    /* Codes_SRS_BUFFER_07_040: [ if the fromEnd variable is true, BUFFER_shrink shall remove the end of the buffer of size decreaseSize. ] */
+                    memcpy(tmp, handle->buffer, alloc_size);
+                    free(handle->buffer);
+                    handle->buffer = tmp;
+                    handle->size = alloc_size;
+                    result = 0;
+                }
+                else
+                {
+                    /* Codes_SRS_BUFFER_07_041: [ if the fromEnd variable is false, BUFFER_shrink shall remove the beginning of the buffer of size decreaseSize. ] */
+                    memcpy(tmp, handle->buffer + decreaseSize, alloc_size);
+                    free(handle->buffer);
+                    handle->buffer = tmp;
+                    handle->size = alloc_size;
+                    result = 0;
+                }
+            }
+        }
+    }
+    return result;
+}
+
 /* Codes_SRS_BUFFER_07_021: [BUFFER_size shall place the size of the associated buffer in the size variable and return zero on success.] */
 int BUFFER_size(BUFFER_HANDLE handle, size_t* size)
 {
@@ -333,6 +465,7 @@
                 if (temp == NULL)
                 {
                     /* Codes_SRS_BUFFER_07_023: [BUFFER_append shall return a nonzero upon any error that is encountered.] */
+                    LogError("Failure: allocating temp buffer.");
                     result = __FAILURE__;
                 }
                 else
@@ -387,6 +520,7 @@
                 if (temp == NULL)
                 {
                     /* Codes_SRS_BUFFER_01_005: [ BUFFER_prepend shall return a non-zero upon value any error that is encountered. ]*/
+                    LogError("Failure: allocating temp buffer.");
                     result = __FAILURE__;
                 }
                 else
@@ -458,6 +592,7 @@
         {
             if (BUFFER_safemalloc(b, suppliedBuff->size) != 0)
             {
+                LogError("Failure: allocating temp buffer.");
                 result = NULL;
             }
             else