Subversion Repositories HelenOS

Rev

Rev 4197 | Rev 4743 | Go to most recent revision | 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 map The character string to integer map. Input/output parameter.
  52.  *  @param 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. Input parameter.
  53.  *  @param 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. Input parameter.
  54.  *  @param value The integral value to be stored for the key character string. Input parameter.
  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 map The character string to integer map. Input parameter.
  63.  *  @param 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. Input parameter.
  64.  *  @param 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. Input parameter.
  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. /** Checks if the map is valid.
  71.  *  @param map The character string to integer map. Input parameter.
  72.  *  @returns TRUE if the map is valid.
  73.  *  @returns FALSE otherwise.
  74.  */
  75. int char_map_is_valid( const char_map_ref map );
  76.  
  77. int char_map_add( char_map_ref map, const char * identifier, size_t length, const int value ){
  78.     if( char_map_is_valid( map ) && ( identifier ) && (( length ) || ( * identifier ))){
  79.         int index;
  80.  
  81.         for( index = 0; index < map->next; ++ index ){
  82.             if( map->items[ index ]->c == * identifier ){
  83.                 ++ identifier;
  84.                 if(( length > 1 ) || (( length == 0 ) && ( * identifier ))){
  85.                     return char_map_add( map->items[ index ], identifier, length ? length - 1 : 0, value );
  86.                 }else{
  87.                     if( map->items[ index ]->value != CHAR_MAP_NULL ) return EEXISTS;
  88.                     map->items[ index ]->value = value;
  89.                     return EOK;
  90.                 }
  91.             }
  92.         }
  93.         return char_map_add_item( map, identifier, length, value );
  94.     }
  95.     return EINVAL;
  96. }
  97.  
  98. int char_map_add_item( char_map_ref map, const char * identifier, size_t length, const int value ){
  99.     if( map->next == ( map->size - 1 )){
  100.         char_map_ref    * tmp;
  101.  
  102.         tmp = ( char_map_ref * ) realloc( map->items, sizeof( char_map_ref ) * 2 * map->size );
  103.         if( ! tmp ) return ENOMEM;
  104.         map->size *= 2;
  105.         map->items = tmp;
  106.     }
  107.     map->items[ map->next ] = ( char_map_ref ) malloc( sizeof( char_map_t ));
  108.     if( ! map->items[ map->next ] ) return ENOMEM;
  109.     if( char_map_initialize( map->items[ map->next ] ) != EOK ){
  110.         free( map->items[ map->next ] );
  111.         map->items[ map->next ] = NULL;
  112.         return ENOMEM;
  113.     }
  114.     map->items[ map->next ]->c = * identifier;
  115.     ++ identifier;
  116.     ++ map->next;
  117.     if(( length > 1 ) || (( length == 0 ) && ( * identifier ))){
  118.         map->items[ map->next - 1 ]->value = CHAR_MAP_NULL;
  119.         return char_map_add_item( map->items[ map->next - 1 ], identifier, length ? length - 1 : 0, value );
  120.     }else{
  121.         map->items[ map->next - 1 ]->value = value;
  122.     }
  123.     return EOK;
  124. }
  125.  
  126. void char_map_destroy( char_map_ref map ){
  127.     if( char_map_is_valid( map )){
  128.         int index;
  129.  
  130.         map->magic = 0;
  131.         for( index = 0; index < map->next; ++ index ){
  132.             char_map_destroy( map->items[ index ] );
  133.         }
  134.         free( map->items );
  135.         map->items = NULL;
  136.     }
  137. }
  138.  
  139. int char_map_exclude( char_map_ref map, const char * identifier, size_t length ){
  140.     char_map_ref    node;
  141.  
  142.     node = char_map_find_node( map, identifier, length );
  143.     if( node ){
  144.         int value;
  145.  
  146.         value = node->value;
  147.         node->value = CHAR_MAP_NULL;
  148.         return value;
  149.     }
  150.     return CHAR_MAP_NULL;
  151. }
  152.  
  153. int char_map_find( const char_map_ref map, const char * identifier, size_t length ){
  154.     char_map_ref    node;
  155.  
  156.     node = char_map_find_node( map, identifier, length );
  157.     return node ? node->value : CHAR_MAP_NULL;
  158. }
  159.  
  160. char_map_ref char_map_find_node( const char_map_ref map, const char * identifier, size_t length ){
  161.     if( ! char_map_is_valid( map )) return NULL;
  162.     if( length || ( * identifier )){
  163.         int index;
  164.  
  165.         for( index = 0; index < map->next; ++ index ){
  166.             if( map->items[ index ]->c == * identifier ){
  167.                 ++ identifier;
  168.                 if( length == 1 ) return map->items[ index ];
  169.                 return char_map_find_node( map->items[ index ], identifier, length ? length - 1 : 0 );
  170.             }
  171.         }
  172.         return NULL;
  173.     }
  174.     return map;
  175. }
  176.  
  177. int char_map_get_value( const char_map_ref map ){
  178.     return char_map_is_valid( map ) ? map->value : CHAR_MAP_NULL;
  179. }
  180.  
  181. int char_map_initialize( char_map_ref map ){
  182.     if( ! map ) return EINVAL;
  183.     map->c = '\0';
  184.     map->value = CHAR_MAP_NULL;
  185.     map->size = 2;
  186.     map->next = 0;
  187.     map->items = malloc( sizeof( char_map_ref ) * map->size );
  188.     if( ! map->items ){
  189.         map->magic = 0;
  190.         return ENOMEM;
  191.     }
  192.     map->items[ map->next ] = NULL;
  193.     map->magic = CHAR_MAP_MAGIC_VALUE;
  194.     return EOK;
  195. }
  196.  
  197. int char_map_is_valid( const char_map_ref map ){
  198.     return map && ( map->magic == CHAR_MAP_MAGIC_VALUE );
  199. }
  200.  
  201. int char_map_update( char_map_ref map, const char * identifier, const size_t length, const int value ){
  202.     char_map_ref    node;
  203.  
  204. //  if( ! char_map_is_valid( map )) return EINVAL;
  205.     node = char_map_find_node( map, identifier, length );
  206.     if( node ){
  207.         node->value = value;
  208.         return EOK;
  209.     }else{
  210.         return char_map_add( map, identifier, length, value );
  211.     }
  212. }
  213.  
  214. /** @}
  215.  */
  216.