Imported Upstream version 2.0.90
[platform/upstream/kbd.git] / src / libkeymap / array.c
1 #include "config.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <sys/types.h>
8
9 #include <keymap/array.h>
10
11 int
12 lk_array_init(struct lk_array *a, ssize_t memb, ssize_t size)
13 {
14         if (!a || memb < 0 || size < 0) {
15                 errno = EINVAL;
16                 return -EINVAL;
17         }
18
19         memset(a, 0, sizeof(struct lk_array));
20
21         a->array = calloc((size_t) size, (size_t) memb);
22         a->memb  = memb;
23         a->total = size;
24
25         if (size && !a->array) {
26                 errno = ENOMEM;
27                 return -ENOMEM;
28         }
29
30         return 0;
31 }
32
33 int
34 lk_array_free(struct lk_array *a)
35 {
36         if (!a) {
37                 errno = EINVAL;
38                 return -EINVAL;
39         }
40         free(a->array);
41         memset(a, 0, sizeof(struct lk_array));
42         return 0;
43 }
44
45 int
46 lk_array_empty(struct lk_array *a)
47 {
48         if (!a) {
49                 errno = EINVAL;
50                 return -EINVAL;
51         }
52
53         memset(a->array, 0, (size_t) (a->memb * a->total));
54         a->count = 0;
55
56         return 0;
57 }
58
59 int
60 lk_array_exists(struct lk_array *a, ssize_t i)
61 {
62         char *s;
63         ssize_t k;
64
65         if (!a || i < 0 || i >= a->total) {
66                 errno = EINVAL;
67                 return 0;
68         }
69
70         s = (char *)(a->array + (a->memb * i));
71
72         for (k = 0; k < a->memb; k++) {
73                 if (s[k] != 0)
74                         return 1;
75         }
76
77         return 0;
78 }
79
80 void *
81 lk_array_get(struct lk_array *a, ssize_t i)
82 {
83         if (!a || i < 0 || i >= a->total) {
84                 errno = EINVAL;
85                 return NULL;
86         }
87         return a->array + (a->memb * i);
88 }
89
90 void *
91 lk_array_get_ptr(struct lk_array *a, ssize_t i)
92 {
93         void **ptr;
94         if (!a || i < 0 || i >= a->total) {
95                 errno = EINVAL;
96                 return NULL;
97         }
98         ptr = a->array;
99         return *(ptr + i);
100 }
101
102 static int
103 array_resize(struct lk_array *a, ssize_t i)
104 {
105         if (!a || i < 0) {
106                 errno = EINVAL;
107                 return -EINVAL;
108         }
109
110         if (i >= a->total) {
111                 void *tmp = realloc(a->array, (size_t) (a->memb * (i + 1)));
112                 if (!tmp) {
113                         errno = ENOMEM;
114                         return -ENOMEM;
115                 }
116
117                 memset(tmp + (a->memb * a->total), 0, (size_t) (a->memb * (i + 1 - a->total)));
118
119                 a->array = tmp;
120                 a->total = i + 1;
121         }
122         return 0;
123 }
124
125 int
126 lk_array_set(struct lk_array *a, ssize_t i, const void *e)
127 {
128         int ret = array_resize(a, i);
129
130         if (ret < 0)
131                 return ret;
132
133         memcpy(a->array + (a->memb * i), e, (size_t) a->memb);
134         a->count++;
135
136         return 0;
137 }
138
139 int
140 lk_array_unset(struct lk_array *a, ssize_t i)
141 {
142         if (!a || i >= a->total) {
143                 errno = EINVAL;
144                 return -EINVAL;
145         }
146
147         if (lk_array_exists(a, i)) {
148                 memset(a->array + (a->memb * i), 0, (size_t) a->memb);
149                 a->count--;
150         }
151
152         return 0;
153 }
154
155 int
156 lk_array_append(struct lk_array *a, const void *e)
157 {
158         int ret = array_resize(a, a->count);
159
160         if (ret < 0)
161                 return ret;
162
163         memcpy(a->array + (a->memb * a->count), e, (size_t) a->memb);
164         a->count++;
165
166         return 0;
167 }