Data Structures | |
struct | JsonEncode_State |
The structure used to maintain the state of a JSON encode process. More... | |
struct | JsonDecode_State |
The structure used to maintain the state of a JSON decode process. More... | |
Functions | |
void | JsonEncode_Init (JsonEncode_State *state) |
Initialize or reset the state of a JsonEncode_State variable. | |
char * | JsonEncode_ObjectOpen (JsonEncode_State *state, char *buf, int *remaining) |
Open up a new JSON object. | |
char * | JsonEncode_ObjectKey (JsonEncode_State *state, char *buf, const char *key, int *remaining) |
Set the key for a JSON object. | |
char * | JsonEncode_ObjectClose (JsonEncode_State *state, char *buf, int *remaining) |
Close a JSON object. | |
char * | JsonEncode_ArrayOpen (JsonEncode_State *state, char *buf, int *remaining) |
Open up a new JSON array. | |
char * | JsonEncode_ArrayClose (JsonEncode_State *state, char *buf, int *remaining) |
Close an array. | |
char * | JsonEncode_String (JsonEncode_State *state, char *buf, const char *string, int *remaining) |
Add a string to the current JSON string. | |
char * | JsonEncode_Int (JsonEncode_State *state, char *buf, int value, int *remaining) |
Add an int to a JSON string. | |
char * | JsonEncode_Bool (JsonEncode_State *state, char *buf, bool value, int *remaining) |
Add a boolean value to a JSON string. | |
void | JsonDecode_SetIntCallback (bool(*int_callback)(void *ctx, int val)) |
Set the function to be called back when an integer is parsed. | |
void | JsonDecode_SetFloatCallback (bool(*float_callback)(void *ctx, float val)) |
Set the function to be called back when a float is parsed. | |
void | JsonDecode_SetBoolCallback (bool(*bool_callback)(void *ctx, bool val)) |
Set the function to be called back when a boolean is parsed. | |
void | JsonDecode_SetStringCallback (bool(*string_callback)(void *ctx, char *string, int len)) |
Set the function to be called back when a string is parsed. | |
void | JsonDecode_SetStartObjCallback (bool(*start_obj_callback)(void *ctx)) |
Set the function to be called back when an object is started. | |
void | JsonDecode_SetObjKeyCallback (bool(*obj_key_callback)(void *ctx, char *key, int len)) |
Set the function to be called back when the key of a key-value pair has been encountered. | |
void | JsonDecode_SetEndObjCallback (bool(*end_obj_callback)(void *ctx)) |
Set the function to be called back when an object is ended. | |
void | JsonDecode_SetStartArrayCallback (bool(*start_array_callback)(void *ctx)) |
Set the function to be called back when an array is started. | |
void | JsonDecode_SetEndArrayCallback (bool(*end_array_callback)(void *ctx)) |
Set the function to be called back when an array is ended. | |
void | JsonDecode_Init (JsonDecode_State *state, void *context) |
Initialize or reset a JsonDecode_State variable. | |
bool | JsonDecode (JsonDecode_State *state, char *text, int len) |
Parse a JSON string. |
From http://www.json.org: "JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate."
JSON is quite widely used when communicating with web servers, or other network enabled devices. It's nice and small, and easy to work with. It's quite well supported in many programming environments, so it's not a bad option for a communication format when you need to talk to other devices from the Make Controller.
Disclaimer - in an attempt to keep it as small and as simple as possible, this library is not completely full featured at the moment. It doesn't process escaped strings for you, and doesn't deal with some of the more exotic numeric representations outlined in the JSON specification. It does, however, work quite well for most other JSON tasks.
You need to provide a few things:
#define MAX_JSON_LEN 256 char jsonbuf[MAX_JSON_LEN]; int remaining = MAX_JSON_LEN; JsonEncode_State s; char *p = jsonbuf; // keep a pointer to the current location JsonEncode_Init(&s); // initialize our state variable p = JsonEncode_ObjectOpen(&s, p, &remaining); p = JsonEncode_String(&s, p, "hello", &remaining); p = JsonEncode_Int(&s, p, 234, &remaining); p = JsonEncode_ObjectClose(&s, p, &remaining); // now the string in jsonbuf looks like {"hello":234} - beautifully formatted JSON int json_len = MAX_JSON_LEN - remaining; // this is the total length of the string in jsonbuf
Note - the library will add the appropriate separators (: or , usually) to the string, depending on the context of the objects and arrays you've opened, or other data you've inserted.
In each callback, return true to continue parsing, or return false and parsing will stop.
If you need to pass around some context that you would like available in each of the callbacks, you can pass it to JsonDecode_Init() and it will be passed to each of the callbacks you've registered. Otherwise, just pass 0 if you don't need it.
// first, define the functions that we want to be called back on bool on_obj_opened(void* ctx) { // will be called when an object has been opened... return true; // keep parsing } bool on_int(void *ctx, int val) { iny my_json_int = val; // called when an int is encountered... return true; // keep parsing } bool on_string(void *ctx, char *string, int len) { // called when a string is encountered... return true; // keep parsing } // Now, register these callbacks with the JSON parser. JsonDecode_SetStartObjCallback(on_obj_opened); JsonDecode_SetIntCallback(on_int); JsonDecode_SetStringCallback(on_string); // Finally, run the parser. JsonDecode_State s; JsonDecode_Init(&s, 0); // pass 0 if you don't need to use any special context char jsonstr[] = "[{\"label\":\"value\",\"label2\":{\"nested\":234}}]"; JsonDecode(&s, jsonstr, strlen(jsonstr)); // now each of our callbacks will be triggered at the appropriate time
Thanks to YAJL (http://code.google.com/p/yajl-c) for some design inspiration.
bool JsonDecode | ( | JsonDecode_State * | state, | |
char * | text, | |||
int | len | |||
) |
Parse a JSON string.
The JSON parser is event based, meaning that you will receive any callbacks you registered for as the elements are encountered in the JSON string.
state | A pointer to the JsonDecode_State variable being used for this decode process. | |
text | The JSON string to parse. | |
len | The length of the JSON string. |
// quotes are escaped since I'm writing it out manually JsonDecode_State s; char jsonstr[] = "[{\"label\":\"value\",\"label2\":{\"nested\":234}}]"; JsonDecode_Init(&s, 0); JsonDecode(jsonstr, strlen(jsonstr), 0); // don't pass in any context // now we expect to be called back on any callbacks we registered.
void JsonDecode_Init | ( | JsonDecode_State * | state, | |
void * | context | |||
) |
Initialize or reset a JsonDecode_State variable.
Do this prior to making a call to JsonDecode().
state | A pointer to the JsonDecode_State variable being used for this decode process. | |
context | An optional paramter that your code can use to pass around a known object within the callbacks. Otherwise, just set it to 0 |
void JsonDecode_SetBoolCallback | ( | bool(*)(void *ctx, bool val) | bool_callback | ) |
Set the function to be called back when a boolean is parsed.
The function must have the format:
bool on_bool(void* context, bool value);
JsonDecode_SetBoolCallback(on_bool);
bool_callback | The function to be called back. |
void JsonDecode_SetEndArrayCallback | ( | bool(*)(void *ctx) | end_array_callback | ) |
Set the function to be called back when an array is ended.
The right brace - ] - is the closing element of an array. The function must have the format:
bool on_array_ended(void* context);
JsonDecode_SetEndArrayCallback(on_array_ended);
end_array_callback | The function to be called back. |
void JsonDecode_SetEndObjCallback | ( | bool(*)(void *ctx) | end_obj_callback | ) |
Set the function to be called back when an object is ended.
The right bracket - } - is the closing element of an object. The function must have the format:
bool on_obj_ended(void* context);
JsonDecode_SetEndObjCallback(on_obj_ended);
end_obj_callback | The function to be called back. |
void JsonDecode_SetFloatCallback | ( | bool(*)(void *ctx, float val) | float_callback | ) |
Set the function to be called back when a float is parsed.
The function must have the format:
bool on_float(void* context, float value);
JsonDecode_SetFloatCallback(on_float);
float_callback | The function to be called back. |
void JsonDecode_SetIntCallback | ( | bool(*)(void *ctx, int val) | int_callback | ) |
Set the function to be called back when an integer is parsed.
The function must have the format:
bool on_int(void* context, int value);
JsonDecode_SetIntCallback(on_int);
int_callback | The function to be called back. |
void JsonDecode_SetObjKeyCallback | ( | bool(*)(void *ctx, char *key, int len) | obj_key_callback | ) |
Set the function to be called back when the key of a key-value pair has been encountered.
A key must always be a string in JSON, so you'll get the string back. This is particularly helpful for setting how the next element (the value in the key-value pair) should be handled.
The function must have the format:
bool on_obj_key(void* context);
JsonDecode_SetObjKeyCallback(on_obj_key);
obj_key_callback | The function to be called back. |
void JsonDecode_SetStartArrayCallback | ( | bool(*)(void *ctx) | start_array_callback | ) |
Set the function to be called back when an array is started.
The left brace - [ - is the starting element of an array. The function must have the format:
bool on_array_started(void* context);
JsonDecode_SetStartArrayCallback(on_array_started);
start_array_callback | The function to be called back. |
void JsonDecode_SetStartObjCallback | ( | bool(*)(void *ctx) | start_obj_callback | ) |
Set the function to be called back when an object is started.
The left bracket - { - is the opening element of an object. The function must have the format:
bool on_obj_started(void* context);
JsonDecode_SetStartObjCallback(on_obj_started);
start_obj_callback | The function to be called back. |
void JsonDecode_SetStringCallback | ( | bool(*)(void *ctx, char *string, int len) | string_callback | ) |
Set the function to be called back when a string is parsed.
Note - escaped elements in strings are respected, but not processed/removed from the string at the moment, since the internal implementation simply points to the string in the original data. If you have escaped data, you'll need to handle it in your code.
The function must have the format:
bool on_string(void* context, char* string);
JsonDecode_SetStringCallback(on_string);
string_callback | The function to be called back. |
char* JsonEncode_ArrayClose | ( | JsonEncode_State * | state, | |
char * | buf, | |||
int * | remaining | |||
) |
Close an array.
Adds a closing ']' to the string.
state | A pointer to the JsonEncode_State variable being used for this encode process. | |
buf | A pointer to the buffer which contains your JSON string. | |
remaining | A pointer to the count of how many bytes are left in your JSON buffer. |
char* JsonEncode_ArrayOpen | ( | JsonEncode_State * | state, | |
char * | buf, | |||
int * | remaining | |||
) |
Open up a new JSON array.
This adds an opening '[' to the json string.
state | A pointer to the JsonEncode_State variable being used for this encode process. | |
buf | A pointer to the buffer holding the JSON string. | |
remaining | A pointer to the count of how many bytes are left in your JSON buffer. |
char* JsonEncode_Bool | ( | JsonEncode_State * | state, | |
char * | buf, | |||
bool | value, | |||
int * | remaining | |||
) |
Add a boolean value to a JSON string.
state | A pointer to the JsonEncode_State variable being used for this encode process. | |
buf | A pointer to the buffer containing the JSON string. | |
value | The boolean value to be added. | |
remaining | A pointer to the count of bytes remaining in the JSON buffer. |
void JsonEncode_Init | ( | JsonEncode_State * | state | ) |
Initialize or reset the state of a JsonEncode_State variable.
Be sure to do this each time before you start parsing.
char* JsonEncode_Int | ( | JsonEncode_State * | state, | |
char * | buf, | |||
int | value, | |||
int * | remaining | |||
) |
Add an int to a JSON string.
state | A pointer to the JsonEncode_State variable being used for this encode process. | |
buf | A pointer to the buffer containing the JSON string. | |
value | The integer to be added. | |
remaining | A pointer to the count of bytes remaining in the JSON buffer. |
char* JsonEncode_ObjectClose | ( | JsonEncode_State * | state, | |
char * | buf, | |||
int * | remaining | |||
) |
Close a JSON object.
Adds a closing '}' to the string.
state | A pointer to the JsonEncode_State variable being used for this encode process. | |
buf | A pointer to the buffer which contains your JSON string. | |
remaining | A pointer to an integer keeping track of how many bytes are left in your JSON buffer. |
char* JsonEncode_ObjectKey | ( | JsonEncode_State * | state, | |
char * | buf, | |||
const char * | key, | |||
int * | remaining | |||
) |
Set the key for a JSON object.
This is a convenience function that simply calls JsonEncode_String(). It is provided to help enforce the idea that the first member of a JSON object pair must be a string.
char* JsonEncode_ObjectOpen | ( | JsonEncode_State * | state, | |
char * | buf, | |||
int * | remaining | |||
) |
Open up a new JSON object.
This adds an opening '{' to the json string.
state | A pointer to the JsonEncode_State variable being used for this encode process. | |
buf | A pointer to the buffer holding the JSON string. | |
remaining | A pointer to the count of how many bytes are left in your JSON buffer. |
char* JsonEncode_String | ( | JsonEncode_State * | state, | |
char * | buf, | |||
const char * | string, | |||
int * | remaining | |||
) |
Add a string to the current JSON string.
Depending on whether you've opened objects, arrays, or other inserted other data, the approprate separating symbols will be added to the string.
state | A pointer to the JsonEncode_State variable being used for this encode process. | |
buf | A pointer to the buffer containing the JSON string. | |
string | The string to be added. | |
remaining | A pointer to the count of bytes remaining in the JSON buffer. |