00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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