source: mainline/uspace/lib/c/include/adt/generic_char_map.h@ 9ee9d5d5

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9ee9d5d5 was 736a330, checked in by Jakub Jermar <jakub@…>, 15 years ago

Get rid of the ERROR_CODE madness in generic char map.

  • 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/** Character string to generic type map declaration.
50 * @param[in] name Name of the map.
51 * @param[in] type Inner object type.
52 */
53#define GENERIC_CHAR_MAP_DECLARE(name, type) \
54 GENERIC_FIELD_DECLARE(name##_items, type) \
55 \
56 typedef struct name name##_t; \
57 typedef name##_t *name##_ref; \
58 \
59 struct name { \
60 char_map_t names; \
61 name##_items_t values; \
62 int magic; \
63 }; \
64 \
65 int name##_add(name##_ref, const char *, const size_t, type *); \
66 int name##_count(name##_ref); \
67 void name##_destroy(name##_ref); \
68 void name##_exclude(name##_ref, const char *, const size_t); \
69 type *name##_find(name##_ref, const char *, const size_t); \
70 int name##_initialize(name##_ref); \
71 int name##_is_valid(name##_ref);
72
73/** Character string to generic type map implementation.
74 *
75 * Should follow declaration with the same parameters.
76 *
77 * @param[in] name Name of the map.
78 * @param[in] type Inner object type.
79 */
80#define GENERIC_CHAR_MAP_IMPLEMENT(name, type) \
81 GENERIC_FIELD_IMPLEMENT(name##_items, type) \
82 \
83 int name##_add(name##_ref map, const char *name, const size_t length, \
84 type *value) \
85 { \
86 int rc; \
87 int index; \
88 if (!name##_is_valid(map)) \
89 return EINVAL; \
90 index = name##_items_add(&map->values, value); \
91 if (index < 0) \
92 return index; \
93 rc = char_map_add(&map->names, name, length, index); \
94 if (rc != EOK) { \
95 name##_items_exclude_index(&map->values, index); \
96 return rc; \
97 } \
98 return EOK; \
99 } \
100 \
101 int name##_count(name##_ref map) \
102 { \
103 return name##_is_valid(map) ? \
104 name##_items_count(&map->values) : -1; \
105 } \
106 \
107 void name##_destroy(name##_ref map) \
108 { \
109 if (name##_is_valid(map)) { \
110 char_map_destroy(&map->names); \
111 name##_items_destroy(&map->values); \
112 } \
113 } \
114 \
115 void name##_exclude(name##_ref map, const char *name, \
116 const size_t length) \
117 { \
118 if (name##_is_valid(map)) { \
119 int index; \
120 index = char_map_exclude(&map->names, name, length); \
121 if (index != CHAR_MAP_NULL) \
122 name##_items_exclude_index(&map->values, \
123 index); \
124 } \
125 } \
126 \
127 type *name##_find(name##_ref map, const char *name, \
128 const size_t length) \
129 { \
130 if (name##_is_valid(map)) { \
131 int index; \
132 index = char_map_find(&map->names, name, length); \
133 if( index != CHAR_MAP_NULL) \
134 return name##_items_get_index(&map->values, \
135 index); \
136 } \
137 return NULL; \
138 } \
139 \
140 int name##_initialize(name##_ref map) \
141 { \
142 int rc; \
143 if (!map) \
144 return EINVAL; \
145 rc = char_map_initialize(&map->names); \
146 if (rc != EOK) \
147 return rc; \
148 rc = name##_items_initialize(&map->values); \
149 if (rc != EOK) { \
150 char_map_destroy(&map->names); \
151 return rc; \
152 } \
153 map->magic = GENERIC_CHAR_MAP_MAGIC_VALUE; \
154 return EOK; \
155 } \
156 \
157 int name##_is_valid(name##_ref map) \
158 { \
159 return map && (map->magic == GENERIC_CHAR_MAP_MAGIC_VALUE); \
160 }
161
162#endif
163
164/** @}
165 */
Note: See TracBrowser for help on using the repository browser.