Azure IoT common library
Fork of azure_c_shared_utility by
constbuffer.c
- Committer:
- wiggly
- Date:
- 2017-08-24
- Revision:
- 34:651c23af382c
- Parent:
- 19:2e0811512ceb
File content as of revision 34:651c23af382c:
// Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. // // PUT NO INCLUDES BEFORE HERE // #include <stdlib.h> #include <stddef.h> #include "azure_c_shared_utility/gballoc.h" #include "azure_c_shared_utility/constbuffer.h" #include "azure_c_shared_utility/xlogging.h" #include "azure_c_shared_utility/refcount.h" typedef struct CONSTBUFFER_HANDLE_DATA_TAG { CONSTBUFFER alias; }CONSTBUFFER_HANDLE_DATA; DEFINE_REFCOUNT_TYPE(CONSTBUFFER_HANDLE_DATA); static CONSTBUFFER_HANDLE CONSTBUFFER_Create_Internal(const unsigned char* source, size_t size) { CONSTBUFFER_HANDLE_DATA* result; /*Codes_SRS_CONSTBUFFER_02_005: [The non-NULL handle returned by CONSTBUFFER_Create shall have its ref count set to "1".]*/ /*Codes_SRS_CONSTBUFFER_02_010: [The non-NULL handle returned by CONSTBUFFER_CreateFromBuffer shall have its ref count set to "1".]*/ result = REFCOUNT_TYPE_CREATE(CONSTBUFFER_HANDLE_DATA); if (result == NULL) { /*Codes_SRS_CONSTBUFFER_02_003: [If creating the copy fails then CONSTBUFFER_Create shall return NULL.]*/ /*Codes_SRS_CONSTBUFFER_02_008: [If copying the content fails, then CONSTBUFFER_CreateFromBuffer shall fail and return NULL.] */ LogError("unable to malloc"); /*return as is*/ } else { /*Codes_SRS_CONSTBUFFER_02_002: [Otherwise, CONSTBUFFER_Create shall create a copy of the memory area pointed to by source having size bytes.]*/ result->alias.size = size; if (size == 0) { result->alias.buffer = NULL; } else { unsigned char* temp = (unsigned char*)malloc(size); if (temp == NULL) { /*Codes_SRS_CONSTBUFFER_02_003: [If creating the copy fails then CONSTBUFFER_Create shall return NULL.]*/ /*Codes_SRS_CONSTBUFFER_02_008: [If copying the content fails, then CONSTBUFFER_CreateFromBuffer shall fail and return NULL.] */ LogError("unable to malloc"); free(result); result = NULL; } else { /*Codes_SRS_CONSTBUFFER_02_004: [Otherwise CONSTBUFFER_Create shall return a non-NULL handle.]*/ /*Codes_SRS_CONSTBUFFER_02_007: [Otherwise, CONSTBUFFER_CreateFromBuffer shall copy the content of buffer.]*/ /*Codes_SRS_CONSTBUFFER_02_009: [Otherwise, CONSTBUFFER_CreateFromBuffer shall return a non-NULL handle.]*/ (void)memcpy(temp, source, size); result->alias.buffer = temp; } } } return (CONSTBUFFER_HANDLE)result; } CONSTBUFFER_HANDLE CONSTBUFFER_Create(const unsigned char* source, size_t size) { CONSTBUFFER_HANDLE_DATA* result; /*Codes_SRS_CONSTBUFFER_02_001: [If source is NULL and size is different than 0 then CONSTBUFFER_Create shall fail and return NULL.]*/ if ( (source == NULL) && (size != 0) ) { LogError("invalid arguments passes to CONSTBUFFER_Create"); result = NULL; } else { result = (CONSTBUFFER_HANDLE_DATA*)CONSTBUFFER_Create_Internal(source, size); } return (CONSTBUFFER_HANDLE)result; } /*this creates a new constbuffer from an existing BUFFER_HANDLE*/ CONSTBUFFER_HANDLE CONSTBUFFER_CreateFromBuffer(BUFFER_HANDLE buffer) { CONSTBUFFER_HANDLE_DATA* result; /*Codes_SRS_CONSTBUFFER_02_006: [If buffer is NULL then CONSTBUFFER_CreateFromBuffer shall fail and return NULL.]*/ if (buffer == NULL) { LogError("invalid arg passed to CONSTBUFFER_CreateFromBuffer"); result = NULL; } else { size_t length = BUFFER_length(buffer); unsigned char* rawBuffer = BUFFER_u_char(buffer); result = (CONSTBUFFER_HANDLE_DATA*)CONSTBUFFER_Create_Internal(rawBuffer, length); } return (CONSTBUFFER_HANDLE)result; } CONSTBUFFER_HANDLE CONSTBUFFER_Clone(CONSTBUFFER_HANDLE constbufferHandle) { if (constbufferHandle == NULL) { /*Codes_SRS_CONSTBUFFER_02_013: [If constbufferHandle is NULL then CONSTBUFFER_Clone shall fail and return NULL.]*/ LogError("invalid arg"); } else { /*Codes_SRS_CONSTBUFFER_02_014: [Otherwise, CONSTBUFFER_Clone shall increment the reference count and return constbufferHandle.]*/ INC_REF(CONSTBUFFER_HANDLE_DATA, constbufferHandle); } return constbufferHandle; } const CONSTBUFFER* CONSTBUFFER_GetContent(CONSTBUFFER_HANDLE constbufferHandle) { const CONSTBUFFER* result; if (constbufferHandle == NULL) { /*Codes_SRS_CONSTBUFFER_02_011: [If constbufferHandle is NULL then CONSTBUFFER_GetContent shall return NULL.]*/ result = NULL; LogError("invalid arg"); } else { /*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.]*/ result = &(((CONSTBUFFER_HANDLE_DATA*)constbufferHandle)->alias); } return result; } void CONSTBUFFER_Destroy(CONSTBUFFER_HANDLE constbufferHandle) { /*Codes_SRS_CONSTBUFFER_02_015: [If constbufferHandle is NULL then CONSTBUFFER_Destroy shall do nothing.]*/ if (constbufferHandle != NULL) { /*Codes_SRS_CONSTBUFFER_02_016: [Otherwise, CONSTBUFFER_Destroy shall decrement the refcount on the constbufferHandle handle.]*/ if (DEC_REF(CONSTBUFFER_HANDLE_DATA, constbufferHandle) == DEC_RETURN_ZERO) { /*Codes_SRS_CONSTBUFFER_02_017: [If the refcount reaches zero, then CONSTBUFFER_Destroy shall deallocate all resources used by the CONSTBUFFER_HANDLE.]*/ CONSTBUFFER_HANDLE_DATA* constbufferHandleData = (CONSTBUFFER_HANDLE_DATA*)constbufferHandle; free((void*)constbufferHandleData->alias.buffer); free(constbufferHandleData); } } }