Skip to content

Latest commit

 

History

History
1135 lines (795 loc) · 34.3 KB

File metadata and controls

1135 lines (795 loc) · 34.3 KB

ssfgobj — Generic Object (BETA)

SSF | Codecs

BETA: This interface is still under development. The API may change in future releases.

Hierarchical generic object tree for building, modifying, and querying structured data independently of any wire format. Designed as a portable in-memory representation that can translate between JSON, UBJSON, and other encoding types.

Dependencies | Notes | Configuration | API Summary | Function Reference

Dependencies

Notes

Configuration

All options are set in ssfoptions.h.

Option Default Description
SSF_GOBJ_CONFIG_MAX_IN_DEPTH 4 Maximum nesting depth for object and array iteration and path traversal

API Summary

Definitions

Symbol Kind Description
SSFObjType_t Enum Value type held by a node; see table below
SSFGObj_t Struct One node in the generic object tree; pass by pointer to all API functions
SSFGObjPathItem_t Struct Path element supplied to the SSFGObjIterateFn_t callback; fields: gobj (SSFGObj_t *), index (int32_t, ≥ 0 for array elements)
SSFGObjIterateFn_t Typedef void (*fn)(SSFGObj_t *gobj, SSFLL_t *path) — callback passed to SSFGObjIterate(); called once per node during depth-first traversal

SSFObjType_t values:

Constant Description
SSF_OBJ_TYPE_NONE Untyped sentinel — initial state, no value assigned
SSF_OBJ_TYPE_STR Null-terminated string
SSF_OBJ_TYPE_BIN Binary byte array
SSF_OBJ_TYPE_INT Signed 64-bit integer
SSF_OBJ_TYPE_UINT Unsigned 64-bit integer
SSF_OBJ_TYPE_FLOAT Double-precision floating-point
SSF_OBJ_TYPE_BOOL Boolean
SSF_OBJ_TYPE_NULL Explicit null (e.g. JSON null)
SSF_OBJ_TYPE_OBJECT Structured object container with named children
SSF_OBJ_TYPE_ARRAY Ordered array container

Functions

Function Description
e.g. bool SSFGObjInit(gobj, maxChildren) Allocate and initialize a new node
e.g. void SSFGObjDeInit(gobj) Free a node and all its children
e.g. bool SSFGObjSetLabel(gobj, labelCStr) Set or clear the node's label
e.g. bool SSFGObjGetLabel(gobj, labelCStrOut, labelCStrOutSize) Copy the node's label into a buffer
e.g. SSFObjType_t SSFGObjGetType(gobj) Return the node's current value type
e.g. size_t SSFGObjGetSize(gobj) Return the size of the node's stored value
e.g. bool SSFGObjSetNone(gobj) Clear the node's value (set type to NONE)
e.g. bool SSFGObjSetString(gobj, valueCStr) Store a string value
e.g. bool SSFGObjGetString(gobj, valueCStrOut, valueCStrOutSize) Copy the node's string value
e.g. bool SSFGObjSetInt(gobj, value) Store a signed 64-bit integer
e.g. bool SSFGObjGetInt(gobj, valueOut) Read the node's signed 64-bit integer
e.g. bool SSFGObjSetUInt(gobj, value) Store an unsigned 64-bit integer
e.g. bool SSFGObjGetUInt(gobj, valueOut) Read the node's unsigned 64-bit integer
e.g. bool SSFGObjSetFloat(gobj, value) Store a double-precision float
e.g. bool SSFGObjGetFloat(gobj, valueOut) Read the node's double-precision float
e.g. bool SSFGObjSetBool(gobj, value) Store a boolean
e.g. bool SSFGObjGetBool(gobj, valueOut) Read the node's boolean
e.g. bool SSFGObjSetBin(gobj, value, valueLen) Store a binary byte array
e.g. bool SSFGObjGetBin(gobj, valueOut, valueSize, valueLenOutOpt) Copy the node's binary value
e.g. bool SSFGObjSetNull(gobj) Set the node's type to NULL
e.g. bool SSFGObjSetObject(gobj) Set the node's type to OBJECT container
e.g. bool SSFGObjSetArray(gobj) Set the node's type to ARRAY container
e.g. bool SSFGObjInsertChild(gobjParent, gobjChild) Append a child node to a container
e.g. bool SSFGObjRemoveChild(gobjParent, gobjChild) Remove a child node from a container
e.g. bool SSFGObjGetObjectLen(gobj, numChildrenOut) Return the number of children of an OBJECT node
e.g. bool SSFGObjGetArrayLen(gobj, numChildrenOut) Return the number of elements of an ARRAY node
e.g. bool SSFGObjFindPath(gobjRoot, path, gobjParentOut, gobjChildOut) Locate a descendant by label path
e.g. bool SSFGObjIterate(gobj, iterateCallback) Depth-first traversal of a subtree

