1/*
2 * CDDL HEADER START
3 *
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
7 * with the License.
8 *
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.
13 *
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]
19 *
20 * CDDL HEADER END
21 */
22/*
23 *	Copyright (c) 1994, by Sun Microsytems, Inc.
24 */
25
26#pragma	ident	"%Z%%M%	%I%	%E% SMI"
27
28#include "libtnf.h"
29
30/*
31 *
32 */
33
34static struct slotinfo *get_slotinfo(tnf_datum_t);
35static struct slot *	get_slot_named(struct slotinfo *, char *);
36static struct slot *	get_slot_indexed(struct slotinfo *, unsigned);
37static tnf_datum_t	get_slot(tnf_datum_t, struct slot *);
38
39/*
40 *
41 */
42
43void
44_tnf_check_slots(tnf_datum_t datum)
45{
46	struct taginfo	*info;
47
48	CHECK_DATUM(datum);
49
50	info = DATUM_INFO(datum);
51
52	/* Must be an aggregate */
53	if (!(INFO_STRUCT(info) || INFO_ARRAY(info)))
54		_tnf_error(DATUM_TNF(datum), TNF_ERR_TYPEMISMATCH);
55}
56
57/*
58 * Helpers
59 */
60
61static struct slotinfo *
62get_slotinfo(tnf_datum_t datum)
63{
64	struct taginfo	*info, *base_info;
65
66	info 		= DATUM_INFO(datum);
67	base_info	= INFO_DERIVED(info)? info->base: info;
68
69	/* XXX base must not be a scalar tag */
70	if (INFO_SCALAR(base_info))
71		_tnf_error(DATUM_TNF(datum), TNF_ERR_BADTNF);
72
73	return (base_info->slotinfo);
74}
75
76static struct slot *
77get_slot_indexed(struct slotinfo *slotinfo, unsigned index)
78{
79	unsigned 	count;
80
81	count 		= slotinfo->slot_count;
82	if (index >= count)
83		return (NULL);
84	else
85		return (&slotinfo->slots[index]);
86}
87
88static struct slot *
89get_slot_named(struct slotinfo *slotinfo, char *name)
90{
91	unsigned 	count, i;
92
93	count 		= slotinfo->slot_count;
94
95	for (i = 0; i < count; i++)
96		if (strcmp(name, slotinfo->slots[i].slot_name) == 0)
97			return (&slotinfo->slots[i]);
98
99	return (NULL);
100}
101
102static tnf_datum_t
103get_slot(tnf_datum_t datum, struct slot *slot)
104{
105	if (slot == NULL) {
106		_tnf_error(DATUM_TNF(datum), TNF_ERR_BADSLOT); /* XXX */
107		return (TNF_DATUM_NULL);
108
109	} else if (INFO_TAGGED(slot->slot_type)) {
110		TNF		*tnf;
111		tnf_ref32_t	*rec;
112
113		tnf = DATUM_TNF(datum);
114		/* LINTED pointer cast may result in improper alignment */
115		rec = _GET_REF32(tnf, (tnf_ref32_t *)
116			(DATUM_VAL(datum) + slot->slot_offset));
117		/* NULL slots are allowed */
118		return ((rec == TNF_NULL)? TNF_DATUM_NULL :
119			RECORD_DATUM(tnf, rec));
120
121	} else			/* inline */
122		return DATUM(slot->slot_type,
123			DATUM_VAL(datum) + slot->slot_offset);
124}
125
126/*
127 *
128 */
129
130unsigned
131tnf_get_slot_count(tnf_datum_t datum)
132{
133	struct slotinfo	*slotinfo;
134
135	CHECK_SLOTS(datum);
136
137	slotinfo = get_slotinfo(datum);
138	return (slotinfo->slot_count);
139}
140
141/*
142 *
143 */
144
145unsigned
146tnf_get_slot_index(tnf_datum_t datum, char *name)
147{
148	struct slotinfo	*slotinfo;
149	struct slot	*slot;
150
151	CHECK_SLOTS(datum);
152
153	slotinfo = get_slotinfo(datum);
154	slot	 = get_slot_named(slotinfo, name);
155
156	if (slot == NULL) {
157		_tnf_error(DATUM_TNF(datum), TNF_ERR_BADSLOT); /* XXX */
158		return (((unsigned)-1));
159	} else
160		return (((char *)slot - (char *)&slotinfo->slots[0])
161			/ sizeof (struct slot));
162}
163
164/*
165 *
166 */
167
168char *
169tnf_get_slot_name(tnf_datum_t datum, unsigned index)
170{
171	struct slotinfo	*slotinfo;
172	struct slot	*slot;
173
174	CHECK_SLOTS(datum);
175
176	slotinfo 	= get_slotinfo(datum);
177	slot		= get_slot_indexed(slotinfo, index);
178
179	if (slot == NULL) {
180		_tnf_error(DATUM_TNF(datum), TNF_ERR_BADSLOT); /* XXX */
181		return ((char *)NULL);
182	} else
183		return (slot->slot_name);
184}
185
186/*
187 *
188 */
189
190tnf_datum_t
191tnf_get_slot_named(tnf_datum_t datum, char *name)
192{
193	struct slotinfo	*slotinfo;
194	struct slot	*slot;
195
196	CHECK_SLOTS(datum);
197
198	slotinfo 	= get_slotinfo(datum);
199	slot		= get_slot_named(slotinfo, name);
200
201	return (get_slot(datum, slot));
202}
203
204/*
205 *
206 */
207
208tnf_datum_t
209tnf_get_slot_indexed(tnf_datum_t datum, unsigned index)
210{
211	struct slotinfo	*slotinfo;
212	struct slot	*slot;
213
214	CHECK_SLOTS(datum);
215
216	slotinfo 	= get_slotinfo(datum);
217	slot		= get_slot_indexed(slotinfo, index);
218
219	return (get_slot(datum, slot));
220}
221