base: Prettier JSON output / options
- Add flags for indenting with 2, 4, or 8 spaces, still defaulting to tabs if none of those are set. - Don't emit a newline before emitting scalar values in dicts.
This commit is contained in:
@@ -463,7 +463,11 @@ typedef enum heim_json_flags {
|
|||||||
HEIM_JSON_F_STRICT = 31,
|
HEIM_JSON_F_STRICT = 31,
|
||||||
HEIM_JSON_F_CNULL2JSNULL = 32,
|
HEIM_JSON_F_CNULL2JSNULL = 32,
|
||||||
HEIM_JSON_F_TRY_DECODE_DATA = 64,
|
HEIM_JSON_F_TRY_DECODE_DATA = 64,
|
||||||
HEIM_JSON_F_ONE_LINE = 128
|
HEIM_JSON_F_ONE_LINE = 128,
|
||||||
|
/* The default is to indent with one tab */
|
||||||
|
HEIM_JSON_F_INDENT2 = 256,
|
||||||
|
HEIM_JSON_F_INDENT4 = 512,
|
||||||
|
HEIM_JSON_F_INDENT8 = 1024,
|
||||||
} heim_json_flags_t;
|
} heim_json_flags_t;
|
||||||
|
|
||||||
heim_object_t heim_json_create(const char *, size_t, heim_json_flags_t,
|
heim_object_t heim_json_create(const char *, size_t, heim_json_flags_t,
|
||||||
|
@@ -66,7 +66,7 @@ struct heim_strbuf {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
base2json(heim_object_t, struct twojson *);
|
base2json(heim_object_t, struct twojson *, int);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
indent(struct twojson *j)
|
indent(struct twojson *j)
|
||||||
@@ -74,8 +74,18 @@ indent(struct twojson *j)
|
|||||||
size_t i = j->indent;
|
size_t i = j->indent;
|
||||||
if (j->flags & HEIM_JSON_F_ONE_LINE)
|
if (j->flags & HEIM_JSON_F_ONE_LINE)
|
||||||
return;
|
return;
|
||||||
while (i--)
|
if (j->flags & HEIM_JSON_F_INDENT2)
|
||||||
j->out(j->ctx, "\t");
|
while (i--)
|
||||||
|
j->out(j->ctx, " ");
|
||||||
|
else if (j->flags & HEIM_JSON_F_INDENT4)
|
||||||
|
while (i--)
|
||||||
|
j->out(j->ctx, " ");
|
||||||
|
else if (j->flags & HEIM_JSON_F_INDENT8)
|
||||||
|
while (i--)
|
||||||
|
j->out(j->ctx, " ");
|
||||||
|
else
|
||||||
|
while (i--)
|
||||||
|
j->out(j->ctx, "\t");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -90,7 +100,7 @@ array2json(heim_object_t value, void *ctx, int *stop)
|
|||||||
j->out(j->ctx, NULL); /* eat previous '\n' if possible */
|
j->out(j->ctx, NULL); /* eat previous '\n' if possible */
|
||||||
j->out(j->ctx, ",\n");
|
j->out(j->ctx, ",\n");
|
||||||
}
|
}
|
||||||
j->ret = base2json(value, j);
|
j->ret = base2json(value, j, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -105,19 +115,29 @@ dict2json(heim_object_t key, heim_object_t value, void *ctx)
|
|||||||
j->out(j->ctx, NULL); /* eat previous '\n' if possible */
|
j->out(j->ctx, NULL); /* eat previous '\n' if possible */
|
||||||
j->out(j->ctx, ",\n");
|
j->out(j->ctx, ",\n");
|
||||||
}
|
}
|
||||||
j->ret = base2json(key, j);
|
j->ret = base2json(key, j, 0);
|
||||||
if (j->ret)
|
if (j->ret)
|
||||||
return;
|
return;
|
||||||
j->out(j->ctx, " : \n");
|
switch (heim_get_tid(value)) {
|
||||||
j->indent++;
|
case HEIM_TID_ARRAY:
|
||||||
j->ret = base2json(value, j);
|
case HEIM_TID_DICT:
|
||||||
if (j->ret)
|
case HEIM_TID_DATA:
|
||||||
return;
|
j->out(j->ctx, ":\n");
|
||||||
j->indent--;
|
j->indent++;
|
||||||
|
j->ret = base2json(value, j, 0);
|
||||||
|
if (j->ret)
|
||||||
|
return;
|
||||||
|
j->indent--;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
j->out(j->ctx, ": ");
|
||||||
|
j->ret = base2json(value, j, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
base2json(heim_object_t obj, struct twojson *j)
|
base2json(heim_object_t obj, struct twojson *j, int skip_indent)
|
||||||
{
|
{
|
||||||
heim_tid_t type;
|
heim_tid_t type;
|
||||||
int first = 0;
|
int first = 0;
|
||||||
@@ -174,7 +194,8 @@ base2json(heim_object_t obj, struct twojson *j)
|
|||||||
int good;
|
int good;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
indent(j);
|
if (!skip_indent)
|
||||||
|
indent(j);
|
||||||
j->out(j->ctx, "\"");
|
j->out(j->ctx, "\"");
|
||||||
for (p = s; (c = *p); p++) {
|
for (p = s; (c = *p); p++) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@@ -383,7 +404,7 @@ base2json(heim_object_t obj, struct twojson *j)
|
|||||||
heim_release(d);
|
heim_release(d);
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
ret = base2json(d, j);
|
ret = base2json(d, j, 0);
|
||||||
heim_release(d);
|
heim_release(d);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -393,17 +414,20 @@ base2json(heim_object_t obj, struct twojson *j)
|
|||||||
|
|
||||||
case HEIM_TID_NUMBER: {
|
case HEIM_TID_NUMBER: {
|
||||||
char num[32];
|
char num[32];
|
||||||
indent(j);
|
if (!skip_indent)
|
||||||
|
indent(j);
|
||||||
snprintf(num, sizeof (num), "%d", heim_number_get_int(obj));
|
snprintf(num, sizeof (num), "%d", heim_number_get_int(obj));
|
||||||
j->out(j->ctx, num);
|
j->out(j->ctx, num);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HEIM_TID_NULL:
|
case HEIM_TID_NULL:
|
||||||
indent(j);
|
if (!skip_indent)
|
||||||
|
indent(j);
|
||||||
j->out(j->ctx, "null");
|
j->out(j->ctx, "null");
|
||||||
break;
|
break;
|
||||||
case HEIM_TID_BOOL:
|
case HEIM_TID_BOOL:
|
||||||
indent(j);
|
if (!skip_indent)
|
||||||
|
indent(j);
|
||||||
j->out(j->ctx, heim_bool_val(obj) ? "true" : "false");
|
j->out(j->ctx, heim_bool_val(obj) ? "true" : "false");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -427,7 +451,7 @@ heim_base2json(heim_object_t obj, void *ctx, heim_json_flags_t flags,
|
|||||||
j.ret = 0;
|
j.ret = 0;
|
||||||
j.first = 1;
|
j.first = 1;
|
||||||
|
|
||||||
return base2json(obj, &j);
|
return base2json(obj, &j, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user