Function Reference

bool SSFGObjInit(SSFGObj_t **gobj, uint16_t maxChildren);

Allocates and initializes a new generic object node via malloc. The node starts with type SSF_OBJ_TYPE_NONE, no label, no value, and an empty child list.

Parameter Direction Type Description
gobj out SSFGObj_t ** Receives the allocated node pointer. Must not be NULL. Must point to a NULL pointer before the call.
maxChildren in uint16_t Maximum number of direct children this node may hold. Pass 0 for leaf nodes. Pass the expected child count for container nodes — SSFGObjInsertChild() returns false for nodes initialized with 0.

Returns: true if the node was allocated and initialized; false if malloc failed.

SSFGObj_t *g = NULL;

SSFGObjInit(&g, 0u);
/* g is a leaf node with type SSF_OBJ_TYPE_NONE */
SSFGObjDeInit(&g);
/* g == NULL */

void SSFGObjDeInit(SSFGObj_t **gobj);

Frees the node and, recursively, all its children including their labels and value data. Sets *gobj to NULL on return.

Parameter Direction Type Description
gobj in-out SSFGObj_t ** Pointer to the node to free. Must not be NULL. *gobj must not be NULL.

Returns: Nothing.

SSFGObj_t *g = NULL;

SSFGObjInit(&g, 0u);
SSFGObjSetInt(g, 42);
SSFGObjDeInit(&g);
/* g == NULL; value memory freed */

bool SSFGObjSetLabel(SSFGObj_t *gobj, SSFCStrIn_t labelCStr);

Assigns a label to the node, replacing any existing one. Passing NULL for labelCStr clears the label without error.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
labelCStr in SSFCStrIn_t Null-terminated label to copy, or NULL to clear.

Returns: true if the label was set or cleared; false if malloc failed when setting.

SSFGObj_t *g = NULL;

SSFGObjInit(&g, 0u);
SSFGObjSetLabel(g, "count");
/* node label is "count" */

SSFGObjSetLabel(g, NULL);
/* label cleared */

SSFGObjDeInit(&g);

bool SSFGObjGetLabel(SSFGObj_t *gobj, SSFCStrOut_t labelCStrOut, size_t labelCStrOutSize);

Copies the node's label into labelCStrOut.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
labelCStrOut out SSFCStrOut_t Buffer to receive the null-terminated label. Must not be NULL.
labelCStrOutSize in size_t Size of labelCStrOut in bytes. Must be at least strlen(label) + 1.

Returns: true if the label was copied; false if no label is set or the buffer is too small.

SSFGObj_t *g = NULL;
char buf[16];

SSFGObjInit(&g, 0u);
SSFGObjSetLabel(g, "count");

if (SSFGObjGetLabel(g, buf, sizeof(buf)))
{
    /* buf == "count" */
}
SSFGObjDeInit(&g);

SSFObjType_t SSFGObjGetType(SSFGObj_t *gobj);

Returns the value type currently held by the node as set by the most recent SSFGObjSet* call.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.

Returns: The current SSFObjType_t of the node.

SSFGObj_t *g = NULL;

SSFGObjInit(&g, 0u);
SSFGObjGetType(g);   /* returns SSF_OBJ_TYPE_NONE */

SSFGObjSetInt(g, 7);
SSFGObjGetType(g);   /* returns SSF_OBJ_TYPE_INT */

SSFGObjDeInit(&g);

size_t SSFGObjGetSize(SSFGObj_t *gobj);

Returns the size in bytes of the value stored in the node. For STR this includes the null terminator. For container types (OBJECT, ARRAY) and valueless types (NONE, NULL) this is 0.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.

Returns: Size in bytes of the stored value, or 0 for valueless types.

SSFGObj_t *g = NULL;

SSFGObjInit(&g, 0u);
SSFGObjSetString(g, "hi");
SSFGObjGetSize(g);   /* returns 3 (strlen("hi") + 1) */

SSFGObjDeInit(&g);

bool SSFGObjSetNone(SSFGObj_t *gobj);

Sets the node's type to SSF_OBJ_TYPE_NONE and frees any existing value data. This is the initial state of every freshly allocated node.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.

