kinetic-c  v0.12.0
Seagate Kinetic Protocol Client Library for C
byte_array.c
Go to the documentation of this file.
1 /*
2 * kinetic-c
3 * Copyright (C) 2015 Seagate Technology.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 */
20 #include "byte_array.h"
21 #include <assert.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <sys/param.h>
27 
29  const char* format, va_list args);
30 
31 ByteArray ByteArray_Create(void* data, size_t len)
32 {
33  return (ByteArray) {
34  .data = (uint8_t*)(data), .len = len
35  };
36 }
37 
39 {
40  return (ByteArray) {
41  .data = (uint8_t*)str, .len = strlen(str)
42  };
43 }
44 
46 {
47  for (size_t i = 0; i < array.len; i++) {
48  array.data[i] = (uint8_t)(i & 0x0FFu);
49  }
50 }
51 
52 ByteArray ByteArray_GetSlice(ByteArray array, size_t start, size_t len)
53 {
54  assert(array.data != NULL);
55  assert(start < array.len);
56  assert(start + len <= array.len);
57  return (ByteArray) {
58  .data = &array.data[start], .len = len
59  };
60 }
61 
63 {
64  assert(buffer != NULL);
65  buffer->bytesUsed = 0;
66 }
67 
68 ByteBuffer ByteBuffer_Create(void* data, size_t max_len, size_t used)
69 {
70  assert(data != NULL);
71  assert(max_len > 0);
72  return (ByteBuffer) {
73  .array = (ByteArray) {.data = (uint8_t*)data, .len = max_len},
74  .bytesUsed = used,
75  };
76 }
77 
79 {
80  return (ByteBuffer) {.array = array, .bytesUsed = 0};
81 }
82 
83 ByteBuffer ByteBuffer_CreateAndAppend(void* data, size_t max_len, const void* value, size_t value_len)
84 {
85  ByteBuffer buf = ByteBuffer_Create(data, max_len, 0);
86  ByteBuffer_Append(&buf, value, value_len);
87  return buf;
88 }
89 
90 ByteBuffer ByteBuffer_CreateAndAppendArray(void* data, size_t max_len, const ByteArray value)
91 {
92  ByteBuffer buf = ByteBuffer_Create(data, max_len, 0);
93  ByteBuffer_AppendArray(&buf, value);
94  return buf;
95 }
96 
97 ByteBuffer ByteBuffer_CreateAndAppendCString(void* data, size_t max_len, const char* value)
98 {
99  ByteBuffer buf = ByteBuffer_Create(data, max_len, 0);
100  ByteBuffer_AppendCString(&buf, value);
101  return buf;
102 }
103 
104 ByteBuffer ByteBuffer_CreateAndAppendDummyData(void* data, size_t max_len, size_t len)
105 {
106  ByteBuffer buf = ByteBuffer_Create(data, max_len, 0);
107  ByteBuffer_AppendDummyData(&buf, len);
108  return buf;
109 }
110 
112 {
113  assert(buffer.array.data != NULL);
114  return ((long)buffer.array.len - (long)buffer.bytesUsed);
115 }
116 
117 ByteArray ByteBuffer_Consume(ByteBuffer* buffer, size_t max_len)
118 {
119  assert(buffer != NULL);
120  assert(buffer->array.data != NULL);
121  if (buffer->bytesUsed >= buffer->array.len) {
122  return BYTE_ARRAY_NONE;
123  }
124  long remaining = ByteBuffer_BytesRemaining(*buffer);
125  assert(remaining >= 0);
126  size_t len = MIN(max_len, (size_t)remaining);
127  ByteArray slice = {
128  .data = &buffer->array.data[buffer->bytesUsed],
129  .len = len,
130  };
131  buffer->bytesUsed += len;
132  return slice;
133 }
134 
135 ByteBuffer* ByteBuffer_Append(ByteBuffer* buffer, const void* data, size_t len)
136 {
137  assert(buffer != NULL);
138  assert(buffer->array.data != NULL);
139  assert(data != NULL);
140  if ((buffer->bytesUsed + len) > buffer->array.len) {
141  return NULL;
142  }
143  memcpy(&buffer->array.data[buffer->bytesUsed], data, len);
144  buffer->bytesUsed += len;
145  assert(buffer != NULL);
146  return buffer;
147 }
148 
150 {
151  assert(buffer != NULL);
152  assert(buffer->array.data != NULL);
153  assert(array.data != NULL);
154  if ((buffer->bytesUsed + array.len) > buffer->array.len) {
155  return NULL;
156  }
157  memcpy(&buffer->array.data[buffer->bytesUsed], array.data, array.len);
158  buffer->bytesUsed += array.len;
159  return buffer;
160 }
161 
163 {
164  assert(buffer != NULL);
165  assert(buffer->array.data != NULL);
166  assert(bufferToAppend.array.data != NULL);
167  assert(bufferToAppend.bytesUsed <= bufferToAppend.array.len);
168  if ((buffer->bytesUsed + bufferToAppend.bytesUsed) > buffer->array.len) {
169  return NULL;
170  }
171  memcpy(&buffer->array.data[buffer->bytesUsed], bufferToAppend.array.data, bufferToAppend.bytesUsed);
172  buffer->bytesUsed += bufferToAppend.bytesUsed;
173  return buffer;
174 }
175 
177 {
178  assert(buffer != NULL);
179  assert(buffer->array.data != NULL);
180  assert(str != NULL);
181  int len = strlen(str);
182  if (len == 0 || ((buffer->bytesUsed + len) > buffer->array.len)) {
183  return NULL;
184  }
185  memcpy(&buffer->array.data[buffer->bytesUsed], str, len);
186  buffer->bytesUsed += len;
187  return buffer;
188 }
189 
190 
191 static ByteBuffer* append_formatted_cstring_va_list(ByteBuffer* buffer, const char* format, va_list args)
192 {
193  char* start = (char*)&buffer->array.data[buffer->bytesUsed];
194  long startLen = (long)buffer->bytesUsed;
195  long maxLen = buffer->array.len;
196  long remainingLen = ByteBuffer_BytesRemaining(*buffer);
197  long extraLen = vsnprintf(start, remainingLen, format, args);
198  if (startLen + extraLen >= maxLen) {
199  return NULL;
200  }
201  buffer->bytesUsed += extraLen;
202  return buffer;
203 }
204 
205 ByteBuffer* ByteBuffer_AppendFormattedCString(ByteBuffer* buffer, const char * format, ...)
206 {
207  assert(buffer != NULL);
208  assert(buffer->array.data != NULL);
209 
210  bool failed = false;
211  va_list args;
212  va_start(args, format);
213 
214  failed = (append_formatted_cstring_va_list(buffer, format, args) == NULL);
215 
216  va_end(args);
217 
218  return failed ? NULL : buffer;
219 }
220 
221 ByteBuffer ByteBuffer_CreateAndAppendFormattedCString(void* data, size_t max_len, const char * format, ...)
222 {
223  ByteBuffer buf = ByteBuffer_Create(data, max_len, 0);
224 
225  va_list args;
226  va_start(args, format);
227  if (append_formatted_cstring_va_list(&buf, format, args) == NULL) {
228  memset(&buf, 0, sizeof(ByteBuffer));
229  }
230  va_end(args);
231 
232  return buf;
233 }
234 
236 {
237  assert(buffer != NULL);
238  assert(buffer->array.data != NULL);
239  if (len == 0 || ((buffer->bytesUsed + len) > buffer->array.len)) {
240  return NULL;
241  }
242  for (size_t i = 0; i < len; i++) {
243  buffer->array.data[buffer->bytesUsed + i] = (uint8_t)(i & 0x0FFu);
244  }
245  buffer->bytesUsed += len;
246  return buffer;
247 }
248 
249 bool ByteBuffer_IsNull(ByteBuffer const buffer)
250 {
251  return buffer.array.data == NULL;
252 }
253 
255 {
256  // There is not check on the return value from calloc by design
257  // the intention is that you can check for malloc failure by
258  // calling ByteBuffer_IsNull on the returned ByteBuffer
259  return ByteBuffer_Create(calloc(1, size), size, 0);
260 }
261 
262 ByteBuffer ByteBuffer_MallocAndAppend(const void* data, size_t len)
263 {
264  assert(data != NULL);
265  assert(len != 0);
266  ByteBuffer buffer = ByteBuffer_Malloc(len);
267  if (ByteBuffer_IsNull(buffer)) { return buffer; }
268  ByteBuffer_Append(&buffer, data, len);
269  return buffer;
270 }
271 
273 {
274  assert(buffer.array.data != NULL);
275  free(buffer.array.data);
276 }
ByteArray ByteArray_CreateWithCString(const char *str)
Definition: byte_array.c:38
ByteBuffer * ByteBuffer_AppendCString(ByteBuffer *buffer, const char *str)
Definition: byte_array.c:176
Structure for handling generic arrays of bytes.
Definition: byte_array.h:34
ByteBuffer ByteBuffer_CreateAndAppendDummyData(void *data, size_t max_len, size_t len)
Definition: byte_array.c:104
Structure for an embedded ByteArray as a buffer.
Definition: byte_array.h:53
void ByteBuffer_Reset(ByteBuffer *buffer)
Definition: byte_array.c:62
long ByteBuffer_BytesRemaining(const ByteBuffer buffer)
Definition: byte_array.c:111
ByteBuffer * ByteBuffer_AppendFormattedCString(ByteBuffer *buffer, const char *format,...)
Definition: byte_array.c:205
ByteBuffer * ByteBuffer_AppendArray(ByteBuffer *buffer, const ByteArray array)
Definition: byte_array.c:149
ByteBuffer ByteBuffer_CreateWithArray(ByteArray array)
Definition: byte_array.c:78
ByteArray ByteBuffer_Consume(ByteBuffer *buffer, size_t max_len)
Definition: byte_array.c:117
void ByteBuffer_Free(ByteBuffer buffer)
Definition: byte_array.c:272
ByteBuffer ByteBuffer_Malloc(size_t size)
Definition: byte_array.c:254
ByteBuffer ByteBuffer_Create(void *data, size_t max_len, size_t used)
Definition: byte_array.c:68
ByteBuffer * ByteBuffer_AppendBuffer(ByteBuffer *buffer, const ByteBuffer bufferToAppend)
Definition: byte_array.c:162
bool ByteBuffer_IsNull(ByteBuffer const buffer)
Definition: byte_array.c:249
ByteBuffer ByteBuffer_CreateAndAppend(void *data, size_t max_len, const void *value, size_t value_len)
Definition: byte_array.c:83
ByteBuffer * ByteBuffer_AppendDummyData(ByteBuffer *buffer, size_t len)
Definition: byte_array.c:235
ByteArray array
ByteArray holding allocated array w/length = allocated size.
Definition: byte_array.h:54
ByteBuffer * ByteBuffer_Append(ByteBuffer *buffer, const void *data, size_t len)
Definition: byte_array.c:135
void ByteArray_FillWithDummyData(ByteArray array)
Definition: byte_array.c:45
static ByteBuffer * append_formatted_cstring_va_list(ByteBuffer *buffer, const char *format, va_list args)
Definition: byte_array.c:191
size_t len
Number of bytes in the data field.
Definition: byte_array.h:35
#define BYTE_ARRAY_NONE
Convenience macro to represent an empty array with no data.
Definition: byte_array.h:40
ByteArray ByteArray_Create(void *data, size_t len)
Definition: byte_array.c:31
uint8_t * data
Pointer to an allocated array of data bytes.
Definition: byte_array.h:36
ByteArray ByteArray_GetSlice(ByteArray array, size_t start, size_t len)
Definition: byte_array.c:52
ByteBuffer ByteBuffer_CreateAndAppendFormattedCString(void *data, size_t max_len, const char *format,...)
Definition: byte_array.c:221
size_t bytesUsed
Reflects the number of bytes used from the array
Definition: byte_array.h:55
ByteBuffer ByteBuffer_CreateAndAppendArray(void *data, size_t max_len, const ByteArray value)
Definition: byte_array.c:90
ByteBuffer ByteBuffer_CreateAndAppendCString(void *data, size_t max_len, const char *value)
Definition: byte_array.c:97
ByteBuffer ByteBuffer_MallocAndAppend(const void *data, size_t len)
Definition: byte_array.c:262