generic_field.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2009 Lukas Mejdrech
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00037 #ifndef LIBC_GENERIC_FIELD_H_
00038 #define LIBC_GENERIC_FIELD_H_
00039 
00040 #include <errno.h>
00041 #include <malloc.h>
00042 #include <mem.h>
00043 #include <unistd.h>
00044 
00046 #define GENERIC_FIELD_MAGIC_VALUE               0x55667788
00047 
00049 #define DTOR_T(identifier) \
00050         void (*identifier)(const void *)
00051 
00057 #define GENERIC_FIELD_DECLARE(name, type) \
00058         typedef struct name name##_t; \
00059         \
00060         struct  name { \
00061                 int size; \
00062                 int next; \
00063                 type **items; \
00064                 int magic; \
00065         }; \
00066         \
00067         int name##_add(name##_t *, type *); \
00068         int name##_count(name##_t *); \
00069         void name##_destroy(name##_t *, DTOR_T()); \
00070         void name##_exclude_index(name##_t *, int, DTOR_T()); \
00071         type **name##_get_field(name##_t *); \
00072         type *name##_get_index(name##_t *, int); \
00073         int name##_initialize(name##_t *); \
00074         int name##_is_valid(name##_t *);
00075 
00083 #define GENERIC_FIELD_IMPLEMENT(name, type) \
00084         int name##_add(name##_t *field, type *value) \
00085         { \
00086                 if (name##_is_valid(field)) { \
00087                         if (field->next == (field->size - 1)) { \
00088                                 type **tmp; \
00089                                 tmp = (type **) realloc(field->items, \
00090                                     sizeof(type *) * 2 * field->size); \
00091                                 if (!tmp) \
00092                                         return ENOMEM; \
00093                                 field->size *= 2; \
00094                                 field->items = tmp; \
00095                         } \
00096                         field->items[field->next] = value; \
00097                         field->next++; \
00098                         field->items[field->next] = NULL; \
00099                         return field->next - 1; \
00100                 } \
00101                 return EINVAL; \
00102         } \
00103         \
00104         int name##_count(name##_t *field) \
00105         { \
00106                 return name##_is_valid(field) ? field->next : -1; \
00107         } \
00108         \
00109         void name##_destroy(name##_t *field, DTOR_T(dtor)) \
00110         { \
00111                 if (name##_is_valid(field)) { \
00112                         int index; \
00113                         field->magic = 0; \
00114                         if (dtor) { \
00115                                 for (index = 0; index < field->next; index++) { \
00116                                         if (field->items[index]) \
00117                                                 dtor(field->items[index]); \
00118                                 } \
00119                         } \
00120                         free(field->items); \
00121                 } \
00122         } \
00123          \
00124         void name##_exclude_index(name##_t *field, int index, DTOR_T(dtor)) \
00125         { \
00126                 if (name##_is_valid(field) && (index >= 0) && \
00127                     (index < field->next) && (field->items[index])) { \
00128                         if (dtor) \
00129                                 dtor(field->items[index]); \
00130                         field->items[index] = NULL; \
00131                 } \
00132         } \
00133          \
00134         type *name##_get_index(name##_t *field, int index) \
00135         { \
00136                 if (name##_is_valid(field) && (index >= 0) && \
00137                     (index < field->next) && (field->items[index])) \
00138                         return field->items[index]; \
00139                 return NULL; \
00140         } \
00141         \
00142         type **name##_get_field(name##_t *field) \
00143         { \
00144                 return name##_is_valid(field) ? field->items : NULL; \
00145         } \
00146         \
00147         int name##_initialize(name##_t *field) \
00148         { \
00149                 if (!field) \
00150                         return EINVAL; \
00151                 field->size = 2; \
00152                 field->next = 0; \
00153                 field->items = (type **) malloc(sizeof(type *) * field->size); \
00154                 if (!field->items) \
00155                         return ENOMEM; \
00156                 field->items[field->next] = NULL; \
00157                 field->magic = GENERIC_FIELD_MAGIC_VALUE; \
00158                 return EOK; \
00159         } \
00160         \
00161         int name##_is_valid(name##_t *field) \
00162         { \
00163                 return field && (field->magic == GENERIC_FIELD_MAGIC_VALUE); \
00164         }
00165 
00166 #endif
00167 

Generated on Thu Jun 2 07:45:46 2011 for HelenOS/USB by  doxygen 1.4.7