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_CHAR_MAP_H_
00038 #define LIBC_GENERIC_CHAR_MAP_H_
00039
00040 #include <unistd.h>
00041 #include <errno.h>
00042
00043 #include <adt/char_map.h>
00044 #include <adt/generic_field.h>
00045
00047 #define GENERIC_CHAR_MAP_MAGIC_VALUE 0x12345622
00048
00050 #define DTOR_T(identifier) \
00051 void (*identifier)(const void *)
00052
00057 #define GENERIC_CHAR_MAP_DECLARE(name, type) \
00058 GENERIC_FIELD_DECLARE(name##_items, type) \
00059 \
00060 typedef struct name name##_t; \
00061 \
00062 struct name { \
00063 char_map_t names; \
00064 name##_items_t values; \
00065 int magic; \
00066 }; \
00067 \
00068 int name##_add(name##_t *, const uint8_t *, const size_t, type *); \
00069 int name##_count(name##_t *); \
00070 void name##_destroy(name##_t *, DTOR_T()); \
00071 void name##_exclude(name##_t *, const uint8_t *, const size_t, DTOR_T()); \
00072 type *name##_find(name##_t *, const uint8_t *, const size_t); \
00073 int name##_initialize(name##_t *); \
00074 int name##_is_valid(name##_t *);
00075
00084 #define GENERIC_CHAR_MAP_IMPLEMENT(name, type) \
00085 GENERIC_FIELD_IMPLEMENT(name##_items, type) \
00086 \
00087 int name##_add(name##_t *map, const uint8_t *name, const size_t length, \
00088 type *value) \
00089 { \
00090 int index; \
00091 if (!name##_is_valid(map)) \
00092 return EINVAL; \
00093 index = name##_items_add(&map->values, value); \
00094 if (index < 0) \
00095 return index; \
00096 return char_map_add(&map->names, name, length, index); \
00097 } \
00098 \
00099 int name##_count(name##_t *map) \
00100 { \
00101 return name##_is_valid(map) ? \
00102 name##_items_count(&map->values) : -1; \
00103 } \
00104 \
00105 void name##_destroy(name##_t *map, DTOR_T(dtor)) \
00106 { \
00107 if (name##_is_valid(map)) { \
00108 char_map_destroy(&map->names); \
00109 name##_items_destroy(&map->values, dtor); \
00110 } \
00111 } \
00112 \
00113 void name##_exclude(name##_t *map, const uint8_t *name, \
00114 const size_t length, DTOR_T(dtor)) \
00115 { \
00116 if (name##_is_valid(map)) { \
00117 int index; \
00118 index = char_map_exclude(&map->names, name, length); \
00119 if (index != CHAR_MAP_NULL) \
00120 name##_items_exclude_index(&map->values, \
00121 index, dtor); \
00122 } \
00123 } \
00124 \
00125 type *name##_find(name##_t *map, const uint8_t *name, \
00126 const size_t length) \
00127 { \
00128 if (name##_is_valid(map)) { \
00129 int index; \
00130 index = char_map_find(&map->names, name, length); \
00131 if( index != CHAR_MAP_NULL) \
00132 return name##_items_get_index(&map->values, \
00133 index); \
00134 } \
00135 return NULL; \
00136 } \
00137 \
00138 int name##_initialize(name##_t *map) \
00139 { \
00140 int rc; \
00141 if (!map) \
00142 return EINVAL; \
00143 rc = char_map_initialize(&map->names); \
00144 if (rc != EOK) \
00145 return rc; \
00146 rc = name##_items_initialize(&map->values); \
00147 if (rc != EOK) { \
00148 char_map_destroy(&map->names); \
00149 return rc; \
00150 } \
00151 map->magic = GENERIC_CHAR_MAP_MAGIC_VALUE; \
00152 return EOK; \
00153 } \
00154 \
00155 int name##_is_valid(name##_t *map) \
00156 { \
00157 return map && (map->magic == GENERIC_CHAR_MAP_MAGIC_VALUE); \
00158 }
00159
00160 #endif
00161