Examples
Basic Example
Contains a basic use example for jsmn parser. This application parses json messages. Message structure shown below.
// JSON Message
{
"request": "moveElement",
"msgID": 1
}
// Callback function used to stored JSON string data in user defined data structure.
signed short parseCallback(myMessage_typ *data, jsmn_callback_data *data2) {
if(data2->Size == 0) {
// Identify the correct structure to use based on the active request.
if(!brsstrcmp(&data2->Structure[1], &"request")) {
if(!brsstrcmp(&data2->Structure[0], &"moveElement")) {
data->request= JSON_REQUEST_MOVE_ELEMENT;
}
else if(!brsstrcmp(&data2->Structure[0], &"stopElement")) {
data->request= JSON_REQUEST_STOP_ELEMENT;
} else {
//Initiate an error for invalid request assignment and add error string to structure
data->error = 1;
brsstrcmp(data->errorString, &"Invalid request for element");
}
} else if(!brsstrcmp(&data2->Structure[1], &"msgID")) {
brsstrcpy(&data->msgID, &data2->Structure[0]);
} else {
// Ignore all other parameters
}
}
return 0;
}
// Cyclic function
void _CYCLIC ProgramCyclic(void) {
// newMessage - BOOL - is populated somewhere in application
// msg - STRING - is populated somewhere in application
if(newMessage) {
// Declare the data, tokens, and parser
jsmn_parser parser;
jsmntok_t tokens[32];
myMessage_typ data; // myMessage_typ = {request: 0}
// Clear all variables
brsmemset(&parser, 0, sizeof(parser));
brsmemset(&tokens, 0, sizeof(tokens));
brsmemset(&data, 0, sizeof(data));
JsmnInit(&parser);
// Assign user defined callback function & data
parser.callback.pFunction= (UDINT)parseCallback;
parser.callback.pUserData = (UDINT)&data;
// Parse message
returnVar = JsmnParse((UDINT)&parser, (UDINT)msg, strlen((char*)msg), (UDINT)&tokens, sizeof(tokens)/sizeof(tokens[0]));
if(returnVar < 0) {
// Handle errors
}
if(data.request >= 0) {
// Handle request
}
}
}
// For:
// Json Message: {"request": "moveElement", "msgID": 1}
// Result:
// data: {request: JSON_REQUEST_MOVE_ELEMENT}
Reentry
Example shows how to use jsmn parse reentry feature. Application parses json data gotten from function getJsonChunk(). Json will be given in chunks, example object shown below.
// JSON Data
{
"command": 1,
"variable": [
"Motor1",
"Motor2"
]
}
char* getJsonChunk(char* json, unsigned long pos) {
// Function returns next chunk of internal json string
// next chunk is determined from current chunk (json) and how far
// parser made it through the chunk (pos)
}
// Cyclic function
void _CYCLIC ProgramCyclic(void) {
if(parseJson) {
// Declare variables
jsmn_parser parser;
jsmntok_t tokens[32];
myData_typ data; // myData_typ = {command: 0, variable: []}
char* json;
// Initialize variables
brsmemset(&parser, 0, sizeof(parser));
brsmemset(&tokens, 0, sizeof(tokens));
brsmemset(&data, 0, sizeof(data));
json = 0;
JsmnInit(&parser);
// Assign user defined callback function & data
parser.callback.pFunction= (UDINT)parseCallback; // parseCallback declared in application
parser.callback.pUserData = (UDINT)&data;
do {
json = getJsonChunk(json, parser.endPos); // Populates json variable
parser.pos = 0; // Reset parser position to start of string
returnVar = JsmnParse((UDINT)&parser, (UDINT)json, strlen((char*)json), (UDINT)&tokens, sizeof(tokens)/sizeof(tokens[0]));
} while(returnVar == JSMN_ERROR_PART)
}
for(i = 0; i < MAX_VARIABLES; i++;) {
// Do something with each variable
// data.variables[i]
}
}
// For a complete json of {"command": 1, "variable": ['Motor1', 'Motor2']}
// Iteration 1
// json = '{"command": 1, "vari'
// parser will successfully parse to position 14. After that JsmnParse will return JSMN_ERROR_PART.
// Iteration 2
// json = '"variable": ['Motor1', 'Motor2']}'
// parser will finish parsing json string and return 7
Callback iterations
This section shows what jsmn_callback_data will be populated with for each iteration given a some common situations.
JSON Primitives
{
"mem1": 1,
"mem2": "2",
"mem3": 3
}
JSON Objects
{
"object": {
"subObject" : {
"mem1": 1
},
"mem2": 2
},
"mem3": 3
}
JSON Arrays
Info
Due to a bug currently arrays will provide 2 callbacks per a token. This can be seen in the iterations below and is not intended.
{
"array": [
1,
2
],
"mem3": 3
}