e108ca3cde0507c8e87b5c63c46a9315dbd989db
[platform/upstream/kmscon.git] / src / shl_array.h
1 /*
2  * shl - Dynamic Array
3  *
4  * Copyright (c) 2011-2012 David Herrmann <dh.herrmann@googlemail.com>
5  * Copyright (c) 2011 University of Tuebingen
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files
9  * (the "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included
16  * in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26
27 /*
28  * A dynamic array implementation
29  */
30
31 #ifndef SHL_ARRAY_H
32 #define SHL_ARRAY_H
33
34 #include <stdbool.h>
35 #include <stddef.h>
36 #include <stdint.h>
37 #include <stdlib.h>
38
39 struct shl_array {
40         size_t element_size;
41         size_t length;
42         size_t size;
43         void *data;
44 };
45
46 #define SHL_ARRAY_AT(_arr, _type, _pos) \
47         (&((_type*)shl_array_get_array(_arr))[(_pos)])
48
49 static inline int shl_array_new(struct shl_array **out, size_t element_size,
50                                 size_t initial_size)
51 {
52         struct shl_array *arr;
53
54         if (!out || !element_size)
55                 return -EINVAL;
56
57         if (!initial_size)
58                 initial_size = 4;
59
60         arr = malloc(sizeof(*arr));
61         if (!arr)
62                 return -ENOMEM;
63         memset(arr, 0, sizeof(*arr));
64         arr->element_size = element_size;
65         arr->length = 0;
66         arr->size = initial_size;
67
68         arr->data = malloc(arr->element_size * arr->size);
69         if (!arr->data) {
70                 free(arr);
71                 return -ENOMEM;
72         }
73
74         *out = arr;
75         return 0;
76 }
77
78 static inline void shl_array_free(struct shl_array *arr)
79 {
80         if (!arr)
81                 return;
82
83         free(arr->data);
84         free(arr);
85 }
86
87 static inline int shl_array_push(struct shl_array *arr, const void *data)
88 {
89         void *tmp;
90         size_t newsize;
91
92         if (!arr || !data)
93                 return -EINVAL;
94
95         if (arr->length >= arr->size) {
96                 newsize = arr->size * 2;
97                 tmp = realloc(arr->data, arr->element_size * newsize);
98                 if (!tmp)
99                         return -ENOMEM;
100
101                 arr->data = tmp;
102                 arr->size = newsize;
103         }
104
105         memcpy(((uint8_t*)arr->data) + arr->element_size * arr->length,
106                data, arr->element_size);
107         ++arr->length;
108
109         return 0;
110 }
111
112 static inline void shl_array_pop(struct shl_array *arr)
113 {
114         if (!arr || !arr->length)
115                 return;
116
117         --arr->length;
118 }
119
120 static inline void *shl_array_get_array(struct shl_array *arr)
121 {
122         if (!arr)
123                 return NULL;
124
125         return arr->data;
126 }
127
128 static inline size_t shl_array_get_length(struct shl_array *arr)
129 {
130         if (!arr)
131                 return 0;
132
133         return arr->length;
134 }
135
136 static inline size_t shl_array_get_bsize(struct shl_array *arr)
137 {
138         if (!arr)
139                 return 0;
140
141         return arr->length * arr->element_size;
142 }
143
144 static inline size_t shl_array_get_element_size(struct shl_array *arr)
145 {
146         if (!arr)
147                 return 0;
148
149         return arr->element_size;
150 }
151
152 #endif /* SHL_ARRAY_H */