Nigel Rantor / azure_c_shared_utility

Fork of azure_c_shared_utility by Azure IoT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers constbuffer.c Source File

constbuffer.c

00001 // Copyright (c) Microsoft. All rights reserved.
00002 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
00003 
00004 //
00005 // PUT NO INCLUDES BEFORE HERE
00006 //
00007 #include <stdlib.h>
00008 #include <stddef.h>
00009 #include "azure_c_shared_utility/gballoc.h"
00010 #include "azure_c_shared_utility/constbuffer.h"
00011 #include "azure_c_shared_utility/xlogging.h"
00012 #include "azure_c_shared_utility/refcount.h"
00013 
00014 typedef struct CONSTBUFFER_HANDLE_DATA_TAG
00015 {
00016     CONSTBUFFER alias;
00017 }CONSTBUFFER_HANDLE_DATA;
00018 
00019 DEFINE_REFCOUNT_TYPE(CONSTBUFFER_HANDLE_DATA);
00020 
00021 static CONSTBUFFER_HANDLE CONSTBUFFER_Create_Internal(const unsigned char* source, size_t size)
00022 {
00023     CONSTBUFFER_HANDLE_DATA* result;
00024     /*Codes_SRS_CONSTBUFFER_02_005: [The non-NULL handle returned by CONSTBUFFER_Create shall have its ref count set to "1".]*/
00025     /*Codes_SRS_CONSTBUFFER_02_010: [The non-NULL handle returned by CONSTBUFFER_CreateFromBuffer shall have its ref count set to "1".]*/
00026     result = REFCOUNT_TYPE_CREATE(CONSTBUFFER_HANDLE_DATA);
00027     if (result == NULL)
00028     {
00029         /*Codes_SRS_CONSTBUFFER_02_003: [If creating the copy fails then CONSTBUFFER_Create shall return NULL.]*/
00030         /*Codes_SRS_CONSTBUFFER_02_008: [If copying the content fails, then CONSTBUFFER_CreateFromBuffer shall fail and return NULL.] */
00031         LogError("unable to malloc");
00032         /*return as is*/
00033     }
00034     else
00035     {
00036         /*Codes_SRS_CONSTBUFFER_02_002: [Otherwise, CONSTBUFFER_Create shall create a copy of the memory area pointed to by source having size bytes.]*/
00037         result->alias.size = size;
00038         if (size == 0)
00039         {
00040             result->alias.buffer = NULL;
00041         }
00042         else
00043         {
00044             unsigned char* temp = (unsigned char*)malloc(size);
00045             if (temp == NULL)
00046             {
00047                 /*Codes_SRS_CONSTBUFFER_02_003: [If creating the copy fails then CONSTBUFFER_Create shall return NULL.]*/
00048                 /*Codes_SRS_CONSTBUFFER_02_008: [If copying the content fails, then CONSTBUFFER_CreateFromBuffer shall fail and return NULL.] */
00049                 LogError("unable to malloc");
00050                 free(result);
00051                 result = NULL;
00052             }
00053             else
00054             {
00055                 
00056                 /*Codes_SRS_CONSTBUFFER_02_004: [Otherwise CONSTBUFFER_Create shall return a non-NULL handle.]*/
00057                 /*Codes_SRS_CONSTBUFFER_02_007: [Otherwise, CONSTBUFFER_CreateFromBuffer shall copy the content of buffer.]*/
00058                 /*Codes_SRS_CONSTBUFFER_02_009: [Otherwise, CONSTBUFFER_CreateFromBuffer shall return a non-NULL handle.]*/
00059                 (void)memcpy(temp, source, size);
00060                 result->alias.buffer = temp;
00061             }
00062         }
00063     }
00064     return (CONSTBUFFER_HANDLE)result;
00065 }
00066 
00067 CONSTBUFFER_HANDLE CONSTBUFFER_Create(const unsigned char* source, size_t size)
00068 {
00069     CONSTBUFFER_HANDLE_DATA* result;
00070     /*Codes_SRS_CONSTBUFFER_02_001: [If source is NULL and size is different than 0 then CONSTBUFFER_Create shall fail and return NULL.]*/
00071     if (
00072         (source == NULL) &&
00073         (size != 0)
00074         )
00075     {
00076         LogError("invalid arguments passes to CONSTBUFFER_Create");
00077         result = NULL;
00078     }
00079     else
00080     {
00081         result = (CONSTBUFFER_HANDLE_DATA*)CONSTBUFFER_Create_Internal(source, size);
00082     }
00083     return (CONSTBUFFER_HANDLE)result;
00084 }
00085 
00086 /*this creates a new constbuffer from an existing BUFFER_HANDLE*/
00087 CONSTBUFFER_HANDLE CONSTBUFFER_CreateFromBuffer(BUFFER_HANDLE buffer)
00088 {
00089     CONSTBUFFER_HANDLE_DATA* result;
00090     /*Codes_SRS_CONSTBUFFER_02_006: [If buffer is NULL then CONSTBUFFER_CreateFromBuffer shall fail and return NULL.]*/
00091     if (buffer == NULL)
00092     {
00093         LogError("invalid arg passed to CONSTBUFFER_CreateFromBuffer");
00094         result = NULL;
00095     }
00096     else
00097     {
00098         size_t length = BUFFER_length(buffer);
00099         unsigned char* rawBuffer = BUFFER_u_char(buffer);
00100         result = (CONSTBUFFER_HANDLE_DATA*)CONSTBUFFER_Create_Internal(rawBuffer, length);
00101     }
00102     return (CONSTBUFFER_HANDLE)result;
00103 }
00104 
00105 CONSTBUFFER_HANDLE CONSTBUFFER_Clone(CONSTBUFFER_HANDLE constbufferHandle)
00106 {
00107     if (constbufferHandle == NULL)
00108     {
00109         /*Codes_SRS_CONSTBUFFER_02_013: [If constbufferHandle is NULL then CONSTBUFFER_Clone shall fail and return NULL.]*/
00110         LogError("invalid arg");
00111     }
00112     else
00113     {
00114         /*Codes_SRS_CONSTBUFFER_02_014: [Otherwise, CONSTBUFFER_Clone shall increment the reference count and return constbufferHandle.]*/
00115         INC_REF(CONSTBUFFER_HANDLE_DATA, constbufferHandle);
00116     }
00117     return constbufferHandle;
00118 }
00119 
00120 const CONSTBUFFER* CONSTBUFFER_GetContent(CONSTBUFFER_HANDLE constbufferHandle)
00121 {
00122     const CONSTBUFFER* result;
00123     if (constbufferHandle == NULL)
00124     {
00125         /*Codes_SRS_CONSTBUFFER_02_011: [If constbufferHandle is NULL then CONSTBUFFER_GetContent shall return NULL.]*/
00126         result = NULL;
00127         LogError("invalid arg");
00128     }
00129     else
00130     {
00131         /*Codes_SRS_CONSTBUFFER_02_012: [Otherwise, CONSTBUFFER_GetContent shall return a const CONSTBUFFER* that matches byte by byte the original bytes used to created the const buffer and has the same length.]*/
00132         result = &(((CONSTBUFFER_HANDLE_DATA*)constbufferHandle)->alias);
00133     }
00134     return result;
00135 }
00136 
00137 void CONSTBUFFER_Destroy(CONSTBUFFER_HANDLE constbufferHandle)
00138 {
00139     /*Codes_SRS_CONSTBUFFER_02_015: [If constbufferHandle is NULL then CONSTBUFFER_Destroy shall do nothing.]*/
00140     if (constbufferHandle != NULL)
00141     {
00142         /*Codes_SRS_CONSTBUFFER_02_016: [Otherwise, CONSTBUFFER_Destroy shall decrement the refcount on the constbufferHandle handle.]*/
00143         if (DEC_REF(CONSTBUFFER_HANDLE_DATA, constbufferHandle) == DEC_RETURN_ZERO)
00144         {
00145             /*Codes_SRS_CONSTBUFFER_02_017: [If the refcount reaches zero, then CONSTBUFFER_Destroy shall deallocate all resources used by the CONSTBUFFER_HANDLE.]*/
00146             CONSTBUFFER_HANDLE_DATA* constbufferHandleData = (CONSTBUFFER_HANDLE_DATA*)constbufferHandle;
00147             free((void*)constbufferHandleData->alias.buffer);
00148             free(constbufferHandleData);
00149         }
00150     }
00151 }