Subversion Repositories HelenOS

Rev

Rev 3846 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3666 mejdrech 1
/*
2
 * Copyright (c) 2008 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
/**
34
 * @file
35
 */
36
 
37
#ifndef __NET_INT_MAP_H__
38
#define __NET_INT_MAP_H__
39
 
40
#include <errno.h>
41
#include <malloc.h>
42
#include <string.h>
43
 
44
#define INT_MAP_MAGIC_VALUE		0x11223344
45
#define INT_MAP_ITEM_MAGIC_VALUE	0x55667788
46
 
47
#define INT_MAP_DECLARE( name, type )						\
48
										\
49
typedef	struct name		name##_t;					\
50
typedef	name##_t *		name##_ref;					\
51
typedef	struct name##_item	name##_item_t;					\
52
typedef	name##_item_t *		name##_item_ref;				\
53
										\
54
struct	name##_item{								\
55
	int	key;								\
56
	type *	value;								\
57
	int	magic;								\
58
};										\
59
										\
60
struct	name{									\
61
	int			size;						\
62
	int			next;						\
63
	name##_item_ref		items;						\
64
	int	magic;								\
65
};										\
66
										\
67
int	name##_add( name##_ref map, int key, type * value );			\
68
int	name##_count( name##_ref map );						\
69
void	name##_destroy( name##_ref map );					\
70
void	name##_exclude( name##_ref map, int key );				\
71
void	name##_exclude_index( name##_ref map, int index );			\
72
type *	name##_find( name##_ref map, int key );					\
73
type *	name##_get_index( name##_ref map, int index );				\
74
int	name##_initialize( name##_ref map );					\
75
int	name##_is_valid( name##_ref map );					\
76
void	name##_item_destroy( name##_item_ref item );				\
77
int	name##_item_is_valid( name##_item_ref item );
78
 
79
#define INT_MAP_IMPLEMENT( name, type )						\
80
										\
81
int name##_add( name##_ref map, int key, type * value ){			\
82
	if( name##_is_valid( map )){						\
83
		if( map->next == ( map->size - 1 )){				\
84
			name##_item_ref	tmp;					\
85
										\
86
			tmp = ( name##_item_ref ) malloc( sizeof( name##_item_t ) * 2 * map->size );	\
87
			if( ! tmp ) return ENOMEM;				\
88
			map->size *= 2;						\
89
			memcpy( tmp, map->items, sizeof( name##_item_t ) * map->next );	\
90
			free( map->items );					\
91
			map->items = tmp;					\
92
		}								\
93
		map->items[ map->next ].key = key;				\
94
		map->items[ map->next ].value = value;				\
95
		map->items[ map->next ].magic = INT_MAP_ITEM_MAGIC_VALUE;	\
96
		++ map->next;							\
97
		map->items[ map->next ].magic = 0;				\
98
		return map->next - 1;						\
99
	}									\
100
	return EINVAL;								\
101
}										\
102
										\
103
int name##_count( name##_ref map ){						\
104
	return name##_is_valid( map ) ? map->next : -1;				\
105
}										\
106
										\
107
void name##_destroy( name##_ref map ){						\
108
	if( name##_is_valid( map )){						\
109
		int	index;							\
110
										\
111
		map->magic = 0;							\
112
		for( index = 0; index < map->next; ++ index ){			\
113
			if( name##_item_is_valid( &( map->items[ index ] ))){	\
114
				name##_item_destroy( &( map->items[ index ] ));	\
115
			}							\
116
		}								\
117
		free( map->items );						\
118
	}									\
119
}										\
120
										\
121
void name##_exclude( name##_ref map, int key ){					\
122
	if( name##_is_valid( map )){						\
123
		int	index;							\
124
										\
125
		for( index = 0; index < map->next; ++ index ){			\
126
			if( name##_item_is_valid( &( map->items[ index ] )) && ( map->items[ index ].key == key )){	\
127
				name##_item_destroy( &( map->items[ index ] ));	\
128
			}							\
129
		}								\
130
	}									\
131
}										\
132
										\
133
void name##_exclude_index( name##_ref map, int index ){				\
134
	if( name##_is_valid( map ) && ( index >= 0 ) && ( index < map->next ) && name##_item_is_valid( &( map->items[ index ] ))){	\
135
		name##_item_destroy( &( map->items[ index ] ));			\
136
	}									\
137
}										\
138
										\
139
type * name##_find( name##_ref map, int key ){					\
140
	if( name##_is_valid( map )){						\
141
		int	index;							\
142
										\
143
		for( index = 0; index < map->next; ++ index ){			\
144
			if( name##_item_is_valid( &( map->items[ index ] )) && ( map->items[ index ].key == key )){	\
145
				return map->items[ index ].value;		\
146
			}							\
147
		}								\
148
	}									\
149
	return NULL;								\
150
}										\
151
										\
152
type * name##_get_index( name##_ref map, int index ){				\
153
	if( name##_is_valid( map ) && ( index >= 0 ) && ( index < map->next ) && name##_item_is_valid( &( map->items[ index ] ))){	\
154
		return map->items[ index ].value;				\
155
	}									\
156
	return NULL;								\
157
}										\
158
										\
159
int name##_initialize( name##_ref map ){					\
160
	if( ! map ) return EINVAL;						\
161
	map->size = 2;								\
162
	map->next = 0;								\
163
	map->items = ( name##_item_ref ) malloc( sizeof( name##_item_t ) * map->size );	\
164
	if( ! map->items ) return ENOMEM;					\
165
	map->items[ map->next ].magic = 0;					\
166
	map->magic = INT_MAP_MAGIC_VALUE;					\
167
	return EOK;								\
168
}										\
169
										\
170
int name##_is_valid( name##_ref map ){						\
171
	return map && ( map->magic == INT_MAP_MAGIC_VALUE );			\
172
}										\
173
										\
174
void name##_item_destroy( name##_item_ref item ){				\
175
	if( name##_item_is_valid( item )){					\
176
		item->magic = 0;						\
177
		if( item->value ){						\
178
			free( item->value );					\
179
			item->value = NULL;					\
180
		}								\
181
	}									\
182
}										\
183
										\
184
int name##_item_is_valid( name##_item_ref item ){				\
185
	return item && ( item->magic == INT_MAP_ITEM_MAGIC_VALUE );		\
186
}
187
 
188
#endif
189
 
190
/** @}
191
 */
192