source: mainline/uspace/lib/c/include/adt/generic_char_map.h@ 5fe7692

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 5fe7692 was 5fe7692, checked in by Petr Koupy <petr.koupy@…>, 14 years ago

Removed side effects from map ADTs.

  • Property mode set to 100644
File size: 4.6 KB
Line 
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
29/** @addtogroup libc
30 * @{
31 */
32
33/** @file
34 * Character string to generic type map.
35 */
36
37#ifndef LIBC_GENERIC_CHAR_MAP_H_
38#define LIBC_GENERIC_CHAR_MAP_H_
39
40#include <unistd.h>
41#include <errno.h>
42
43#include <adt/char_map.h>
44#include <adt/generic_field.h>
45
46/** Internal magic value for a&nbsp;map consistency check. */
47#define GENERIC_CHAR_MAP_MAGIC_VALUE 0x12345622
48
49/** Generic destructor function pointer. */
50#define DTOR_T(identifier) \
51 void (*identifier)(const void *)
52
53/** Character string to generic type map declaration.
54 * @param[in] name Name of the map.
55 * @param[in] type Inner object type.
56 */
57#define GENERIC_CHAR_MAP_DECLARE(name, type) \
58 GENERIC_FIELD_DECLARE(name##_items, type) \
59 \
60 typedef struct name name##_t; \
61 \
62 struct name { \
63 char_map_t names; \
64 name##_items_t values; \
65 int magic; \
66 }; \
67 \
68 int name##_add(name##_t *, const uint8_t *, const size_t, type *); \
69 int name##_count(name##_t *); \
70 void name##_destroy(name##_t *, DTOR_T()); \
71 void name##_exclude(name##_t *, const uint8_t *, const size_t, DTOR_T()); \
72 type *name##_find(name##_t *, const uint8_t *, const size_t); \
73 int name##_initialize(name##_t *); \
74 int name##_is_valid(name##_t *);
75
76/** Character string to generic type map implementation.
77 *
78 * Should follow declaration with the same parameters.
79 *
80 * @param[in] name Name of the map.
81 * @param[in] type Inner object type.
82 *
83 */
84#define GENERIC_CHAR_MAP_IMPLEMENT(name, type) \
85 GENERIC_FIELD_IMPLEMENT(name##_items, type) \
86 \
87 int name##_add(name##_t *map, const uint8_t *name, const size_t length, \
88 type *value) \
89 { \
90 int index; \
91 if (!name##_is_valid(map)) \
92 return EINVAL; \
93 index = name##_items_add(&map->values, value); \
94 if (index < 0) \
95 return index; \
96 return char_map_add(&map->names, name, length, index); \
97 } \
98 \
99 int name##_count(name##_t *map) \
100 { \
101 return name##_is_valid(map) ? \
102 name##_items_count(&map->values) : -1; \
103 } \
104 \
105 void name##_destroy(name##_t *map, DTOR_T(dtor)) \
106 { \
107 if (name##_is_valid(map)) { \
108 char_map_destroy(&map->names); \
109 name##_items_destroy(&map->values, dtor); \
110 } \
111 } \
112 \
113 void name##_exclude(name##_t *map, const uint8_t *name, \
114 const size_t length, DTOR_T(dtor)) \
115 { \
116 if (name##_is_valid(map)) { \
117 int index; \
118 index = char_map_exclude(&map->names, name, length); \
119 if (index != CHAR_MAP_NULL) \
120 name##_items_exclude_index(&map->values, \
121 index, dtor); \
122 } \
123 } \
124 \
125 type *name##_find(name##_t *map, const uint8_t *name, \
126 const size_t length) \
127 { \
128 if (name##_is_valid(map)) { \
129 int index; \
130 index = char_map_find(&map->names, name, length); \
131 if( index != CHAR_MAP_NULL) \
132 return name##_items_get_index(&map->values, \
133 index); \
134 } \
135 return NULL; \
136 } \
137 \
138 int name##_initialize(name##_t *map) \
139 { \
140 int rc; \
141 if (!map) \
142 return EINVAL; \
143 rc = char_map_initialize(&map->names); \
144 if (rc != EOK) \
145 return rc; \
146 rc = name##_items_initialize(&map->values); \
147 if (rc != EOK) { \
148 char_map_destroy(&map->names); \
149 return rc; \
150 } \
151 map->magic = GENERIC_CHAR_MAP_MAGIC_VALUE; \
152 return EOK; \
153 } \
154 \
155 int name##_is_valid(name##_t *map) \
156 { \
157 return map && (map->magic == GENERIC_CHAR_MAP_MAGIC_VALUE); \
158 }
159
160#endif
161
162/** @}
163 */
Note: See TracBrowser for help on using the repository browser.