utility/json_parser/parse_example1.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 is a basic JSON parsing example.
* It uses a statically allocated buffer for reading chunked of the JSON file.
* The JSON file is read the the 'reader' callback.
* Each JSON token is dynamically allocated and added to the context linked-list.
* The context and tokens linked-list is de-allocated at the end.
*/
gos_result_t parse_example1(const char *filename)
{
gos_result_t result;
gos_json_parse_context_t *context = NULL;
char buffer[128];
const gos_json_parse_config_t config =
{
.buffer = buffer,
.buffer_len = sizeof(buffer),
.reader = file_reader
};
GOS_LOG("\r\n\r\nParsing: %s", filename);
if (GOS_FAILED(result, gos_file_open(filename, GOS_FILE_LOCATION_EXTENDED, false, &handle)))
{
GOS_LOG("Failed to open: %s", filename);
}
else 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, (void*)handle)))
{
GOS_LOG("Failed to parse json file");
}
else
{
GOS_LOG("JSON file contents:");
for (const gos_json_tok_t *tok = gos_json_context_get_token(context, NULL, NULL); tok != NULL; tok = tok->next)
{
switch(tok->type)
{
{
GOS_LOG("Object: %u", tok->data.uint32);
}
break;
{
GOS_LOG("Array: %u", tok->data.uint32);
}
break;
{
GOS_LOG("String: %s", tok->data.str);
}
break;
{
GOS_LOG("Boolean: %s", tok->data.boolean ? "true" : "false");
}
break;
{
GOS_LOG("Integer: %u", tok->data.uint32);
}
break;
{
char str[16];
GOS_LOG("Integer64: %s", uint64_to_str(tok->data.uint64, str));
}
break;
{
GOS_LOG("Float: %s", tok->data.str);
}
break;
{
GOS_LOG("NUll:");
}
break;
default:
{
GOS_LOG("Unknown type: %d", tok->type);
}
break;
}
}
}
gos_file_close(handle);
GOS_LOG("Finished");
return result;
}
/*************************************************************************************************
* The parser will call this until it returns an error or
* the 'bytes_read' parameter is return with a 0 value.
*/
static gos_result_t file_reader(void *user, void *data, uint32_t max_length, uint32_t *bytes_read)
{
uint32_t file_handle = (uint32_t)user;
uint32_t has_more_data;
gos_file_poll(file_handle, &has_more_data);
if (has_more_data == 0)
{
// no more data so set this to 0 to tell the parser to stop calling this reader
*bytes_read = 0;
}
else if (GOS_FAILED(result, gos_file_read(file_handle, data, max_length, bytes_read)))
{
}
return result;
}