Encoding JSON data

The following code sample uses the libjson library to encode file information as JSON data and stores that data in a string.

The prepare_file_info() function creates an encoder and adds the necessary objects and fields to store information about a file. The information is organized based on the file_t structure used in the decoding example. Then, the function writes the encoder buffer's contents to the string space provided by the caller.

#include <stdio.h>
#include <sys/json.h>

bool prepare_file_info(char *str, int max_finfo_size)
{
    // In this example, we hardcode the field settings but often, they would be input
    // by a user or come from another source (e.g., a file or program)
    int id = 76;
    int type = 4;
    long long size = 99;
    const char *path = "/var/dhclient/leases";

    json_encoder_t *enc = json_encoder_create();

    // Write the 'id' value as a separate field in the top-level object, then write the
    // 'path', 'type', and 'size' fields in a nested object, 'info'.
    json_encoder_start_object(enc, NULL);
    json_encoder_add_int(enc, "id", id);
    json_encoder_start_object(enc, "info");
    json_encoder_add_string(enc, "path", path);
    json_encoder_add_int(enc, "type", type);
    json_encoder_add_int_ll(enc, "size", size);
    json_encoder_end_object(enc);
    json_encoder_end_object(enc);

    // For error checking, we don't need to check the return value of each function
    // since any error will cause the subsequent json_encoder_buffer() call to fail. 
    // Common errors are mismatched object or array start and end calls (which are 
    // programming errors) and out-of-memory errors.
    json_encoder_error_t status = json_encoder_get_status(enc);
    
    // If everything above has succeeded, json_encoder_get_status() will return 
    // JSON_ENCODER_OK
    if ( status != JSON_ENCODER_OK ) {
        printf("Data preparation failed\n");
        return false;
    }

    // Write the JSON data into the string space provided by the caller
    snprintf(str, max_finfo_size, "JSON:%s\n", json_encoder_buffer(enc));
    json_encoder_destroy(enc);
    
    return true;
}
The resulting string stored in str is:
JSON:{"id":76,"info":{"type":4,"path":"/var/dhclient/leases","size":99}}

Using jsnprintf() instead of an encoder

You can use jsnprintf() to generate something similar. This utility function is simpler to use than an encoder but is less versatile. Consider the following example:
char buffer[1024];
int rc = jsnprintf(buffer, 
                   sizeof(buffer), 
                   "{  id:%d , info:{type:%d,path:%s, is_link:%b}     }", 
                   id, type, path, 0);
The resulting string in buffer is:
{ "id":76, "info":{ "type":4, "path":"/var/dhclient/leases", "is_link":false}}
Notice that the spacing of the output doesn't match the input. The format string can also be prefixed with options delimited by a ‘:’. Currently, the only option is c, which means generate a compact JSON string with no extra spaces. For example:
int rc = jsnprintf(buffer, 
                   sizeof(buffer), 
                   ":c:{  id:%d , info:{type:%d,path:%s, is_link:%b}     }", 
                   id, type, path, 0);
generates:
{"id":76,"info":{"type":4,"path":"/var/dhclient/leases","is_link":false}}