utility/json_parser/parse_example9.c

/*******************************************************************************
* # License
* Copyright 2019 Silicon Laboratories Inc. www.silabs.com
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include "gos.h"
/*************************************************************************************************
* This demonstrates reading nested values from a JSON structure.
*
*
* The parsed JSON looks like:
*
{
"name": "Product",
"properties": {
"id": {
"type": "number",
"description": "Product identifier",
"required": true
},
"name": {
"description": "Name of the product",
"type": "string",
"required": true
},
"price": {
"type": "number",
"minimum": 0,
"required": true
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
*
*
*/
gos_result_t parse_example9(const char *filename)
{
gos_result_t result;
gos_json_parse_context_t *context = NULL;
char *json_data = NULL;
GOS_LOG("\r\n\r\nParsing: %s", filename);
if (GOS_FAILED(result, read_file(filename, &json_data)))
{
GOS_LOG("Failed to read: %s", filename);
return result;
}
const gos_json_parse_config_t config =
{
.buffer = json_data,
.buffer_len = strlen(json_data)
};
if (GOS_FAILED(result, gos_json_parse_context_init(&context, &config)))
{
GOS_LOG("Failed to initialize json parsing context");
}
else if (GOS_FAILED(result, gos_json_parse_chunked(context, NULL)))
{
GOS_LOG("Failed to parse json file");
}
else
{
gos_json_tok_t *prop = JSON_GET_VALUE(context, "properties");
gos_json_tok_t *prop_tags = JSON_GET_VALUE_WITH(context, "tags", prop);
gos_json_tok_t *prop_tags_type = JSON_GET_VALUE_WITH(context, "type", prop_tags);
gos_json_tok_t *prop_tags_items = JSON_GET_VALUE_WITH(context, "items", prop_tags);
gos_json_tok_t *prop_tags_items_type = JSON_GET_VALUE_WITH(context, "type", prop_tags_items);
if (prop != NULL)
{
GOS_LOG("properties has %d tokens", JSON_UINT32(prop));
if (prop_tags != NULL)
{
GOS_LOG("properties.tags has %d tokens", JSON_UINT32(prop_tags));
if (prop_tags_type != NULL)
{
GOS_LOG("properties.tags.type : %s", JSON_STR(prop_tags_type));
}
else
{
GOS_LOG("Failed to get properties.tags.type token");
}
if (prop_tags_items != NULL)
{
GOS_LOG("properties.tags.items has %d tokens", JSON_UINT32(prop_tags_items));
if (prop_tags_items_type != NULL)
{
GOS_LOG("properties.tags.items.type : %s", JSON_STR(prop_tags_items_type));
}
else
{
GOS_LOG("Failed to get properties.tags.items.type token");
}
}
else
{
GOS_LOG("Failed to get properties.tags.items token");
}
}
else
{
GOS_LOG("Failed to get properties.tags token");
}
}
else
{
GOS_LOG("Failed to get properties token");
}
}
gos_free(json_data);
GOS_LOG("Finished");
return result;
}
/*************************************************************************************************
* Pre-read the JSON file into a buffer
*/
static gos_result_t read_file(const char *filename, char **buffer)
{
gos_result_t result;
uint8_t *ptr;
if (GOS_FAILED(result, gos_file_open(filename, GOS_FILE_LOCATION_EXTENDED, false, &handle)))
{
}
else if (GOS_FAILED(result, gos_file_get_descriptor(handle, &fd)))
{
}
else if (GOS_FAILED(result, gos_malloc("json", &ptr, fd.size+1)))
{
}
else if (GOS_FAILED(result, gos_file_read(handle, ptr, fd.size, NULL)))
{
}
else
{
ptr[fd.size] = 0; // null-terminate string
*buffer = (char*)ptr;
}
return result;
}