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
Line 
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
43#include <adt/char_map.h>
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 */
59int char_map_add_item(char_map_ref map, const char * identifier, size_t length, const int value);
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 */
68char_map_ref char_map_find_node(const char_map_ref map, const char * identifier, const size_t length);
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 */
75int char_map_get_value(const char_map_ref map);
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 */
82int char_map_is_valid(const char_map_ref map);
83
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;
87
88 for(index = 0; index < map->next; ++ index){
89 if(map->items[index]->c == * identifier){
90 ++ identifier;
91 if((length > 1) || ((length == 0) && (*identifier))){
92 return char_map_add(map->items[index], identifier, length ? length - 1 : 0, value);
93 }else{
94 if(map->items[index]->value != CHAR_MAP_NULL){
95 return EEXISTS;
96 }
97 map->items[index]->value = value;
98 return EOK;
99 }
100 }
101 }
102 return char_map_add_item(map, identifier, length, value);
103 }
104 return EINVAL;
105}
106
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;
110
111 tmp = (char_map_ref *) realloc(map->items, sizeof(char_map_ref) * 2 * map->size);
112 if(! tmp){
113 return ENOMEM;
114 }
115 map->size *= 2;
116 map->items = tmp;
117 }
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;
125 return ENOMEM;
126 }
127 map->items[map->next]->c = * identifier;
128 ++ identifier;
129 ++ map->next;
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);
133 }else{
134 map->items[map->next - 1]->value = value;
135 }
136 return EOK;
137}
138
139void char_map_destroy(char_map_ref map){
140 if(char_map_is_valid(map)){
141 int index;
142
143 map->magic = 0;
144 for(index = 0; index < map->next; ++ index){
145 char_map_destroy(map->items[index]);
146 }
147 free(map->items);
148 map->items = NULL;
149 }
150}
151
152int char_map_exclude(char_map_ref map, const char * identifier, size_t length){
153 char_map_ref node;
154
155 node = char_map_find_node(map, identifier, length);
156 if(node){
157 int value;
158
159 value = node->value;
160 node->value = CHAR_MAP_NULL;
161 return value;
162 }
163 return CHAR_MAP_NULL;
164}
165
166int char_map_find(const char_map_ref map, const char * identifier, size_t length){
167 char_map_ref node;
168
169 node = char_map_find_node(map, identifier, length);
170 return node ? node->value : CHAR_MAP_NULL;
171}
172
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;
179
180 for(index = 0; index < map->next; ++ index){
181 if(map->items[index]->c == * identifier){
182 ++ identifier;
183 if(length == 1){
184 return map->items[index];
185 }
186 return char_map_find_node(map->items[index], identifier, length ? length - 1 : 0);
187 }
188 }
189 return NULL;
190 }
191 return map;
192}
193
194int char_map_get_value(const char_map_ref map){
195 return char_map_is_valid(map) ? map->value : CHAR_MAP_NULL;
196}
197
198int char_map_initialize(char_map_ref map){
199 if(! map){
200 return EINVAL;
201 }
202 map->c = '\0';
203 map->value = CHAR_MAP_NULL;
204 map->size = 2;
205 map->next = 0;
206 map->items = malloc(sizeof(char_map_ref) * map->size);
207 if(! map->items){
208 map->magic = 0;
209 return ENOMEM;
210 }
211 map->items[map->next] = NULL;
212 map->magic = CHAR_MAP_MAGIC_VALUE;
213 return EOK;
214}
215
216int char_map_is_valid(const char_map_ref map){
217 return map && (map->magic == CHAR_MAP_MAGIC_VALUE);
218}
219
220int char_map_update(char_map_ref map, const char * identifier, const size_t length, const int value){
221 char_map_ref node;
222
223// if(! char_map_is_valid(map)) return EINVAL;
224 node = char_map_find_node(map, identifier, length);
225 if(node){
226 node->value = value;
227 return EOK;
228 }else{
229 return char_map_add(map, identifier, length, value);
230 }
231}
232
233/** @}
234 */
Note: See TracBrowser for help on using the repository browser.