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; }