1 /*
2 map.c - a map (associative array) implementation
3
4 Copyright (c) 2002 - 2005, 2017 dbjh
5
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21 #ifdef _MSC_VER
22 #pragma warning(push)
23 #pragma warning(disable: 4668) // 'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives'
24 #endif
25 #include <stdio.h>
26 #ifdef _MSC_VER
27 #pragma warning(pop)
28 #endif
29 #include <stdlib.h>
30 #include <string.h>
31 #include "map.h"
32 #if defined DJGPP && defined DLL
33 #include "dxedll_priv.h"
34 #endif
35
36
37 st_map_t *
map_create(int n_elements)38 map_create (int n_elements)
39 {
40 st_map_t *map;
41 int size = sizeof (st_map_t) + n_elements * sizeof (st_map_element_t);
42
43 if ((map = (st_map_t *) malloc (size)) == NULL)
44 {
45 fprintf (stderr, "ERROR: Not enough memory for buffer (%d bytes)\n", size);
46 exit (1);
47 }
48 map->data = (st_map_element_t *) (((unsigned char *) map) + sizeof (st_map_t));
49 memset (map->data, MAP_FREE_KEY, n_elements * sizeof (st_map_element_t));
50 map->size = n_elements;
51 map->cmp_key = map_cmp_key_def;
52 return map;
53 }
54
55
56 st_map_t *
map_resize(st_map_t * map,int n_elements)57 map_resize (st_map_t *map, int n_elements)
58 {
59 int size = sizeof (st_map_t) + n_elements * sizeof (st_map_element_t);
60 st_map_t *old_map = map;
61
62 if ((map = (st_map_t *) realloc (old_map, size)) == NULL)
63 {
64 fprintf (stderr, "ERROR: Not enough memory for buffer (%d bytes)\n", size);
65 free (old_map);
66 exit (1);
67 }
68 map->data = (st_map_element_t *) (((unsigned char *) map) + sizeof (st_map_t));
69 if (n_elements > map->size)
70 memset (((unsigned char *) map->data) + map->size * sizeof (st_map_element_t),
71 MAP_FREE_KEY, (n_elements - map->size) * sizeof (st_map_element_t));
72 map->size = n_elements;
73 return map;
74 }
75
76
77 void
map_copy(st_map_t * dest,st_map_t * src)78 map_copy (st_map_t *dest, st_map_t *src)
79 {
80 memcpy (dest->data, src->data, src->size * sizeof (st_map_element_t));
81 dest->cmp_key = src->cmp_key;
82 }
83
84
85 int
map_cmp_key_def(void * key1,void * key2)86 map_cmp_key_def (void *key1, void *key2)
87 {
88 return key1 != key2;
89 }
90
91
92 st_map_t *
map_put(st_map_t * map,void * key,void * object)93 map_put (st_map_t *map, void *key, void *object)
94 {
95 int n = 0;
96
97 while (n < map->size && map->data[n].key != MAP_FREE_KEY &&
98 map->cmp_key (map->data[n].key, key))
99 n++;
100
101 if (n == map->size) // current map is full
102 map = map_resize (map, map->size + 20);
103
104 map->data[n].key = key;
105 map->data[n].object = object;
106
107 return map;
108 }
109
110
111 void *
map_get(st_map_t * map,void * key)112 map_get (st_map_t *map, void *key)
113 {
114 int n = 0;
115
116 while (n < map->size && (map->data[n].key == MAP_FREE_KEY ||
117 map->cmp_key (map->data[n].key, key)))
118 n++;
119
120 if (n == map->size)
121 return NULL;
122
123 return map->data[n].object;
124 }
125
126
127 void
map_del(st_map_t * map,void * key)128 map_del (st_map_t *map, void *key)
129 {
130 int n = 0;
131
132 while (n < map->size && (map->data[n].key == MAP_FREE_KEY ||
133 map->cmp_key (map->data[n].key, key)))
134 n++;
135
136 if (n < map->size)
137 map->data[n].key = MAP_FREE_KEY;
138 }
139
140
141 void
map_dump(st_map_t * map)142 map_dump (st_map_t *map)
143 {
144 int n = 0;
145
146 while (n < map->size)
147 {
148 printf ("%p -> %p\n", map->data[n].key, map->data[n].object);
149 n++;
150 }
151 }
152