Skip to content

Commit

Permalink
[pgmoneta#357] yaml-like text format & json clone
Browse files Browse the repository at this point in the history
  • Loading branch information
Jubilee101 committed Aug 16, 2024
1 parent d4ae018 commit 68bd3e6
Show file tree
Hide file tree
Showing 13 changed files with 337 additions and 109 deletions.
3 changes: 2 additions & 1 deletion src/include/art.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,13 @@ pgmoneta_art_iterator_has_next(struct art_iterator* iter);
/**
* Convert the ART tree to string
* @param t The ART tree
* @param format The format
* @param tag The optional tag
* @param indent The indent
* @return The string
*/
char*
pgmoneta_art_to_string(struct art* t, char* tag, int indent);
pgmoneta_art_to_string(struct art* t, int32_t format, char* tag, int indent);

#ifdef __cplusplus
}
Expand Down
3 changes: 2 additions & 1 deletion src/include/deque.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,13 @@ pgmoneta_deque_destroy(struct deque* deque);
/**
* Convert what's inside deque to string
* @param deque The deque
* @param format The format
* @param tag [Optional] The tag, which will be applied before the content if not null
* @param indent The current indentation
* @return The string
*/
char*
pgmoneta_deque_to_string(struct deque* deque, char* tag, int indent);
pgmoneta_deque_to_string(struct deque* deque, int32_t format, char* tag, int indent);

/**
* Create a deque iterator
Expand Down
15 changes: 13 additions & 2 deletions src/include/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,20 +177,22 @@ pgmoneta_json_append(struct json* array, uintptr_t entry, enum value_type type);
/**
* Convert a json to string
* @param object The json object
* @param format The format
* @param tag The optional tag
* @param indent The indent
* @return The json formatted string
*/
char*
pgmoneta_json_to_string(struct json* object, char* tag, int indent);
pgmoneta_json_to_string(struct json* object, int32_t format, char* tag, int indent);

/**
* Print a json object
* @param object The object
* @param format The format
* @param indent_per_level The indent per level
*/
void
pgmoneta_json_print(struct json* object);
pgmoneta_json_print(struct json* object, int32_t format);

/**
* Get json array length
Expand Down Expand Up @@ -250,6 +252,15 @@ pgmoneta_json_iterator_has_next(struct json_iterator* iter);
int
pgmoneta_json_parse_string(char* str, struct json** obj);

/**
* Clone a json object
* @param from The from object
* @param to [out] The to object
* @return 0 if success, 1 if otherwise
*/
int
pgmoneta_json_clone(struct json* from, struct json** to);

#ifdef __cplusplus
}
#endif
Expand Down
3 changes: 3 additions & 0 deletions src/include/pgmoneta.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ extern "C" {
#define INCORRECT_SLOT_TYPE 2

#define INDENT_PER_LEVEL 2
#define FORMAT_JSON 0
#define FORMAT_TEXT 1
#define BULLET_POINT "- "

#define likely(x) __builtin_expect (!!(x), 1)
#define unlikely(x) __builtin_expect (!!(x), 0)
Expand Down
5 changes: 3 additions & 2 deletions src/include/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ extern "C" {
#include <stdbool.h>

typedef void (*data_destroy_cb)(uintptr_t data);
typedef char* (*data_to_string_cb)(uintptr_t data, char* tag, int indent);
typedef char* (*data_to_string_cb)(uintptr_t data, int32_t format, char* tag, int indent);

enum value_type {
ValueInt8,
Expand Down Expand Up @@ -100,12 +100,13 @@ pgmoneta_value_data(struct value* value);
/**
* Convert a value to string
* @param value The value
* @param format The format
* @param tag The optional tag
* @param indent The indent
* @return The string
*/
char*
pgmoneta_value_to_string(struct value* value, char* tag, int indent);
pgmoneta_value_to_string(struct value* value, int32_t format, char* tag, int indent);

/**
* Convert a double value to value data, since straight type cast discards the decimal part
Expand Down
3 changes: 2 additions & 1 deletion src/include/verify.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,13 @@ pgmoneta_verify(SSL* ssl, int client_fd, int server, char* backup_id, char* dire
/**
* Convert a verify entry to string
* @param entry The entry
* @param format The format
* @param tag The optional tag
* @param indent The indent
* @return The string in json format
*/
char*
pgmoneta_verify_entry_to_string(struct verify_entry* entry, char* tag, int indent);
pgmoneta_verify_entry_to_string(struct verify_entry* entry, int32_t format, char* tag, int indent);

#ifdef __cplusplus
}
Expand Down
137 changes: 116 additions & 21 deletions src/libpgmoneta/art.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ struct to_string_param
char* str;
int indent;
int cnt;
char* tag;
struct art* t;
};

Expand Down Expand Up @@ -283,7 +284,16 @@ static struct value*
art_search(struct art* t, unsigned char* key, uint32_t key_len);

static int
art_to_string_cb(void* param, const unsigned char* key, uint32_t key_len, struct value* value);
art_to_json_string_cb(void* param, const unsigned char* key, uint32_t key_len, struct value* value);

static int
art_to_text_string_cb(void* param, const unsigned char* key, uint32_t key_len, struct value* value);

static char*
to_json_string(struct art* t, char* tag, int indent);

static char*
to_text_string(struct art* t, char* tag, int indent);

int
pgmoneta_art_init(struct art** tree)
Expand Down Expand Up @@ -363,27 +373,17 @@ pgmoneta_art_iterate(struct art* t, art_callback cb, void* data)
}

