Subversion Repositories HelenOS

Rev

Rev 4197 | Rev 4743 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3666 mejdrech 1
/*
3912 mejdrech 2
 * Copyright (c) 2009 Lukas Mejdrech
3666 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
3846 mejdrech 30
 *  @{
3666 mejdrech 31
 */
32
 
33
/** @file
3912 mejdrech 34
 *  Character string to integer map implementation.
35
 *  @see char_map.h
3666 mejdrech 36
 */
37
 
38
#include <errno.h>
39
#include <malloc.h>
4192 mejdrech 40
#include <mem.h>
3666 mejdrech 41
#include <unistd.h>
42
 
43
#include "char_map.h"
44
 
3912 mejdrech 45
/** Internal magic value for a&nbsp;consistency check.
3846 mejdrech 46
 */
3666 mejdrech 47
#define CHAR_MAP_MAGIC_VALUE    0x12345611
48
 
3846 mejdrech 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.
3912 mejdrech 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.
3846 mejdrech 54
 *  @param value The integral value to be stored for the key character string. Input parameter.
55
 *  @returns EOK on success.
3912 mejdrech 56
 *  @returns ENOMEM if there is not enough memory left.
3846 mejdrech 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 );
3666 mejdrech 60
 
3846 mejdrech 61
/** Returns the node assigned to the key from the map.
62
 *  @param map The character string to integer map. Input parameter.
3912 mejdrech 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.
3846 mejdrech 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 ))){
3666 mejdrech 79
        int index;
80
 
81
        for( index = 0; index < map->next; ++ index ){
82
            if( map->items[ index ]->c == * identifier ){
83
                ++ identifier;
4332 mejdrech 84
                if(( length > 1 ) || (( length == 0 ) && ( * identifier ))){
85
                    return char_map_add( map->items[ index ], identifier, length ? length - 1 : 0, value );
3666 mejdrech 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
        }
3846 mejdrech 93
        return char_map_add_item( map, identifier, length, value );
3666 mejdrech 94
    }
95
    return EINVAL;
96
}
97
 
3846 mejdrech 98
int char_map_add_item( char_map_ref map, const char * identifier, size_t length, const int value ){
3666 mejdrech 99
    if( map->next == ( map->size - 1 )){
100
        char_map_ref    * tmp;
101
 
4197 mejdrech 102
        tmp = ( char_map_ref * ) realloc( map->items, sizeof( char_map_ref ) * 2 * map->size );
3666 mejdrech 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;
4197 mejdrech 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
    }
3666 mejdrech 114
    map->items[ map->next ]->c = * identifier;
115
    ++ identifier;
3846 mejdrech 116
    ++ map->next;
4332 mejdrech 117
    if(( length > 1 ) || (( length == 0 ) && ( * identifier ))){
3846 mejdrech 118
        map->items[ map->next - 1 ]->value = CHAR_MAP_NULL;
4332 mejdrech 119
        return char_map_add_item( map->items[ map->next - 1 ], identifier, length ? length - 1 : 0, value );
3666 mejdrech 120
    }else{
3846 mejdrech 121
        map->items[ map->next - 1 ]->value = value;
3666 mejdrech 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 );
4197 mejdrech 135
        map->items = NULL;
3666 mejdrech 136
    }
137
}
138
 
3846 mejdrech 139
int char_map_exclude( char_map_ref map, const char * identifier, size_t length ){
3666 mejdrech 140
    char_map_ref    node;
141
 
3846 mejdrech 142
    node = char_map_find_node( map, identifier, length );
3666 mejdrech 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
 
3846 mejdrech 153
int char_map_find( const char_map_ref map, const char * identifier, size_t length ){
3666 mejdrech 154
    char_map_ref    node;
155
 
3846 mejdrech 156
    node = char_map_find_node( map, identifier, length );
3666 mejdrech 157
    return node ? node->value : CHAR_MAP_NULL;
158
}
159
 
3846 mejdrech 160
char_map_ref char_map_find_node( const char_map_ref map, const char * identifier, size_t length ){
3666 mejdrech 161
    if( ! char_map_is_valid( map )) return NULL;
3846 mejdrech 162
    if( length || ( * identifier )){
3666 mejdrech 163
        int index;
164
 
165
        for( index = 0; index < map->next; ++ index ){
166
            if( map->items[ index ]->c == * identifier ){
167
                ++ identifier;
4332 mejdrech 168
                if( length == 1 ) return map->items[ index ];
169
                return char_map_find_node( map->items[ index ], identifier, length ? length - 1 : 0 );
3666 mejdrech 170
            }
171
        }
172
        return NULL;
173
    }
174
    return map;
175
}
176
 
3846 mejdrech 177
int char_map_get_value( const char_map_ref map ){
3666 mejdrech 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;
4197 mejdrech 183
    map->c = '\0';
3666 mejdrech 184
    map->value = CHAR_MAP_NULL;
185
    map->size = 2;
186
    map->next = 0;
187
    map->items = malloc( sizeof( char_map_ref ) * map->size );
4197 mejdrech 188
    if( ! map->items ){
189
        map->magic = 0;
190
        return ENOMEM;
191
    }
3666 mejdrech 192
    map->items[ map->next ] = NULL;
193
    map->magic = CHAR_MAP_MAGIC_VALUE;
194
    return EOK;
195
}
196
 
3846 mejdrech 197
int char_map_is_valid( const char_map_ref map ){
3666 mejdrech 198
    return map && ( map->magic == CHAR_MAP_MAGIC_VALUE );
199
}
200
 
3846 mejdrech 201
int char_map_update( char_map_ref map, const char * identifier, const size_t length, const int value ){
3666 mejdrech 202
    char_map_ref    node;
203
 
204
//  if( ! char_map_is_valid( map )) return EINVAL;
3846 mejdrech 205
    node = char_map_find_node( map, identifier, length );
3666 mejdrech 206
    if( node ){
207
        node->value = value;
208
        return EOK;
209
    }else{
3846 mejdrech 210
        return char_map_add( map, identifier, length, value );
3666 mejdrech 211
    }
212
}
213
 
214
/** @}
215
 */