4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license from the top-level
9 * OPENSOLARIS.LICENSE or <http://opensource.org/licenses/CDDL-1.0>.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each file
14 * and include the License file from the top-level OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049).
24 * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.
33 #include <sys/sysmacros.h>
34 #include "zed_strings.h"
38 avl_node_t
*iteratorp
;
41 struct zed_strings_node
{
47 typedef struct zed_strings_node zed_strings_node_t
;
50 * Compare zed_strings_node_t nodes [x1] and [x2].
51 * As required for the AVL tree, return -1 for <, 0 for ==, and +1 for >.
54 _zed_strings_node_compare(const void *x1
, const void *x2
)
63 s1
= ((const zed_strings_node_t
*) x1
)->key
;
65 s2
= ((const zed_strings_node_t
*) x2
)->key
;
79 * Return a new string container, or NULL on error.
82 zed_strings_create(void)
86 zsp
= calloc(1, sizeof (*zsp
));
90 avl_create(&zsp
->tree
, _zed_strings_node_compare
,
91 sizeof (zed_strings_node_t
), offsetof(zed_strings_node_t
, node
));
93 zsp
->iteratorp
= NULL
;
98 * Destroy the string node [np].
101 _zed_strings_node_destroy(zed_strings_node_t
*np
)
107 if (np
->key
!= np
->val
)
119 * Return a new string node for storing the string [val], or NULL on error.
120 * If [key] is specified, it will be used to index the node; otherwise,
121 * the string [val] will be used.
124 _zed_strings_node_create(const char *key
, const char *val
)
126 zed_strings_node_t
*np
;
130 np
= calloc(1, sizeof (*np
));
134 np
->val
= strdup(val
);
139 np
->key
= strdup(key
);
148 _zed_strings_node_destroy(np
);
153 * Destroy the string container [zsp] and all nodes within.
156 zed_strings_destroy(zed_strings_t
*zsp
)
159 zed_strings_node_t
*np
;
165 while ((np
= avl_destroy_nodes(&zsp
->tree
, &cookie
)))
166 _zed_strings_node_destroy(np
);
168 avl_destroy(&zsp
->tree
);
173 * Add a copy of the string [s] indexed by [key] to the container [zsp].
174 * If [key] already exists within the container [zsp], it will be replaced
175 * with the new string [s].
176 * If [key] is NULL, the string [s] will be used as the key.
177 * Return 0 on success, or -1 on error.
180 zed_strings_add(zed_strings_t
*zsp
, const char *key
, const char *s
)
182 zed_strings_node_t
*newp
, *oldp
;
191 newp
= _zed_strings_node_create(key
, s
);
195 oldp
= avl_find(&zsp
->tree
, newp
, NULL
);
197 avl_remove(&zsp
->tree
, oldp
);
198 _zed_strings_node_destroy(oldp
);
200 avl_add(&zsp
->tree
, newp
);
205 * Return the first string in container [zsp].
206 * Return NULL if there are no strings, or on error.
207 * This can be called multiple times to re-traverse [zsp].
208 * XXX: Not thread-safe.
211 zed_strings_first(zed_strings_t
*zsp
)
217 zsp
->iteratorp
= avl_first(&zsp
->tree
);
221 return (((zed_strings_node_t
*) zsp
->iteratorp
)->val
);
226 * Return the next string in container [zsp].
227 * Return NULL after the last string, or on error.
228 * This must be called after zed_strings_first().
229 * XXX: Not thread-safe.
232 zed_strings_next(zed_strings_t
*zsp
)
241 zsp
->iteratorp
= AVL_NEXT(&zsp
->tree
, zsp
->iteratorp
);
245 return (((zed_strings_node_t
*)zsp
->iteratorp
)->val
);
249 * Return the number of strings in container [zsp], or -1 on error.
252 zed_strings_count(zed_strings_t
*zsp
)
258 return (avl_numnodes(&zsp
->tree
));