Azure IoT common library
Fork of azure_c_shared_utility by
Diff: constbuffer.c
- Revision:
- 0:fa2de1b79154
- Child:
- 6:c55b013dfc2a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/constbuffer.c Fri Apr 08 12:01:36 2016 -0700 @@ -0,0 +1,152 @@ +// 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> +#ifdef _CRTDBG_MAP_ALLOC +#include <crtdbg.h> +#endif +#include "azure_c_shared_utility/gballoc.h" + +#include "azure_c_shared_utility/constbuffer.h" +#include "azure_c_shared_utility/iot_logging.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.]*/ + 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 + { + result = (CONSTBUFFER_HANDLE_DATA*)CONSTBUFFER_Create_Internal(BUFFER_u_char(buffer), BUFFER_length(buffer)); + } + 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); + } + } +}