4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 #pragma ident "%Z%%M% %I% %E% SMI"
35 * MODULE: dat_dictionary.c
37 * PURPOSE: dictionary data structure
39 * $Id: dat_dictionary.c,v 1.11 2003/08/05 19:01:48 jlentini Exp $
43 #include "dat_dictionary.h"
52 typedef struct DAT_DICTIONARY_NODE
54 DAT_PROVIDER_INFO key
;
55 DAT_DICTIONARY_DATA data
;
56 struct DAT_DICTIONARY_NODE
*prev
;
57 struct DAT_DICTIONARY_NODE
*next
;
58 } DAT_DICTIONARY_NODE
;
63 DAT_DICTIONARY_NODE
*head
;
64 DAT_DICTIONARY_NODE
*tail
;
70 * Function Declarations
75 dat_dictionary_key_dup(
76 const DAT_PROVIDER_INFO
*old_key
,
77 DAT_PROVIDER_INFO
*new_key
);
80 dat_dictionary_key_is_equal(
81 const DAT_PROVIDER_INFO
*key_a
,
82 const DAT_PROVIDER_INFO
*key_b
);
93 * Function: dat_dictionary_create
97 dat_dictionary_create(
98 OUT DAT_DICTIONARY
**pp_dictionary
)
100 DAT_DICTIONARY
*p_dictionary
;
103 dat_os_assert(NULL
!= pp_dictionary
);
105 status
= DAT_SUCCESS
;
107 /* create the dictionary */
108 p_dictionary
= dat_os_alloc(sizeof (DAT_DICTIONARY
));
109 if (NULL
== p_dictionary
) {
110 status
= DAT_ERROR(DAT_INSUFFICIENT_RESOURCES
,
111 DAT_RESOURCE_MEMORY
);
115 (void) dat_os_memset(p_dictionary
, '\0', sizeof (DAT_DICTIONARY
));
117 /* create the head node */
118 p_dictionary
->head
= dat_os_alloc(sizeof (DAT_DICTIONARY_NODE
));
119 if (NULL
== p_dictionary
->head
) {
120 status
= DAT_ERROR(DAT_INSUFFICIENT_RESOURCES
,
121 DAT_RESOURCE_MEMORY
);
125 (void) dat_os_memset(p_dictionary
->head
, '\0',
126 sizeof (DAT_DICTIONARY_NODE
));
128 /* create the tail node */
129 p_dictionary
->tail
= dat_os_alloc(sizeof (DAT_DICTIONARY_NODE
));
130 if (NULL
== p_dictionary
->tail
) {
131 status
= DAT_ERROR(DAT_INSUFFICIENT_RESOURCES
,
132 DAT_RESOURCE_MEMORY
);
136 (void) dat_os_memset(p_dictionary
->tail
, '\0',
137 sizeof (DAT_DICTIONARY_NODE
));
139 p_dictionary
->head
->next
= p_dictionary
->tail
;
140 p_dictionary
->tail
->prev
= p_dictionary
->head
;
142 *pp_dictionary
= p_dictionary
;
145 if (DAT_SUCCESS
!= status
) {
146 if (NULL
!= p_dictionary
) {
147 dat_os_free(p_dictionary
, sizeof (DAT_DICTIONARY
));
149 if (NULL
!= p_dictionary
->head
) {
150 dat_os_free(p_dictionary
->head
,
151 sizeof (DAT_DICTIONARY_NODE
));
154 if (NULL
!= p_dictionary
->tail
) {
155 dat_os_free(p_dictionary
->tail
,
156 sizeof (DAT_DICTIONARY_NODE
));
166 * Function: dat_dictionary_destroy
170 dat_dictionary_destroy(
171 IN DAT_DICTIONARY
*p_dictionary
)
173 DAT_DICTIONARY_NODE
*cur_node
;
175 dat_os_assert(NULL
!= p_dictionary
);
177 while (NULL
!= p_dictionary
->head
) {
178 cur_node
= p_dictionary
->head
;
179 p_dictionary
->head
= cur_node
->next
;
181 dat_os_free(cur_node
, sizeof (DAT_DICTIONARY_NODE
));
184 dat_os_free(p_dictionary
, sizeof (DAT_DICTIONARY
));
186 return (DAT_SUCCESS
);
191 * Function: dat_dictionary_size
196 IN DAT_DICTIONARY
*p_dictionary
,
197 OUT DAT_COUNT
*p_size
)
199 dat_os_assert(NULL
!= p_dictionary
);
200 dat_os_assert(NULL
!= p_size
);
202 *p_size
= p_dictionary
->size
;
204 return (DAT_SUCCESS
);
209 * Function: dat_dictionary_entry_create
213 dat_dictionary_entry_create(
214 OUT DAT_DICTIONARY_ENTRY
*p_entry
)
216 DAT_DICTIONARY_NODE
*node
;
217 DAT_RETURN dat_status
;
219 dat_os_assert(NULL
!= p_entry
);
221 dat_status
= DAT_SUCCESS
;
223 node
= dat_os_alloc(sizeof (DAT_DICTIONARY_NODE
));
225 dat_status
= DAT_ERROR(DAT_INSUFFICIENT_RESOURCES
,
226 DAT_RESOURCE_MEMORY
);
238 * Function: dat_dictionary_entry_destroy
242 dat_dictionary_entry_destroy(
243 OUT DAT_DICTIONARY_ENTRY entry
)
245 dat_os_free(entry
, sizeof (DAT_DICTIONARY_NODE
));
246 return (DAT_SUCCESS
);
251 * Function: dat_dictionary_insert
255 dat_dictionary_insert(
256 IN DAT_DICTIONARY
*p_dictionary
,
257 IN DAT_DICTIONARY_ENTRY entry
,
258 IN
const DAT_PROVIDER_INFO
*key
,
259 IN DAT_DICTIONARY_DATA data
)
261 DAT_RETURN dat_status
;
262 DAT_DICTIONARY_NODE
*cur_node
, *prev_node
, *next_node
;
264 dat_os_assert(NULL
!= p_dictionary
);
265 dat_os_assert(NULL
!= entry
);
269 if (DAT_SUCCESS
== dat_dictionary_search(p_dictionary
, key
, NULL
)) {
270 dat_status
= DAT_ERROR(DAT_PROVIDER_ALREADY_REGISTERED
, 0);
274 dat_status
= dat_dictionary_key_dup(key
, &cur_node
->key
);
275 if (DAT_SUCCESS
!= dat_status
) {
279 /* insert node at end of list to preserve registration order */
280 prev_node
= p_dictionary
->tail
->prev
;
281 next_node
= p_dictionary
->tail
;
283 cur_node
->data
= data
;
284 cur_node
->next
= next_node
;
285 cur_node
->prev
= prev_node
;
287 prev_node
->next
= cur_node
;
288 next_node
->prev
= cur_node
;
290 p_dictionary
->size
++;
298 * Function: dat_dictionary_search
302 dat_dictionary_search(
303 IN DAT_DICTIONARY
*p_dictionary
,
304 IN
const DAT_PROVIDER_INFO
*key
,
305 OUT DAT_DICTIONARY_DATA
*p_data
)
307 DAT_DICTIONARY_NODE
*cur_node
;
310 dat_os_assert(NULL
!= p_dictionary
);
312 status
= DAT_ERROR(DAT_NAME_NOT_FOUND
, 0);
314 for (cur_node
= p_dictionary
->head
->next
;
315 p_dictionary
->tail
!= cur_node
;
316 cur_node
= cur_node
->next
) {
317 if (DAT_TRUE
== dat_dictionary_key_is_equal(&cur_node
->key
,
319 if (NULL
!= p_data
) {
320 *p_data
= cur_node
->data
;
323 status
= DAT_SUCCESS
;
334 * Function: dat_dictionary_enumerate
338 dat_dictionary_enumerate(
339 IN DAT_DICTIONARY
*p_dictionary
,
340 IN DAT_DICTIONARY_DATA array
[],
341 IN DAT_COUNT array_size
)
343 DAT_DICTIONARY_NODE
*cur_node
;
347 dat_os_assert(NULL
!= p_dictionary
);
348 dat_os_assert(NULL
!= array
);
350 status
= DAT_SUCCESS
;
352 if (array_size
< p_dictionary
->size
) {
353 status
= DAT_ERROR(DAT_INSUFFICIENT_RESOURCES
, 0);
357 for (cur_node
= p_dictionary
->head
->next
, i
= 0;
358 p_dictionary
->tail
!= cur_node
;
359 cur_node
= cur_node
->next
, i
++) {
360 array
[i
] = cur_node
->data
;
369 * Function: dat_dictionary_remove
373 dat_dictionary_remove(
374 IN DAT_DICTIONARY
*p_dictionary
,
375 IN DAT_DICTIONARY_ENTRY
*p_entry
,
376 IN
const DAT_PROVIDER_INFO
*key
,
377 OUT DAT_DICTIONARY_DATA
*p_data
)
379 DAT_DICTIONARY_NODE
*cur_node
, *prev_node
, *next_node
;
382 dat_os_assert(NULL
!= p_dictionary
);
383 dat_os_assert(NULL
!= p_entry
);
385 status
= DAT_ERROR(DAT_NAME_NOT_FOUND
, 0);
387 for (cur_node
= p_dictionary
->head
->next
;
388 p_dictionary
->tail
!= cur_node
;
389 cur_node
= cur_node
->next
) {
390 if (DAT_TRUE
== dat_dictionary_key_is_equal(&cur_node
->key
,
392 if (NULL
!= p_data
) {
393 *p_data
= cur_node
->data
;
396 prev_node
= cur_node
->prev
;
397 next_node
= cur_node
->next
;
399 prev_node
->next
= next_node
;
400 next_node
->prev
= prev_node
;
404 p_dictionary
->size
--;
406 status
= DAT_SUCCESS
;
418 * Internal Function Definitions
424 * Function: dat_dictionary_key_create
428 dat_dictionary_key_dup(
429 const DAT_PROVIDER_INFO
*old_key
,
430 DAT_PROVIDER_INFO
*new_key
)
432 dat_os_assert(NULL
!= old_key
);
433 dat_os_assert(NULL
!= new_key
);
435 (void) dat_os_strncpy(new_key
->ia_name
, old_key
->ia_name
,
436 DAT_NAME_MAX_LENGTH
);
437 new_key
->dapl_version_major
= old_key
->dapl_version_major
;
438 new_key
->dapl_version_minor
= old_key
->dapl_version_minor
;
439 new_key
->is_thread_safe
= old_key
->is_thread_safe
;
441 return (DAT_SUCCESS
);
446 * Function: dat_dictionary_key_is_equal
450 dat_dictionary_key_is_equal(
451 const DAT_PROVIDER_INFO
*key_a
,
452 const DAT_PROVIDER_INFO
*key_b
)
454 if ((dat_os_strlen(key_a
->ia_name
) == dat_os_strlen(key_b
->ia_name
)) &&
455 (!dat_os_strncmp(key_a
->ia_name
, key_b
->ia_name
,
456 dat_os_strlen(key_a
->ia_name
))) &&
457 (key_a
->dapl_version_major
== key_b
->dapl_version_major
) &&
458 (key_a
->dapl_version_minor
== key_b
->dapl_version_minor
) &&
459 (key_a
->is_thread_safe
== key_b
->is_thread_safe
)) {