Returns: true always.

SSFGObj_t *g = NULL;

SSFGObjInit(&g, 0u);
SSFGObjSetInt(g, 42);
SSFGObjSetNone(g);
SSFGObjGetType(g);   /* returns SSF_OBJ_TYPE_NONE */

SSFGObjDeInit(&g);

bool SSFGObjSetString(SSFGObj_t *gobj, SSFCStrIn_t valueCStr);

Stores a copy of valueCStr in the node. The node's type becomes SSF_OBJ_TYPE_STR.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
valueCStr in SSFCStrIn_t Null-terminated string to store. Must not be NULL.

Returns: true if the value was stored; false if malloc failed.

SSFGObj_t *g = NULL;

SSFGObjInit(&g, 0u);

if (SSFGObjSetString(g, "hello"))
{
    /* node type is SSF_OBJ_TYPE_STR, SSFGObjGetSize(g) == 6 */
}
SSFGObjDeInit(&g);

bool SSFGObjGetString(SSFGObj_t *gobj, SSFCStrOut_t valueCStrOut, size_t valueCStrOutSize);

Copies the node's string value into valueCStrOut.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
valueCStrOut out SSFCStrOut_t Buffer to receive the null-terminated string. Must not be NULL.
valueCStrOutSize in size_t Size of valueCStrOut in bytes. Must be at least strlen(value) + 1.

Returns: true if the string was copied; false if the node type is not SSF_OBJ_TYPE_STR or the buffer is too small.

SSFGObj_t *g = NULL;
char buf[16];

SSFGObjInit(&g, 0u);
SSFGObjSetString(g, "hello");

if (SSFGObjGetString(g, buf, sizeof(buf)))
{
    /* buf == "hello" */
}
SSFGObjDeInit(&g);

bool SSFGObjSetInt(SSFGObj_t *gobj, int64_t value);

Stores a signed 64-bit integer. The node's type becomes SSF_OBJ_TYPE_INT.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
value in int64_t Signed integer value to store.

Returns: true if the value was stored; false if malloc failed.

SSFGObj_t *g = NULL;

SSFGObjInit(&g, 0u);

if (SSFGObjSetInt(g, -42))
{
    /* node type is SSF_OBJ_TYPE_INT */
}
SSFGObjDeInit(&g);

bool SSFGObjGetInt(SSFGObj_t *gobj, int64_t *valueOut);

Reads the node's signed 64-bit integer value.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
valueOut out int64_t * Receives the integer value. Must not be NULL.

Returns: true if the value was read; false if the node type is not SSF_OBJ_TYPE_INT.

SSFGObj_t *g = NULL;
int64_t val;

SSFGObjInit(&g, 0u);
SSFGObjSetInt(g, -42);

if (SSFGObjGetInt(g, &val))
{
    /* val == -42 */
}
SSFGObjDeInit(&g);

bool SSFGObjSetUInt(SSFGObj_t *gobj, uint64_t value);

Stores an unsigned 64-bit integer. The node's type becomes SSF_OBJ_TYPE_UINT.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
value in uint64_t Unsigned integer value to store.

Returns: true if the value was stored; false if malloc failed.

SSFGObj_t *g = NULL;

SSFGObjInit(&g, 0u);

if (SSFGObjSetUInt(g, 100u))
{
    /* node type is SSF_OBJ_TYPE_UINT */
}
SSFGObjDeInit(&g);

bool SSFGObjGetUInt(SSFGObj_t *gobj, uint64_t *valueOut);

Reads the node's unsigned 64-bit integer value.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
valueOut out uint64_t * Receives the unsigned integer value. Must not be NULL.

Returns: true if the value was read; false if the node type is not SSF_OBJ_TYPE_UINT.

SSFGObj_t *g = NULL;
uint64_t val;

SSFGObjInit(&g, 0u);
SSFGObjSetUInt(g, 100u);

if (SSFGObjGetUInt(g, &val))
{
    /* val == 100 */
}
SSFGObjDeInit(&g);

bool SSFGObjSetFloat(SSFGObj_t *gobj, double value);

Stores a double-precision floating-point value. The node's type becomes SSF_OBJ_TYPE_FLOAT.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
value in double Double-precision float to store.

Returns: true if the value was stored; false if malloc failed.

SSFGObj_t *g = NULL;

SSFGObjInit(&g, 0u);

