Files
cworker/clib/jblock.c
2023-09-04 22:12:47 +02:00

356 lines
9.0 KiB
C

/*
*
* Copyright 2023 Oleg Borodin <borodin@unix7.org>
*
*/
#include <jblock.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define INIT_CAPA 64
static void* jstring_init(jstring_t* str);
static void* jstring_append(jstring_t* str, char* add);
static char* jstring_getref(jstring_t* str);
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) {
jstring_t jstr;
jstring_init(&jstr);
jstring_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);
jstring_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);
jstring_append(&jstr, buffer);
free(buffer);
break;
}
case JKVTYPE_FLT: {
char* buffer = NULL;
asprintf(&buffer, "%e", jb->kvarr[i].flt);
jstring_append(&jstr, buffer);
free(buffer);
break;
}
case JKVTYPE_BOOL: {
if (jb->kvarr[i].flag) {
jstring_append(&jstr, "true");
} else {
jstring_append(&jstr, "false");
}
break;
}
case JKVTYPE_STR: {
char* buffer = NULL;
asprintf(&buffer, "\"%s\"", jb->kvarr[i].str);
jstring_append(&jstr, buffer);
free(buffer);
break;
}
}
if (i < jb->kvsize - 1) {
jstring_append(&jstr, ",");
}
}
jstring_append(&jstr, "}");
*res = jstring_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);
}
/* String container */
static void* jstring_init(jstring_t* str) {
str->data = malloc(INIT_CAPA + 1);
if (str->data == NULL) return NULL;
memset(str->data, '\0', INIT_CAPA + 1);
str->capa = INIT_CAPA;
str->size = 0;
return str->data;
}
static void* jstring_append(jstring_t* str, char* add) {
size_t addsize = strlen(add);
size_t newsize = str->size + addsize;
if (newsize > str->capa) {
char* newstr = realloc(str->data, newsize + 1);
if (newstr == NULL) return NULL;
}
strcpy(&(str->data[str->size]), add);
str->data[newsize + 1] = '\0';
str->capa = newsize;
str->size = newsize;
return str->data;
}
static char* jstring_getref(jstring_t* str) {
return str->data;
}
/* Integer array */
jintarr_t* new_jintarr(void) {
jintarr_t* arr = malloc(sizeof(jintarr_t));
if (arr == NULL) return NULL;
if (jintarr_init(arr) == NULL) {
jintarr_free(arr);
return NULL;
}
return arr;
}
void* jintarr_init(jintarr_t* array) {
array->data = malloc(INIT_CAPA * sizeof(int64_t));
if (array->data == NULL) return NULL;
memset(array->data, 0, INIT_CAPA);
array->capa = INIT_CAPA;
array->size = 0;
return array->data;
}
void* jintarr_append(jintarr_t* array, int64_t add) {
if (array->size + 1 > array->capa) {
size_t newcapa = (array->capa * 10) / 6 ;
int64_t* newarray = realloc(array->data, newcapa);
if (newarray == NULL) return NULL;
array->capa = newcapa;
array->data = newarray;
}
array->data[array->size++] = add;
return array->data;
}
int64_t* jintarr_getref(jintarr_t* array) {
return array->data;
}
void jintarr_destroy(jintarr_t* array) {
if (array == NULL) return;
free(array->data);
}
void jintarr_free(jintarr_t* array) {
jintarr_destroy(array);
free(array->data);
}
/* Float array */
void* jfltarr_init(jfltarr_t* array) {
array->data = malloc(INIT_CAPA * sizeof(double));
if (array->data == NULL) return NULL;
memset(array->data, 0, INIT_CAPA);
array->capa = INIT_CAPA;
array->size = 0;
return array->data;
}
void* jfltarr_append(jfltarr_t* array, double add) {
if (array->size + 1 > array->capa) {
size_t newcapa = (array->capa * 10) / 6 ;
double* newarray = realloc(array->data, newcapa);
if (newarray == NULL) return NULL;
array->capa = newcapa;
array->data = newarray;
}
array->data[array->size++] = add;
return array->data;
}
double* jfltarr_getref(jfltarr_t* array) {
return array->data;
}
void jfltarr_destroy(jfltarr_t* array) {
if (array == NULL) return;
free(array->data);
}
/* Bool array */
void* jboolarr_init(jboolarr_t* array) {
array->data = malloc(INIT_CAPA * sizeof(bool));
if (array->data == NULL) return NULL;
memset(array->data, 0, INIT_CAPA);
array->capa = INIT_CAPA;
array->size = 0;
return array->data;
}
void* jboolarr_append(jboolarr_t* array, bool add) {
if (array->size + 1 > array->capa) {
size_t newcapa = (array->capa * 10) / 6 ;
bool* newarray = realloc(array->data, newcapa);
if (newarray == NULL) return NULL;
array->capa = newcapa;
array->data = newarray;
}
array->data[array->size++] = add;
return array->data;
}
bool* jboolarr_getref(jboolarr_t* array) {
return array->data;
}
void jboolarr_destroy(jboolarr_t* array) {
if (array == NULL) return;
free(array->data);
}
/* 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;
}