mirror of
https://codeberg.org/grunfink/snac2.git
synced 2024-11-22 05:15:04 +00:00
Backport from xs.
This commit is contained in:
parent
15f755960b
commit
6949d7df8a
2 changed files with 53 additions and 57 deletions
108
xs_json.h
108
xs_json.h
|
@ -4,9 +4,10 @@
|
||||||
|
|
||||||
#define _XS_JSON_H
|
#define _XS_JSON_H
|
||||||
|
|
||||||
xs_str *xs_json_dumps_pp(const xs_val *data, int indent);
|
|
||||||
int xs_json_dump_pp(const xs_val *data, int indent, FILE *f);
|
int xs_json_dump_pp(const xs_val *data, int indent, FILE *f);
|
||||||
|
xs_str *xs_json_dumps_pp(const xs_val *data, int indent);
|
||||||
#define xs_json_dumps(data) xs_json_dumps_pp(data, 0)
|
#define xs_json_dumps(data) xs_json_dumps_pp(data, 0)
|
||||||
|
#define xs_json_dump(data, f) xs_json_dumps_pp(data, 0, f)
|
||||||
xs_val *xs_json_loads(const xs_str *json);
|
xs_val *xs_json_loads(const xs_str *json);
|
||||||
xs_val *xs_json_load(FILE *f);
|
xs_val *xs_json_load(FILE *f);
|
||||||
|
|
||||||
|
@ -17,63 +18,55 @@ xs_val *xs_json_load(FILE *f);
|
||||||
|
|
||||||
/** JSON dumps **/
|
/** JSON dumps **/
|
||||||
|
|
||||||
static xs_str *_xs_json_dumps_str(xs_str *s, const char *data)
|
static void _xs_json_dump_str(const char *data, FILE *f)
|
||||||
/* dumps a string in JSON format */
|
/* dumps a string in JSON format */
|
||||||
{
|
{
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
s = xs_str_cat(s, "\"");
|
fputs("\"", f);
|
||||||
|
|
||||||
while ((c = *data)) {
|
while ((c = *data)) {
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
s = xs_str_cat(s, "\\n");
|
fputs("\\n", f);
|
||||||
else
|
else
|
||||||
if (c == '\r')
|
if (c == '\r')
|
||||||
s = xs_str_cat(s, "\\r");
|
fputs("\\r", f);
|
||||||
else
|
else
|
||||||
if (c == '\t')
|
if (c == '\t')
|
||||||
s = xs_str_cat(s, "\\t");
|
fputs("\\t", f);
|
||||||
else
|
else
|
||||||
if (c == '\\')
|
if (c == '\\')
|
||||||
s = xs_str_cat(s, "\\\\");
|
fputs("\\\\", f);
|
||||||
else
|
else
|
||||||
if (c == '"')
|
if (c == '"')
|
||||||
s = xs_str_cat(s, "\\\"");
|
fputs("\\\"", f);
|
||||||
else
|
else
|
||||||
if (c < 32) {
|
if (c < 32)
|
||||||
char tmp[10];
|
fprintf(f, "\\u%04x", (unsigned int) c);
|
||||||
|
|
||||||
snprintf(tmp, sizeof(tmp), "\\u%04x", (unsigned int) c);
|
|
||||||
s = xs_str_cat(s, tmp);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
s = xs_append_m(s, data, 1);
|
fputc(c, f);
|
||||||
|
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = xs_str_cat(s, "\"");
|
fputs("\"", f);
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static xs_str *_xs_json_indent(xs_str *s, int level, int indent)
|
static void _xs_json_indent(int level, int indent, FILE *f)
|
||||||
/* adds indentation */
|
/* adds indentation */
|
||||||
{
|
{
|
||||||
if (indent) {
|
if (indent) {
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
s = xs_str_cat(s, "\n");
|
fputc('\n', f);
|
||||||
|
|
||||||
for (n = 0; n < level * indent; n++)
|
for (n = 0; n < level * indent; n++)
|
||||||
s = xs_str_cat(s, " ");
|
fputc(' ', f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static xs_str *_xs_json_dumps(xs_str *s, const xs_val *s_data, int level, int indent)
|
static void _xs_json_dump(const xs_val *s_data, int level, int indent, FILE *f)
|
||||||
/* dumps partial data as JSON */
|
/* dumps partial data as JSON */
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
@ -82,85 +75,87 @@ static xs_str *_xs_json_dumps(xs_str *s, const xs_val *s_data, int level, int in
|
||||||
|
|
||||||
switch (xs_type(data)) {
|
switch (xs_type(data)) {
|
||||||
case XSTYPE_NULL:
|
case XSTYPE_NULL:
|
||||||
s = xs_str_cat(s, "null");
|
fputs("null", f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XSTYPE_TRUE:
|
case XSTYPE_TRUE:
|
||||||
s = xs_str_cat(s, "true");
|
fputs("true", f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XSTYPE_FALSE:
|
case XSTYPE_FALSE:
|
||||||
s = xs_str_cat(s, "false");
|
fputs("false", f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XSTYPE_NUMBER:
|
case XSTYPE_NUMBER:
|
||||||
s = xs_str_cat(s, xs_number_str(data));
|
fputs(xs_number_str(data), f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XSTYPE_LIST:
|
case XSTYPE_LIST:
|
||||||
s = xs_str_cat(s, "[");
|
fputc('[', f);
|
||||||
|
|
||||||
while (xs_list_iter(&data, &v)) {
|
while (xs_list_iter(&data, &v)) {
|
||||||
if (c != 0)
|
if (c != 0)
|
||||||
s = xs_str_cat(s, ",");
|
fputc(',', f);
|
||||||
|
|
||||||
s = _xs_json_indent(s, level + 1, indent);
|
_xs_json_indent(level + 1, indent, f);
|
||||||
s = _xs_json_dumps(s, v, level + 1, indent);
|
_xs_json_dump(v, level + 1, indent, f);
|
||||||
|
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = _xs_json_indent(s, level, indent);
|
_xs_json_indent(level, indent, f);
|
||||||
s = xs_str_cat(s, "]");
|
fputc(']', f);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XSTYPE_DICT:
|
case XSTYPE_DICT:
|
||||||
s = xs_str_cat(s, "{");
|
fputc('{', f);
|
||||||
|
|
||||||
xs_str *k;
|
xs_str *k;
|
||||||
while (xs_dict_iter(&data, &k, &v)) {
|
while (xs_dict_iter(&data, &k, &v)) {
|
||||||
if (c != 0)
|
if (c != 0)
|
||||||
s = xs_str_cat(s, ",");
|
fputc(',', f);
|
||||||
|
|
||||||
s = _xs_json_indent(s, level + 1, indent);
|
_xs_json_indent(level + 1, indent, f);
|
||||||
|
|
||||||
s = _xs_json_dumps_str(s, k);
|
_xs_json_dump_str(k, f);
|
||||||
s = xs_str_cat(s, ":");
|
fputc(':', f);
|
||||||
|
|
||||||
if (indent)
|
if (indent)
|
||||||
s = xs_str_cat(s, " ");
|
fputc(' ', f);
|
||||||
|
|
||||||
s = _xs_json_dumps(s, v, level + 1, indent);
|
_xs_json_dump(v, level + 1, indent, f);
|
||||||
|
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = _xs_json_indent(s, level, indent);
|
_xs_json_indent(level, indent, f);
|
||||||
s = xs_str_cat(s, "}");
|
fputc('}', f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XSTYPE_STRING:
|
case XSTYPE_STRING:
|
||||||
s = _xs_json_dumps_str(s, data);
|
_xs_json_dump_str(data, f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
xs_str *xs_json_dumps_pp(const xs_val *data, int indent)
|
xs_str *xs_json_dumps_pp(const xs_val *data, int indent)
|
||||||
/* dumps a piece of data as JSON */
|
/* dumps data as a JSON string */
|
||||||
{
|
{
|
||||||
xstype t = xs_type(data);
|
|
||||||
xs_str *s = NULL;
|
xs_str *s = NULL;
|
||||||
|
size_t sz;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
if (t == XSTYPE_LIST || t == XSTYPE_DICT) {
|
if ((f = open_memstream(&s, &sz)) != NULL) {
|
||||||
s = xs_str_new(NULL);
|
int r = xs_json_dump_pp(data, indent, f);
|
||||||
s = _xs_json_dumps(s, data, 0, indent);
|
fclose(f);
|
||||||
|
|
||||||
|
if (!r)
|
||||||
|
s = xs_free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
@ -170,13 +165,14 @@ xs_str *xs_json_dumps_pp(const xs_val *data, int indent)
|
||||||
int xs_json_dump_pp(const xs_val *data, int indent, FILE *f)
|
int xs_json_dump_pp(const xs_val *data, int indent, FILE *f)
|
||||||
/* dumps data into a file as JSON */
|
/* dumps data into a file as JSON */
|
||||||
{
|
{
|
||||||
xs *j = xs_json_dumps_pp(data, indent);
|
xstype t = xs_type(data);
|
||||||
|
|
||||||
if (j == NULL)
|
if (t == XSTYPE_LIST || t == XSTYPE_DICT) {
|
||||||
return 0;
|
_xs_json_dump(data, 0, indent, f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
fwrite(j, strlen(j), 1, f);
|
return 0;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
/* 5ad148b1c1dbbf7b4550c9fcd13d96ac6def2d21 */
|
/* 7ee8d1e20f4adc0a1cddd64b290efee94e055f32 */
|
||||||
|
|
Loading…
Reference in a new issue