Subversion Repositories HelenOS

Rev

Rev 4197 | Rev 4743 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4197 Rev 4332
1
/*
1
/*
2
 * Copyright (c) 2009 Lukas Mejdrech
2
 * Copyright (c) 2009 Lukas Mejdrech
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
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
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.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
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
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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
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.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup net
29
/** @addtogroup net
30
 *  @{
30
 *  @{
31
 */
31
 */
32
 
32
 
33
/** @file
33
/** @file
34
 *  Character string to integer map implementation.
34
 *  Character string to integer map implementation.
35
 *  @see char_map.h
35
 *  @see char_map.h
36
 */
36
 */
37
 
37
 
38
#include <errno.h>
38
#include <errno.h>
39
#include <malloc.h>
39
#include <malloc.h>
40
#include <mem.h>
40
#include <mem.h>
41
#include <unistd.h>
41
#include <unistd.h>
42
 
42
 
43
#include "char_map.h"
43
#include "char_map.h"
44
 
44
 
45
/** Internal magic value for a&nbsp;consistency check.
45
/** Internal magic value for a&nbsp;consistency check.
46
 */
46
 */
47
#define CHAR_MAP_MAGIC_VALUE    0x12345611
47
#define CHAR_MAP_MAGIC_VALUE    0x12345611
48
 
48
 
49
/** Adds the value with the key to the map.
49
/** Adds the value with the key to the map.
50
 *  Creates new nodes to map the key.
50
 *  Creates new nodes to map the key.
51
 *  @param map The character string to integer map. Input/output parameter.
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.
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.
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.
54
 *  @param value The integral value to be stored for the key character string. Input parameter.
55
 *  @returns EOK on success.
55
 *  @returns EOK on success.
56
 *  @returns ENOMEM if there is not enough memory left.
56
 *  @returns ENOMEM if there is not enough memory left.
57
 *  @returns EEXIST if the key character string is already used.
57
 *  @returns EEXIST if the key character string is already used.
58
 */
58
 */
59
int char_map_add_item( char_map_ref map, const char * identifier, size_t length, const int value );
59
int char_map_add_item( char_map_ref map, const char * identifier, size_t length, const int value );
60
 
60
 
61
/** Returns the node assigned to the key from the map.
61
/** Returns the node assigned to the key from the map.
62
 *  @param map The character string to integer map. Input parameter.
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.
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.
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.
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.
66
 *  @returns NULL if the key is not assigned a&nbsp;node.
67
 */
67
 */
68
char_map_ref    char_map_find_node( const char_map_ref map, const char * identifier, const size_t length );
68
char_map_ref    char_map_find_node( const char_map_ref map, const char * identifier, const size_t length );
69
 
69
 
70
/** Checks if the map is valid.
70
/** Checks if the map is valid.
71
 *  @param map The character string to integer map. Input parameter.
71
 *  @param map The character string to integer map. Input parameter.
72
 *  @returns TRUE if the map is valid.
72
 *  @returns TRUE if the map is valid.
73
 *  @returns FALSE otherwise.
73
 *  @returns FALSE otherwise.
74
 */
74
 */
75
int char_map_is_valid( const char_map_ref map );
75
int char_map_is_valid( const char_map_ref map );
76
 
76
 
77
int char_map_add( char_map_ref map, const char * identifier, size_t length, const int value ){
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 ))){
78
    if( char_map_is_valid( map ) && ( identifier ) && (( length ) || ( * identifier ))){
79
        int index;
79
        int index;
80
 
80
 
81
        for( index = 0; index < map->next; ++ index ){
81
        for( index = 0; index < map->next; ++ index ){
82
            if( map->items[ index ]->c == * identifier ){
82
            if( map->items[ index ]->c == * identifier ){
83
                ++ identifier;
83
                ++ identifier;
84
                if( length ) -- length;
-
 
85
                if( length || ( * identifier )){
84
                if(( length > 1 ) || (( length == 0 ) && ( * identifier ))){
86
                    return char_map_add( map->items[ index ], identifier, length, value );
85
                    return char_map_add( map->items[ index ], identifier, length ? length - 1 : 0, value );
87
                }else{
86
                }else{
88
                    if( map->items[ index ]->value != CHAR_MAP_NULL ) return EEXISTS;
87
                    if( map->items[ index ]->value != CHAR_MAP_NULL ) return EEXISTS;
89
                    map->items[ index ]->value = value;
88
                    map->items[ index ]->value = value;
90
                    return EOK;
89
                    return EOK;
91
                }
90
                }
92
            }
91
            }
93
        }
92
        }
94
        return char_map_add_item( map, identifier, length, value );
93
        return char_map_add_item( map, identifier, length, value );
95
    }
94
    }
