source: mainline/uspace/srv/net/structures/char_map.c@ f1848d6

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since f1848d6 was 21580dd, checked in by Lukas Mejdrech <lukas@…>, 15 years ago

Merged with network branch svn://svn.helenos.org/HelenOS/branches/network revision 4759; ipc_share_* and ipc_data_* changed to async_*; client connection in module.c returns on IPC_M_PHONE_HUNGUP; * Qemu scripts renamed to net-qe.*; (the dp8390 does not respond)

  • Property mode set to 100644
File size: 7.5 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 "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 ) return EEXISTS;
95 map->items[ index ]->value = value;
96 return EOK;
97 }
98 }
99 }
100 return char_map_add_item( map, identifier, length, value );
101 }
102 return EINVAL;
103}
104
105int char_map_add_item( char_map_ref map, const char * identifier, size_t length, const int value ){
106 if( map->next == ( map->size - 1 )){
107 char_map_ref * tmp;
108
109 tmp = ( char_map_ref * ) realloc( map->items, sizeof( char_map_ref ) * 2 * map->size );
110 if( ! tmp ) return ENOMEM;
111 map->size *= 2;
112 map->items = tmp;
113 }
114 map->items[ map->next ] = ( char_map_ref ) malloc( sizeof( char_map_t ));
115 if( ! map->items[ map->next ] ) return ENOMEM;
116 if( char_map_initialize( map->items[ map->next ] ) != EOK ){
117 free( map->items[ map->next ] );
118 map->items[ map->next ] = NULL;
119 return ENOMEM;
120 }
121 map->items[ map->next ]->c = * identifier;
122 ++ identifier;
123 ++ map->next;
124 if(( length > 1 ) || (( length == 0 ) && ( * identifier ))){
125 map->items[ map->next - 1 ]->value = CHAR_MAP_NULL;
126 return char_map_add_item( map->items[ map->next - 1 ], identifier, length ? length - 1 : 0, value );
127 }else{
128 map->items[ map->next - 1 ]->value = value;
129 }
130 return EOK;
131}
132
133void char_map_destroy( char_map_ref map ){
134 if( char_map_is_valid( map )){
135 int index;
136
137 map->magic = 0;
138 for( index = 0; index < map->next; ++ index ){
139 char_map_destroy( map->items[ index ] );
140 }
141 free( map->items );
142 map->items = NULL;
143 }
144}
145
146int char_map_exclude( char_map_ref map, const char * identifier, size_t length ){
147 char_map_ref node;
148
149 node = char_map_find_node( map, identifier, length );
150 if( node ){
151 int value;
152
153 value = node->value;
154 node->value = CHAR_MAP_NULL;
155 return value;
156 }
157 return CHAR_MAP_NULL;
158}
159
160int char_map_find( const char_map_ref map, const char * identifier, size_t length ){
161 char_map_ref node;
162
163 node = char_map_find_node( map, identifier, length );
164 return node ? node->value : CHAR_MAP_NULL;
165}
166
167char_map_ref char_map_find_node( const char_map_ref map, const char * identifier, size_t length ){
168 if( ! char_map_is_valid( map )) return NULL;
169 if( length || ( * identifier )){
170 int index;
171
172 for( index = 0; index < map->next; ++ index ){
173 if( map->items[ index ]->c == * identifier ){
174 ++ identifier;
175 if( length == 1 ) return map->items[ index ];
176 return char_map_find_node( map->items[ index ], identifier, length ? length - 1 : 0 );
177 }
178 }
179 return NULL;
180 }
181 return map;
182}
183
184int char_map_get_value( const char_map_ref map ){
185 return char_map_is_valid( map ) ? map->value : CHAR_MAP_NULL;
186}
187
188int char_map_initialize( char_map_ref map ){
189 if( ! map ) return EINVAL;
190 map->c = '\0';
191 map->value = CHAR_MAP_NULL;
192 map->size = 2;
193 map->next = 0;
194 map->items = malloc( sizeof( char_map_ref ) * map->size );
195 if( ! map->items ){
196 map->magic = 0;
197 return ENOMEM;
198 }
199 map->items[ map->next ] = NULL;
200 map->magic = CHAR_MAP_MAGIC_VALUE;
201 return EOK;
202}
203
204int char_map_is_valid( const char_map_ref map ){
205 return map && ( map->magic == CHAR_MAP_MAGIC_VALUE );
206}
207
208int char_map_update( char_map_ref map, const char * identifier, const size_t length, const int value ){
209 char_map_ref node;
210
211// if( ! char_map_is_valid( map )) return EINVAL;
212 node = char_map_find_node( map, identifier, length );
213 if( node ){
214 node->value = value;
215 return EOK;
216 }else{
217 return char_map_add( map, identifier, length, value );
218 }
219}
220
221/** @}
222 */
Note: See TracBrowser for help on using the repository browser.