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) 1994, by Sun Microsytems, Inc.
26 #pragma ident "%Z%%M% %I% %E% SMI"
31 * XXX This module assumes that all arrays are self-sized records.
38 static struct taginfo
* get_array_info(
40 struct taginfo
**base
,
42 struct taginfo
**elt_base
);
45 * XXX Assumes arrays are (self-sized) records
49 _tnf_check_array(tnf_datum_t datum
)
53 CHECK_RECORD(datum
); /* XXX */
55 info
= DATUM_INFO(datum
);
57 if (!INFO_ARRAY(info
))
58 _tnf_error(DATUM_TNF(datum
), TNF_ERR_TYPEMISMATCH
);
66 static struct taginfo
*
69 struct taginfo
**basep
,
70 struct taginfo
**eltp
,
71 struct taginfo
**elt_basep
)
73 struct taginfo
*info
, *base
, *elt
, *elt_base
;
75 info
= DATUM_INFO(datum
);
76 base
= INFO_DERIVED(info
) ? info
->base
: info
;
78 if (INFO_DERIVED(base
) || (!INFO_ARRAY(base
)))
79 _tnf_error(DATUM_TNF(datum
), TNF_ERR_INTERNAL
);
81 elt
= base
->base
; /* XXX base slot is reused for elttype */
82 elt_base
= INFO_DERIVED(elt
) ? elt
->base
: elt
;
86 *elt_basep
= elt_base
;
91 * Return number of elements in array
95 tnf_get_element_count(tnf_datum_t datum
)
97 size_t hdr_size
, elt_size
, self_size
;
98 struct taginfo
*base
, *elt
, *elt_base
;
102 (void) get_array_info(datum
, &base
, &elt
, &elt_base
);
103 hdr_size
= base
->hdrsize
;
104 elt_size
= INFO_ELEMENT_SIZE(elt_base
);
105 self_size
= _tnf_get_self_size(DATUM_TNF(datum
),
106 /* LINTED pointer cast may result in improper alignment */
107 DATUM_RECORD(datum
));
108 return (((self_size
- hdr_size
) / elt_size
));
112 * Fetch indexed element
116 tnf_get_element(tnf_datum_t datum
, unsigned index
)
118 size_t hdr_size
, elt_size
, self_size
;
119 struct taginfo
*base
, *elt
, *elt_base
;
120 unsigned count
, offset
;
124 (void) get_array_info(datum
, &base
, &elt
, &elt_base
);
125 hdr_size
= base
->hdrsize
;
126 elt_size
= INFO_ELEMENT_SIZE(elt_base
);
127 self_size
= _tnf_get_self_size(DATUM_TNF(datum
),
128 /* LINTED pointer cast may result in improper alignment */
129 DATUM_RECORD(datum
));
131 count
= (self_size
- hdr_size
) / elt_size
;
134 _tnf_error(DATUM_TNF(datum
), TNF_ERR_BADINDEX
);
136 offset
= hdr_size
+ (index
* elt_size
);
139 * If tagged, use the tag to construct datum
141 if (INFO_TAGGED(elt
)) {
145 tnf
= DATUM_TNF(datum
);
146 /* LINTED pointer cast may result in improper alignment */
147 rec
= _GET_REF32(tnf
, (tnf_ref32_t
*)
148 (DATUM_VAL(datum
) + offset
));
149 /* NULL elements are allowed */
150 return ((rec
== TNF_NULL
)? TNF_DATUM_NULL
:
151 RECORD_DATUM(tnf
, rec
));
153 return (DATUM(elt
, DATUM_VAL(datum
) + offset
));
157 * Return element type of array
161 tnf_get_element_type(tnf_datum_t datum
)
163 struct taginfo
*base
, *elt
, *elt_base
;
167 (void) get_array_info(datum
, &base
, &elt
, &elt_base
);
169 return (RECORD_DATUM(DATUM_TNF(datum
), elt
->tag
));
173 * Return a char pointer for string record
177 tnf_get_chars(tnf_datum_t datum
)
179 struct taginfo
*info
, *base
, *elt
, *elt_base
;
183 info
= get_array_info(datum
, &base
, &elt
, &elt_base
);
185 if (!INFO_STRING(info
))
186 _tnf_error(DATUM_TNF(datum
), TNF_ERR_TYPEMISMATCH
);
188 return (DATUM_VAL(datum
) + base
->hdrsize
);
192 * Return the base pointer of array
196 tnf_get_elements(tnf_datum_t datum
)
198 struct taginfo
*base
, *elt
, *elt_base
;
202 (void) get_array_info(datum
, &base
, &elt
, &elt_base
);
204 return ((caddr_t
)(DATUM_VAL(datum
) + base
->hdrsize
));