96
    return EINVAL;
95
    return EINVAL;
97
}
96
}
98
 
97
 
99
int char_map_add_item( char_map_ref map, const char * identifier, size_t length, const int value ){
98
int char_map_add_item( char_map_ref map, const char * identifier, size_t length, const int value ){
100
    if( map->next == ( map->size - 1 )){
99
    if( map->next == ( map->size - 1 )){
101
        char_map_ref    * tmp;
100
        char_map_ref    * tmp;
102
 
101
 
103
        tmp = ( char_map_ref * ) realloc( map->items, sizeof( char_map_ref ) * 2 * map->size );
102
        tmp = ( char_map_ref * ) realloc( map->items, sizeof( char_map_ref ) * 2 * map->size );
104
        if( ! tmp ) return ENOMEM;
103
        if( ! tmp ) return ENOMEM;
105
        map->size *= 2;
104
        map->size *= 2;
106
        map->items = tmp;
105
        map->items = tmp;
107
    }
106
    }
108
    map->items[ map->next ] = ( char_map_ref ) malloc( sizeof( char_map_t ));
107
    map->items[ map->next ] = ( char_map_ref ) malloc( sizeof( char_map_t ));
109
    if( ! map->items[ map->next ] ) return ENOMEM;
108
    if( ! map->items[ map->next ] ) return ENOMEM;
110
    if( char_map_initialize( map->items[ map->next ] ) != EOK ){
109
    if( char_map_initialize( map->items[ map->next ] ) != EOK ){
111
        free( map->items[ map->next ] );
110
        free( map->items[ map->next ] );
112
        map->items[ map->next ] = NULL;
111
        map->items[ map->next ] = NULL;
113
        return ENOMEM;
112
        return ENOMEM;
114
    }
113
    }
115
    map->items[ map->next ]->c = * identifier;
114
    map->items[ map->next ]->c = * identifier;
116
    ++ identifier;
115
    ++ identifier;
117
    if( length ) -- length;
-
 
118
    ++ map->next;
116
    ++ map->next;
119
    if( length || ( * identifier )){
117
    if(( length > 1 ) || (( length == 0 ) && ( * identifier ))){
120
        map->items[ map->next - 1 ]->value = CHAR_MAP_NULL;
118
        map->items[ map->next - 1 ]->value = CHAR_MAP_NULL;
121
        return char_map_add_item( map->items[ map->next - 1 ], identifier, length, value );
119
        return char_map_add_item( map->items[ map->next - 1 ], identifier, length ? length - 1 : 0, value );
122
    }else{
120
    }else{
123
        map->items[ map->next - 1 ]->value = value;
121
        map->items[ map->next - 1 ]->value = value;
124
    }
122
    }
125
    return EOK;
123
    return EOK;
126
}
124
}
127
 
125
 
128
void char_map_destroy( char_map_ref map ){
126
void char_map_destroy( char_map_ref map ){
129
    if( char_map_is_valid( map )){
127
    if( char_map_is_valid( map )){
130
        int index;
128
        int index;
131
 
129
 
132
        map->magic = 0;
130
        map->magic = 0;
133
        for( index = 0; index < map->next; ++ index ){
131
        for( index = 0; index < map->next; ++ index ){
134
            char_map_destroy( map->items[ index ] );
132
            char_map_destroy( map->items[ index ] );
135
        }
133
        }
136
        free( map->items );
134
        free( map->items );
137
        map->items = NULL;
135
        map->items = NULL;
138
    }
136
    }
139
}
137
}
140
 
138
 
141
int char_map_exclude( char_map_ref map, const char * identifier, size_t length ){
139
int char_map_exclude( char_map_ref map, const char * identifier, size_t length ){
142
    char_map_ref    node;
140
    char_map_ref    node;
143
 
141
 
144
    node = char_map_find_node( map, identifier, length );
142
    node = char_map_find_node( map, identifier, length );
145
    if( node ){
143
    if( node ){
146
        int value;
144
        int value;
147
 
145
 
148
        value = node->value;
146
        value = node->value;
149
        node->value = CHAR_MAP_NULL;
147
        node->value = CHAR_MAP_NULL;
150
        return value;
148
        return value;
151
    }
149
    }
152
    return CHAR_MAP_NULL;
150
    return CHAR_MAP_NULL;
153
}
151
}
154
 
