source: mainline/uspace/lib/socket/include/adt/generic_field.h@ 849ed54

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 849ed54 was 849ed54, checked in by Martin Decky <martin@…>, 15 years ago

Networking work:
Split the networking stack into end-user library (libsocket) and two helper libraries (libnet and libnetif).
Don't use over-the-hand compiling and linking, but rather separation of conserns.
There might be still some issues and the non-modular networking architecture is currently broken, but this will be fixed soon.

  • Property mode set to 100644
File size: 5.7 KB
RevLine 
[21580dd]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 */
[aadf01e]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);
[21580dd]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 */
[aadf01e]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){ \
88 return ENOMEM; \
89 } \
90 field->size *= 2; \
91 field->items = tmp; \
92 } \
93 field->items[field->next] = value; \
94 ++ field->next; \
95 field->items[field->next] = NULL; \
96 return field->next - 1; \
97 } \
98 return EINVAL; \
99} \
100 \
101int name##_count(name##_ref field){ \
102 return name##_is_valid(field) ? field->next : -1; \
103} \
104 \
105void name##_destroy(name##_ref field){ \
106 if(name##_is_valid(field)){ \
107 int index; \
108 \
109 field->magic = 0; \
110 for(index = 0; index < field->next; ++ index){ \
111 if(field->items[index]){ \
112 free(field->items[index]); \
113 } \
114 } \
115 free(field->items); \
116 } \
117} \
118 \
119void name##_exclude_index(name##_ref field, int index){ \
120 if(name##_is_valid(field) && (index >= 0) && (index < field->next) && (field->items[index])){ \
121 free(field->items[index]); \
122 field->items[index] = NULL; \
123 } \
124} \
125 \
126type * name##_get_index(name##_ref field, int index){ \
127 if(name##_is_valid(field) && (index >= 0) && (index < field->next) && (field->items[index])){ \
128 return field->items[index]; \
129 } \
130 return NULL; \
131} \
132 \
133type ** name##_get_field(name##_ref field){ \
134 return name##_is_valid(field) ? field->items : NULL; \
135} \
136 \
137int name##_initialize(name##_ref field){ \
138 if(! field){ \
139 return EINVAL; \
140 } \
141 field->size = 2; \
142 field->next = 0; \
143 field->items = (type **) malloc(sizeof(type *) * field->size); \
144 if(! field->items){ \
145 return ENOMEM; \
146 } \
147 field->items[field->next] = NULL; \
148 field->magic = GENERIC_FIELD_MAGIC_VALUE; \
149 return EOK; \
150} \
151 \
152int name##_is_valid(name##_ref field){ \
153 return field && (field->magic == GENERIC_FIELD_MAGIC_VALUE); \
[21580dd]154}
155
156#endif
157
158/** @}
159 */
160
Note: See TracBrowser for help on using the repository browser.