CX Framework
Cross-platform C utility framework
Loading...
Searching...
No Matches
JSON Parsing

Data Structures

struct  JSONParseState
 

Typedefs

typedef struct JSONParseState JSONParseState
 
typedef void(* jsonParseCB) (JSONParseEvent *ev, void *userdata)
 

Functions

bool jsonParseInit (JSONParseState *state, StreamBuffer *sb)
 
JSONParseEventjsonParseNext (JSONParseState *state)
 
void jsonParsePush (JSONParseState *state, JSONParseEvent *ev)
 
void jsonParseDestroy (JSONParseState *state)
 
bool jsonParse (StreamBuffer *sb, jsonParseCB callback, void *userdata)
 
SSDNode * jsonParseTree (StreamBuffer *sb)
 
SSDNode * jsonParseTreeCustom (StreamBuffer *sb, SSDTree *tree)
 
SSDNode * jsonTreeFromString (strref str)
 

Detailed Description

Parse JSON from stream buffers into SSD trees, via callbacks, or via pull-mode iteration.

The JSON parser supports three modes:

Pull-Mode Parsing (jsonParseInit / jsonParseNext / jsonParseDestroy): Initializes a parser state, then retrieves events one at a time by calling jsonParseNext(). This is the most flexible mode and is the foundation for the other two.

Event-Driven Parsing (jsonParse): Invokes a callback for each JSON element as it's parsed. Suitable for streaming large files or custom data processing. Implemented as a wrapper around the pull-mode API.

Tree Parsing (jsonParseTree): Fully loads JSON into an SSD tree for convenient random access and manipulation.

All modes require a stream buffer in PULL mode.

Example (event-driven):

void handleEvent(JSONParseEvent *ev, void *ctx) {
if (ev->etype == JSON_String) {
printf("String: %s\n", strC(ev->edata.strData));
}
}
VFSFile *file = vfsOpen(vfs, _SL("data.json"), FS_Read);
StreamBuffer *sb = sbufCreate(4096);
sbufFilePRegisterPull(sb, file, true);
jsonParse(sb, handleEvent, NULL);
@ FS_Read
Open for reading.
Definition fs.h:321
VFSFile * vfsOpen(VFS *vfs, strref path, flags_t flags)
bool jsonParse(StreamBuffer *sb, jsonParseCB callback, void *userdata)
@ JSON_String
String value parsed.
Definition jsoncommon.h:62
#define sbufCreate(targetsz,...)
Definition streambuf.h:275
const char * strC(strref s)
#define _SL(s)
Inline ASCII string literal with compile-time embedded length (STR_LEN8). Content must be < 200 bytes...
Definition strliteral.h:207
JsonEventType etype
Type of event.
Definition jsoncommon.h:112
union JSONParseEvent::@26 edata
Event-specific data.
string strData
String value (for JSON_String, JSON_Object_Key, JSON_Error)
Definition jsoncommon.h:120

Example (tree parsing):

VFSFile *file = vfsOpen(vfs, _SL("config.json"), FS_Read);
StreamBuffer *sb = sbufCreate(4096);
sbufFilePRegisterPull(sb, file, true);
SSDNode *root = jsonParseTree(sb);
string name = 0;
ssdVal(root, _SL("/user/name"), string, &name);
objRelease(&root);
#define objRelease(pinst)
Definition objclass.h:257
SSDNode * jsonParseTree(StreamBuffer *sb)
#define ssdVal(type, root, path, def)
Definition ssdtree.h:345

Example (pull-mode):

StreamBuffer *sb = sbufCreate(4096);
sbufFilePRegisterPull(sb, file, true);
jsonParseInit(&state, sb);
while (jsonParseNext(&state, &ev)) {
if (ev.etype == JSON_String)
printf("String: %s\n", strC(ev.edata.strData));
}
bool jsonParseInit(JSONParseState *state, StreamBuffer *sb)
void jsonParseDestroy(JSONParseState *state)
JSONParseEvent * jsonParseNext(JSONParseState *state)
void sbufFinish(StreamBuffer **sb)

Typedef Documentation

◆ jsonParseCB

typedef void(* jsonParseCB) (JSONParseEvent *ev, void *userdata)

void (*jsonParseCB)(JSONParseEvent *ev, void *userdata)

Callback function type for event-driven JSON parsing.

This callback is invoked for each JSON element as it's parsed. The JSONParseEvent contains the event type, current parser context, and event-specific data.

IMPORTANT: String data in events (strData) is only valid during the callback. Copy the string if you need to retain it.

Parameters
evParse event containing type, context, and data
userdataUser context pointer passed to jsonParse()

Definition at line 185 of file jsonparse.h.

◆ JSONParseState

Pull-mode JSON parser state

Holds the state for incremental JSON parsing via jsonParseNext(). Allocate on the stack or heap; initialize with jsonParseInit().

Function Documentation

◆ jsonParse()

bool jsonParse ( StreamBuffer *  sb,
jsonParseCB  callback,
void *  userdata 
)

bool jsonParse(StreamBuffer *sb, jsonParseCB callback, void *userdata)

Parses JSON data using an event-driven callback interface.

The stream buffer must be configured in PULL mode before calling this function. The parser invokes the callback for each JSON element: objects, arrays, strings, numbers, booleans, and null values.

This mode is ideal for:

  • Processing large JSON files with low memory overhead
  • Custom data transformations during parsing
  • Selective data extraction without building full tree
