Synopsis
PDX_MSGT mda_TraverseEntity(long option, void *ent, MDA_TRAVERSE *func)
Purpose
Invoke a function for each field in an entity.
Description
The specified function will be called for each field in the entity. This function can be used to traverse an existing entity field by field (as in the case of a formatter) or, by specifying the MDA_MALLOC_SPACE option, it can traverse and build a new entity (as in the case of a parser). The passed in function should have the following binding:
.RS 3 PDX_MSGT func (void *ent, int count, int type, void *data, DDF_FLD *fld) .RE
The arguments to this function are as follows: .IP ent 10 Entity being traversed. This will match the entity specified in ent to the mda_TraverseEntity call. It is passed in so that memory can be allocated with mda_Malloc in the user function. .IP count Number of fields to be processed in this call. For scalar fields this will always be set to 1. For fixed, pointer to fixed, and variable arrays this will be the total number of elements in the array. For DDF_STRUCT, DDF_UNION, and DDF_COUNT fields @a count will always be 1. For DDF_ENDENT and DDF_ENDSTRUCT count will always be 0. .IP type Type of fields to be processed in this call. Note that the count argument is only applicable for certain types of fields. .IP data Location of the field in memory. If count is greater than one then this is the base address of the array. .IP fld The DDF field entry for the field be processed. The user function can use any of the ddf_GetFieldxxx functions to obtain additional information about the field (such as checking for certain attributes). .LP
This function is reentrant so the user function can check for a PTR field type and call mda_TraverseEntity to recursively traverse the entity.
The application function which is invoked should be designed to ignore unexpected field types so that new DDF data types will not require application code changes.
The field types DDF_ENDENT and DDF_ENDSTRUCT should be treated as flags. For these field types the data, and fld parameters are undefined and should not be use. The count field will always be 0 for these fields.
Pointer to fixed and variable arrays are passed as the actual array location. In order to obtain the address of the array pointer the function mda_GetTraverseAddr should be called. This will return the location of the array pointer such that the following equality is true:
.nf *(char **) mda_GetTraverseAddr() == data .fi
By obtaining the array pointer address, an application can malloc or realloc memory to the array from a function called by mda_TraverseEntity.
When a UNION field is passed, the data argument points to the union type field so that the user function can set the union type by:
.RS 3 mda_SetUnionType (data, IAP__INT); .RE COUNT fields can be set as follows:
.RS 3 *(DDF_COUNT_TYPE *) data = n; .RE
An example user function to display the values of all integer fields in an entity would be:
.nf #include "ddf_Interface.h" #include "mda_Interface.h"
PDX_MSGT print_ints (void *ent, int count, int type, void *data, DDF_FLD *fld) { int dsize, i; char *name;
dsize = ddf_GetFieldSize (fld); // Get field size if (type == DDF_INT) { name = ddf_GetFieldName(fld); // Get field name
for (i=0; i<count; i++, (char *) data += dsize) { printf ("%s - %dn", name, *(int *) data); } } return (MDA_NOERR); } .fi
Input
option
MDA_MALLOC_SPACE
Allocate memory for arrays before calling the application function.
MDA_MALLOC_SPACE2
Same as MDA_MALLOC_SPACE except if an array has already been allocated, the old memory will be freed before the new memory is allocated. This option is most useful when the entity being traversed was defaulted using mda_DefaultEntity which may allocate memory to the entity under certain conditions (see the mda_DefaultEntity man page). If this option is specified, any non-NULL array pointers are assumed to point to valid memory (this will be the case if the entity was defaulted with mda_DefaultEntity).
MDA_REALLOC_SPACE
Same as MDA_MALLOC_SPACE2 except that if an array has already been allocated, it will be reallocated.
ent
Entity to be traversed
func
Function to be invoked for each field
Return
MDA error code