xref: /titanic_52/usr/src/lib/libtnf/struct.c (revision 18c2aff776a775d34a4c9893a4c72e0434d68e36)
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 
34 static struct slotinfo *get_slotinfo(tnf_datum_t);
35 static struct slot *	get_slot_named(struct slotinfo *, char *);
36 static struct slot *	get_slot_indexed(struct slotinfo *, unsigned);
37 static tnf_datum_t	get_slot(tnf_datum_t, struct slot *);
38 
39 /*
40  *
41  */
42 
43 void
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 
61 static struct slotinfo *
62 get_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 
76 static struct slot *
77 get_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 
88 static struct slot *
89 get_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 
102 static tnf_datum_t
103 get_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 
130 unsigned
131 tnf_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 
145 unsigned
146 tnf_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 
168 char *
169 tnf_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 
190 tnf_datum_t
191 tnf_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 
208 tnf_datum_t
209 tnf_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