if (SSFGObjSetFloat(g, 3.14))
{
    /* node type is SSF_OBJ_TYPE_FLOAT */
}
SSFGObjDeInit(&g);

bool SSFGObjGetFloat(SSFGObj_t *gobj, double *valueOut);

Reads the node's double-precision float value.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
valueOut out double * Receives the float value. Must not be NULL.

Returns: true if the value was read; false if the node type is not SSF_OBJ_TYPE_FLOAT.

SSFGObj_t *g = NULL;
double val;

SSFGObjInit(&g, 0u);
SSFGObjSetFloat(g, 3.14);

if (SSFGObjGetFloat(g, &val))
{
    /* val == 3.14 */
}
SSFGObjDeInit(&g);

bool SSFGObjSetBool(SSFGObj_t *gobj, bool value);

Stores a boolean value. The node's type becomes SSF_OBJ_TYPE_BOOL.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
value in bool Boolean value to store.

Returns: true if the value was stored; false if malloc failed.

SSFGObj_t *g = NULL;

SSFGObjInit(&g, 0u);

if (SSFGObjSetBool(g, true))
{
    /* node type is SSF_OBJ_TYPE_BOOL */
}
SSFGObjDeInit(&g);

bool SSFGObjGetBool(SSFGObj_t *gobj, bool *valueOut);

Reads the node's boolean value.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
valueOut out bool * Receives the boolean value. Must not be NULL.

Returns: true if the value was read; false if the node type is not SSF_OBJ_TYPE_BOOL.

SSFGObj_t *g = NULL;
bool val;

SSFGObjInit(&g, 0u);
SSFGObjSetBool(g, true);

if (SSFGObjGetBool(g, &val))
{
    /* val == true */
}
SSFGObjDeInit(&g);

bool SSFGObjSetBin(SSFGObj_t *gobj, uint8_t *value, size_t valueLen);

Stores a copy of a binary byte array. The node's type becomes SSF_OBJ_TYPE_BIN. valueLen may be 0 to store an empty binary node.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
value in uint8_t * Pointer to the bytes to copy. Must not be NULL.
valueLen in size_t Number of bytes to copy. May be 0.

Returns: true if the value was stored; false if malloc failed.

SSFGObj_t *g = NULL;
uint8_t data[] = {0x01u, 0x02u, 0x03u};

SSFGObjInit(&g, 0u);

if (SSFGObjSetBin(g, data, sizeof(data)))
{
    /* node type is SSF_OBJ_TYPE_BIN, SSFGObjGetSize(g) == 3 */
}
SSFGObjDeInit(&g);

bool SSFGObjGetBin(SSFGObj_t *gobj, uint8_t *valueOut, size_t valueSize,
                   size_t *valueLenOutOpt);

Copies the node's binary value into valueOut.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.
valueOut out uint8_t * Buffer to receive the binary data. Must not be NULL.
valueSize in size_t Size of valueOut in bytes. Must be at least the stored data size.
valueLenOutOpt out (opt) size_t * If not NULL, receives the number of bytes copied.

Returns: true if the data was copied; false if the node type is not SSF_OBJ_TYPE_BIN or valueSize is too small.

SSFGObj_t *g = NULL;
uint8_t data[] = {0x01u, 0x02u, 0x03u};
uint8_t buf[8];
size_t len;

SSFGObjInit(&g, 0u);
SSFGObjSetBin(g, data, sizeof(data));

if (SSFGObjGetBin(g, buf, sizeof(buf), &len))
{
    /* len == 3, buf[0..2] == {0x01, 0x02, 0x03} */
}
SSFGObjDeInit(&g);

bool SSFGObjSetNull(SSFGObj_t *gobj);

Sets the node's type to SSF_OBJ_TYPE_NULL, representing an explicit null value (e.g. JSON null). Unlike SSF_OBJ_TYPE_NONE, this is a meaningful typed value.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.

Returns: true always.

SSFGObj_t *g = NULL;

SSFGObjInit(&g, 0u);
SSFGObjSetNull(g);
SSFGObjGetType(g);   /* returns SSF_OBJ_TYPE_NULL */

SSFGObjDeInit(&g);

bool SSFGObjSetObject(SSFGObj_t *gobj);

Sets the node's type to SSF_OBJ_TYPE_OBJECT, marking it as a structured named-child container (analogous to a JSON object {}). Call before SSFGObjInsertChild().

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.

Returns: true always.

SSFGObj_t *parent = NULL;

