Subversion Repositories HelenOS

Rev

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

Rev 3846 Rev 3886
1
/*
1
/*
2
 * Copyright (c) 2008 Lukas Mejdrech
2
 * Copyright (c) 2008 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
 *  A character string to integer map implementation file.
34
 *  A character string to integer map implementation file.
35
 */
35
 */
36
 
36
 
37
#include <errno.h>
37
#include <errno.h>
38
#include <malloc.h>
38
#include <malloc.h>
39
#include <unistd.h>
39
#include <unistd.h>
40
#include <string.h>
40
#include <string.h>
41
 
41
 
42
#include "char_map.h"
42
#include "char_map.h"
43
 
43
 
44
/** An&nbsp;internal magic value for a&nbsp;consistency check.
44
/** An&nbsp;internal magic value for a&nbsp;consistency check.
45
 */
45
 */
46
#define CHAR_MAP_MAGIC_VALUE    0x12345611
46
#define CHAR_MAP_MAGIC_VALUE    0x12345611
47
 
47
 
48
/** Adds the value with the key to the map.
48
/** Adds the value with the key to the map.
49
 *  Creates new nodes to map the key.
49
 *  Creates new nodes to map the key.
50
 *  @param map The character string to integer map. Input/output parameter.
50
 *  @param map The character string to integer map. Input/output parameter.
51
 *  @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.
51
 *  @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 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.
52
 *  @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 value The integral value to be stored for the key character string. Input parameter.
53
 *  @param value The integral value to be stored for the key character string. Input parameter.
54
 *  @returns EOK on success.
54
 *  @returns EOK on success.
55
 *  @returns ENOMEM if there is no memory left.
55
 *  @returns ENOMEM if there is no memory left.
56
 *  @returns EEXIST if the key character string is already used.
56
 *  @returns EEXIST if the key character string is already used.
57
 */
57
 */
58
int char_map_add_item( char_map_ref map, const char * identifier, size_t length, const int value );
58
int char_map_add_item( char_map_ref map, const char * identifier, size_t length, const int value );
59
 
59
 
60
/** Returns the node assigned to the key from the map.
60
/** Returns the node assigned to the key from the map.
61
 *  @param map The character string to integer map. Input parameter.
61
 *  @param map The character string to integer map. Input parameter.
62
 *  @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.
62
 *  @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 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.
63
 *  @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
 *  @returns The node holding the integral value assigned to the key character string.
64
 *  @returns The node holding the integral value assigned to the key character string.
65
 *  @returns NULL if the key is not assigned a&nbsp;node.
65
 *  @returns NULL if the key is not assigned a&nbsp;node.
66
 */
66
 */
67
char_map_ref    char_map_find_node( const char_map_ref map, const char * identifier, const size_t length );
67
char_map_ref    char_map_find_node( const char_map_ref map, const char * identifier, const size_t length );
68
 
68
 
69
/** Checks if the map is valid.
69
/** Checks if the map is valid.
70
 *  @param map The character string to integer map. Input parameter.
70
 *  @param map The character string to integer map. Input parameter.
71
 *  @returns TRUE if the map is valid.
71
 *  @returns TRUE if the map is valid.
72
 *  @returns FALSE otherwise.
72
 *  @returns FALSE otherwise.
73
 */
73
 */
74
int char_map_is_valid( const char_map_ref map );
74
int char_map_is_valid( const char_map_ref map );
75
 
75
 
76
int char_map_add( char_map_ref map, const char * identifier, size_t length, const int value ){
76
int char_map_add( char_map_ref map, const char * identifier, size_t length, const int value ){
77
    if( char_map_is_valid( map ) && ( identifier ) && (( length ) || ( * identifier ))){
77
    if( char_map_is_valid( map ) && ( identifier ) && (( length ) || ( * identifier ))){
78
        int index;
78
        int index;
79
 
79
 
80
        for( index = 0; index < map->next; ++ index ){
80
        for( index = 0; index < map->next; ++ index ){
81
            if( map->items[ index ]->c == * identifier ){
81
            if( map->items[ index ]->c == * identifier ){
82
                ++ identifier;
82
                ++ identifier;
83
                if( length ) -- length;
83
                if( length ) -- length;
84
                if( length || ( * identifier )){
84
                if( length || ( * identifier )){
85
                    return char_map_add( map->items[ index ], identifier, length, value );
85
                    return char_map_add( map->items[ index ], identifier, length, value );
86
                }else{
86
                }else{
87
                    if( map->items[ index ]->value != CHAR_MAP_NULL ) return EEXISTS;
87
                    if( map->items[ index ]->value != CHAR_MAP_NULL ) return EEXISTS;
88
                    map->items[ index ]->value = value;
88
                    map->items[ index ]->value = value;
89
                    return EOK;
89
                    return EOK;
90
                }
90
                }
91
            }
91
            }
92
        }
92
        }
93
        return char_map_add_item( map, identifier, length, value );
93
        return char_map_add_item( map, identifier, length, value );
94
    }
94
    }
95
    return EINVAL;
95
    return EINVAL;
96
}
96
}
97
 
