static struct taginfo * /* ARGSUSED */ init_abstract_info(TNF *tnf, tnf_ref32_t *tag, struct taginfo *info) { if (INFO_SCALAR(info) || INFO_DERIVED(info) || INFO_STRUCT(info) || INFO_ARRAY(info)) _tnf_error(tnf, TNF_ERR_INTERNAL); if (info->size == (size_t)-1) _tnf_error(tnf, TNF_ERR_BADTNF); return (info); }
static struct taginfo * init_struct_info(TNF *tnf, tnf_ref32_t *tag, struct taginfo *info) { if ((!INFO_STRUCT(info)) || (INFO_DERIVED(info) || INFO_ARRAY(info) || INFO_SCALAR(info))) _tnf_error(tnf, TNF_ERR_INTERNAL); if (info->size == (size_t)-1) _tnf_error(tnf, TNF_ERR_BADTNF); /* Get slot information */ init_slots(tnf, tag, info); return (info); }
static struct taginfo * /* ARGSUSED */ init_scalar_info(TNF *tnf, tnf_ref32_t *tag, struct taginfo *info) { if ((!INFO_SCALAR(info)) || (INFO_DERIVED(info) || INFO_ARRAY(info) || INFO_STRUCT(info))) _tnf_error(tnf, TNF_ERR_INTERNAL); if (info->size == (size_t)-1) _tnf_error(tnf, TNF_ERR_BADTNF); /* XXX alignment already done */ return (info); }
static void check_scalar(tnf_datum_t datum) { CHECK_DATUM(datum); if (!INFO_SCALAR(DATUM_INFO(datum))) _tnf_error(DATUM_TNF(datum), TNF_ERR_TYPEMISMATCH); /* XXX Need to check for exact scalar type match as well */ }
void _tnf_check_record(tnf_datum_t datum) { CHECK_DATUM(datum); /* All records must be tagged */ if (!INFO_TAGGED(DATUM_INFO(datum))) _tnf_error(DATUM_TNF(datum), TNF_ERR_TYPEMISMATCH); }
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); }
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 taginfo * init_derived_info(TNF *tnf, tnf_ref32_t *tag, struct taginfo *info) { tnf_ref32_t *base_tag; if (!INFO_DERIVED(info)) _tnf_error(tnf, TNF_ERR_INTERNAL); /* Ensure ultimate base information is available */ base_tag = _tnf_get_base_tag(tnf, tag); info->base = _tnf_get_info(tnf, base_tag); return (info); }
static struct taginfo * init_array_info(TNF *tnf, tnf_ref32_t *tag, struct taginfo *info) { tnf_ref32_t *elt_tag; int defeat; if ((!INFO_ARRAY(info)) || (INFO_DERIVED(info) || INFO_STRUCT(info) || INFO_SCALAR(info))) _tnf_error(tnf, TNF_ERR_INTERNAL); /* XXX special-case abstract array tag */ defeat = (strcmp(info->name, TNF_N_ARRAY) == 0); /* Require all arrays to be self-sized records */ if (!(INFO_TAGGED(info) && (info->size == (size_t)-1))) if (!defeat) _tnf_error(tnf, TNF_ERR_BADTNF); /* Store array header size */ info->hdrsize = _tnf_get_header_size(tnf, tag); /* XXX Temporary sanity check */ if (info->hdrsize != sizeof (struct tnf_array_hdr)) if (!defeat) _tnf_error(tnf, TNF_ERR_BADTNF); /* Get slot information */ init_slots(tnf, tag, info); /* Get info for element type */ elt_tag = (tnf_ref32_t *)_tnf_get_slot_typed(tnf, tag, /* LINTED pointer cast may result in improper alignment */ TNF_N_ELEMENT_TYPE); /* XXX tnf_array has element_type == NULL */ info->base = elt_tag ? _tnf_get_info(tnf, elt_tag): NULL; return (info); }
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); }
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)); }
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); }
static void init_slots(TNF *tnf, tnf_ref32_t *tag, struct taginfo *info) { tnf_ref32_t *slot_types, *slot_names; tnf_ref32_t *types, *names; unsigned count, i, offset; struct slotinfo *slotinfo; slot_types = (tnf_ref32_t *) /* LINTED pointer cast may result in improper alignment */ _tnf_get_slot_typed(tnf, tag, TNF_N_SLOT_TYPES); slot_names = (tnf_ref32_t *) /* LINTED pointer cast may result in improper alignment */ _tnf_get_slot_typed(tnf, tag, TNF_N_SLOT_NAMES); /* abstract tags have no slots */ if (slot_types == TNF_NULL) return; count = _tnf_get_element_count(tnf, slot_types, sizeof (tnf_ref32_t)); /* LINTED pointer cast may result in improper alignment */ types = (tnf_ref32_t *)_tnf_get_elements(tnf, slot_types); names = ((slot_names == TNF_NULL) ? TNF_NULL : /* LINTED pointer cast may result in improper alignment */ (tnf_ref32_t *)_tnf_get_elements(tnf, slot_names)); slotinfo = (struct slotinfo *) calloc(1, sizeof (unsigned) + (count * sizeof (struct slot))); if (slotinfo == (struct slotinfo *)NULL) _tnf_error(tnf, TNF_ERR_ALLOCFAIL); slotinfo->slot_count = count; offset = 0; for (i = 0; i < count; i++) { tnf_ref32_t *type_elt, *name_elt; struct taginfo *elt_info; size_t ref_size, align; /* XXX No checks here for missing tags */ type_elt = _GET_REF32(tnf, &types[i]); name_elt = names ? _GET_REF32(tnf, &names[i]) : TNF_NULL; /* Resolve slot tag into taginfo */ elt_info = _tnf_get_info(tnf, type_elt); slotinfo->slots[i].slot_type = elt_info; slotinfo->slots[i].slot_name = ((name_elt != TNF_NULL) ? _tnf_get_chars(tnf, name_elt) : _tnf_get_name(tnf, type_elt)); /* Get cached reference size */ ref_size = INFO_REF_SIZE(elt_info); /* Get cached alignment */ align = INFO_ALIGN(elt_info); /* XXX */ /* Adjust offset to account for alignment, if needed */ offset = ALIGN(offset, align); slotinfo->slots[i].slot_offset = offset; /* Bump offset by reference size */ offset += ref_size; } info->slotinfo = slotinfo; }