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
_tnf_check_slots(tnf_datum_t datum)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 *
get_slotinfo(tnf_datum_t datum)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 *
get_slot_indexed(struct slotinfo * slotinfo,unsigned index)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 *
get_slot_named(struct slotinfo * slotinfo,char * name)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
get_slot(tnf_datum_t datum,struct slot * slot)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
tnf_get_slot_count(tnf_datum_t datum)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
tnf_get_slot_index(tnf_datum_t datum,char * name)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 *
tnf_get_slot_name(tnf_datum_t datum,unsigned index)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
tnf_get_slot_named(tnf_datum_t datum,char * name)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
tnf_get_slot_indexed(tnf_datum_t datum,unsigned index)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