vgmstream/cli/vjson.h
2024-07-28 18:24:40 +02:00

155 lines
3.2 KiB
C

#ifndef _VJSON_H_
#define _VJSON_H_
/* What is this crap, you may wonder? For probably non-existant use cases Jansson was added to write JSON info,
* but external libs are a pain to maintain. For now this glorified string joiner replaces it.
*
* On incorrect usage or small buf it'll create invalid JSON because who cares, try-parse-catch as usual.
*/
#include <stdio.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdbool.h>
#define VJSON_STACK_MAX 16
typedef struct {
char* buf;
int buf_len;
char* bufp;
int buf_left;
bool stack[VJSON_STACK_MAX];
int stack_pos;
bool is_last_key;
} vjson_t;
static void vjson_init(vjson_t* j, char* buf, int buf_len) {
j->buf = buf;
j->buf_len = buf_len;
j->bufp = buf;
j->buf_left = buf_len;
}
static void vjson_raw(vjson_t* j, const char* str) {
if (!str)
str = "null";
int done = snprintf(j->bufp, j->buf_left, "%s", str);
j->bufp += done;
j->buf_left -= done;
}
static void vjson_comma_(vjson_t* j) {
if (j->stack[j->stack_pos] && !j->is_last_key) {
vjson_raw(j, ",");
}
j->stack[j->stack_pos] = true;
j->is_last_key = false;
}
static void vjson_open_(vjson_t* j, const char* str) {
vjson_comma_(j);
vjson_raw(j, str);
if (j->stack_pos + 1 >= VJSON_STACK_MAX)
return;
j->stack_pos++;
j->stack[j->stack_pos] = false;
}
static void vjson_close_(vjson_t* j, const char* str) {
//vjson_comma_(j);
vjson_raw(j, str);
if (j->stack_pos - 1 <= 0)
return;
j->stack[j->stack_pos] = false;
j->stack_pos--;
}
static void vjson_arr_open(vjson_t* j) {
vjson_open_(j, "[");
}
static void vjson_arr_close(vjson_t* j) {
vjson_close_(j, "]");
}
static void vjson_obj_open(vjson_t* j) {
vjson_open_(j, "{");
}
static void vjson_obj_close(vjson_t* j) {
vjson_close_(j, "}");
}
static void vjson_key(vjson_t* j, const char* key) {
vjson_comma_(j);
vjson_raw(j, "\"");
vjson_raw(j, key);
vjson_raw(j, "\":");
j->is_last_key = true;
}
static void vjson_str(vjson_t* j, const char* str) {
vjson_comma_(j);
if (!str || str[0] == '\0') {
vjson_raw(j, NULL);
}
else {
vjson_raw(j, "\"");
vjson_raw(j, str);
vjson_raw(j, "\"");
}
}
static void vjson_int(vjson_t* j, int64_t num) {
vjson_comma_(j);
char tmp[32] = {0};
snprintf(tmp, sizeof(tmp), "%" PRId64, num);
vjson_raw(j, tmp);
}
#if 0
static void vjson_dbl(vjson_t* j, double num) {
vjson_comma_(j);
char tmp[32] = {0};
snprintf(tmp, sizeof(tmp), "%f", num);
vjson_raw(j, tmp);
}
#endif
void vjson_null(vjson_t* j){
vjson_comma_(j);
vjson_raw(j, "null");
}
static void vjson_intnull(vjson_t* j, int64_t num) {
if (num == 0) {
vjson_str(j, NULL);
}
else {
vjson_int(j, num);
}
}
static void vjson_keystr(vjson_t* j, const char* key, const char* val) {
vjson_key(j, key);
vjson_str(j, val);
}
static void vjson_keyint(vjson_t* j, const char* key, int64_t val) {
vjson_key(j, key);
vjson_int(j, val);
}
static void vjson_keyintnull(vjson_t* j, const char* key, int64_t val) {
vjson_key(j, key);
vjson_intnull(j, val);
}
#endif