SSFGObjInit(&parent, 4u);   /* up to 4 children */
SSFGObjSetObject(parent);
SSFGObjGetType(parent);     /* returns SSF_OBJ_TYPE_OBJECT */

SSFGObjDeInit(&parent);

bool SSFGObjSetArray(SSFGObj_t *gobj);

Sets the node's type to SSF_OBJ_TYPE_ARRAY, marking it as an ordered child container (analogous to a JSON array []). Call before SSFGObjInsertChild().

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node. Must not be NULL.

Returns: true always.

SSFGObj_t *parent = NULL;

SSFGObjInit(&parent, 4u);   /* up to 4 children */
SSFGObjSetArray(parent);
SSFGObjGetType(parent);     /* returns SSF_OBJ_TYPE_ARRAY */

SSFGObjDeInit(&parent);

bool SSFGObjInsertChild(SSFGObj_t *gobjParent, SSFGObj_t *gobjChild);

Appends gobjChild to the end of gobjParent's child list. The parent must have been initialized with maxChildren > 0 and its type must be SSF_OBJ_TYPE_OBJECT or SSF_OBJ_TYPE_ARRAY. Once inserted, the child's lifetime is managed by the parent.

Parameter Direction Type Description
gobjParent in SSFGObj_t * Pointer to the parent node. Must not be NULL. Must have type SSF_OBJ_TYPE_OBJECT or SSF_OBJ_TYPE_ARRAY.
gobjChild in SSFGObj_t * Pointer to the child node to insert. Must not be NULL.

Returns: true if the child was inserted; false if the parent's child list is full or was never initialized (maxChildren = 0).

SSFGObj_t *parent = NULL;
SSFGObj_t *child = NULL;

SSFGObjInit(&parent, 2u);   /* capacity for 2 children */
SSFGObjSetObject(parent);

SSFGObjInit(&child, 0u);
SSFGObjSetLabel(child, "count");
SSFGObjSetInt(child, 42);

if (SSFGObjInsertChild(parent, child))
{
    /* child is now owned by parent */
}
SSFGObjDeInit(&parent);     /* frees parent and child */

bool SSFGObjRemoveChild(SSFGObj_t *gobjParent, SSFGObj_t *gobjChild);

Removes gobjChild from gobjParent's child list. After removal the caller owns the child and must either re-insert it or free it with SSFGObjDeInit().

Parameter Direction Type Description
gobjParent in SSFGObj_t * Pointer to the parent node. Must not be NULL. Must have type SSF_OBJ_TYPE_OBJECT or SSF_OBJ_TYPE_ARRAY.
gobjChild in SSFGObj_t * Pointer to the child to remove. Must not be NULL.

Returns: true if the child was found and removed; false otherwise.

SSFGObj_t *parent = NULL;
SSFGObj_t *child = NULL;

SSFGObjInit(&parent, 2u);
SSFGObjSetObject(parent);
SSFGObjInit(&child, 0u);
SSFGObjSetInt(child, 1);
SSFGObjInsertChild(parent, child);

if (SSFGObjRemoveChild(parent, child))
{
    /* child removed; caller now owns it */
    SSFGObjDeInit(&child);
}
SSFGObjDeInit(&parent);

bool SSFGObjGetObjectLen(SSFGObj_t *gobj, uint32_t *numChildren);

Returns the number of children currently attached to an OBJECT node. The call fails if gobj is not of type SSF_OBJ_TYPE_OBJECT; in particular, an ARRAY node is rejected. A zero-capacity OBJECT (one initialized with maxChildren = 0 and then set to OBJECT) is valid and reports 0.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node whose child count is requested. Must not be NULL.
numChildren out uint32_t * Receives the number of children on success. Left unchanged on failure. Must not be NULL.

Returns: true if gobj is an OBJECT and *numChildren has been written with the child count; false if gobj is any other type. On failure *numChildren is left unchanged.

SSFGObj_t *obj = NULL;
SSFGObj_t *child = NULL;
uint32_t n = 0;

SSFGObjInit(&obj, 2u);
SSFGObjSetObject(obj);

SSFGObjInit(&child, 0u);
SSFGObjSetLabel(child, "count");
SSFGObjSetInt(child, 42);
SSFGObjInsertChild(obj, child);

if (SSFGObjGetObjectLen(obj, &n))
{
    /* n == 1 */
}
SSFGObjDeInit(&obj);

bool SSFGObjGetArrayLen(SSFGObj_t *gobj, uint32_t *numChildren);

