source: mainline/uspace/srv/net/structures/generic_field.h@ 21580dd

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 21580dd was 21580dd, checked in by Lukas Mejdrech <lukas@…>, 15 years ago

Merged with network branch svn://svn.helenos.org/HelenOS/branches/network revision 4759; ipc_share_* and ipc_data_* changed to async_*; client connection in module.c returns on IPC_M_PHONE_HUNGUP; * Qemu scripts renamed to net-qe.*; (the dp8390 does not respond)

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Copyright (c) 2009 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/** @file
34 * Generic type field.
35 */
36
37#ifndef __GENERIC_FIELD_H__
38#define __GENERIC_FIELD_H__
39
40#include <errno.h>
41#include <malloc.h>
42#include <mem.h>
43#include <unistd.h>
44
45/** Internal magic value for a&nbsp;field consistency check.
46 */
47#define GENERIC_FIELD_MAGIC_VALUE 0x55667788
48
49/** Generic type field declaration.
50 * @param[in] name Name of the field.
51 * @param[in] type Inner object type.
52 */
53#define GENERIC_FIELD_DECLARE( name, type ) \
54 \
55typedef struct name name##_t; \
56typedef name##_t * name##_ref; \
57 \
58struct name{ \
59 int size; \
60 int next; \
61 type ** items; \
62 int magic; \
63}; \
64 \
65int name##_add( name##_ref field, type * value ); \
66int name##_count( name##_ref field ); \
67void name##_destroy( name##_ref field ); \
68void name##_exclude_index( name##_ref field, int index ); \
69type ** name##_get_field( name##_ref field ); \
70type * name##_get_index( name##_ref field, int index ); \
71int name##_initialize( name##_ref field ); \
72int name##_is_valid( name##_ref field );
73
74/** Generic type field implementation.
75 * Should follow declaration with the same parameters.
76 * @param[in] name Name of the field.
77 * @param[in] type Inner object type.
78 */
79#define GENERIC_FIELD_IMPLEMENT( name, type ) \
80 \
81int name##_add( name##_ref field, type * value ){ \
82 if( name##_is_valid( field )){ \
83 if( field->next == ( field->size - 1 )){ \
84 type ** tmp; \
85 \
86 tmp = ( type ** ) realloc( field->items, sizeof( type * ) * 2 * field->size ); \
87 if( ! tmp ) return ENOMEM; \
88 field->size *= 2; \
89 field->items = tmp; \
90 } \
91 field->items[ field->next ] = value; \
92 ++ field->next; \
93 field->items[ field->next ] = NULL; \
94 return field->next - 1; \
95 } \
96 return EINVAL; \
97} \
98 \
99int name##_count( name##_ref field ){ \
100 return name##_is_valid( field ) ? field->next : -1; \
101} \
102 \
103void name##_destroy( name##_ref field ){ \
104 if( name##_is_valid( field )){ \
105 int index; \
106 \
107 field->magic = 0; \
108 for( index = 0; index < field->next; ++ index ){ \
109 if( field->items[ index ] ) free( field->items[ index ] ); \
110 } \
111 free( field->items ); \
112 } \
113} \
114 \
115void name##_exclude_index( name##_ref field, int index ){ \
116 if( name##_is_valid( field ) && ( index >= 0 ) && ( index < field->next ) && ( field->items[ index ] )){ \
117 free( field->items[ index ] ); \
118 field->items[ index ] = NULL; \
119 } \
120} \
121 \
122type * name##_get_index( name##_ref field, int index ){ \
123 if( name##_is_valid( field ) && ( index >= 0 ) && ( index < field->next ) && ( field->items[ index ] )){ \
124 return field->items[ index ]; \
125 } \
126 return NULL; \
127} \
128 \
129type ** name##_get_field( name##_ref field ){ \
130 return name##_is_valid( field ) ? field->items : NULL; \
131} \
132 \
133int name##_initialize( name##_ref field ){ \
134 if( ! field ) return EINVAL; \
135 field->size = 2; \
136 field->next = 0; \
137 field->items = ( type ** ) malloc( sizeof( type * ) * field->size ); \
138 if( ! field->items ) return ENOMEM; \
139 field->items[ field->next ] = NULL; \
140 field->magic = GENERIC_FIELD_MAGIC_VALUE; \
141 return EOK; \
142} \
143 \
144int name##_is_valid( name##_ref field ){ \
145 return field && ( field->magic == GENERIC_FIELD_MAGIC_VALUE ); \
146}
147
148#endif
149
150/** @}
151 */
152
Note: See TracBrowser for help on using the repository browser.