Sequences of Structs

The generated OOP artifacts can be generated in such a way to take advantage of parent/child class objects.

Take for example a "KeyID" identifier pattern, made up of two c32 (fixed length fields) and two u4 (unsigned int).

  • KeyID: u4c32c32u4 (Flags, KeyName, KeyGroup, KeySpec)

  • A KeyID.java class has four members,

    • int flags;

    • byte [] KeyName = new byte[32];

    • byte [] KeyGroup = new byte[32];

    • int spec;

With the above, it becomes possible to generate structs of structs, ie with patterns like `u1v2` where the u1 encodes a '3' for example, and the v2 encodes three separate, serialized, KeyID structs.

Longer term, it should be possible to provide a pattern methodology that accepts pattern identifiers within the pattern like `u2s2u4*:KeyID`. The compiler would then generate the `u2v2u4*` suitable for the module's top-level sub-function `cmd` struct, and then include the necessary "stacked"  cmds_scanf() calls to first parse `cmd`, then to parse the `v2` into a keyid struct.

On serialization, a "KeySet" object would first compute the sizes of each KeyID, and then arrive at a final serialization length for itself, including its own requirements and structure. For each KeyID in the array, it would:

  1. Capture the serialized length (Added to a running total),

  2. Add 4 bytes to the running total,

  3. Create a TL buffer with the length of the child object, and then the serialized child object, which it would append to the running byte buffer.


The above results in a "vN" like "unsigned int l_keys; unsigned char * p_keys".  The [lp]_keys values could then be passed to common internal functions that treat it as a standardized forward-scannable list:

[source,text]

...

struct {

unsigned int cKeyID;

unsigned int cKeyIDBfrLen;

unsigned char *cKeyIDBfr;

unsigned int flags;

unsigned int l_data;

unsigned char *p_data;

} cmd;

struct { // KeyID

unsigned int flags;

unsigned char *KeyName;

unsigned char *KeyGroup;

unsigned int spec;

} keyid;

struct keyid * p_keyid;

// parse command data

if ((err = cmds_scanf(l_cmd, p_cmd, "u1v2u4*", sizeof(cmd), &cmd)) != 0)

goto cleanup;

unsigned LIST * list = // prepare list struct

sdki_list_first(cmd.cKeyIDBfrLen, cmd.cKeyIDBfr);

while (!err && list)) {

struct { // KeyID

unsigned int flags;

unsigned char keyName[32];

unsigned char keyGroup[32];

unsigned int spec;

} keyid;

// parse command data

if ((err = cmds_scanf(list->length, list->data, "u4c32c32u4",

sizeof(keyid), &keyid)) != 0)

goto cleanup;

if (!err) {

// . . . process the first item

err = sdki_list_next(list); // advances data to point at next field

}

}

...