Returns the number of elements currently attached to an ARRAY node. The call fails if gobj is not of type SSF_OBJ_TYPE_ARRAY; in particular, an OBJECT node is rejected. A zero-capacity ARRAY (one initialized with maxChildren = 0 and then set to ARRAY) is valid and reports 0.

Parameter Direction Type Description
gobj in SSFGObj_t * Pointer to the node whose element count is requested. Must not be NULL.
numChildren out uint32_t * Receives the number of elements on success. Left unchanged on failure. Must not be NULL.

Returns: true if gobj is an ARRAY and *numChildren has been written with the element count; false if gobj is any other type. On failure *numChildren is left unchanged.

SSFGObj_t *arr = NULL;
SSFGObj_t *elem = NULL;
uint32_t n = 0;

SSFGObjInit(&arr, 2u);
SSFGObjSetArray(arr);

SSFGObjInit(&elem, 0u);
SSFGObjSetInt(elem, 10);
SSFGObjInsertChild(arr, elem);

if (SSFGObjGetArrayLen(arr, &n))
{
    /* n == 1 */
}
SSFGObjDeInit(&arr);

bool SSFGObjFindPath(SSFGObj_t *gobjRoot, SSFCStrIn_t *path,
                     SSFGObj_t **gobjParentOut, SSFGObj_t **gobjChildOut);

Locates a descendant node by following a null-terminated array of label strings from gobjRoot. gobjRoot must be an OBJECT or ARRAY node. path is a const char * array where each entry names a child at the corresponding depth; the array must end with a NULL sentinel at index SSF_GOBJ_CONFIG_MAX_IN_DEPTH.

Parameter Direction Type Description
gobjRoot in SSFGObj_t * Root to search from. Must not be NULL. Must have type SSF_OBJ_TYPE_OBJECT or SSF_OBJ_TYPE_ARRAY.
path in SSFCStrIn_t * Array of label strings. Each entry names a child at the corresponding depth. Must be NULL-terminated; path[SSF_GOBJ_CONFIG_MAX_IN_DEPTH] must be NULL.
gobjParentOut out SSFGObj_t ** Receives the direct parent of the found node. Must not be NULL. *gobjParentOut must be NULL before the call.
gobjChildOut out SSFGObj_t ** Receives the found node. Must not be NULL. *gobjChildOut must be NULL before the call.

Returns: true if the path was resolved; false if any label was not found or gobjRoot is not a container type.

SSFGObj_t *root = NULL;
SSFGObj_t *child = NULL;
SSFGObj_t *foundParent = NULL;
SSFGObj_t *found = NULL;
int64_t val;
SSFCStrIn_t path[SSF_GOBJ_CONFIG_MAX_IN_DEPTH + 1];

SSFGObjInit(&root, 2u);
SSFGObjSetObject(root);

SSFGObjInit(&child, 0u);
SSFGObjSetLabel(child, "count");
SSFGObjSetInt(child, 42);
SSFGObjInsertChild(root, child);

memset(path, 0, sizeof(path));
path[0] = "count";

if (SSFGObjFindPath(root, path, &foundParent, &found))
{
    SSFGObjGetInt(found, &val);   /* val == 42 */
}
SSFGObjDeInit(&root);   /* frees root and child */

bool SSFGObjIterate(SSFGObj_t *gobj, SSFGObjIterateFn_t iterateCallback);

Performs a depth-first traversal of the subtree rooted at gobj, invoking iterateCallback once for every node including gobj itself. The callback receives the current node and a linked list of SSFGObjPathItem_t nodes representing the path from the traversal root to the current node.

Parameter Direction Type Description
gobj in SSFGObj_t * Root of the subtree to traverse. Must not be NULL.
iterateCallback in SSFGObjIterateFn_t Callback invoked for each node. Must not be NULL.

Returns: true if traversal completed; false if the nesting depth exceeded SSF_GOBJ_CONFIG_MAX_IN_DEPTH.

void myCallback(SSFGObj_t *gobj, SSFLL_t *path)
{
    /* Called once per node; inspect gobj->dataType, gobj->labelCStr, etc. */
}

SSFGObj_t *root = NULL;
SSFGObj_t *child = NULL;

SSFGObjInit(&root, 2u);
SSFGObjSetObject(root);
SSFGObjInit(&child, 0u);
SSFGObjSetLabel(child, "x");
SSFGObjSetInt(child, 1);
SSFGObjInsertChild(root, child);

SSFGObjIterate(root, myCallback);
/* myCallback called twice: once for root, once for child */

SSFGObjDeInit(&root);