|
#ifndef RJSON_H
|
|
#define RJSON_H
|
|
#include "rmalloc.h"
|
|
#include "rtypes.h"
|
|
#include "rstring.h"
|
|
#include "rtemp.h"
|
|
#include "rtime.h"
|
|
#include "rtest.h"
|
|
|
|
typedef struct rjson_t {
|
|
char *content;
|
|
size_t length;
|
|
size_t size;
|
|
} rjson_t;
|
|
|
|
rjson_t *rjson() {
|
|
rjson_t *json = rmalloc(sizeof(rjson_t));
|
|
json->size = 1024;
|
|
json->length = 0;
|
|
json->content = (char *)rmalloc(json->size);
|
|
json->content[0] = 0;
|
|
return json;
|
|
}
|
|
|
|
void rjson_write(rjson_t *rjs, char *content) {
|
|
size_t len = strlen(content);
|
|
while (rjs->size < rjs->length + len + 1) {
|
|
rjs->content = realloc(rjs->content, rjs->size + 1024);
|
|
rjs->size += 1024;
|
|
}
|
|
strcat(rjs->content, content);
|
|
rjs->length += len;
|
|
}
|
|
|
|
void rjson_object_start(rjson_t *rjs) {
|
|
if (rstrendswith(rjs->content, "}"))
|
|
rjson_write(rjs, ",");
|
|
rjson_write(rjs, "{");
|
|
}
|
|
void rjson_object_close(rjson_t *rjs) {
|
|
if (rstrendswith(rjs->content, ",")) {
|
|
rjs->content[rjs->length - 1] = 0;
|
|
rjs->length--;
|
|
}
|
|
rjson_write(rjs, "}");
|
|
}
|
|
void rjson_array_start(rjson_t *rjs) {
|
|
if (rjs->length && (rstrendswith(rjs->content, "}") || rstrendswith(rjs->content, "]")))
|
|
rjson_write(rjs, ",");
|
|
rjson_write(rjs, "[");
|
|
}
|
|
void rjson_array_close(rjson_t *rjs) {
|
|
if (rstrendswith(rjs->content, ",")) {
|
|
rjs->content[rjs->length - 1] = 0;
|
|
rjs->length--;
|
|
}
|
|
rjson_write(rjs, "]");
|
|
}
|
|
|
|
void rjson_kv_string(rjson_t *rjs, char *key, char *value) {
|
|
if (rjs->length && !rstrendswith(rjs->content, "{") && !rstrendswith(rjs->content, "[")) {
|
|
rjson_write(rjs, ",");
|
|
}
|
|
rjson_write(rjs, "\"");
|
|
rjson_write(rjs, key);
|
|
rjson_write(rjs, "\":\"");
|
|
char *value_str = (char *)rmalloc(strlen(value) + 4096);
|
|
rstraddslashes(value, value_str);
|
|
rjson_write(rjs, value_str);
|
|
free(value_str);
|
|
rjson_write(rjs, "\"");
|
|
}
|
|
|
|
void rjson_kv_int(rjson_t *rjs, char *key, ulonglong value) {
|
|
if (rjs->length && !rstrendswith(rjs->content, "{") && !rstrendswith(rjs->content, "[")) {
|
|
rjson_write(rjs, ",");
|
|
}
|
|
rjson_write(rjs, "\"");
|
|
rjson_write(rjs, key);
|
|
rjson_write(rjs, "\":");
|
|
char value_str[100] = {0};
|
|
sprintf(value_str, "%lld", value);
|
|
rjson_write(rjs, value_str);
|
|
}
|
|
void rjson_kv_number(rjson_t *rjs, char *key, ulonglong value) {
|
|
if (rjs->length && !rstrendswith(rjs->content, "{") && !rstrendswith(rjs->content, "[")) {
|
|
rjson_write(rjs, ",");
|
|
}
|
|
rjson_write(rjs, "\"");
|
|
rjson_write(rjs, key);
|
|
rjson_write(rjs, "\":");
|
|
rjson_write(rjs, "\"");
|
|
|
|
rjson_write(rjs, sbuf(rformat_number(value)));
|
|
rjson_write(rjs, "\"");
|
|
}
|
|
|
|
void rjson_kv_bool(rjson_t *rjs, char *key, int value) {
|
|
if (rjs->length && !rstrendswith(rjs->content, "{") && !rstrendswith(rjs->content, "[")) {
|
|
rjson_write(rjs, ",");
|
|
}
|
|
rjson_write(rjs, "\"");
|
|
rjson_write(rjs, key);
|
|
rjson_write(rjs, "\":");
|
|
rjson_write(rjs, value > 0 ? "true" : "false");
|
|
}
|
|
|
|
void rjson_kv_duration(rjson_t *rjs, char *key, nsecs_t value) {
|
|
if (rjs->length && !rstrendswith(rjs->content, "{") && !rstrendswith(rjs->content, "[")) {
|
|
rjson_write(rjs, ",");
|
|
}
|
|
rjson_write(rjs, "\"");
|
|
rjson_write(rjs, key);
|
|
rjson_write(rjs, "\":");
|
|
rjson_write(rjs, "\"");
|
|
|
|
rjson_write(rjs, sbuf(format_time(value)));
|
|
rjson_write(rjs, "\"");
|
|
}
|
|
void rjson_free(rjson_t *rsj) {
|
|
free(rsj->content);
|
|
free(rsj);
|
|
}
|
|
|
|
void rjson_key(rjson_t *rsj, char *key) {
|
|
rjson_write(rsj, "\"");
|
|
rjson_write(rsj, key);
|
|
rjson_write(rsj, "\":");
|
|
}
|
|
#endif |