Changeset 3c213f6 in mainline
- Timestamp:
- 2010-09-26T15:00:29Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2544442
- Parents:
- 0402bda5
- Location:
- uspace/lib/c
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/adt/char_map.c
r0402bda5 r3c213f6 27 27 */ 28 28 29 /** @addtogroup net29 /** @addtogroup libc 30 30 * @{ 31 31 */ … … 35 35 * @see char_map.h 36 36 */ 37 38 #include <adt/char_map.h> 37 39 38 40 #include <errno.h> … … 41 43 #include <unistd.h> 42 44 43 #include <adt/char_map.h> 44 45 /** Internal magic value for a consistency check. 46 */ 45 /** Internal magic value for a consistency check. */ 47 46 #define CHAR_MAP_MAGIC_VALUE 0x12345611 48 47 49 48 /** 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 */ 59 int 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 node. 67 */ 68 char_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 value. 74 */ 75 int char_map_get_value(const char_map_ref map); 49 * 50 * Creates new nodes to map the key. 51 * 52 * @param[in,out] map The character string to integer map. 53 * @param[in] identifier The key zero ('\0') terminated character string. 54 * The key character string is processed until the first 55 * terminating zero ('\0') character after the given 56 * length is found. 57 * @param[in] length The key character string length. The parameter may be 58 * zero (0) which means that the string is processed until 59 * the terminating zero ('\0') character is found. 60 * @param[in] value The integral value to be stored for the key character 61 * string. 62 * @returns EOK on success. 63 * @returns ENOMEM if there is not enough memory left. 64 * @returns EEXIST if the key character string is already used. 65 */ 66 static int 67 char_map_add_item(char_map_ref map, const char *identifier, size_t length, 68 const int value) 69 { 70 if (map->next == (map->size - 1)) { 71 char_map_ref *tmp; 72 73 tmp = (char_map_ref *) realloc(map->items, 74 sizeof(char_map_ref) * 2 * map->size); 75 if (!tmp) 76 return ENOMEM; 77 78 map->size *= 2; 79 map->items = tmp; 80 } 81 82 map->items[map->next] = (char_map_ref) malloc(sizeof(char_map_t)); 83 if (!map->items[map->next]) 84 return ENOMEM; 85 86 if (char_map_initialize(map->items[map->next]) != EOK) { 87 free(map->items[map->next]); 88 map->items[map->next] = NULL; 89 return ENOMEM; 90 } 91 92 map->items[map->next]->c = * identifier; 93 ++ identifier; 94 ++ map->next; 95 if ((length > 1) || ((length == 0) && (*identifier))) { 96 map->items[map->next - 1]->value = CHAR_MAP_NULL; 97 return char_map_add_item(map->items[map->next - 1], identifier, 98 length ? length - 1 : 0, value); 99 } else { 100 map->items[map->next - 1]->value = value; 101 } 102 103 return EOK; 104 } 76 105 77 106 /** 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 */ 82 int char_map_is_valid(const char_map_ref map); 83 84 int 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))){ 107 * 108 * @param[in] map The character string to integer map. 109 * @returns TRUE if the map is valid. 110 * @returns FALSE otherwise. 111 */ 112 static int char_map_is_valid(const char_map_ref map) 113 { 114 return map && (map->magic == CHAR_MAP_MAGIC_VALUE); 115 } 116 117 /** Adds the value with the key to the map. 118 * 119 * @param[in,out] map The character string to integer map. 120 * @param[in] identifier The key zero ('\0') terminated character string. The 121 * key character string is processed until the first 122 * terminating zero ('\0') character after the given 123 * length is found. 124 * @param[in] length The key character string length. The parameter may be 125 * zero (0) which means that the string is processed until 126 * the terminating zero ('\\0') character is found. 127 * @param[in] value The integral value to be stored for the key character 128 * string. 129 * @returns EOK on success. 130 * @returns EINVAL if the map is not valid. 131 * @returns EINVAL if the identifier parameter is NULL. 132 * @returns EINVAL if the length parameter zero (0) and the 133 * identifier parameter is an empty character string (the 134 * first character is the terminating zero ('\0') 135 * character. 136 * @returns EEXIST if the key character string is already used. 137 * @returns Other error codes as defined for the 138 * char_map_add_item() function. 139 */ 140 int 141 char_map_add(char_map_ref map, const char *identifier, size_t length, 142 const int value) 143 { 144 if (char_map_is_valid(map) && (identifier) && 145 ((length) || (*identifier))) { 86 146 int index; 87 147 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 } 148 for (index = 0; index < map->next; ++ index) { 149 if (map->items[index]->c != *identifier) 150 continue; 151 152 ++ identifier; 153 if((length > 1) || ((length == 0) && (*identifier))) { 154 return char_map_add(map->items[index], 155 identifier, length ? length - 1 : 0, value); 156 } else { 157 if (map->items[index]->value != CHAR_MAP_NULL) 158 return EEXISTS; 159 160 map->items[index]->value = value; 161 return EOK; 100 162 } 101 163 } 102 164 return char_map_add_item(map, identifier, length, value); 103 165 } 166 104 167 return EINVAL; 105 168 } 106 169 107 int 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 139 void char_map_destroy(char_map_ref map){ 140 if(char_map_is_valid(map)){ 170 /** Clears and destroys the map. 171 * 172 * @param[in,out] map The character string to integer map. 173 */ 174 void char_map_destroy(char_map_ref map) 175 { 176 if (char_map_is_valid(map)) { 141 177 int index; 142 178 143 179 map->magic = 0; 144 for (index = 0; index < map->next; ++ index){180 for (index = 0; index < map->next; ++index) 145 181 char_map_destroy(map->items[index]); 146 } 182 147 183 free(map->items); 148 184 map->items = NULL; … … 150 186 } 151 187 152 int char_map_exclude(char_map_ref map, const char * identifier, size_t length){ 188 /** Returns the node assigned to the key from the map. 189 * 190 * @param[in] map The character string to integer map. 191 * @param[in] identifier The key zero ('\0') terminated character string. The 192 * key character string is processed until the first 193 * terminating zero ('\0') character after the given length 194 * is found. 195 * @param[in] length The key character string length. The parameter may be 196 * zero (0) which means that the string is processed until 197 * the terminating zero ('\0') character is found. 198 * @returns The node holding the integral value assigned to the key 199 * character string. 200 * @returns NULL if the key is not assigned a node. 201 */ 202 static char_map_ref 203 char_map_find_node(const char_map_ref map, const char *identifier, 204 size_t length) 205 { 206 if (!char_map_is_valid(map)) 207 return NULL; 208 209 if (length || (*identifier)) { 210 int index; 211 212 for (index = 0; index < map->next; ++index) { 213 if (map->items[index]->c == *identifier) { 214 ++identifier; 215 if (length == 1) 216 return map->items[index]; 217 218 return char_map_find_node(map->items[index], 219 identifier, length ? length - 1 : 0); 220 } 221 } 222 223 return NULL; 224 } 225 226 return map; 227 } 228 229 /** Excludes the value assigned to the key from the map. 230 * 231 * The entry is cleared from the map. 232 * 233 * @param[in,out] map The character string to integer map. 234 * @param[in] identifier The key zero ('\0') terminated character string. The 235 * key character string is processed until the first 236 * terminating zero ('\0') character after the given length 237 * is found. 238 * @param[in] length The key character string length. The parameter may be 239 * zero (0) which means that the string is processed until 240 * the terminating zero ('\0') character is found. 241 * @returns The integral value assigned to the key character string. 242 * @returns CHAR_MAP_NULL if the key is not assigned a value. 243 */ 244 int char_map_exclude(char_map_ref map, const char *identifier, size_t length) 245 { 153 246 char_map_ref node; 154 247 155 248 node = char_map_find_node(map, identifier, length); 156 if (node){249 if (node) { 157 250 int value; 158 251 … … 164 257 } 165 258 166 int char_map_find(const char_map_ref map, const char * identifier, size_t length){ 259 /** Returns the value assigned to the key from the map. 260 * 261 * @param[in] map The character string to integer map. 262 * @param[in] identifier The key zero ('\0') terminated character string. The 263 * key character string is processed until the first 264 * terminating zero ('\0') character after the given length 265 * is found. 266 * @param[in] length The key character string length. The parameter may be 267 * zero (0) which means that the string is processed until 268 * the terminating zero ('\0') character is found. 269 * @returns The integral value assigned to the key character string. 270 * @returns CHAR_MAP_NULL if the key is not assigned a value. 271 */ 272 int char_map_find(const char_map_ref map, const char *identifier, size_t length) 273 { 167 274 char_map_ref node; 168 275 … … 171 278 } 172 279 173 char_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 194 int char_map_get_value(const char_map_ref map){ 195 return char_map_is_valid(map) ? map->value : CHAR_MAP_NULL; 196 } 197 198 int char_map_initialize(char_map_ref map){ 199 if(! map){ 280 /** Initializes the map. 281 * 282 * @param[in,out] map The character string to integer map. 283 * @returns EOK on success. 284 * @returns EINVAL if the map parameter is NULL. 285 * @returns ENOMEM if there is not enough memory left. 286 */ 287 int char_map_initialize(char_map_ref map) 288 { 289 if (!map) 200 290 return EINVAL; 201 } 291 202 292 map->c = '\0'; 203 293 map->value = CHAR_MAP_NULL; 204 294 map->size = 2; 205 295 map->next = 0; 296 206 297 map->items = malloc(sizeof(char_map_ref) * map->size); 207 if (! map->items){298 if (!map->items) { 208 299 map->magic = 0; 209 300 return ENOMEM; 210 301 } 302 211 303 map->items[map->next] = NULL; 212 304 map->magic = CHAR_MAP_MAGIC_VALUE; 305 213 306 return EOK; 214 307 } 215 308 216 int char_map_is_valid(const char_map_ref map){ 217 return map && (map->magic == CHAR_MAP_MAGIC_VALUE); 218 } 219 220 int char_map_update(char_map_ref map, const char * identifier, const size_t length, const int value){ 309 /** Adds or updates the value with the key to the map. 310 * 311 * @param[in,out] map The character string to integer map. 312 * @param[in] identifier The key zero ('\0') terminated character string. The 313 * key character string is processed until the first 314 * terminating zero ('\0') character after the given length 315 * is found. 316 * @param[in] length The key character string length. The parameter may be 317 * zero (0) which means that the string is processed until 318 * the terminating zero ('\0') character is found. 319 * @param[in] value The integral value to be stored for the key character 320 * string. 321 * @returns EOK on success. 322 * @returns EINVAL if the map is not valid. 323 * @returns EINVAL if the identifier parameter is NULL. 324 * @returns EINVAL if the length parameter zero (0) and the 325 * identifier parameter is an empty character string (the 326 * first character is the terminating zero ('\0) character. 327 * @returns EEXIST if the key character string is already used. 328 * @returns Other error codes as defined for the char_map_add_item() 329 * function. 330 */ 331 int 332 char_map_update(char_map_ref map, const char *identifier, const size_t length, 333 const int value) 334 { 221 335 char_map_ref node; 222 336 223 // if(! char_map_is_valid(map)) return EINVAL;224 337 node = char_map_find_node(map, identifier, length); 225 if (node){338 if (node) { 226 339 node->value = value; 227 340 return EOK; 228 } else{229 return char_map_add(map, identifier, length, value);230 }341 } 342 343 return char_map_add(map, identifier, length, value); 231 344 } 232 345 -
uspace/lib/c/include/adt/char_map.h
r0402bda5 r3c213f6 27 27 */ 28 28 29 /** @addtogroup net29 /** @addtogroup libc 30 30 * @{ 31 31 */ … … 38 38 #define __CHAR_MAP_H__ 39 39 40 /** Invalid assigned value used also if an entry does not exist. 41 */ 40 #include <libarch/types.h> 41 42 /** Invalid assigned value used also if an entry does not exist. */ 42 43 #define CHAR_MAP_NULL (-1) 43 44 … … 50 51 * @see char_map 51 52 */ 52 typedef char_map_t * 53 typedef char_map_t *char_map_ref; 53 54 54 55 /** Character string to integer map item. 55 * This structure recursivelly contains itself as a character by character tree. 56 * The actually mapped character string consists o fall the parent characters and the actual one. 56 * 57 * This structure recursivelly contains itself as a character by character tree. 58 * The actually mapped character string consists of all the parent characters 59 * and the actual one. 57 60 */ 58 struct char_map{ 59 /** Actually mapped character. 60 */ 61 struct char_map { 62 /** Actually mapped character. */ 61 63 char c; 62 /** Stored integral value. 63 */ 64 /** Stored integral value. */ 64 65 int value; 65 /** Next character array size. 66 */ 66 /** Next character array size. */ 67 67 int size; 68 /** First free position in the next character array. 69 */ 68 /** First free position in the next character array. */ 70 69 int next; 71 /** Next character array. 72 */ 73 char_map_ref * items; 74 /** Consistency check magic value. 75 */ 70 /** Next character array. */ 71 char_map_ref *items; 72 /** Consistency check magic value. */ 76 73 int magic; 77 74 }; 78 75 79 /** Adds the value with the key to the map. 80 * @param[in,out] map The character string to integer map. 81 * @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. 82 * @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. 83 * @param[in] value The integral value to be stored for the key character string. 84 * @returns EOK on success. 85 * @returns EINVAL if the map is not valid. 86 * @returns EINVAL if the identifier parameter is NULL. 87 * @returns EINVAL if the length parameter zero (0) and the identifier parameter is an empty character string (the first character is the terminating zero ('\\0') character. 88 * @returns EEXIST if the key character string is already used. 89 * @returns Other error codes as defined for the char_map_add_item() function. 90 */ 91 extern int char_map_add(char_map_ref map, const char * identifier, size_t length, const int value); 92 93 /** Clears and destroys the map. 94 * @param[in,out] map The character string to integer map. 95 */ 96 extern void char_map_destroy(char_map_ref map); 97 98 /** Excludes the value assigned to the key from the map. 99 * The entry is cleared from the map. 100 * @param[in,out] map The character string to integer map. 101 * @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. 102 * @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. 103 * @returns The integral value assigned to the key character string. 104 * @returns CHAR_MAP_NULL if the key is not assigned a value. 105 */ 106 extern int char_map_exclude(char_map_ref map, const char * identifier, size_t length); 107 108 /** Returns the value assigned to the key from the map. 109 * @param[in] map The character string to integer map. 110 * @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. 111 * @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. 112 * @returns The integral value assigned to the key character string. 113 * @returns CHAR_MAP_NULL if the key is not assigned a value. 114 */ 115 extern int char_map_find(const char_map_ref map, const char * identifier, size_t length); 116 117 /** Initializes the map. 118 * @param[in,out] map The character string to integer map. 119 * @returns EOK on success. 120 * @returns EINVAL if the map parameter is NULL. 121 * @returns ENOMEM if there is not enough memory left. 122 */ 123 extern int char_map_initialize(char_map_ref map); 124 125 /** Adds or updates the value with the key to the map. 126 * @param[in,out] map The character string to integer map. 127 * @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. 128 * @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. 129 * @param[in] value The integral value to be stored for the key character string. 130 * @returns EOK on success. 131 * @returns EINVAL if the map is not valid. 132 * @returns EINVAL if the identifier parameter is NULL. 133 * @returns EINVAL if the length parameter zero (0) and the identifier parameter is an empty character string (the first character is the terminating zero ('\\0) character. 134 * @returns EEXIST if the key character string is already used. 135 * @returns Other error codes as defined for the char_map_add_item() function. 136 */ 137 extern int char_map_update(char_map_ref map, const char * identifier, size_t length, const int value); 76 extern int char_map_initialize(char_map_ref); 77 extern void char_map_destroy(char_map_ref); 78 extern int char_map_exclude(char_map_ref, const char *, size_t); 79 extern int char_map_add(char_map_ref, const char *, size_t, const int); 80 extern int char_map_find(const char_map_ref, const char *, size_t); 81 extern int char_map_update(char_map_ref, const char *, size_t, const int); 138 82 139 83 #endif
Note:
See TracChangeset
for help on using the changeset viewer.