LIRC libraries
Linux Infrared Remote Control
Toggle main menu visibility
Loading...
Searching...
No Matches
dictionary.c
Go to the documentation of this file.
1
/* Copyright (c) 2000-2007 by Nicolas Devillard.
2
* Copyright (x) 2009 by Tim Post <tinkertim@gmail.com>
3
* MIT License
4
*
5
* Permission is hereby granted, free of charge, to any person obtaining a
6
* copy of this software and associated documentation files (the "Software"),
7
* to deal in the Software without restriction, including without limitation
8
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
* and/or sell copies of the Software, and to permit persons to whom the
10
* Software is furnished to do so, subject to the following conditions:
11
*
12
* The above copyright notice and this permission notice shall be included in
13
* all copies or substantial portions of the Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
* DEALINGS IN THE SOFTWARE.
22
*/
23
38
39
#include "
dictionary.h
"
40
41
#include <stdio.h>
42
#include <stdlib.h>
43
#include <string.h>
44
#include <unistd.h>
45
47
#define MAXVALSZ 1024
48
50
#define DICTMINSZ 128
51
53
#define DICT_INVALID_KEY ((char*)-1)
54
60
static
void
* mem_double(
void
* ptr,
int
size)
61
{
62
void
* newptr;
63
64
newptr = calloc(2 * size, 1);
65
if
(newptr == NULL)
66
return
NULL;
67
memcpy(newptr, ptr, size);
68
free(ptr);
69
return
newptr;
70
}
71
72
/* The remaining exposed functions are documented in dictionary.h */
73
74
unsigned
dictionary_hash
(
const
char
* key)
75
{
76
int
len;
77
unsigned
hash;
78
int
i;
79
80
len = strlen(key);
81
for
(hash = 0, i = 0; i < len; i++) {
82
hash += (unsigned)key[i];
83
hash += (hash << 10);
84
hash ^= (hash >> 6);
85
}
86
hash += (hash << 3);
87
hash ^= (hash >> 11);
88
hash += (hash << 15);
89
return
hash;
90
}
91
92
dictionary
*
dictionary_new
(
int
size)
93
{
94
dictionary
* d;
95
96
/* If no size was specified, allocate space for DICTMINSZ */
97
if
(size <
DICTMINSZ
)
98
size =
DICTMINSZ
;
99
100
if
(!(d = (
dictionary
*)calloc(1,
sizeof
(
dictionary
))))
101
return
NULL;
102
d->size = size;
103
d->val = (
char
**)calloc(size,
sizeof
(
char
*));
104
d->key = (
char
**)calloc(size,
sizeof
(
char
*));
105
d->hash = (
unsigned
int
*)calloc(size,
sizeof
(
unsigned
));
106
return
d;
107
}
108
109
void
dictionary_del
(
dictionary
* d)
110
{
111
int
i;
112
113
if
(d == NULL)
114
return
;
115
for
(i = 0; i < d->size; i++) {
116
if
(d->key[i] != NULL)
117
free(d->key[i]);
118
if
(d->val[i] != NULL)
119
free(d->val[i]);
120
}
121
free(d->val);
122
free(d->key);
123
free(d->hash);
124
free(d);
125
return
;
126
}
127
128
const
char
*
dictionary_get
(
dictionary
* d,
const
char
* key,
const
char
* def)
129
{
130
unsigned
hash;
131
int
i;
132
133
hash =
dictionary_hash
(key);
134
for
(i = 0; i < d->size; i++) {
135
if
(d->key[i] == NULL)
136
continue
;
137
/* Compare hash */
138
if
(hash == d->hash[i]) {
139
/* Compare string, to avoid hash collisions */
140
if
(!strcmp(key, d->key[i]))
141
return
d->val[i];
142
}
143
}
144
return
def;
145
}
146
147
int
dictionary_set
(
dictionary
* d,
const
char
* key,
const
char
* val)
148
{
149
int
i;
150
unsigned
hash;
151
152
if
(d == NULL || key == NULL)
153
return
-1;
154
155
/* Compute hash for this key */
156
hash =
dictionary_hash
(key);
157
/* Find if value is already in dictionary */
158
if
(d->n > 0) {
159
for
(i = 0; i < d->size; i++) {
160
if
(d->key[i] == NULL)
161
continue
;
162
/* Same hash value */
163
if
(hash == d->hash[i]) {
164
/* Same key */
165
if
(!strcmp(key, d->key[i])) {
166
/* Found a value: modify and return */
167
if
(d->val[i] != NULL)
168
free(d->val[i]);
169
d->val[i] = val ? strdup(val) : NULL;
170
/* Value has been modified: return */
171
return
0;
172
}
173
}
174
}
175
}
176
177
/* Add a new value
178
* See if dictionary needs to grow */
179
if
(d->n == d->size) {
180
/* Reached maximum size: reallocate dictionary */
181
d->val = (
char
**)mem_double(d->val, d->size *
sizeof
(
char
*));
182
d->key = (
char
**)mem_double(d->key, d->size *
sizeof
(
char
*));
183
d->hash = (
unsigned
int
*)
184
mem_double(d->hash, d->size *
sizeof
(
unsigned
));
185
if
((d->val == NULL) || (d->key == NULL) || (d->hash == NULL))
186
/* Cannot grow dictionary */
187
return
-1;
188
/* Double size */
189
d->size *= 2;
190
}
191
192
/* Insert key in the first empty slot */
193
for
(i = 0; i < d->size; i++) {
194
if
(d->key[i] == NULL)
195
/* Add key here */
196
break
;
197
}
198
/* Copy key */
199
d->key[i] = strdup(key);
200
d->val[i] = val ? strdup(val) : NULL;
201
d->hash[i] = hash;
202
d->n++;
203
return
0;
204
}
205
206
void
dictionary_unset
(
dictionary
* d,
const
char
* key)
207
{
208
unsigned
hash;
209
int
i;
210
211
if
(key == NULL)
212
return
;
213
214
hash =
dictionary_hash
(key);
215
for
(i = 0; i < d->size; i++) {
216
if
(d->key[i] == NULL)
217
continue
;
218
/* Compare hash */
219
if
(hash == d->hash[i]) {
220
/* Compare string, to avoid hash collisions */
221
if
(!strcmp(key, d->key[i]))
222
/* Found key */
223
break
;
224
}
225
}
226
if
(i >= d->size)
227
/* Key not found */
228
return
;
229
230
free(d->key[i]);
231
d->key[i] = NULL;
232
if
(d->val[i] != NULL) {
233
free(d->val[i]);
234
d->val[i] = NULL;
235
}
236
d->hash[i] = 0;
237
d->n--;
238
return
;
239
}
240
241
void
dictionary_dump
(
dictionary
* d, FILE* out)
242
{
243
int
i;
244
245
if
(d == NULL || out == NULL)
246
return
;
247
if
(d->n < 1) {
248
fprintf(out,
"empty dictionary\n"
);
249
return
;
250
}
251
for
(i = 0; i < d->size; i++) {
252
if
(d->key[i]) {
253
fprintf(out,
"%20s\t[%s]\n"
,
254
d->key[i],
255
d->val[i] ? d->val[i] :
"UNDEF"
);
256
}
257
}
258
return
;
259
}
260
dictionary.h
Implements a dictionary for string variables.
dictionary_unset
void dictionary_unset(dictionary *d, const char *key)
Delete a key in a dictionary.
Definition
dictionary.c:206
dictionary
struct _dictionary_ dictionary
Dictionary object.
dictionary_dump
void dictionary_dump(dictionary *d, FILE *out)
Dump a dictionary to an opened file pointer.
Definition
dictionary.c:241
dictionary_hash
unsigned dictionary_hash(const char *key)
Compute the hash key for a string.
Definition
dictionary.c:74
dictionary_new
dictionary * dictionary_new(int size)
Create a new dictionary object.
Definition
dictionary.c:92
dictionary_get
const char * dictionary_get(dictionary *d, const char *key, const char *def)
Get a value from a dictionary.
Definition
dictionary.c:128
dictionary_del
void dictionary_del(dictionary *d)
Delete a dictionary object.
Definition
dictionary.c:109
dictionary_set
int dictionary_set(dictionary *d, const char *key, const char *val)
Set a value in a dictionary.
Definition
dictionary.c:147
DICTMINSZ
#define DICTMINSZ
Minimal allocated number of entries in a dictionary.
Definition
dictionary.c:50
lib
dictionary.c
Generated by
1.17.0