source: mainline/uspace/lib/socket/adt/char_map.c@ 849ed54

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 849ed54 was 849ed54, checked in by Martin Decky <martin@…>, 15 years ago

Networking work:
Split the networking stack into end-user library (libsocket) and two helper libraries (libnet and libnetif).
Don't use over-the-hand compiling and linking, but rather separation of conserns.
There might be still some issues and the non-modular networking architecture is currently broken, but this will be fixed soon.

  • Property mode set to 100644
File size: 7.4 KB
RevLine 
[21580dd]1/*
2 * Copyright (c) 2009 Lukas Mejdrech
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup net
30 * @{
31 */
32
33/** @file
34 * Character string to integer map implementation.
35 * @see char_map.h
36 */
37
38#include <errno.h>
39#include <malloc.h>
40#include <mem.h>
41#include <unistd.h>
42
[849ed54]43#include <adt/char_map.h>
[21580dd]44
45/** Internal magic value for a&nbsp;consistency check.
46 */
47#define CHAR_MAP_MAGIC_VALUE 0x12345611
48
49/** Adds the value with the key to the map.
50 * Creates new nodes to map the key.
51 * @param[in,out] map The character string to integer map.
52 * @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
53 * @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
54 * @param[in] value The integral value to be stored for the key character string.
55 * @returns EOK on success.
56 * @returns ENOMEM if there is not enough memory left.
57 * @returns EEXIST if the key character string is already used.
58 */
[aadf01e]59int char_map_add_item(char_map_ref map, const char * identifier, size_t length, const int value);
[21580dd]60
61/** Returns the node assigned to the key from the map.
62 * @param[in] map The character string to integer map.
63 * @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
64 * @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
65 * @returns The node holding the integral value assigned to the key character string.
66 * @returns NULL if the key is not assigned a&nbsp;node.
67 */
[aadf01e]68char_map_ref char_map_find_node(const char_map_ref map, const char * identifier, const size_t length);
[21580dd]69
70/** Returns the value assigned to the map.
71 * @param[in] map The character string to integer map.
72 * @returns The integral value assigned to the map.
73 * @returns CHAR_MAP_NULL if the map is not assigned a&nbsp;value.
74 */
[aadf01e]75int char_map_get_value(const char_map_ref map);
[21580dd]76
77/** Checks if the map is valid.
78 * @param[in] map The character string to integer map.
79 * @returns TRUE if the map is valid.
80 * @returns FALSE otherwise.
81 */
[aadf01e]82int char_map_is_valid(const char_map_ref map);
[21580dd]83
[aadf01e]84int char_map_add(char_map_ref map, const char * identifier, size_t length, const int value){
85 if(char_map_is_valid(map) && (identifier) && ((length) || (*identifier))){
86 int index;
[21580dd]87
[aadf01e]88 for(index = 0; index < map->next; ++ index){
89 if(map->items[index]->c == * identifier){
[21580dd]90 ++ identifier;
[aadf01e]91 if((length > 1) || ((length == 0) && (*identifier))){
92 return char_map_add(map->items[index], identifier, length ? length - 1 : 0, value);
[21580dd]93 }else{
[aadf01e]94 if(map->items[index]->value != CHAR_MAP_NULL){
95 return EEXISTS;
96 }
97 map->items[index]->value = value;
[21580dd]98 return EOK;
99 }
100 }
101 }
[aadf01e]102 return char_map_add_item(map, identifier, length, value);
[21580dd]103 }
104 return EINVAL;
105}
106
[aadf01e]107int char_map_add_item(char_map_ref map, const char * identifier, size_t length, const int value){
108 if(map->next == (map->size - 1)){
109 char_map_ref *tmp;
[21580dd]110
[aadf01e]111 tmp = (char_map_ref *) realloc(map->items, sizeof(char_map_ref) * 2 * map->size);
112 if(! tmp){
113 return ENOMEM;
114 }
[21580dd]115 map->size *= 2;
116 map->items = tmp;
117 }
[aadf01e]118 map->items[map->next] = (char_map_ref) malloc(sizeof(char_map_t));
119 if(! map->items[map->next]){
120 return ENOMEM;
121 }
122 if(char_map_initialize(map->items[map->next]) != EOK){
123 free(map->items[map->next]);
124 map->items[map->next] = NULL;
[21580dd]125 return ENOMEM;
126 }
[aadf01e]127 map->items[map->next]->c = * identifier;
[21580dd]128 ++ identifier;
129 ++ map->next;
[aadf01e]130 if((length > 1) || ((length == 0) && (*identifier))){
131 map->items[map->next - 1]->value = CHAR_MAP_NULL;
132 return char_map_add_item(map->items[map->next - 1], identifier, length ? length - 1 : 0, value);
[21580dd]133 }else{
[aadf01e]134 map->items[map->next - 1]->value = value;
[21580dd]135 }
136 return EOK;
137}
138
[aadf01e]139void char_map_destroy(char_map_ref map){
140 if(char_map_is_valid(map)){
141 int index;
[21580dd]142
143 map->magic = 0;
[aadf01e]144 for(index = 0; index < map->next; ++ index){
145 char_map_destroy(map->items[index]);
[21580dd]146 }
[aadf01e]147 free(map->items);
[21580dd]148 map->items = NULL;
149 }
150}
151
[aadf01e]152int char_map_exclude(char_map_ref map, const char * identifier, size_t length){
153 char_map_ref node;
[21580dd]154
[aadf01e]155 node = char_map_find_node(map, identifier, length);
156 if(node){
157 int value;
[21580dd]158
159 value = node->value;
160 node->value = CHAR_MAP_NULL;
161 return value;
162 }
163 return CHAR_MAP_NULL;
164}
165
[aadf01e]166int char_map_find(const char_map_ref map, const char * identifier, size_t length){
167 char_map_ref node;
[21580dd]168
[aadf01e]169 node = char_map_find_node(map, identifier, length);
[21580dd]170 return node ? node->value : CHAR_MAP_NULL;
171}
172
[aadf01e]173char_map_ref char_map_find_node(const char_map_ref map, const char * identifier, size_t length){
174 if(! char_map_is_valid(map)){
175 return NULL;
176 }
177 if(length || (*identifier)){
178 int index;
[21580dd]179
[aadf01e]180 for(index = 0; index < map->next; ++ index){
181 if(map->items[index]->c == * identifier){
[21580dd]182 ++ identifier;
[aadf01e]183 if(length == 1){
184 return map->items[index];
185 }
186 return char_map_find_node(map->items[index], identifier, length ? length - 1 : 0);
[21580dd]187 }
188 }
189 return NULL;
190 }
191 return map;
192}
193
[aadf01e]194int char_map_get_value(const char_map_ref map){
195 return char_map_is_valid(map) ? map->value : CHAR_MAP_NULL;
[21580dd]196}
197
[aadf01e]198int char_map_initialize(char_map_ref map){
199 if(! map){
200 return EINVAL;
201 }
[21580dd]202 map->c = '\0';
203 map->value = CHAR_MAP_NULL;
204 map->size = 2;
205 map->next = 0;
[aadf01e]206 map->items = malloc(sizeof(char_map_ref) * map->size);
207 if(! map->items){
[21580dd]208 map->magic = 0;
209 return ENOMEM;
210 }
[aadf01e]211 map->items[map->next] = NULL;
[21580dd]212 map->magic = CHAR_MAP_MAGIC_VALUE;
213 return EOK;
214}
215
[aadf01e]216int char_map_is_valid(const char_map_ref map){
217 return map && (map->magic == CHAR_MAP_MAGIC_VALUE);
[21580dd]218}
219
[aadf01e]220int char_map_update(char_map_ref map, const char * identifier, const size_t length, const int value){
221 char_map_ref node;
[21580dd]222
[aadf01e]223// if(! char_map_is_valid(map)) return EINVAL;
224 node = char_map_find_node(map, identifier, length);
225 if(node){
[21580dd]226 node->value = value;
227 return EOK;
228 }else{
[aadf01e]229 return char_map_add(map, identifier, length, value);
[21580dd]230 }
231}
232
233/** @}
234 */
Note: See TracBrowser for help on using the repository browser.