Files
cworker/clib/jblock.c
2023-09-04 23:41:03 +02:00

216 lines
5.4 KiB
C

/*
*
* Copyright 2023 Oleg Borodin <borodin@unix7.org>
*
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <cstring.h>
#include <cdynarr.h>
#include <jblock.h>
#define INIT_CAPA 64
static char* strcopy(char* src);
void jblock_init(jblock_t* jb) {
jb->kvsize = 0;
jb->kvcapa = INIT_CAPA;
jb->kvarr = malloc(sizeof(jkeyval_t) * INIT_CAPA);
}
jblock_t* new_jblock() {
jblock_t* jb = malloc(sizeof(jblock_t));
if (jb == NULL) return NULL;
jblock_init(jb);
return jb;
}
static void* jblock_checkalloc(jblock_t* jb) {
if (jb->kvsize == jb->kvcapa) {
size_t newsize = jb->kvcapa * 2;
jkeyval_t* newarr = realloc(jb->kvarr, sizeof(jkeyval_t) * newsize);
if (newarr == NULL) {
return NULL;
}
jb->kvarr = newarr;
jb->kvcapa = newsize;
}
return jb->kvarr;
}
static bool jblock_keyexists(jblock_t* jb, char* key) {
for (int i = 0; i < jb->kvsize; i++) {
if (strcmp(key, jb->kvarr[i].key) == 0) {
return true;
}
}
return false;
}
int jblock_addint(jblock_t* jb, char* key, int64_t val) {
if (jblock_keyexists(jb, key)) {
return -2;
}
if (jblock_checkalloc(jb) == NULL) {
return -1;
}
jb->kvarr[jb->kvsize].key = strcopy(key);
jb->kvarr[jb->kvsize].num = val;
jb->kvarr[jb->kvsize].type = JKVTYPE_INT;
return ++jb->kvsize;
}
int jblock_addfloat(jblock_t* jb, char* key, double val) {
if (jblock_keyexists(jb, key)) {
return -2;
}
if (jblock_checkalloc(jb) == NULL) {
return -1;
}
jb->kvarr[jb->kvsize].key = strcopy(key);
jb->kvarr[jb->kvsize].flt = val;
jb->kvarr[jb->kvsize].type = JKVTYPE_FLT;
return ++jb->kvsize;
}
int jblock_addbool(jblock_t* jb, char* key, bool val) {
if (jblock_keyexists(jb, key)) {
return -2;
}
if (jblock_checkalloc(jb) == NULL) {
return -1;
}
jb->kvarr[jb->kvsize].key = strcopy(key);
jb->kvarr[jb->kvsize].flag = val;
jb->kvarr[jb->kvsize].type = JKVTYPE_BOOL;
return ++jb->kvsize;
}
int jblock_addstr(jblock_t* jb, char* key, char* val) {
if (jblock_keyexists(jb, key)) {
return -2;
}
if (jblock_checkalloc(jb) == NULL) {
return -1;
}
jb->kvarr[jb->kvsize].key = strcopy(key);
jb->kvarr[jb->kvsize].str = strcopy(val);
jb->kvarr[jb->kvsize].type = JKVTYPE_STR;
return ++jb->kvsize;
}
void jblock_outjson(jblock_t* jb, char** res) {
cstring_t jstr;
cstring_init(&jstr);
cstring_append(&jstr, "{");
for (int i = 0; i < jb->kvsize; i++) {
switch (jb->kvarr[i].type) {
case JKVTYPE_STR:
case JKVTYPE_BOOL:
case JKVTYPE_FLT:
case JKVTYPE_INT: {
char* buffer = NULL;
asprintf(&buffer, "\"%s\":", jb->kvarr[i].key);
cstring_append(&jstr, buffer);
free(buffer);
break;
}
default: {
continue;
}
}
switch (jb->kvarr[i].type) {
case JKVTYPE_INT: {
char* buffer = NULL;
asprintf(&buffer, "%ld", jb->kvarr[i].num);
cstring_append(&jstr, buffer);
free(buffer);
break;
}
case JKVTYPE_FLT: {
char* buffer = NULL;
asprintf(&buffer, "%e", jb->kvarr[i].flt);
cstring_append(&jstr, buffer);
free(buffer);
break;
}
case JKVTYPE_BOOL: {
if (jb->kvarr[i].flag) {
cstring_append(&jstr, "true");
} else {
cstring_append(&jstr, "false");
}
break;
}
case JKVTYPE_STR: {
char* buffer = NULL;
asprintf(&buffer, "\"%s\"", jb->kvarr[i].str);
cstring_append(&jstr, buffer);
free(buffer);
break;
}
}
if (i < jb->kvsize - 1) {
cstring_append(&jstr, ",");
}
}
cstring_append(&jstr, "}");
*res = cstring_getref(&jstr);
}
void jblock_destroy(jblock_t* jb) {
if (jb == NULL) return;
for (int i = 0; i < jb->kvsize; i++) {
switch (jb->kvarr[i].type) {
case JKVTYPE_BLK: {
jblock_destroy(jb->kvarr[i].blk);
break;
}
//case JKVTYPE_BLKARR: {
// break;
//}
case JKVTYPE_STR: {
free(jb->kvarr[i].str);
break;
}
case JKVTYPE_INTARR: {
//free(jb->kvarr[i].numarr);
break;
}
case JKVTYPE_BOOLARR: {
//free(jb->kvarr[i].flagarr);
break;
}
case JKVTYPE_FLTARR: {
//free(jb->kvarr[i].fltarr);
break;
}
}
free(jb->kvarr[i].key);
}
jb->kvsize = 0;
jb->kvcapa = 0;
jb->kvarr = NULL;
}
void jblock_free(jblock_t* jb) {
jblock_destroy(jb);
free(jb);
}
/* Tools */
static char* strcopy(char* src) {
size_t srcsize = strlen(src) + 1;
char* dst = malloc(srcsize);
memset(dst, '\0', srcsize);
strcpy(dst, src);
return dst;
}