152
 
155
int char_map_find( const char_map_ref map, const char * identifier, size_t length ){
153
int char_map_find( const char_map_ref map, const char * identifier, size_t length ){
156
    char_map_ref    node;
154
    char_map_ref    node;
157
 
155
 
158
    node = char_map_find_node( map, identifier, length );
156
    node = char_map_find_node( map, identifier, length );
159
    return node ? node->value : CHAR_MAP_NULL;
157
    return node ? node->value : CHAR_MAP_NULL;
160
}
158
}
161
 
159
 
162
char_map_ref char_map_find_node( const char_map_ref map, const char * identifier, size_t length ){
160
char_map_ref char_map_find_node( const char_map_ref map, const char * identifier, size_t length ){
163
    if( ! char_map_is_valid( map )) return NULL;
161
    if( ! char_map_is_valid( map )) return NULL;
164
    if( length ) -- length;
-
 
165
    if( length || ( * identifier )){
162
    if( length || ( * identifier )){
166
        int index;
163
        int index;
167
 
164
 
168
        for( index = 0; index < map->next; ++ index ){
165
        for( index = 0; index < map->next; ++ index ){
169
            if( map->items[ index ]->c == * identifier ){
166
            if( map->items[ index ]->c == * identifier ){
170
                ++ identifier;
167
                ++ identifier;
-
 
168
                if( length == 1 ) return map->items[ index ];
171
                return char_map_find_node( map->items[ index ], identifier, length );
169
                return char_map_find_node( map->items[ index ], identifier, length ? length - 1 : 0 );
172
            }
170
            }
173
        }
171
        }
174
        return NULL;
172
        return NULL;
175
    }
173
    }
176
    return map;
174
    return map;
177
}
175
}
178
 
176
 
179
int char_map_get_value( const char_map_ref map ){
177
int char_map_get_value( const char_map_ref map ){
180
    return char_map_is_valid( map ) ? map->value : CHAR_MAP_NULL;
178
    return char_map_is_valid( map ) ? map->value : CHAR_MAP_NULL;
181
}
179
}
182
 
180
 
183
int char_map_initialize( char_map_ref map ){
181
int char_map_initialize( char_map_ref map ){
184
    if( ! map ) return EINVAL;
182
    if( ! map ) return EINVAL;
185
    map->c = '\0';
183
    map->c = '\0';
186
    map->value = CHAR_MAP_NULL;
184
    map->value = CHAR_MAP_NULL;
187
    map->size = 2;
185
    map->size = 2;
188
    map->next = 0;
186
    map->next = 0;
189
    map->items = malloc( sizeof( char_map_ref ) * map->size );
187
    map->items = malloc( sizeof( char_map_ref ) * map->size );
190
    if( ! map->items ){
188
    if( ! map->items ){
191
        map->magic = 0;
189
        map->magic = 0;
192
        return ENOMEM;
190
        return ENOMEM;
193
    }
191
    }
194
    map->items[ map->next ] = NULL;
192
    map->items[ map->next ] = NULL;
195
    map->magic = CHAR_MAP_MAGIC_VALUE;
193
    map->magic = CHAR_MAP_MAGIC_VALUE;
196
    return EOK;
194
    return EOK;
197
}
195
}
198
 
196
 
199
int char_map_is_valid( const char_map_ref map ){
197
int char_map_is_valid( const char_map_ref map ){
200
    return map && ( map->magic == CHAR_MAP_MAGIC_VALUE );
198
    return map && ( map->magic == CHAR_MAP_MAGIC_VALUE );
201
}
199
}
202
 
200
 
203
int char_map_update( char_map_ref map, const char * identifier, const size_t length, const int value ){
201
int char_map_update( char_map_ref map, const char * identifier, const size_t length, const int value ){
204
    char_map_ref    node;
202
    char_map_ref    node;
205
 
203
 
206
//  if( ! char_map_is_valid( map )) return EINVAL;
204
//  if( ! char_map_is_valid( map )) return EINVAL;
207
    node = char_map_find_node( map, identifier, length );
205
    node = char_map_find_node( map, identifier, length );
208
    if( node ){
206
    if( node ){
209
        node->value = value;
207
        node->value = value;
210
        return EOK;
208
        return EOK;
211
    }else{
209
    }else{
212
        return char_map_add( map, identifier, length, value );
210
        return char_map_add( map, identifier, length, value );
213
    }
211
    }
214
}
212
}
215
 
213
 
216
/** @}
214
/** @}
217
 */
215
 */
218
 
216