Files
Arquivotheca.Solaris-2.5/lib/libtnf/array.c
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

185 lines
3.6 KiB
C
Executable File

/*
* Copyright (c) 1994, by Sun Microsytems, Inc.
*/
#pragma ident "@(#)array.c 1.11 94/10/04 SMI"
#include "libtnf.h"
/*
* XXX This module assumes that all arrays are self-sized records.
*/
/*
*
*/
static struct taginfo * get_array_info(
tnf_datum_t,
struct taginfo **base,
struct taginfo **elt,
struct taginfo **elt_base);
/*
* XXX Assumes arrays are (self-sized) records
*/
void
_tnf_check_array(tnf_datum_t datum)
{
struct taginfo *info;
CHECK_RECORD(datum); /* XXX */
info = DATUM_INFO(datum);
if (!INFO_ARRAY(info))
_tnf_error(DATUM_TNF(datum), TNF_ERR_TYPEMISMATCH);
}
/*
* Helper
*/
static struct taginfo *
get_array_info(
tnf_datum_t datum,
struct taginfo **basep,
struct taginfo **eltp,
struct taginfo **elt_basep)
{
struct taginfo *info, *base, *elt, *elt_base;
info = DATUM_INFO(datum);
base = INFO_DERIVED(info) ? info->base : info;
if (INFO_DERIVED(base) || (!INFO_ARRAY(base)))
_tnf_error(DATUM_TNF(datum), TNF_ERR_INTERNAL);
elt = base->base; /* XXX base slot is reused for elttype */
elt_base = INFO_DERIVED(elt) ? elt->base : elt;
*basep = base;
*eltp = elt;
*elt_basep = elt_base;
return (info);
}
/*
* Return number of elements in array
*/
unsigned
tnf_get_element_count(tnf_datum_t datum)
{
size_t hdr_size, elt_size, self_size;
struct taginfo *base, *elt, *elt_base;
CHECK_ARRAY(datum);
(void) get_array_info(datum, &base, &elt, &elt_base);
hdr_size = base->hdrsize;
elt_size = INFO_ELEMENT_SIZE(elt_base);
self_size = _tnf_get_self_size(DATUM_TNF(datum),
/* LINTED pointer cast may result in improper alignment */
DATUM_RECORD(datum));
return (((self_size - hdr_size) / elt_size));
}
/*
* Fetch indexed element
*/
tnf_datum_t
tnf_get_element(tnf_datum_t datum, unsigned index)
{
size_t hdr_size, elt_size, self_size;
struct taginfo *base, *elt, *elt_base;
unsigned count, offset;
CHECK_ARRAY(datum);
(void) get_array_info(datum, &base, &elt, &elt_base);
hdr_size = base->hdrsize;
elt_size = INFO_ELEMENT_SIZE(elt_base);
self_size = _tnf_get_self_size(DATUM_TNF(datum),
/* LINTED pointer cast may result in improper alignment */
DATUM_RECORD(datum));
count = (self_size - hdr_size) / elt_size;
if (index >= count)
_tnf_error(DATUM_TNF(datum), TNF_ERR_BADINDEX);
offset = hdr_size + (index * elt_size);
/*
* If tagged, use the tag to construct datum
*/
if (INFO_TAGGED(elt)) {
TNF *tnf;
tnf_ref32_t *rec;
tnf = DATUM_TNF(datum);
/* LINTED pointer cast may result in improper alignment */
rec = _GET_REF32(tnf, (tnf_ref32_t *)
(DATUM_VAL(datum) + offset));
/* NULL elements are allowed */
return ((rec == TNF_NULL)? TNF_DATUM_NULL :
RECORD_DATUM(tnf, rec));
} else
return (DATUM(elt, DATUM_VAL(datum) + offset));
}
/*
* Return element type of array
*/
tnf_datum_t
tnf_get_element_type(tnf_datum_t datum)
{
struct taginfo *base, *elt, *elt_base;
CHECK_ARRAY(datum);
(void) get_array_info(datum, &base, &elt, &elt_base);
return (RECORD_DATUM(DATUM_TNF(datum), elt->tag));
}
/*
* Return a char pointer for string record
*/
char *
tnf_get_chars(tnf_datum_t datum)
{
struct taginfo *info, *base, *elt, *elt_base;
CHECK_ARRAY(datum);
info = get_array_info(datum, &base, &elt, &elt_base);
if (!INFO_STRING(info))
_tnf_error(DATUM_TNF(datum), TNF_ERR_TYPEMISMATCH);
return (DATUM_VAL(datum) + base->hdrsize);
}
/*
* Return the base pointer of array
*/
caddr_t
tnf_get_elements(tnf_datum_t datum)
{
struct taginfo *base, *elt, *elt_base;
CHECK_ARRAY(datum);
(void) get_array_info(datum, &base, &elt, &elt_base);
return ((caddr_t)(DATUM_VAL(datum) + base->hdrsize));
}