200 lines
3.5 KiB
C
Executable File
200 lines
3.5 KiB
C
Executable File
/*
|
|
* Copyright (c) 1994, by Sun Microsytems, Inc.
|
|
*/
|
|
|
|
#pragma ident "@(#)struct.c 1.10 94/10/04 SMI"
|
|
|
|
#include "libtnf.h"
|
|
|
|
/*
|
|
*
|
|
*/
|
|
|
|
static struct slotinfo *get_slotinfo(tnf_datum_t);
|
|
static struct slot * get_slot_named(struct slotinfo *, char *);
|
|
static struct slot * get_slot_indexed(struct slotinfo *, unsigned);
|
|
static tnf_datum_t get_slot(tnf_datum_t, struct slot *);
|
|
|
|
/*
|
|
*
|
|
*/
|
|
|
|
void
|
|
_tnf_check_slots(tnf_datum_t datum)
|
|
{
|
|
struct taginfo *info;
|
|
|
|
CHECK_DATUM(datum);
|
|
|
|
info = DATUM_INFO(datum);
|
|
|
|
/* Must be an aggregate */
|
|
if (!(INFO_STRUCT(info) || INFO_ARRAY(info)))
|
|
_tnf_error(DATUM_TNF(datum), TNF_ERR_TYPEMISMATCH);
|
|
}
|
|
|
|
/*
|
|
* Helpers
|
|
*/
|
|
|
|
static struct slotinfo *
|
|
get_slotinfo(tnf_datum_t datum)
|
|
{
|
|
struct taginfo *info, *base_info;
|
|
|
|
info = DATUM_INFO(datum);
|
|
base_info = INFO_DERIVED(info)? info->base: info;
|
|
|
|
/* XXX base must not be a scalar tag */
|
|
if (INFO_SCALAR(base_info))
|
|
_tnf_error(DATUM_TNF(datum), TNF_ERR_BADTNF);
|
|
|
|
return (base_info->slotinfo);
|
|
}
|
|
|
|
static struct slot *
|
|
get_slot_indexed(struct slotinfo *slotinfo, unsigned index)
|
|
{
|
|
unsigned count;
|
|
|
|
count = slotinfo->slot_count;
|
|
if (index >= count)
|
|
return (NULL);
|
|
else
|
|
return (&slotinfo->slots[index]);
|
|
}
|
|
|
|
static struct slot *
|
|
get_slot_named(struct slotinfo *slotinfo, char *name)
|
|
{
|
|
unsigned count, i;
|
|
|
|
count = slotinfo->slot_count;
|
|
|
|
for (i = 0; i < count; i++)
|
|
if (strcmp(name, slotinfo->slots[i].slot_name) == 0)
|
|
return (&slotinfo->slots[i]);
|
|
|
|
return (NULL);
|
|
}
|
|
|
|
static tnf_datum_t
|
|
get_slot(tnf_datum_t datum, struct slot *slot)
|
|
{
|
|
if (slot == NULL) {
|
|
_tnf_error(DATUM_TNF(datum), TNF_ERR_BADSLOT); /* XXX */
|
|
return (TNF_DATUM_NULL);
|
|
|
|
} else if (INFO_TAGGED(slot->slot_type)) {
|
|
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) + slot->slot_offset));
|
|
/* NULL slots are allowed */
|
|
return ((rec == TNF_NULL)? TNF_DATUM_NULL :
|
|
RECORD_DATUM(tnf, rec));
|
|
|
|
} else /* inline */
|
|
return DATUM(slot->slot_type,
|
|
DATUM_VAL(datum) + slot->slot_offset);
|
|
}
|
|
|
|
/*
|
|
*
|
|
*/
|
|
|
|
unsigned
|
|
tnf_get_slot_count(tnf_datum_t datum)
|
|
{
|
|
struct slotinfo *slotinfo;
|
|
|
|
CHECK_SLOTS(datum);
|
|
|
|
slotinfo = get_slotinfo(datum);
|
|
return (slotinfo->slot_count);
|
|
}
|
|
|
|
/*
|
|
*
|
|
*/
|
|
|
|
unsigned
|
|
tnf_get_slot_index(tnf_datum_t datum, char *name)
|
|
{
|
|
struct slotinfo *slotinfo;
|
|
struct slot *slot;
|
|
|
|
CHECK_SLOTS(datum);
|
|
|
|
slotinfo = get_slotinfo(datum);
|
|
slot = get_slot_named(slotinfo, name);
|
|
|
|
if (slot == NULL) {
|
|
_tnf_error(DATUM_TNF(datum), TNF_ERR_BADSLOT); /* XXX */
|
|
return (((unsigned)-1));
|
|
} else
|
|
return (((char *)slot - (char *)&slotinfo->slots[0])
|
|
/ sizeof (struct slot));
|
|
}
|
|
|
|
/*
|
|
*
|
|
*/
|
|
|
|
char *
|
|
tnf_get_slot_name(tnf_datum_t datum, unsigned index)
|
|
{
|
|
struct slotinfo *slotinfo;
|
|
struct slot *slot;
|
|
|
|
CHECK_SLOTS(datum);
|
|
|
|
slotinfo = get_slotinfo(datum);
|
|
slot = get_slot_indexed(slotinfo, index);
|
|
|
|
if (slot == NULL) {
|
|
_tnf_error(DATUM_TNF(datum), TNF_ERR_BADSLOT); /* XXX */
|
|
return ((char *)NULL);
|
|
} else
|
|
return (slot->slot_name);
|
|
}
|
|
|
|
/*
|
|
*
|
|
*/
|
|
|
|
tnf_datum_t
|
|
tnf_get_slot_named(tnf_datum_t datum, char *name)
|
|
{
|
|
struct slotinfo *slotinfo;
|
|
struct slot *slot;
|
|
|
|
CHECK_SLOTS(datum);
|
|
|
|
slotinfo = get_slotinfo(datum);
|
|
slot = get_slot_named(slotinfo, name);
|
|
|
|
return (get_slot(datum, slot));
|
|
}
|
|
|
|
/*
|
|
*
|
|
*/
|
|
|
|
tnf_datum_t
|
|
tnf_get_slot_indexed(tnf_datum_t datum, unsigned index)
|
|
{
|
|
struct slotinfo *slotinfo;
|
|
struct slot *slot;
|
|
|
|
CHECK_SLOTS(datum);
|
|
|
|
slotinfo = get_slotinfo(datum);
|
|
slot = get_slot_indexed(slotinfo, index);
|
|
|
|
return (get_slot(datum, slot));
|
|
}
|