source: azure_iot_hub/trunk/azure_iohub/c-utility/src/constbuffer.c@ 388

Last change on this file since 388 was 388, checked in by coas-nagasima, 5 years ago

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 10.0 KB
Line 
1// Copyright (c) Microsoft. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
4#include <stdlib.h>
5#include <stddef.h>
6#include "azure_c_shared_utility/macro_utils.h"
7#include "azure_c_shared_utility/gballoc.h"
8#include "azure_c_shared_utility/constbuffer.h"
9#include "azure_c_shared_utility/xlogging.h"
10#include "azure_c_shared_utility/refcount.h"
11
12#define CONSTBUFFER_TYPE_VALUES \
13 CONSTBUFFER_TYPE_COPIED, \
14 CONSTBUFFER_TYPE_MEMORY_MOVED, \
15 CONSTBUFFER_TYPE_WITH_CUSTOM_FREE
16
17MU_DEFINE_ENUM(CONSTBUFFER_TYPE, CONSTBUFFER_TYPE_VALUES)
18
19typedef struct CONSTBUFFER_HANDLE_DATA_TAG
20{
21 CONSTBUFFER alias;
22 COUNT_TYPE count;
23 CONSTBUFFER_TYPE buffer_type;
24 CONSTBUFFER_CUSTOM_FREE_FUNC custom_free_func;
25 void* custom_free_func_context;
26} CONSTBUFFER_HANDLE_DATA;
27
28static CONSTBUFFER_HANDLE CONSTBUFFER_Create_Internal(const unsigned char* source, size_t size)
29{
30 CONSTBUFFER_HANDLE result;
31 /*Codes_SRS_CONSTBUFFER_02_005: [The non-NULL handle returned by CONSTBUFFER_Create shall have its ref count set to "1".]*/
32 /*Codes_SRS_CONSTBUFFER_02_010: [The non-NULL handle returned by CONSTBUFFER_CreateFromBuffer shall have its ref count set to "1".]*/
33 result = (CONSTBUFFER_HANDLE)malloc(sizeof(CONSTBUFFER_HANDLE_DATA) + size);
34 if (result == NULL)
35 {
36 /*Codes_SRS_CONSTBUFFER_02_003: [If creating the copy fails then CONSTBUFFER_Create shall return NULL.]*/
37 /*Codes_SRS_CONSTBUFFER_02_008: [If copying the content fails, then CONSTBUFFER_CreateFromBuffer shall fail and return NULL.] */
38 LogError("unable to malloc");
39 /*return as is*/
40 }
41 else
42 {
43 INIT_REF_VAR(result->count);
44
45 /*Codes_SRS_CONSTBUFFER_02_002: [Otherwise, CONSTBUFFER_Create shall create a copy of the memory area pointed to by source having size bytes.]*/
46 result->alias.size = size;
47 if (size == 0)
48 {
49 result->alias.buffer = NULL;
50 }
51 else
52 {
53 unsigned char* temp = (void*)(result + 1);
54 /*Codes_SRS_CONSTBUFFER_02_004: [Otherwise CONSTBUFFER_Create shall return a non-NULL handle.]*/
55 /*Codes_SRS_CONSTBUFFER_02_007: [Otherwise, CONSTBUFFER_CreateFromBuffer shall copy the content of buffer.]*/
56 /*Codes_SRS_CONSTBUFFER_02_009: [Otherwise, CONSTBUFFER_CreateFromBuffer shall return a non-NULL handle.]*/
57 (void)memcpy(temp, source, size);
58 result->alias.buffer = temp;
59 }
60
61 result->buffer_type = CONSTBUFFER_TYPE_COPIED;
62 }
63 return result;
64}
65
66CONSTBUFFER_HANDLE CONSTBUFFER_Create(const unsigned char* source, size_t size)
67{
68 CONSTBUFFER_HANDLE result;
69 /*Codes_SRS_CONSTBUFFER_02_001: [If source is NULL and size is different than 0 then CONSTBUFFER_Create shall fail and return NULL.]*/
70 if (
71 (source == NULL) &&
72 (size != 0)
73 )
74 {
75 LogError("invalid arguments passes to CONSTBUFFER_Create");
76 result = NULL;
77 }
78 else
79 {
80 result = CONSTBUFFER_Create_Internal(source, size);
81 }
82 return result;
83}
84
85/*this creates a new constbuffer from an existing BUFFER_HANDLE*/
86CONSTBUFFER_HANDLE CONSTBUFFER_CreateFromBuffer(BUFFER_HANDLE buffer)
87{
88 CONSTBUFFER_HANDLE result;
89 /*Codes_SRS_CONSTBUFFER_02_006: [If buffer is NULL then CONSTBUFFER_CreateFromBuffer shall fail and return NULL.]*/
90 if (buffer == NULL)
91 {
92 LogError("invalid arg passed to CONSTBUFFER_CreateFromBuffer");
93 result = NULL;
94 }
95 else
96 {
97 size_t length = BUFFER_length(buffer);
98 unsigned char* rawBuffer = BUFFER_u_char(buffer);
99 result = CONSTBUFFER_Create_Internal(rawBuffer, length);
100 }
101 return result;
102}
103
104CONSTBUFFER_HANDLE CONSTBUFFER_CreateWithMoveMemory(unsigned char* source, size_t size)
105{
106 CONSTBUFFER_HANDLE result;
107
108 /* Codes_SRS_CONSTBUFFER_01_001: [ If source is NULL and size is different than 0 then CONSTBUFFER_Create shall fail and return NULL. ]*/
109 if ((source == NULL) && (size > 0))
110 {
111 LogError("Invalid arguments: unsigned char* source=%p, size_t size=%u", source, (unsigned int)size);
112 result = NULL;
113 }
114 else
115 {
116 result = (CONSTBUFFER_HANDLE)malloc(sizeof(CONSTBUFFER_HANDLE_DATA));
117 if (result == NULL)
118 {
119 /* Codes_SRS_CONSTBUFFER_01_005: [ If any error occurs, CONSTBUFFER_CreateWithMoveMemory shall fail and return NULL. ]*/
120 LogError("malloc failed");
121 }
122 else
123 {
124 /* Codes_SRS_CONSTBUFFER_01_004: [ If source is non-NULL and size is 0, the source pointer shall be owned (and freed) by the newly created instance of const buffer. ]*/
125 /* Codes_SRS_CONSTBUFFER_01_002: [ CONSTBUFFER_CreateWithMoveMemory shall store the source and size and return a non-NULL handle to the newly created const buffer. ]*/
126 result->alias.buffer = source;
127 result->alias.size = size;
128 result->buffer_type = CONSTBUFFER_TYPE_MEMORY_MOVED;
129
130 /* Codes_SRS_CONSTBUFFER_01_003: [ The non-NULL handle returned by CONSTBUFFER_CreateWithMoveMemory shall have its ref count set to "1". ]*/
131 INIT_REF_VAR(result->count);
132 }
133 }
134
135 return result;
136}
137
138CONSTBUFFER_HANDLE CONSTBUFFER_CreateWithCustomFree(const unsigned char* source, size_t size, CONSTBUFFER_CUSTOM_FREE_FUNC customFreeFunc, void* customFreeFuncContext)
139{
140 CONSTBUFFER_HANDLE result;
141
142 /* Codes_SRS_CONSTBUFFER_01_014: [ customFreeFuncContext shall be allowed to be NULL. ]*/
143
144 if (
145 /* Codes_SRS_CONSTBUFFER_01_006: [ If source is NULL and size is different than 0 then CONSTBUFFER_CreateWithCustomFree shall fail and return NULL. ]*/
146 ((source == NULL) && (size > 0)) ||
147 /* Codes_SRS_CONSTBUFFER_01_013: [ If customFreeFunc is NULL, CONSTBUFFER_CreateWithCustomFree shall fail and return NULL. ]*/
148 (customFreeFunc == NULL)
149 )
150 {
151 LogError("Invalid arguments: unsigned char* source=%p, size_t size=%u, customFreeFunc=%p, customFreeFuncContext=%p",
152 source, (unsigned int)size, customFreeFunc, customFreeFuncContext);
153 result = NULL;
154 }
155 else
156 {
157 result = (CONSTBUFFER_HANDLE)malloc(sizeof(CONSTBUFFER_HANDLE_DATA));
158 if (result == NULL)
159 {
160 /* Codes_SRS_CONSTBUFFER_01_011: [ If any error occurs, CONSTBUFFER_CreateWithMoveMemory shall fail and return NULL. ]*/
161 LogError("malloc failed");
162 }
163 else
164 {
165 /* Codes_SRS_CONSTBUFFER_01_007: [ If source is non-NULL and size is 0, the source pointer shall be owned (and freed) by the newly created instance of const buffer. ]*/
166 /* Codes_SRS_CONSTBUFFER_01_008: [ CONSTBUFFER_CreateWithCustomFree shall store the source and size and return a non-NULL handle to the newly created const buffer. ]*/
167 result->alias.buffer = source;
168 result->alias.size = size;
169 result->buffer_type = CONSTBUFFER_TYPE_WITH_CUSTOM_FREE;
170
171 /* Codes_SRS_CONSTBUFFER_01_009: [ CONSTBUFFER_CreateWithCustomFree shall store customFreeFunc and customFreeFuncContext in order to use them to free the memory when the CONST buffer resources are freed. ]*/
172 result->custom_free_func = customFreeFunc;
173 result->custom_free_func_context = customFreeFuncContext;
174
175 /* Codes_SRS_CONSTBUFFER_01_010: [ The non-NULL handle returned by CONSTBUFFER_CreateWithCustomFree shall have its ref count set to 1. ]*/
176 INIT_REF_VAR(result->count);
177 }
178 }
179
180 return result;
181}
182
183void CONSTBUFFER_IncRef(CONSTBUFFER_HANDLE constbufferHandle)
184{
185 if (constbufferHandle == NULL)
186 {
187 /*Codes_SRS_CONSTBUFFER_02_013: [If constbufferHandle is NULL then CONSTBUFFER_IncRef shall return.]*/
188 LogError("Invalid arguments: CONSTBUFFER_HANDLE constbufferHandle=%p", constbufferHandle);
189 }
190 else
191 {
192 /*Codes_SRS_CONSTBUFFER_02_014: [Otherwise, CONSTBUFFER_IncRef shall increment the reference count.]*/
193 INC_REF_VAR(constbufferHandle->count);
194 }
195}
196
197const CONSTBUFFER* CONSTBUFFER_GetContent(CONSTBUFFER_HANDLE constbufferHandle)
198{
199 const CONSTBUFFER* result;
200 if (constbufferHandle == NULL)
201 {
202 /*Codes_SRS_CONSTBUFFER_02_011: [If constbufferHandle is NULL then CONSTBUFFER_GetContent shall return NULL.]*/
203 result = NULL;
204 LogError("invalid arg");
205 }
206 else
207 {
208 /*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.]*/
209 result = &(constbufferHandle->alias);
210 }
211 return result;
212}
213
214void CONSTBUFFER_DecRef(CONSTBUFFER_HANDLE constbufferHandle)
215{
216 if (constbufferHandle == NULL)
217 {
218 /*Codes_SRS_CONSTBUFFER_02_015: [If constbufferHandle is NULL then CONSTBUFFER_DecRef shall do nothing.]*/
219 LogError("Invalid arguments: CONSTBUFFER_HANDLE constbufferHandle=%p", constbufferHandle);
220 }
221 else
222 {
223 /*Codes_SRS_CONSTBUFFER_02_016: [Otherwise, CONSTBUFFER_DecRef shall decrement the refcount on the constbufferHandle handle.]*/
224 if (DEC_REF_VAR(constbufferHandle->count) == DEC_RETURN_ZERO)
225 {
226 if (constbufferHandle->buffer_type == CONSTBUFFER_TYPE_MEMORY_MOVED)
227 {
228 free((void*)constbufferHandle->alias.buffer);
229 }
230 else if (constbufferHandle->buffer_type == CONSTBUFFER_TYPE_WITH_CUSTOM_FREE)
231 {
232 /* Codes_SRS_CONSTBUFFER_01_012: [ If the buffer was created by calling CONSTBUFFER_CreateWithCustomFree, the customFreeFunc function shall be called to free the memory, while passed customFreeFuncContext as argument. ]*/
233 constbufferHandle->custom_free_func(constbufferHandle->custom_free_func_context);
234 }
235
236 /*Codes_SRS_CONSTBUFFER_02_017: [If the refcount reaches zero, then CONSTBUFFER_DecRef shall deallocate all resources used by the CONSTBUFFER_HANDLE.]*/
237 free(constbufferHandle);
238 }
239 }
240}
Note: See TracBrowser for help on using the repository browser.