1 /* vifm
2 * Copyright (C) 2015 xaizek.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include "dynarray.h"
20
21 #include <stddef.h> /* NULL size_t offsetof() */
22 #include <stdlib.h> /* free() realloc() */
23 #include <string.h> /* memset() */
24
25 /* Gets dynarray_t from pointer to its data. */
26 #define CAST(da) (dynarray_t*)((char *)(da) - offsetof(dynarray_t, data))
27
28 /* Information storage for the dynarray. */
29 typedef struct
30 {
31 size_t size; /* Amount of actually used memory (not counting this). */
32 size_t capacity; /* Amount of available memory (not counting this). */
33 char data[]; /* The rest of memory. */
34 }
35 dynarray_t;
36
37 void *
dynarray_extend(void * darray,size_t more)38 dynarray_extend(void *darray, size_t more)
39 {
40 dynarray_t *dynarray;
41 dynarray_t *new;
42 size_t capacity;
43 size_t size;
44
45 dynarray = (darray != NULL) ? CAST(darray) : NULL;
46 capacity = (dynarray != NULL) ? dynarray->capacity : 0U;
47 size = (dynarray != NULL) ? dynarray->size : 0U;
48 if(capacity >= size + more)
49 {
50 if(dynarray != NULL)
51 {
52 dynarray->size += more;
53 }
54 return darray;
55 }
56
57 capacity = (size + more)*((dynarray != NULL) ? 2 : 1);
58 new = realloc(dynarray, sizeof(dynarray_t) + capacity);
59 if(new == NULL)
60 {
61 return NULL;
62 }
63
64 new->capacity = capacity;
65 new->size = size + more;
66
67 return new->data;
68 }
69
70 void *
dynarray_cextend(void * darray,size_t more)71 dynarray_cextend(void *darray, size_t more)
72 {
73 dynarray_t *dynarray = (darray != NULL) ? CAST(darray) : NULL;
74 size_t size = (dynarray != NULL) ? dynarray->size : 0U;
75 char *new = dynarray_extend(darray, more);
76 if(new != NULL)
77 {
78 memset(new + size, 0, more);
79 }
80 return new;
81 }
82
83 void
dynarray_free(void * darray)84 dynarray_free(void *darray)
85 {
86 if(darray != NULL)
87 {
88 free(CAST(darray));
89 }
90 }
91
92 void *
dynarray_shrink(void * darray)93 dynarray_shrink(void *darray)
94 {
95 dynarray_t *dynarray = CAST(darray);
96 if(dynarray->capacity > dynarray->size)
97 {
98 dynarray = realloc(dynarray, sizeof(*dynarray) + dynarray->size);
99 if(dynarray != NULL)
100 {
101 dynarray->capacity = dynarray->size;
102 return dynarray->data;
103 }
104 }
105 return darray;
106 }
107
108 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
109 /* vim: set cinoptions+=t0 : */
110