char*
pgmoneta_art_to_string(struct art* t, char* tag, int indent)
pgmoneta_art_to_string(struct art* t, int32_t format, char* tag, int indent)
{
char* ret = NULL;
ret = pgmoneta_indent(ret, tag, indent);
if (t == NULL || t->size == 0)
if (format == FORMAT_JSON)
{
ret = pgmoneta_append(ret, "{}");
return ret;
return to_json_string(t, tag, indent);
}
ret = pgmoneta_append(ret, "{\n");
struct to_string_param param = {
.indent = indent + INDENT_PER_LEVEL,
.str = ret,
.t = t,
.cnt = 0,
};
pgmoneta_art_iterate(t, art_to_string_cb, &param);
ret = pgmoneta_append(NULL, param.str);
ret = pgmoneta_indent(ret, NULL, indent);
ret = pgmoneta_append(ret, "}");
return ret;
else if (format == FORMAT_TEXT)
{
return to_text_string(t, tag, indent);
}
return NULL;
}

static uint32_t
Expand Down Expand Up @@ -1465,15 +1465,110 @@ art_search(struct art* t, unsigned char* key, uint32_t key_len)
}

static int
art_to_string_cb(void* param, const unsigned char* key, uint32_t key_len, struct value* value)
art_to_json_string_cb(void* param, const unsigned char* key, uint32_t key_len, struct value* value)
{
struct to_string_param* p = (struct to_string_param*) param;
char* str = NULL;
char* tag = NULL;
p->cnt++;
bool has_next = p->cnt < p->t->size;
str = pgmoneta_value_to_string(value, (char*)key, p->indent);
tag = pgmoneta_append_char(tag, '"');
tag = pgmoneta_append(tag, (char*)key);
tag = pgmoneta_append_char(tag, '"');
tag = pgmoneta_append(tag, ": ");
str = pgmoneta_value_to_string(value, FORMAT_JSON, tag, p->indent);
free(tag);
p->str = pgmoneta_append(p->str, str);
p->str = pgmoneta_append(p->str, has_next ? ",\n" : "\n");

free(str);
return 0;
}

static int
art_to_text_string_cb(void* param, const unsigned char* key, uint32_t key_len, struct value* value)
{
struct to_string_param* p = (struct to_string_param*) param;
char* str = NULL;
char* tag = NULL;
p->cnt++;
bool has_next = p->cnt < p->t->size;
tag = pgmoneta_append(tag, (char*)key);
tag = pgmoneta_append(tag, ": ");
if (value->type == ValueJSON)
{
tag = pgmoneta_append(tag, "\n");
}
if (pgmoneta_compare_string(p->tag, BULLET_POINT))
{
if (p->cnt == 1)
{
str = pgmoneta_value_to_string(value, FORMAT_TEXT, tag, 0);
}
else
{
str = pgmoneta_value_to_string(value, FORMAT_TEXT, tag, p->indent + INDENT_PER_LEVEL);
}
}
else
{
str = pgmoneta_value_to_string(value, FORMAT_TEXT, tag, p->indent);
}
free(tag);
p->str = pgmoneta_append(p->str, str);
p->str = pgmoneta_append(p->str, has_next ? "\n" : "");

free(str);
return 0;
}

static char*
to_json_string(struct art* t, char* tag, int indent)
{
char* ret = NULL;
ret = pgmoneta_indent(ret, tag, indent);
if (t == NULL || t->size == 0)
{
ret = pgmoneta_append(ret, "{}");
return ret;
}
ret = pgmoneta_append(ret, "{\n");
struct to_string_param param = {
.indent = indent + INDENT_PER_LEVEL,
.str = ret,
.t = t,
.cnt = 0,
};
pgmoneta_art_iterate(t, art_to_json_string_cb, &param);
ret = pgmoneta_append(NULL, param.str);
ret = pgmoneta_indent(ret, NULL, indent);
ret = pgmoneta_append(ret, "}");
return ret;
}

static char*
to_text_string(struct art* t, char* tag, int indent)
{
char* ret = NULL;
int next_indent = indent;
if (tag != NULL && !pgmoneta_compare_string(tag, BULLET_POINT))
{
ret = pgmoneta_indent(ret, tag, indent);
next_indent += INDENT_PER_LEVEL;
}
if (t == NULL || t->size == 0)
{
ret = pgmoneta_append(ret, "{}");
return ret;
}
struct to_string_param param = {
.indent = next_indent,
.str = ret,
.t = t,
.cnt = 0,
.tag = tag
};
pgmoneta_art_iterate(t, art_to_text_string_cb, &param);
ret = pgmoneta_append(NULL, param.str);
return ret;
}
Loading

0 comments on commit 68bd3e6

Please sign in to comment.