Parameters
sbStream buffer in pull mode
callbackFunction to invoke for each parse event
userdataUser context passed to callbacks
Returns
true on successful parse, false on error

Example:

typedef struct {
int objectCount;
int arrayCount;
} Stats;
void countElements(JSONParseEvent *ev, void *ctx) {
Stats *stats = (Stats *)ctx;
if (ev->etype == JSON_Object_Begin) stats->objectCount++;
if (ev->etype == JSON_Array_Begin) stats->arrayCount++;
}
Stats stats = {0};
StreamBuffer *sb = sbufCreate(4096);
sbufFilePRegisterPull(sb, file, true);
jsonParse(sb, countElements, &stats);
@ JSON_Object_Begin
New object starts at current context.
Definition jsoncommon.h:52
@ JSON_Array_Begin
New array starts at current context.
Definition jsoncommon.h:58

◆ jsonParseDestroy()

void jsonParseDestroy ( JSONParseState state)

void jsonParseDestroy(JSONParseState *state)

Destroys a pull-mode JSON parser state and releases all resources.

Safe to call at any point during parsing (for early abandonment) or after parsing is complete. The stream buffer is finalized as part of destruction.

Parameters
stateParser state to destroy

◆ jsonParseInit()

bool jsonParseInit ( JSONParseState state,
StreamBuffer *  sb 
)

bool jsonParseInit(JSONParseState *state, StreamBuffer *sb)

Initializes a pull-mode JSON parser state.

The stream buffer must be configured in PULL mode before calling this function. After initialization, call jsonParseNext() repeatedly to retrieve events, then jsonParseDestroy() to clean up.

Parameters
stateParser state to initialize
sbStream buffer in pull mode
Returns
true on success, false if stream buffer setup fails

Example:

StreamBuffer *sb = sbufCreate(4096);
sbufStrPRegisterPull(sb, jsonStr);
jsonParseInit(&state, sb);
while (jsonParseNext(&state, &ev)) {
// process ev
}
bool sbufStrPRegisterPull(StreamBuffer *sb, strref str)

◆ jsonParseNext()

JSONParseEvent * jsonParseNext ( JSONParseState state)

bool jsonParseNext(JSONParseState *state, JSONParseEvent *ev)

Retrieves the next parse event from a pull-mode JSON parser.

Each call advances the parser and returns an event. The event data remains valid until the next call to jsonParseNext() or jsonParseDestroy().

Returns Pointer to an event structure Returns NULL only after JSON_End has been delivered.

Parameters
stateParser state initialized with jsonParseInit()
Returns
Pointer to the next event, or NULL when parsing is complete

◆ jsonParsePush()

void jsonParsePush ( JSONParseState state,
JSONParseEvent ev 
)

void jsonParsePush(JSONParseState *state, JSONParseEvent *ev)

Pushes a parse event to the tail of the event queue.

Events in the queue are returned by jsonParseNext() before any new events are parsed from the stream. Use this to defer events for later consumption by a different part of a complex parser.

String data in the event is deep-copied; the caller retains ownership of the original event.

Parameters
stateParser state initialized with jsonParseInit()
evEvent to enqueue

◆ jsonParseTree()

SSDNode * jsonParseTree ( StreamBuffer *  sb)

SSDNode *jsonParseTree(StreamBuffer *sb)

Parses JSON data into an SSD tree.

Fully loads the JSON data into a semi-structured data tree for convenient access and manipulation. The returned tree root must be released with objRelease() when done.

The stream buffer must be configured in PULL mode before calling this function.

Parameters
sbStream buffer in pull mode
Returns
Root node of parsed tree, or NULL on error

Example:

VFSFile *file = vfsOpen(vfs, _SL("data.json"), FS_Read);
StreamBuffer *sb = sbufCreate(4096);
sbufFilePRegisterPull(sb, file, true);
SSDNode *root = jsonParseTree(sb);
if (root) {
string value = 0;
ssdVal(root, _SL("/path/to/value"), string, &value);
objRelease(&root);
}

◆ jsonParseTreeCustom()

SSDNode * jsonParseTreeCustom ( StreamBuffer *  sb,
SSDTree *  tree 
)

SSDNode *jsonParseTreeCustom(StreamBuffer *sb, SSDTree *tree)

Parses JSON data into an existing SSD tree.

Like jsonParseTree(), but allows using a pre-existing SSDTree for node allocation. Useful when you need to control tree properties or maintain multiple related trees.

Parameters
sbStream buffer in pull mode
treeExisting SSD tree to allocate nodes from (optional, NULL creates new tree)
Returns
Root node of parsed tree, or NULL on error

◆ jsonTreeFromString()

SSDNode * jsonTreeFromString ( strref  str)

SSDNode *jsonTreeFromString(strref str)

Parses JSON data from a string into an SSD tree.

Convenience function that internally creates a stream buffer, parses the JSON string, and returns the resulting tree. Equivalent to manually setting up a stream buffer with sbufStrPRegisterPull() and calling jsonParseTree().

Parameters
strJSON string to parse
Returns
Root node of parsed tree, or NULL on error

Example:

SSDNode *root = jsonTreeFromString(_SL("{\")name\": \"test\", \"value\": 42}");
if (root) {
int32 value;
ssdVal(root, _SL("/value"), int32, &value);
objRelease(&root);
}
SSDNode * jsonTreeFromString(strref str)