Subversion Repositories HelenOS

Rev

Rev 4743 | 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
3912 mejdrech 30
 *  @{
3666 mejdrech 31
 */
32
 
3912 mejdrech 33
/** @file
4704 mejdrech 34
 *  Integer to generic type map.
3666 mejdrech 35
 */
36
 
37
#ifndef __NET_INT_MAP_H__
38
#define __NET_INT_MAP_H__
39
 
40
#include <errno.h>
41
#include <malloc.h>
4192 mejdrech 42
#include <mem.h>
4576 mejdrech 43
#include <unistd.h>
3666 mejdrech 44
 
4704 mejdrech 45
/** Internal magic value for a&nbsp;map consistency check.
46
 */
3846 mejdrech 47
#define INT_MAP_MAGIC_VALUE         0x11223344
4704 mejdrech 48
 
49
/** Internal magic value for an item consistency check.
50
 */
3666 mejdrech 51
#define INT_MAP_ITEM_MAGIC_VALUE    0x55667788
52
 
4704 mejdrech 53
/** Integer to generic type map declaration.
4756 mejdrech 54
 *  @param[in] name Name of the map.
55
 *  @param[in] type Inner object type.
4704 mejdrech 56
 */
3846 mejdrech 57
#define INT_MAP_DECLARE( name, type )                                           \
58
                                                                                \
59
typedef struct name         name##_t;                                           \
60
typedef name##_t *          name##_ref;                                         \
61
typedef struct name##_item  name##_item_t;                                      \
62
typedef name##_item_t *     name##_item_ref;                                    \
63
                                                                                \
64
struct  name##_item{                                                            \
65
    int     key;                                                                \
66
    type *  value;                                                              \
67
    int     magic;                                                              \
68
};                                                                              \
69
                                                                                \
70
struct  name{                                                                   \
4743 mejdrech 71
    int             size;                                                       \
3846 mejdrech 72
    int             next;                                                       \
73
    name##_item_ref items;                                                      \
74
    int             magic;                                                      \
75
};                                                                              \
76
                                                                                \
77
int     name##_add( name##_ref map, int key, type * value );                    \
78
void    name##_clear( name##_ref map );                                         \
79
int     name##_count( name##_ref map );                                         \
80
void    name##_destroy( name##_ref map );                                       \
81
void    name##_exclude( name##_ref map, int key );                              \
82
void    name##_exclude_index( name##_ref map, int index );                      \
83
type *  name##_find( name##_ref map, int key );                                 \
84
type *  name##_get_index( name##_ref map, int index );                          \
85
int     name##_initialize( name##_ref map );                                    \
86
int     name##_is_valid( name##_ref map );                                      \
87
void    name##_item_destroy( name##_item_ref item );                            \
88
int     name##_item_is_valid( name##_item_ref item );
3666 mejdrech 89
 
4704 mejdrech 90
/** Integer to generic type map implementation.
91
 *  Should follow declaration with the same parameters.
4756 mejdrech 92
 *  @param[in] name Name of the map.
93
 *  @param[in] type Inner object type.
4704 mejdrech 94
 */
3846 mejdrech 95
#define INT_MAP_IMPLEMENT( name, type )                                         \
96
                                                                                \
97
int name##_add( name##_ref map, int key, type * value ){                        \
98
    if( name##_is_valid( map )){                                                \
99
        if( map->next == ( map->size - 1 )){                                    \
100
            name##_item_ref tmp;                                                \
101
                                                                                \
4197 mejdrech 102
            tmp = ( name##_item_ref ) realloc( map->items, sizeof( name##_item_t ) * 2 * map->size );   \
3846 mejdrech 103
            if( ! tmp ) return ENOMEM;                                          \
104
            map->size *= 2;                                                     \
105
            map->items = tmp;                                                   \
106
        }                                                                       \
107
        map->items[ map->next ].key = key;                                      \
108
        map->items[ map->next ].value = value;                                  \
109
        map->items[ map->next ].magic = INT_MAP_ITEM_MAGIC_VALUE;               \
110
        ++ map->next;                                                           \
111
        map->items[ map->next ].magic = 0;                                      \
112
        return map->next - 1;                                                   \
113
    }                                                                           \
114
    return EINVAL;                                                              \
115
}                                                                               \
116
                                                                                \
117
void name##_clear( name##_ref map ){                                            \
118
    if( name##_is_valid( map )){                                                \
119
        int index;                                                              \
120
                                                                                \
121
/*      map->magic = 0;*/                                                       \
122
        for( index = 0; index < map->next; ++ index ){                          \
123
            if( name##_item_is_valid( &( map->items[ index ] ))){               \
124
                name##_item_destroy( &( map->items[ index ] ));                 \
125
            }                                                                   \
126
        }                                                                       \
127
        map->next = 0;                                                          \
128
        map->items[ map->next ].magic = 0;                                      \
129
/*      map->magic = INT_MAP_MAGIC_VALUE;*/                                     \
130
    }                                                                           \
