dmi_fields_decode_into
Synopsis
#include <opendmi/field.h>
bool dmi_fields_decode_into(
dmi_decoder_t *decoder,
const dmi_field_t *fields,
size_t length,
void *info);
bool dmi_fields_encode_from(
dmi_encoder_t *encoder,
const dmi_field_t *fields,
size_t length,
const void *info);
Description
The dmi_fields_decode_into function reads a part of a structure according to
a list of fields, the way dmi_fields_decode reads a whole structure, for
the decoding handlers which read the rest of the structure themselves: e.g. a
record or a descriptor whose layout depends on a type the structure gives,
whose length the structure gives too.
The fields, declared with DMI_FIELD and its kin, are read from the next
length bytes of the structure, from the position of decoder, into info,
a structure of the type the fields name. The decoder is then moved past the
length bytes, whatever the fields have left unread, so that the bytes a part
holds beyond the fields it is known to hold are stepped over.
The bytes of the part are the data the groups of the fields may end before,
see DMI_FIELD_GROUP. A part which ends at the beginning of a group, or in
the middle of it, leaves the fields it is too short for unset, along with the
present members of their groups, and the structure is marked neither as
partial nor as incomplete, since it is the part which is short rather than the
structure. The fields before the first group are required.
The dmi_fields_encode_from function undoes it, for the encoding handlers
which write the rest of the structure themselves, the way
dmi_fields_encode writes a whole structure: the fields are written from
info into the next length bytes of the structure, and the bytes of the
part the fields do not describe are written the way the encoder writes the
bytes the model does not hold, i.e. the ones of the source data in the
preserve mode, and zeros in the canonical one. Writing stops at the first
group the part does not hold, and, in the preserve mode, where the source data
of the part ends.
Parameters
decoder-
Decoder of the structure, see
dmi_decoder_initialize, positioned at the part. encoder-
Encoder of the structure, see
dmi_encoder_initialize, positioned at the part. fields-
Fields of the part, terminated by an empty field.
length-
Number of the bytes of the part.
info-
Structure the fields are read into, or written from.
Return value
dmi_fields_decode_into returns true if the part has been decoded, and
false if the structure holds fewer than length bytes from the position of
the decoder, if the part is too short for the required fields, or on the
errors below.
dmi_fields_encode_from returns true if the part has been encoded, and
false on the errors below.
Errors
DMI_ERROR_ARGUMENT_NULL-
Decoder or encoder, fields or structure is
nullptr. DMI_ERROR_ARGUMENT_INVALID-
A field declares a number wider than the widest one the engine reads and writes, which is eight bytes.
DMI_ERROR_STATE_INVALID-
A field cannot be written, or the fields are longer than the part (
dmi_fields_encode_from). DMI_ERROR_OUT_OF_MEMORY-
Elements of an array cannot be allocated, or buffers of the encoder cannot grow.
Example
The v2 descriptor of a USB network interface, whose length follows the device type and counts it along with itself:
static const dmi_field_t usb_v2_fields[] = {
DMI_FIELD(dmi_mgmt_nhi_usb_v2_t, vendor_id, dmi_word_t),
DMI_FIELD(dmi_mgmt_nhi_usb_v2_t, product_id, dmi_word_t),
DMI_FIELD_STRING(dmi_mgmt_nhi_usb_v2_t, serial_number),
DMI_FIELD_BINARY(dmi_mgmt_nhi_usb_v2_t, mac_address, 6),
// Device characteristics are present since DSP0270 1.3
DMI_FIELD_GROUP(),
DMI_FIELD(dmi_mgmt_nhi_usb_v2_t, characteristics, dmi_word_t),
DMI_FIELD(dmi_mgmt_nhi_usb_v2_t, credential_bootstrapping_handle, dmi_word_t),
{}
};
dmi_byte_t length = 0;
if (dmi_decoder_get(decoder, dmi_byte_t, &length) and (length >= 2))
dmi_fields_decode_into(decoder, usb_v2_fields, length - 2, &nhi->usb_v2);