int_map.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_INT_MAP_H_
00038 #define LIBC_INT_MAP_H_
00039 
00040 #include <errno.h>
00041 #include <malloc.h>
00042 #include <mem.h>
00043 #include <unistd.h>
00044 
00046 #define INT_MAP_MAGIC_VALUE             0x11223344
00047 
00049 #define INT_MAP_ITEM_MAGIC_VALUE        0x55667788
00050 
00052 #define DTOR_T(identifier) \
00053         void (*identifier)(const void *)
00054 
00060 #define INT_MAP_DECLARE(name, type) \
00061         typedef struct name name##_t; \
00062         typedef struct name##_item name##_item_t; \
00063         \
00064         struct  name##_item { \
00065                 int key; \
00066                 type *value; \
00067                 int magic; \
00068         }; \
00069         \
00070         struct  name { \
00071                 int size; \
00072                 int next; \
00073                 name##_item_t *items; \
00074                 int magic; \
00075         }; \
00076         \
00077         int name##_add(name##_t *, int, type *); \
00078         void name##_clear(name##_t *, DTOR_T()); \
00079         int name##_count(name##_t *); \
00080         void name##_destroy(name##_t *, DTOR_T()); \
00081         void name##_exclude(name##_t *, int, DTOR_T()); \
00082         void name##_exclude_index(name##_t *, int, DTOR_T()); \
00083         type *name##_find(name##_t *, int); \
00084         int name##_update(name##_t *, int, int); \
00085         type *name##_get_index(name##_t *, int); \
00086         int name##_initialize(name##_t *); \
00087         int name##_is_valid(name##_t *); \
00088         void name##_item_destroy(name##_item_t *, DTOR_T()); \
00089         int name##_item_is_valid(name##_item_t *);
00090 
00098 #define INT_MAP_IMPLEMENT(name, type) \
00099         int name##_add(name##_t *map, int key, type *value) \
00100         { \
00101                 if (name##_is_valid(map)) { \
00102                         if (map->next == (map->size - 1)) { \
00103                                 name##_item_t *tmp; \
00104                                 tmp = (name##_item_t *) realloc(map->items, \
00105                                     sizeof(name##_item_t) * 2 * map->size); \
00106                                 if (!tmp) \
00107                                         return ENOMEM; \
00108                                 map->size *= 2; \
00109                                 map->items = tmp; \
00110                         } \
00111                         map->items[map->next].key = key; \
00112                         map->items[map->next].value = value; \
00113                         map->items[map->next].magic = INT_MAP_ITEM_MAGIC_VALUE; \
00114                         ++map->next; \
00115                         map->items[map->next].magic = 0; \
00116                         return map->next - 1; \
00117                 } \
00118                 return EINVAL; \
00119         } \
00120         \
00121         void name##_clear(name##_t *map, DTOR_T(dtor)) \
00122         { \
00123                 if (name##_is_valid(map)) { \
00124                         int index; \
00125                         for (index = 0; index < map->next; ++index) { \
00126                                 if (name##_item_is_valid(&map->items[index])) { \
00127                                         name##_item_destroy( \
00128                                             &map->items[index], dtor); \
00129                                 } \
00130                         } \
00131                         map->next = 0; \
00132                         map->items[map->next].magic = 0; \
00133                 } \
00134         } \
00135         \
00136         int name##_count(name##_t *map) \
00137         { \
00138                 return name##_is_valid(map) ? map->next : -1; \
00139         } \
00140         \
00141         void name##_destroy(name##_t *map, DTOR_T(dtor)) \
00142         { \
00143                 if (name##_is_valid(map)) { \
00144                         int index; \
00145                         map->magic = 0; \
00146                         for (index = 0; index < map->next; ++index) { \
00147                                 if (name##_item_is_valid(&map->items[index])) { \
00148                                         name##_item_destroy( \
00149                                             &map->items[index], dtor); \
00150                                 } \
00151                         } \
00152                         free(map->items); \
00153                 } \
00154         } \
00155         \
00156         void name##_exclude(name##_t *map, int key, DTOR_T(dtor)) \
00157         { \
00158                 if (name##_is_valid(map)) { \
00159                         int index; \
00160                         for (index = 0; index < map->next; ++index) { \
00161                                 if (name##_item_is_valid(&map->items[index]) && \
00162                                     (map->items[index].key == key)) { \
00163                                         name##_item_destroy( \
00164                                             &map->items[index], dtor); \
00165                                 } \
00166                         } \
00167                 } \
00168         } \
00169         \
00170         void name##_exclude_index(name##_t *map, int index, DTOR_T(dtor)) \
00171         { \
00172                 if (name##_is_valid(map) && (index >= 0) && \
00173                     (index < map->next) && \
00174                     name##_item_is_valid(&map->items[index])) { \
00175                         name##_item_destroy(&map->items[index], dtor); \
00176                 } \
00177         } \
00178         \
00179         type *name##_find(name##_t *map, int key) \
00180         { \
00181                 if (name##_is_valid(map)) { \
00182                         int index; \
00183                         for (index = 0; index < map->next; ++index) { \
00184                                 if (name##_item_is_valid(&map->items[index]) && \
00185                                     (map->items[index].key == key)) { \
00186                                         return map->items[index].value; \
00187                                 } \
00188                         } \
00189                 } \
00190                 return NULL; \
00191         } \
00192         \
00193         int name##_update(name##_t *map, int key, int new_key) \
00194         { \
00195                 if (name##_is_valid(map)) { \
00196                         int index; \
00197                         for (index = 0; index < map->next; ++index) { \
00198                                 if (name##_item_is_valid(&map->items[index])) { \
00199                                         if (map->items[index].key == new_key) \
00200                                                 return EEXIST; \
00201                                         if (map->items[index].key == key) { \
00202                                                 map->items[index].key = \
00203                                                     new_key; \
00204                                                 return EOK; \
00205                                         } \
00206                                 } \
00207                         } \
00208                 } \
00209                 return ENOENT; \
00210         } \
00211         \
00212         type *name##_get_index(name##_t *map, int index) \
00213         { \
00214                 if (name##_is_valid(map) && (index >= 0) && \
00215                     (index < map->next) && \
00216                     name##_item_is_valid(&map->items[index])) { \
00217                         return map->items[index].value; \
00218                 } \
00219                 return NULL; \
00220         } \
00221         \
00222         int name##_initialize(name##_t *map) \
00223         { \
00224                 if (!map) \
00225                         return EINVAL; \
00226                 map->size = 2; \
00227                 map->next = 0; \
00228                 map->items = (name##_item_t *) malloc(sizeof(name##_item_t) * \
00229                     map->size); \
00230                 if (!map->items) \
00231                         return ENOMEM; \
00232                 map->items[map->next].magic = 0; \
00233                 map->magic = INT_MAP_MAGIC_VALUE; \
00234                 return EOK; \
00235         } \
00236         \
00237         int name##_is_valid(name##_t *map) \
00238         { \
00239                 return map && (map->magic == INT_MAP_MAGIC_VALUE); \
00240         } \
00241         \
00242         void name##_item_destroy(name##_item_t *item, DTOR_T(dtor)) \
00243         { \
00244                 if (name##_item_is_valid(item)) { \
00245                         item->magic = 0; \
00246                         if (item->value) { \
00247                                 if (dtor) \
00248                                         dtor(item->value); \
00249                                 item->value = NULL; \
00250                         } \
00251                 } \
00252         } \
00253         \
00254         int name##_item_is_valid(name##_item_t *item) \
00255         { \
00256                 return item && (item->magic == INT_MAP_ITEM_MAGIC_VALUE); \
00257         }
00258 
00259 #endif
00260 

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