97
 
98
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 ){
99
    if( map->next == ( map->size - 1 )){
99
    if( map->next == ( map->size - 1 )){
100
        char_map_ref    * tmp;
100
        char_map_ref    * tmp;
101
 
101
 
102
        tmp = ( char_map_ref * ) malloc( sizeof( char_map_ref ) * 2 * map->size );
102
        tmp = ( char_map_ref * ) malloc( sizeof( char_map_ref ) * 2 * map->size );
103
        if( ! tmp ) return ENOMEM;
103
        if( ! tmp ) return ENOMEM;
104
        map->size *= 2;
104
        map->size *= 2;
105
        memcpy( tmp, map->items, sizeof( char_map_ref ) * map->next );
105
        memcpy( tmp, map->items, sizeof( char_map_ref ) * map->next );
106
        free( map->items );
106
        free( map->items );
107
        map->items = tmp;
107
        map->items = tmp;
108
    }
108
    }
109
    map->items[ map->next ] = ( char_map_ref ) malloc( sizeof( char_map_t ));
109
    map->items[ map->next ] = ( char_map_ref ) malloc( sizeof( char_map_t ));
110
    if( ! map->items[ map->next ] ) return ENOMEM;
110
    if( ! map->items[ map->next ] ) return ENOMEM;
111
    char_map_initialize( map->items[ map->next ] );
111
    char_map_initialize( map->items[ map->next ] );
112
    map->items[ map->next ]->c = * identifier;
112
    map->items[ map->next ]->c = * identifier;
113
    ++ identifier;
113
    ++ identifier;
114
    if( length ) -- length;
114
    if( length ) -- length;
115
    ++ map->next;
115
    ++ map->next;
116
    if( length || ( * identifier )){
116
    if( length || ( * identifier )){
117
        map->items[ map->next - 1 ]->value = CHAR_MAP_NULL;
117
        map->items[ map->next - 1 ]->value = CHAR_MAP_NULL;
118
        return char_map_add_item( map->items[ map->next - 1 ], identifier, length, value );
118
        return char_map_add_item( map->items[ map->next - 1 ], identifier, length, value );
119
    }else{
119
    }else{
120
        map->items[ map->next - 1 ]->value = value;
120
        map->items[ map->next - 1 ]->value = value;
121
    }
121
    }
122
    return EOK;
122
    return EOK;
123
}
123
}
124
 
124
 
125
void char_map_destroy( char_map_ref map ){
125
void char_map_destroy( char_map_ref map ){
126
    if( char_map_is_valid( map )){
126
    if( char_map_is_valid( map )){
127
        int index;
127
        int index;
128
 
128
 
129
        map->magic = 0;
129
        map->magic = 0;
130
        for( index = 0; index < map->next; ++ index ){
130
        for( index = 0; index < map->next; ++ index ){
131
            char_map_destroy( map->items[ index ] );
131
            char_map_destroy( map->items[ index ] );
132
        }
132
        }
133
        free( map->items );
133
        free( map->items );
134
    }
134
    }
135
}
135
}
136
 
136
 
137
int char_map_exclude( char_map_ref map, const char * identifier, size_t length ){
137
int char_map_exclude( char_map_ref map, const char * identifier, size_t length ){
138
    char_map_ref    node;
138
    char_map_ref    node;
139
 
139
 
140
    node = char_map_find_node( map, identifier, length );
140
    node = char_map_find_node( map, identifier, length );
141
    if( node ){
141
    if( node ){
142
        int value;
142
        int value;
143
 
143
 
144
        value = node->value;
144
        value = node->value;
145
        node->value = CHAR_MAP_NULL;
145
        node->value = CHAR_MAP_NULL;
146
        return value;
146
        return value;
147
    }
147
    }
148
    return CHAR_MAP_NULL;
148
    return CHAR_MAP_NULL;
149
}
149
}
150
 
