source: mainline/uspace/lib/c/include/adt/generic_field.h@ 9f3864a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9f3864a was 442ebbe, checked in by Jakub Jermar <jakub@…>, 15 years ago

Cstyle fixes.

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