picox  0.1
xbyte_array.h
[詳解]
1 
14 /*
15  * License: MIT license
16  * Copyright (c) <2016> <MaskedW [maskedw00@gmail.com]>
17  *
18  * Permission is hereby granted, free of charge, to any person
19  * obtaining a copy of this software and associated documentation
20  * files (the "Software"), to deal in the Software without
21  * restriction, including without limitation the rights to use, copy,
22  * modify, merge, publish, distribute, sublicense, and/or sell copies
23  * of the Software, and to permit persons to whom the Software is
24  * furnished to do so, subject to the following conditions:
25  *
26  * The above copyright notice and this permission notice shall be
27  * included in all copies or substantial portions of the Software.
28  *
29  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
33  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
34  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
35  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36  * SOFTWARE.
37  */
38 
39 #ifndef picox_container_xbyte_array_h_
40 #define picox_container_xbyte_array_h_
41 
42 
43 #include <picox/core/xcore.h>
44 
45 
61 #ifdef __cplusplus
62 extern "C" {
63 #endif /* __cplusplus */
64 
65 
68 typedef struct
69 {
71  uint8_t* m_data;
72  size_t m_size;
73  size_t m_capacity;
74  bool m_is_heapdata;
75 } XByteArray;
76 
77 
88 static inline bool
89 xbarray_init(XByteArray* self, void* buffer, size_t size)
90 {
91  X_ASSERT(self);
92 
93  memset(self, 0, sizeof(*self));
94  if (! buffer)
95  {
96  buffer = (uint8_t*)x_malloc(size);
97  if (! buffer)
98  return false;
99  self->m_is_heapdata = true;
100  }
101  self->m_data = buffer;
102  self->m_capacity = size;
103 
104  return true;
105 }
106 
107 
110 static inline void
112 {
113  X_ASSERT(self);
114  if (self->m_is_heapdata)
115  {
116  x_free(self->m_data);
117  self->m_is_heapdata = false;
118  }
119  self->m_data = NULL;
120  self->m_size = 0;
121  self->m_capacity = 0;
122 }
123 
124 
127 static inline const uint8_t*
129 {
130  X_ASSERT(self);
131  return self->m_data;
132 }
133 
134 
137 static inline uint8_t*
139 {
140  return (uint8_t*)xbarray_const_data(self);
141 }
142 
143 
146 static inline const uint8_t*
147 xbarray_const_at(const XByteArray* self, size_t index)
148 {
149  X_ASSERT(self);
150  X_ASSERT(self->m_size > index);
151  return self->m_data + index;
152 }
153 
154 
157 static inline uint8_t*
158 xbarray_at(XByteArray* self, size_t index)
159 {
160  return (uint8_t*)xbarray_const_at(self, index);
161 }
162 
163 
166 static inline size_t
168 {
169  X_ASSERT(self);
170  return self->m_size;
171 }
172 
173 
176 static inline size_t
178 {
179  X_ASSERT(self);
180  return self->m_capacity;
181 }
182 
183 
186 static inline bool
188 {
189  X_ASSERT(self);
190  return ! self->m_size;
191 }
192 
193 
196 static inline bool
198 {
199  X_ASSERT(self);
200  return self->m_size == self->m_capacity;
201 }
202 
203 
206 static inline size_t
208 {
209  X_ASSERT(self);
210  return self->m_capacity - self->m_size;
211 }
212 
213 
216 static inline void
218 {
219  X_ASSERT(self);
220  self->m_size = 0;
221 }
222 
223 
226 static inline void
227 xbarray_fill(XByteArray* self, uint8_t value)
228 {
229  X_ASSERT(self);
230  memset(self->m_data, value, self->m_size);
231 }
232 
233 
247 static inline bool
248 xbarray_reserve(XByteArray* self, size_t size)
249 {
250  X_ASSERT(self);
251  if (self->m_capacity >= size)
252  return true;
253 
254  if (! self->m_is_heapdata)
255  return false;
256 
257  uint8_t* const buf = (uint8_t*)x_realloc2(self->m_data,
258  self->m_size,
259  size);
260  if (! buf)
261  return false;
262 
263  self->m_data = buf;
264  self->m_capacity = size;
265 
266  return true;
267 }
268 
269 
278 static inline bool
280 {
281  const size_t space = self->m_capacity - self->m_size;
282  if (space >= size)
283  return true;
284 
285  const size_t new_capcity = size > space + self->m_capacity ?
286  size :
287  self->m_capacity * 2;
288  return xbarray_reserve(self, new_capcity);
289 }
290 
291 
294 static inline void
296 {
297  const bool ok = xbarray_make_space_if(self, size);
298  X_ASSERT(ok);
299  X_UNUSED(ok);
300 }
301 
302 
305 static inline void
306 xbarray_push_back_n(XByteArray* self, const void* src, size_t size)
307 {
308  X_ASSERT(self);
309  X_ASSERT(src);
310 
311  xbarray_strict_make_space_if(self, size);
312  memcpy(self->m_data + self->m_size, src, size);
313  self->m_size += size;
314 }
315 
316 
319 static inline void
320 xbarray_push_back(XByteArray* self, uint8_t value)
321 {
322  X_ASSERT(self);
323 
324  xbarray_strict_make_space_if(self, sizeof(value));
325  *(self->m_data + self->m_size) = value;
326  self->m_size += 1;
327 }
328 
329 
334 static inline void
335 xbarray_pop_back_n(XByteArray* self, void* dst, size_t size)
336 {
337  X_ASSERT(self);
338  X_ASSERT(dst);
339  X_ASSERT(self->m_size >= size);
340 
341  self->m_size -= size;
342  if (dst)
343  memcpy(dst, self->m_data + self->m_size, size);
344 }
345 
346 
349 static inline uint8_t
351 {
352  X_ASSERT(self);
353  self->m_size -= 1;
354  const uint8_t value = *(self->m_data + self->m_size);
355 
356  return value;
357 }
358 
359 
366 static inline bool
368 {
369  X_ASSERT(self);
370 
371  uint8_t* const buf = (uint8_t*)x_realloc2(self->m_data,
372  self->m_capacity,
373  self->m_size);
374  if (! buf)
375  return false;
376 
377  self->m_data = buf;
378  self->m_capacity = self->m_size;
379 
380  return true;
381 }
382 
383 
386 static inline void
387 xbarray_insert_n(XByteArray* self, size_t index, const void* src, size_t size)
388 {
389  X_ASSERT(self);
390 
391  if (index == self->m_size)
392  {
393  xbarray_push_back_n(self, src, size);
394  return;
395  }
396 
397  X_ASSERT(src);
398  X_ASSERT(index <= self->m_size);
399 
400  xbarray_strict_make_space_if(self, size);
401  memmove(self->m_data + index + size,
402  self->m_data + index,
403  self->m_size - index);
404  memcpy(self->m_data + index, src, size);
405  self->m_size += size;
406 }
407 
408 
411 static inline void
412 xbarray_insert(XByteArray* self, size_t index, uint8_t value)
413 {
414  xbarray_insert_n(self, index, &value, sizeof(value));
415 }
416 
417 
420 static inline void
421 xbarray_erase_n(XByteArray* self, size_t index, size_t size)
422 {
423  X_ASSERT(self);
424  X_ASSERT(index <= self->m_size);
425 
426  memmove(self->m_data + index,
427  self->m_data + index + size,
428  self->m_size - (index + size));
429  self->m_size -= size;
430 }
431 
432 
435 static inline void
436 xbarray_erase(XByteArray* self, size_t index)
437 {
438  xbarray_erase_n(self, index, sizeof(uint8_t));
439 }
440 
441 
442 #ifdef __cplusplus
443 }
444 #endif /* __cplusplus */
445 
446 
452 #endif /* picox_container_xbyte_array_h_ */
static void xbarray_insert(XByteArray *self, size_t index, uint8_t value)
バッファ先頭からn番目にvalueを挿入します
Definition: xbyte_array.h:412
static void * x_realloc2(void *old_mem, size_t old_size, size_t new_size)
old_memが指すold_sizeバイトのメモリブロックをnew_sizeバイトに再割当てして返します ...
Definition: xstdlib.h:138
static uint8_t * xbarray_data(XByteArray *self)
バッファ先頭を指すポインタを返します
Definition: xbyte_array.h:138
static bool xbarray_full(const XByteArray *self)
バッファが拡張なしで格納できる上限に達しているかどうかを返します
Definition: xbyte_array.h:197
static void xbarray_fill(XByteArray *self, uint8_t value)
バッファをvalueで埋めます
Definition: xbyte_array.h:227
static bool xbarray_shrink_to_fit(XByteArray *self)
バッファの容量を有効バイト数まで切り詰めます
Definition: xbyte_array.h:367
static const uint8_t * xbarray_const_at(const XByteArray *self, size_t index)
バッファ先頭からnバイト後方を指すコンストポインタを返します
Definition: xbyte_array.h:147
static size_t xbarray_size(const XByteArray *self)
バッファに格納されたバイト数を返します
Definition: xbyte_array.h:167
static void xbarray_strict_make_space_if(XByteArray *self, size_t size)
X_ASSERT()による検査を行うxbarray_make_space_if()です
Definition: xbyte_array.h:295
可変長バイト配列管理構造体
Definition: xbyte_array.h:68
static void xbarray_erase(XByteArray *self, size_t index)
バッファ先頭からn番目を除去します
Definition: xbyte_array.h:436
static bool xbarray_init(XByteArray *self, void *buffer, size_t size)
バッファを初期化します
Definition: xbyte_array.h:89
static size_t xbarray_capacity(const XByteArray *self)
バッファに割り当てられたバイト数を返します
Definition: xbyte_array.h:177
static uint8_t xbarray_pop_back(XByteArray *self)
バッファ末尾から1バイトを除去して返します
Definition: xbyte_array.h:350
static void xbarray_insert_n(XByteArray *self, size_t index, const void *src, size_t size)
バッファ先頭からn番目にsrcからsizeバイトを挿入します
Definition: xbyte_array.h:387
static void x_free(void *ptr)
ptrが指すメモリ空間を開放します
Definition: xstdlib.h:73
#define X_UNUSED(x)
コンパイラによる未使用変数の警告を抑制するマクロです。
Definition: xutils.h:161
static bool xbarray_reserve(XByteArray *self, size_t size)
バッファにsizeバイト以上の容量を確保します
Definition: xbyte_array.h:248
static void xbarray_push_back(XByteArray *self, uint8_t value)
バッファ末尾にvalueを追加します
Definition: xbyte_array.h:320
static void * x_malloc(size_t size)
sizeバイトのメモリを割り当てて返します
Definition: xstdlib.h:59
static void xbarray_erase_n(XByteArray *self, size_t index, size_t size)
バッファ先頭からn番目 ~ n + sizeの範囲を除去します
Definition: xbyte_array.h:421
static void xbarray_clear(XByteArray *self)
バッファの要素数を0にします
Definition: xbyte_array.h:217
static bool xbarray_empty(const XByteArray *self)
バッファが空かどうかを返します
Definition: xbyte_array.h:187
static const uint8_t * xbarray_const_data(const XByteArray *self)
バッファ先頭を指すコンストポインタを返します
Definition: xbyte_array.h:128
static void xbarray_deinit(XByteArray *self)
バッファを破棄します
Definition: xbyte_array.h:111
static void xbarray_push_back_n(XByteArray *self, const void *src, size_t size)
バッファ末尾にsrcからsizeバイトを追加します
Definition: xbyte_array.h:306
static size_t xbarray_space(const XByteArray *self)
バッファが拡張なしで格納できる空きバイト数を返します
Definition: xbyte_array.h:207
static uint8_t * xbarray_at(XByteArray *self, size_t index)
バッファ先頭からnバイト後方を指すポインタを返します
Definition: xbyte_array.h:158
static void xbarray_pop_back_n(XByteArray *self, void *dst, size_t size)
バッファ末尾からsizeバイトを除去します
Definition: xbyte_array.h:335
static bool xbarray_make_space_if(XByteArray *self, size_t size)
sizeバイトを格納する空き容量がない場合、バッファを拡張します
Definition: xbyte_array.h:279