00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00038 #include <adt/char_map.h>
00039
00040 #include <errno.h>
00041 #include <malloc.h>
00042 #include <mem.h>
00043 #include <unistd.h>
00044
00046 #define CHAR_MAP_MAGIC_VALUE 0x12345611
00047
00066 static int
00067 char_map_add_item(char_map_t *map, const uint8_t *identifier, size_t length,
00068 const int value)
00069 {
00070 if (map->next == (map->size - 1)) {
00071 char_map_t **tmp;
00072
00073 tmp = (char_map_t **) realloc(map->items,
00074 sizeof(char_map_t *) * 2 * map->size);
00075 if (!tmp)
00076 return ENOMEM;
00077
00078 map->size *= 2;
00079 map->items = tmp;
00080 }
00081
00082 map->items[map->next] = (char_map_t *) malloc(sizeof(char_map_t));
00083 if (!map->items[map->next])
00084 return ENOMEM;
00085
00086 if (char_map_initialize(map->items[map->next]) != EOK) {
00087 free(map->items[map->next]);
00088 map->items[map->next] = NULL;
00089 return ENOMEM;
00090 }
00091
00092 map->items[map->next]->c = *identifier;
00093 identifier++;
00094 map->next++;
00095 if ((length > 1) || ((length == 0) && *identifier)) {
00096 map->items[map->next - 1]->value = CHAR_MAP_NULL;
00097 return char_map_add_item(map->items[map->next - 1], identifier,
00098 length ? length - 1 : 0, value);
00099 } else {
00100 map->items[map->next - 1]->value = value;
00101 }
00102
00103 return EOK;
00104 }
00105
00112 static int char_map_is_valid(const char_map_t *map)
00113 {
00114 return map && (map->magic == CHAR_MAP_MAGIC_VALUE);
00115 }
00116
00140 int
00141 char_map_add(char_map_t *map, const uint8_t *identifier, size_t length,
00142 const int value)
00143 {
00144 if (char_map_is_valid(map) && identifier && (length || *identifier)) {
00145 int index;
00146
00147 for (index = 0; index < map->next; index++) {
00148 if (map->items[index]->c != *identifier)
00149 continue;
00150
00151 identifier++;
00152 if((length > 1) || ((length == 0) && *identifier)) {
00153 return char_map_add(map->items[index],
00154 identifier, length ? length - 1 : 0, value);
00155 } else {
00156 if (map->items[index]->value != CHAR_MAP_NULL)
00157 return EEXISTS;
00158
00159 map->items[index]->value = value;
00160 return EOK;
00161 }
00162 }
00163 return char_map_add_item(map, identifier, length, value);
00164 }
00165
00166 return EINVAL;
00167 }
00168
00173 void char_map_destroy(char_map_t *map)
00174 {
00175 if (char_map_is_valid(map)) {
00176 int index;
00177
00178 map->magic = 0;
00179 for (index = 0; index < map->next; index++)
00180 char_map_destroy(map->items[index]);
00181
00182 free(map->items);
00183 map->items = NULL;
00184 }
00185 }
00186
00201 static char_map_t *
00202 char_map_find_node(const char_map_t *map, const uint8_t *identifier,
00203 size_t length)
00204 {
00205 if (!char_map_is_valid(map))
00206 return NULL;
00207
00208 if (length || *identifier) {
00209 int index;
00210
00211 for (index = 0; index < map->next; index++) {
00212 if (map->items[index]->c == *identifier) {
00213 identifier++;
00214 if (length == 1)
00215 return map->items[index];
00216
00217 return char_map_find_node(map->items[index],
00218 identifier, length ? length - 1 : 0);
00219 }
00220 }
00221
00222 return NULL;
00223 }
00224
00225 return (char_map_t *) map;
00226 }
00227
00243 int char_map_exclude(char_map_t *map, const uint8_t *identifier, size_t length)
00244 {
00245 char_map_t *node;
00246
00247 node = char_map_find_node(map, identifier, length);
00248 if (node) {
00249 int value;
00250
00251 value = node->value;
00252 node->value = CHAR_MAP_NULL;
00253 return value;
00254 }
00255 return CHAR_MAP_NULL;
00256 }
00257
00271 int char_map_find(const char_map_t *map, const uint8_t *identifier, size_t length)
00272 {
00273 char_map_t *node;
00274
00275 node = char_map_find_node(map, identifier, length);
00276 return node ? node->value : CHAR_MAP_NULL;
00277 }
00278
00286 int char_map_initialize(char_map_t *map)
00287 {
00288 if (!map)
00289 return EINVAL;
00290
00291 map->c = '\0';
00292 map->value = CHAR_MAP_NULL;
00293 map->size = 2;
00294 map->next = 0;
00295
00296 map->items = malloc(sizeof(char_map_t *) * map->size);
00297 if (!map->items) {
00298 map->magic = 0;
00299 return ENOMEM;
00300 }
00301
00302 map->items[map->next] = NULL;
00303 map->magic = CHAR_MAP_MAGIC_VALUE;
00304
00305 return EOK;
00306 }
00307
00330 int
00331 char_map_update(char_map_t *map, const uint8_t *identifier, const size_t length,
00332 const int value)
00333 {
00334 char_map_t *node;
00335
00336 node = char_map_find_node(map, identifier, length);
00337 if (node) {
00338 node->value = value;
00339 return EOK;
00340 }
00341
00342 return char_map_add(map, identifier, length, value);
00343 }
00344