Subversion Repositories HelenOS

Rev

Rev 4743 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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.  */
  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&nbsp;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&nbsp;value.
  74.  */
  75. int 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.  */
  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 ))){
  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.  
  105. int 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.  
  133. void 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.  
  146. int 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.  
  160. int 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.  
  167. char_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.  
  184. int char_map_get_value( const char_map_ref map ){
  185.     return char_map_is_valid( map ) ? map->value : CHAR_MAP_NULL;
  186. }
  187.  
  188. int 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.  
  204. int char_map_is_valid( const char_map_ref map ){
  205.     return map && ( map->magic == CHAR_MAP_MAGIC_VALUE );
  206. }
  207.  
  208. int 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.  */
  223.