131
}                                                                               \
132
                                                                                \
133
int name##_count( name##_ref map ){                                             \
134
    return name##_is_valid( map ) ? map->next : -1;                             \
135
}                                                                               \
136
                                                                                \
137
void name##_destroy( name##_ref map ){                                          \
138
    if( name##_is_valid( map )){                                                \
139
        int index;                                                              \
140
                                                                                \
141
        map->magic = 0;                                                         \
142
        for( index = 0; index < map->next; ++ index ){                          \
143
            if( name##_item_is_valid( &( map->items[ index ] ))){               \
144
                name##_item_destroy( &( map->items[ index ] ));                 \
145
            }                                                                   \
146
        }                                                                       \
147
        free( map->items );                                                     \
148
    }                                                                           \
149
}                                                                               \
150
                                                                                \
151
void name##_exclude( name##_ref map, int key ){                                 \
152
    if( name##_is_valid( map )){                                                \
153
        int index;                                                              \
154
                                                                                \
155
        for( index = 0; index < map->next; ++ index ){                          \
3666 mejdrech 156
            if( name##_item_is_valid( &( map->items[ index ] )) && ( map->items[ index ].key == key )){ \
3846 mejdrech 157
                name##_item_destroy( &( map->items[ index ] ));                 \
158
            }                                                                   \
159
        }                                                                       \
160
    }                                                                           \
161
}                                                                               \
162
                                                                                \
163
void name##_exclude_index( name##_ref map, int index ){                         \
3666 mejdrech 164
    if( name##_is_valid( map ) && ( index >= 0 ) && ( index < map->next ) && name##_item_is_valid( &( map->items[ index ] ))){  \
3846 mejdrech 165
        name##_item_destroy( &( map->items[ index ] ));                         \
166
    }                                                                           \
167
}                                                                               \
168
                                                                                \
169
type * name##_find( name##_ref map, int key ){                                  \
170
    if( name##_is_valid( map )){                                                \
171
        int index;                                                              \
172
                                                                                \
173
        for( index = 0; index < map->next; ++ index ){                          \
3666 mejdrech 174
            if( name##_item_is_valid( &( map->items[ index ] )) && ( map->items[ index ].key == key )){ \
3846 mejdrech 175
                return map->items[ index ].value;                               \
176
            }                                                                   \
177
        }                                                                       \
178
    }                                                                           \
179
    return NULL;                                                                \
180
}                                                                               \
181
                                                                                \
182
type * name##_get_index( name##_ref map, int index ){                           \
3666 mejdrech 183
    if( name##_is_valid( map ) && ( index >= 0 ) && ( index < map->next ) && name##_item_is_valid( &( map->items[ index ] ))){  \
3846 mejdrech 184
        return map->items[ index ].value;                                       \
185
    }                                                                           \
186
    return NULL;                                                                \
187
}                                                                               \
188
                                                                                \
189
int name##_initialize( name##_ref map ){                                        \
190
    if( ! map ) return EINVAL;                                                  \
191
    map->size = 2;                                                              \
192
    map->next = 0;                                                              \
3666 mejdrech 193
    map->items = ( name##_item_ref ) malloc( sizeof( name##_item_t ) * map->size ); \
3846 mejdrech 194
    if( ! map->items ) return ENOMEM;                                           \
195
    map->items[ map->next ].magic = 0;                                          \
196
    map->magic = INT_MAP_MAGIC_VALUE;                                           \
197
    return EOK;                                                                 \
198
}                                                                               \
199
                                                                                \
200
int name##_is_valid( name##_ref map ){                                          \
201
    return map && ( map->magic == INT_MAP_MAGIC_VALUE );                        \
202
}                                                                               \
203
                                                                                \
204
void name##_item_destroy( name##_item_ref item ){                               \
205
    if( name##_item_is_valid( item )){                                          \
206
        item->magic = 0;                                                        \
207
        if( item->value ){                                                      \
208
            free( item->value );                                                \
209
            item->value = NULL;                                                 \
210
        }                                                                       \
211
    }                                                                           \
212
}                                                                               \
213
                                                                                \
214
int name##_item_is_valid( name##_item_ref item ){                               \
215
    return item && ( item->magic == INT_MAP_ITEM_MAGIC_VALUE );                 \
3666 mejdrech 216
}
217
 
218
#endif
219
 
220
/** @}
221
 */
222