utility/json_parser/parse_example2.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 having the entire JSON string pre-read into a buffer.
* The json buffer is then parsed and the tokens are looked up by their string value.
*
*
* The parsed JSON looks like:
*
* {
* "colorsArray":[{
* "colorName":"red",
* "hexValue":"#f00"
* },
* {
* "colorName":"green",
* "hexValue":"#0f0"
* }
* ]}
*
*
*/
gos_result_t parse_example2(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
{
// get the array token
const gos_json_tok_t *color_array = gos_json_context_get_value(context, "colorsArray", NULL);
if (color_array == NULL || color_array->type != GOS_JSON_TYPE_ARRAY)
{
GOS_LOG("Malformed JSON!");
goto cleanup;
}
GOS_LOG("Color names/values: (%d)", color_array->data.uint32);
const gos_json_tok_t *obj_tok = color_array->next; // the first object in the array
for (int color_count = color_array->data.uint32; color_count > 0 && obj_tok != NULL; --color_count)
{
const gos_json_tok_t *name_tok = gos_json_context_get_value(context, "colorName", obj_tok);
const gos_json_tok_t *value_tok = gos_json_context_get_value(context, "hexValue", obj_tok);
if (name_tok == NULL || value_tok == NULL)
{
GOS_LOG("Malformed JSON!");
result = GOS_ERROR;
break;
}
GOS_LOG("%s : %s", name_tok->data.str, value_tok->data.str);
// Just skip to a token in the current object
// The gos_json_context_get_value() automatically searches for the next object starting at this token
obj_tok = name_tok->next;
}
}
cleanup:
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;
}