107 lines
2.2 KiB
C
107 lines
2.2 KiB
C
#include <stdlib.h>
|
|
#include <jansson.h>
|
|
#include "jsh.h"
|
|
|
|
struct stream *jsh_new_stream(char *name, FILE *out_file, size_t buf_size)
|
|
{
|
|
if (name == NULL || out_file == NULL || buf_size == 0) {
|
|
return NULL;
|
|
}
|
|
struct stream *s = (struct stream *) malloc(sizeof(struct stream));
|
|
s->name = name;
|
|
s->first = true;
|
|
s->out = out_file;
|
|
s->buf_size = buf_size;
|
|
s->counter = 0;
|
|
s->root = s;
|
|
s->data = json_object();
|
|
return s;
|
|
}
|
|
|
|
void jsh_close_stream(struct stream *s)
|
|
{
|
|
// TODO: close data -> values
|
|
free(s);
|
|
}
|
|
|
|
void jsh_start_stream(struct stream *s)
|
|
{
|
|
fprintf(s->out, "[");
|
|
}
|
|
|
|
void jsh_end_stream(struct stream *s)
|
|
{
|
|
jsh_flush(s->root);
|
|
fprintf(s->out, "]");
|
|
}
|
|
|
|
void add_comma_if_not_first(struct stream *s)
|
|
{
|
|
if (s->first) {
|
|
s->first = false;
|
|
} else {
|
|
fprintf(s->out, ", ");
|
|
}
|
|
}
|
|
|
|
void jsh_flush(struct stream *s)
|
|
{
|
|
if (s->root->counter == 0) {
|
|
return;
|
|
}
|
|
|
|
struct stream *sub;
|
|
for (sub = s->first_child; sub != NULL; sub = sub->next) {
|
|
add_comma_if_not_first(s);
|
|
fprintf(s->out, "{\"%s\": [", sub->name);
|
|
jsh_flush(sub);
|
|
sub->first = true;
|
|
fprintf(s->out, "]}");
|
|
}
|
|
s->root->counter = 0;
|
|
|
|
if (json_object_size(s->data) != 0) {
|
|
add_comma_if_not_first(s);
|
|
json_dumpf(s->data, s->out, JSON_ENCODE_ANY);
|
|
const char *key;
|
|
json_t *value;
|
|
json_object_foreach(s->data, key, value) {
|
|
json_array_clear(json_object_get(s->data, key));
|
|
}
|
|
json_object_clear(s->data);
|
|
}
|
|
}
|
|
|
|
struct stream *jsh_new_substream(struct stream *s, char * name)
|
|
{
|
|
struct stream *child_stream = jsh_new_stream(name, s->out, s->buf_size);
|
|
child_stream->root = s->root;
|
|
child_stream->next = NULL;
|
|
|
|
if (s->first_child != NULL) {
|
|
// find last child and set its next to be the new child
|
|
struct stream *current_child = s->first_child;
|
|
while (current_child->next != NULL) {
|
|
current_child = current_child->next;
|
|
}
|
|
current_child->next = child_stream;
|
|
} else {
|
|
s->first_child = child_stream;
|
|
}
|
|
return child_stream;
|
|
}
|
|
|
|
void jsh_output(struct stream *s, char *key, json_t *value)
|
|
{
|
|
json_t *values = json_object_get(s->data, key);
|
|
if (values == NULL) {
|
|
values = json_array();
|
|
}
|
|
if (s->root->counter >= s->buf_size) {
|
|
jsh_flush(s->root);
|
|
}
|
|
s->root->counter++;
|
|
json_array_append(values, value);
|
|
json_object_set(s->data, key, values);
|
|
}
|