150
 
151
int char_map_find( const char_map_ref map, const char * identifier, size_t length ){
151
int char_map_find( const char_map_ref map, const char * identifier, size_t length ){
152
    char_map_ref    node;
152
    char_map_ref    node;
153
 
153
 
154
    node = char_map_find_node( map, identifier, length );
154
    node = char_map_find_node( map, identifier, length );
155
    return node ? node->value : CHAR_MAP_NULL;
155
    return node ? node->value : CHAR_MAP_NULL;
156
}
156
}
157
 
157
 
158
char_map_ref char_map_find_node( const char_map_ref map, const char * identifier, size_t length ){
158
char_map_ref char_map_find_node( const char_map_ref map, const char * identifier, size_t length ){
159
    if( ! char_map_is_valid( map )) return NULL;
159
    if( ! char_map_is_valid( map )) return NULL;
160
    if( length ) -- length;
160
    if( length ) -- length;
161
    if( length || ( * identifier )){
161
    if( length || ( * identifier )){
162
        int index;
162
        int index;
163
 
163
 
164
        for( index = 0; index < map->next; ++ index ){
164
        for( index = 0; index < map->next; ++ index ){
165
            if( map->items[ index ]->c == * identifier ){
165
            if( map->items[ index ]->c == * identifier ){
166
                ++ identifier;
166
                ++ identifier;
167
                return char_map_find_node( map->items[ index ], identifier, length );
167
                return char_map_find_node( map->items[ index ], identifier, length );
168
            }
168
            }
169
        }
169
        }
170
        return NULL;
170
        return NULL;
171
    }
171
    }
172
    return map;
172
    return map;
173
}
173
}
174
 
174
 
175
int char_map_get_value( const char_map_ref map ){
175
int char_map_get_value( const char_map_ref map ){
176
    return char_map_is_valid( map ) ? map->value : CHAR_MAP_NULL;
176
    return char_map_is_valid( map ) ? map->value : CHAR_MAP_NULL;
177
}
177
}
178
 
178
 
179
int char_map_initialize( char_map_ref map ){
179
int char_map_initialize( char_map_ref map ){
180
    if( ! map ) return EINVAL;
180
    if( ! map ) return EINVAL;
181
    map->c = 0;
181
    map->c = 0;
182
    map->value = CHAR_MAP_NULL;
182
    map->value = CHAR_MAP_NULL;
183
    map->size = 2;
183
    map->size = 2;
184
    map->next = 0;
184
    map->next = 0;
185
    map->items = malloc( sizeof( char_map_ref ) * map->size );
185
    map->items = malloc( sizeof( char_map_ref ) * map->size );
186
    if( ! map->items ) return ENOMEM;
186
    if( ! map->items ) return ENOMEM;
187
    map->items[ map->next ] = NULL;
187
    map->items[ map->next ] = NULL;
188
    map->magic = CHAR_MAP_MAGIC_VALUE;
188
    map->magic = CHAR_MAP_MAGIC_VALUE;
189
    return EOK;
189
    return EOK;
190
}
190
}
191
 
191
 
192
int char_map_is_valid( const char_map_ref map ){
192
int char_map_is_valid( const char_map_ref map ){
193
    return map && ( map->magic == CHAR_MAP_MAGIC_VALUE );
193
    return map && ( map->magic == CHAR_MAP_MAGIC_VALUE );
194
}
194
}
195
 
195
 
196
int char_map_update( char_map_ref map, const char * identifier, const size_t length, const int value ){
196
int char_map_update( char_map_ref map, const char * identifier, const size_t length, const int value ){
197
    char_map_ref    node;
197
    char_map_ref    node;
198
 
198
 
199
//  if( ! char_map_is_valid( map )) return EINVAL;
199
//  if( ! char_map_is_valid( map )) return EINVAL;
200
    node = char_map_find_node( map, identifier, length );
200
    node = char_map_find_node( map, identifier, length );
201
    if( node ){
201
    if( node ){
202
        node->value = value;
202
        node->value = value;
203
        return EOK;
203
        return EOK;
204
    }else{
204
    }else{
205
        return char_map_add( map, identifier, length, value );
205
        return char_map_add( map, identifier, length, value );
206
    }
206
    }
207
}
207
}
208
 
208
 
209
/** @}
209
/** @}
210
 */
210
 */
211
 
211