utility/json_parser/parse_all_examples.c

/*
* EVALUATION AND USE OF THIS SOFTWARE IS SUBJECT TO THE TERMS AND
* CONDITIONS OF THE CONTROLLING LICENSE AGREEMENT FOUND AT LICENSE.md
* IN THIS SDK. IF YOU DO NOT AGREE TO THE LICENSE TERMS AND CONDITIONS,
* PLEASE RETURN ALL SOURCE FILES TO SILICON LABORATORIES.
* (c) Copyright 2018, Silicon Laboratories Inc. All rights reserved.
*/
#include "gos.h"
#define GOS_LOG_LIMIT (253)
/*************************************************************************************************
* Parse all the files in the 'json/' folder and display their contents
*/
gos_result_t parse_all_examples(void)
{
gos_result_t result;
gos_file_t *file_list;
params.filter.name = "json/*";
if (GOS_FAILED(result, gos_file_list(&params, &file_list, NULL, NULL)))
{
GOS_LOG("Failed to get file listing: %d", result);
}
else
{
for (const gos_file_t *file = file_list; file != NULL; file = file->next)
{
if (GOS_FAILED(result, parse_file(file->name)))
{
break;
}
}
}
GOS_LOG("Finished");
return result;
}
/*************************************************************************************************/
static gos_result_t parse_file(const char *filename)
{
gos_result_t result;
gos_json_parse_context_t *context = NULL;
char buffer[512];
const gos_json_parse_config_t config =
{
.buffer = buffer,
.buffer_len = sizeof(buffer),
.reader = file_reader
};
GOS_LOG("\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
{
int tok_stack[10];
int level = 0;
memset(tok_stack, 0, sizeof(tok_stack));
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)
{
level = print_token(tok, level, tok_stack);
}
}
gos_file_close(handle);
return result;
}
/*************************************************************************************************/
static int print_token(const gos_json_tok_t *tok, int level, int *tok_stack)
{
char print_buffer[128];
char *print_ptr = print_buffer;
if (level > 0)
{
if (tok_stack[level-1] >= 0)
{
while (tok_stack[level-1] == 0)
{
--level;
}
for (int l = level; l > 0; --l)
{
*print_ptr++ = ' ';
*print_ptr++ = ' ';
*print_ptr++ = ' ';
}
--tok_stack[level-1];
}
}
switch(tok->type)
{
{
sprintf(print_ptr, "Object: %u", (unsigned int)tok->data.uint32);
tok_stack[level++] = tok->data.uint32;
}
break;
{
sprintf(print_ptr, "Array: %u", (unsigned int)tok->data.uint32);
tok_stack[level++] = tok->data.uint32;
}
break;
{
sprintf(print_ptr, "String: %s", tok->data.str);
}
break;
{
sprintf(print_ptr, "Boolean: %s", tok->data.boolean ? "true" : "false");
}
break;
{
sprintf(print_ptr, "Integer: %u", (unsigned int)tok->data.uint32);
}
break;
{
char str[16];
sprintf(print_ptr, "Integer64: %s", uint64_to_str(tok->data.uint64, str));
}
break;
{
sprintf(print_ptr, "Float: %s", tok->data.str);
}
break;
{
sprintf(print_ptr, "NULL element");
}
break;
default:
{
sprintf(print_ptr, "Unknown type: %d", (int)tok->type);
}
break;
}
// GOS_LOG_LIMIT is maximum amount of characters GOS_LOG() will print. To print a string longer than that, use gos_write_log instead.
if ((tok->type == GOS_JSON_TYPE_STRING) && ((strlen(" ") * level) + strlen("String: ") + strlen(tok->data.str) > GOS_LOG_LIMIT))
{
gos_write_log(print_buffer, strlen(" ")*level + strlen("String: ") + strlen(tok->data.str));
}
else
{
GOS_LOG("%s", print_buffer);
}
return level;
}
/*************************************************************************************************
* 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;
}