mirror of
https://github.com/akheron/jansson.git
synced 2025-04-05 21:45:04 +00:00
dump: Revise whitespace usage
- Never append newline to output - By default, add spaces between array and object items for more readable output - Introduce the flag JSON_COMPACT to not add the aforementioned spaces
This commit is contained in:
parent
bf01067a8a
commit
f236c14dc5
6 changed files with 221 additions and 22 deletions
|
@ -494,16 +494,30 @@ This sections describes the functions that can be used to encode
|
|||
values to JSON. Only objects and arrays can be encoded, since they are
|
||||
the only valid "root" values of a JSON text.
|
||||
|
||||
By default, the output has no newlines, and spaces are used between
|
||||
array and object elements for a readable output. This behavior can be
|
||||
altered by using the ``JSON_INDENT`` and ``JSON_COMPACT`` flags
|
||||
described below. A newline is never appended to the end of the encoded
|
||||
JSON data.
|
||||
|
||||
Each function takes a *flags* parameter that controls some aspects of
|
||||
how the data is encoded. Its default value is 0. The following macros
|
||||
can be ORed together to obtain *flags*.
|
||||
|
||||
``JSON_INDENT(n)``
|
||||
Pretty-print the result, indenting arrays and objects by *n*
|
||||
spaces. The valid range for *n* is between 0 and 255, other values
|
||||
result in an undefined output. If ``JSON_INDENT`` is not used or
|
||||
*n* is 0, no pretty-printing is done and the result is a compact
|
||||
representation.
|
||||
Pretty-print the result, using newlines between array and object
|
||||
items, and indenting with *n* spaces. The valid range for *n* is
|
||||
between 0 and 255, other values result in an undefined output. If
|
||||
``JSON_INDENT`` is not used or *n* is 0, no newlines are inserted
|
||||
between array and object items.
|
||||
|
||||
``JSON_COMPACT``
|
||||
This flag enables a compact representation, i.e. sets the separator
|
||||
between array and object items to ``","`` and between object keys
|
||||
and values to ``":"``. Without this flag, the corresponding
|
||||
separators are ``", "`` and ``": "`` for more readable output.
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
The following functions perform the actual JSON encoding. The result
|
||||
is in UTF-8.
|
||||
|
|
40
src/dump.c
40
src/dump.c
|
@ -42,7 +42,7 @@ static int dump_to_file(const char *buffer, int size, void *data)
|
|||
/* 256 spaces (the maximum indentation size) */
|
||||
static char whitespace[] = " ";
|
||||
|
||||
static int dump_indent(unsigned long flags, int depth, dump_func dump, void *data)
|
||||
static int dump_indent(unsigned long flags, int depth, int space, dump_func dump, void *data)
|
||||
{
|
||||
if(JSON_INDENT(flags) > 0)
|
||||
{
|
||||
|
@ -57,6 +57,10 @@ static int dump_indent(unsigned long flags, int depth, dump_func dump, void *dat
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
else if(space && !(flags & JSON_COMPACT))
|
||||
{
|
||||
return dump(" ", 1, data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -173,7 +177,7 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
|
|||
return -1;
|
||||
if(n == 0)
|
||||
return dump("]", 1, data);
|
||||
if(dump_indent(flags, depth + 1, dump, data))
|
||||
if(dump_indent(flags, depth + 1, 0, dump, data))
|
||||
return -1;
|
||||
|
||||
for(i = 0; i < n; ++i) {
|
||||
|
@ -184,12 +188,12 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
|
|||
if(i < n - 1)
|
||||
{
|
||||
if(dump(",", 1, data) ||
|
||||
dump_indent(flags, depth + 1, dump, data))
|
||||
dump_indent(flags, depth + 1, 1, dump, data))
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dump_indent(flags, depth, dump, data))
|
||||
if(dump_indent(flags, depth, 0, dump, data))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -202,6 +206,17 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
|
|||
{
|
||||
json_object_t *object;
|
||||
void *iter;
|
||||
const char *separator;
|
||||
int separator_length;
|
||||
|
||||
if(flags & JSON_COMPACT) {
|
||||
separator = ":";
|
||||
separator_length = 1;
|
||||
}
|
||||
else {
|
||||
separator = ": ";
|
||||
separator_length = 2;
|
||||
}
|
||||
|
||||
/* detect circular references */
|
||||
object = json_to_object(json);
|
||||
|
@ -215,7 +230,7 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
|
|||
return -1;
|
||||
if(!iter)
|
||||
return dump("}", 1, data);
|
||||
if(dump_indent(flags, depth + 1, dump, data))
|
||||
if(dump_indent(flags, depth + 1, 0, dump, data))
|
||||
return -1;
|
||||
|
||||
while(iter)
|
||||
|
@ -223,7 +238,7 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
|
|||
void *next = json_object_iter_next((json_t *)json, iter);
|
||||
|
||||
dump_string(json_object_iter_key(iter), dump, data);
|
||||
if(dump(": ", 2, data) ||
|
||||
if(dump(separator, separator_length, data) ||
|
||||
do_dump(json_object_iter_value(iter), flags, depth + 1,
|
||||
dump, data))
|
||||
return -1;
|
||||
|
@ -231,12 +246,12 @@ static int do_dump(const json_t *json, unsigned long flags, int depth,
|
|||
if(next)
|
||||
{
|
||||
if(dump(",", 1, data) ||
|
||||
dump_indent(flags, depth + 1, dump, data))
|
||||
dump_indent(flags, depth + 1, 1, dump, data))
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dump_indent(flags, depth, dump, data))
|
||||
if(dump_indent(flags, depth, 0, dump, data))
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -270,11 +285,6 @@ char *json_dumps(const json_t *json, unsigned long flags)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if(dump_to_strbuffer("\n", 1, (void *)&strbuff)) {
|
||||
strbuffer_close(&strbuff);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = strdup(strbuffer_value(&strbuff));
|
||||
strbuffer_close(&strbuff);
|
||||
|
||||
|
@ -286,9 +296,7 @@ int json_dumpf(const json_t *json, FILE *output, unsigned long flags)
|
|||
if(!json_is_array(json) && !json_is_object(json))
|
||||
return -1;
|
||||
|
||||
if(do_dump(json, flags, 0, dump_to_file, (void *)output))
|
||||
return -1;
|
||||
return dump_to_file("\n", 1, (void *)output);
|
||||
return do_dump(json, flags, 0, dump_to_file, (void *)output);
|
||||
}
|
||||
|
||||
int json_dump_file(const json_t *json, const char *path, unsigned long flags)
|
||||
|
|
|
@ -143,6 +143,7 @@ json_t *json_loadf(FILE *input, json_error_t *error);
|
|||
json_t *json_load_file(const char *path, json_error_t *error);
|
||||
|
||||
#define JSON_INDENT(n) (n & 0xFF)
|
||||
#define JSON_COMPACT 0x100
|
||||
|
||||
char *json_dumps(const json_t *json, unsigned long flags);
|
||||
int json_dumpf(const json_t *json, FILE *output, unsigned long flags);
|
||||
|
|
1
test/.gitignore
vendored
1
test/.gitignore
vendored
|
@ -3,6 +3,7 @@ loads_dumps
|
|||
load_file_dump_file
|
||||
testlogs
|
||||
testprogs/test_array
|
||||
testprogs/test_dump
|
||||
testprogs/test_number
|
||||
testprogs/test_object
|
||||
testprogs/test_simple
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
check_PROGRAMS = test_array test_simple test_number test_object
|
||||
check_PROGRAMS = test_array test_dump test_simple test_number test_object
|
||||
|
||||
test_array_SOURCES = test_array.c util.h
|
||||
test_dump_SOURCES = test_dump.c util.h
|
||||
test_simple_SOURCES = test_simple.c util.h
|
||||
test_number_SOURCES = test_number.c util.h
|
||||
test_object_SOURCES = test_object.c util.h
|
||||
|
|
174
test/testprogs/test_dump.c
Normal file
174
test/testprogs/test_dump.c
Normal file
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
|
||||
*
|
||||
* Jansson is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <jansson.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
|
||||
static json_t *create_object()
|
||||
{
|
||||
json_t *object;
|
||||
|
||||
object = json_object();
|
||||
if(!object)
|
||||
fail("unable to create an object");
|
||||
|
||||
if(json_object_set_new(object, "a", json_integer(1)) ||
|
||||
json_object_set_new(object, "b", json_integer(2)))
|
||||
fail("unable to set object values");
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
static json_t *create_array()
|
||||
{
|
||||
json_t *array;
|
||||
|
||||
array = json_array();
|
||||
if(!array)
|
||||
fail("unable to create an array");
|
||||
|
||||
if(json_array_append_new(array, json_integer(1)) ||
|
||||
json_array_append_new(array, json_integer(2)))
|
||||
fail("unable to append array values");
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
#define NORMAL_OBJECT "{\"a\": 1, \"b\": 2}"
|
||||
#define NORMAL_ARRAY "[1, 2]"
|
||||
|
||||
static void test_normal()
|
||||
{
|
||||
json_t *object;
|
||||
json_t *array;
|
||||
char *result;
|
||||
|
||||
object = create_object();
|
||||
array = create_array();
|
||||
|
||||
result = json_dumps(object, 0);
|
||||
if(strcmp(result, NORMAL_OBJECT) != 0)
|
||||
fail("unexpected encoded object");
|
||||
free(result);
|
||||
|
||||
result = json_dumps(array, 0);
|
||||
if(strcmp(result, NORMAL_ARRAY) != 0)
|
||||
fail("unexpected encoded array");
|
||||
free(result);
|
||||
|
||||
json_decref(object);
|
||||
json_decref(array);
|
||||
}
|
||||
|
||||
|
||||
#define INDENTED_OBJECT \
|
||||
"{\n" \
|
||||
" \"a\": 1,\n" \
|
||||
" \"b\": 2\n" \
|
||||
"}"
|
||||
#define INDENTED_ARRAY \
|
||||
"[\n" \
|
||||
" 1,\n" \
|
||||
" 2\n" \
|
||||
"]"
|
||||
|
||||
static void test_indent()
|
||||
{
|
||||
json_t *object;
|
||||
json_t *array;
|
||||
char *result;
|
||||
|
||||
object = create_object();
|
||||
array = create_array();
|
||||
|
||||
result = json_dumps(object, JSON_INDENT(4));
|
||||
if(strcmp(result, INDENTED_OBJECT) != 0)
|
||||
fail("unexpected encoded object");
|
||||
free(result);
|
||||
|
||||
result = json_dumps(array, JSON_INDENT(4));
|
||||
if(strcmp(result, INDENTED_ARRAY) != 0)
|
||||
fail("unexpected encoded array");
|
||||
free(result);
|
||||
|
||||
json_decref(object);
|
||||
json_decref(array);
|
||||
}
|
||||
|
||||
|
||||
#define COMPACT_OBJECT "{\"a\":1,\"b\":2}"
|
||||
#define COMPACT_ARRAY "[1,2]"
|
||||
|
||||
static void test_compact()
|
||||
{
|
||||
json_t *object;
|
||||
json_t *array;
|
||||
char *result;
|
||||
|
||||
object = create_object();
|
||||
array = create_array();
|
||||
|
||||
result = json_dumps(object, JSON_COMPACT);
|
||||
if(strcmp(result, COMPACT_OBJECT) != 0)
|
||||
fail("unexpected encoded object");
|
||||
free(result);
|
||||
|
||||
result = json_dumps(array, JSON_COMPACT);
|
||||
if(strcmp(result, COMPACT_ARRAY) != 0)
|
||||
fail("unexpected encoded array");
|
||||
free(result);
|
||||
|
||||
json_decref(object);
|
||||
json_decref(array);
|
||||
}
|
||||
|
||||
|
||||
#define INDENTED_COMPACT_OBJECT \
|
||||
"{\n" \
|
||||
" \"a\":1,\n" \
|
||||
" \"b\":2\n" \
|
||||
"}"
|
||||
#define INDENTED_COMPACT_ARRAY \
|
||||
"[\n" \
|
||||
" 1,\n" \
|
||||
" 2\n" \
|
||||
"]"
|
||||
|
||||
static void test_compact_indent()
|
||||
{
|
||||
json_t *object;
|
||||
json_t *array;
|
||||
char *result;
|
||||
|
||||
object = create_object();
|
||||
array = create_array();
|
||||
|
||||
result = json_dumps(object, JSON_INDENT(4) | JSON_COMPACT);
|
||||
if(strcmp(result, INDENTED_COMPACT_OBJECT) != 0)
|
||||
fail("unexpected encoded object");
|
||||
free(result);
|
||||
|
||||
result = json_dumps(array, JSON_INDENT(4) | JSON_COMPACT);
|
||||
if(strcmp(result, INDENTED_COMPACT_ARRAY) != 0)
|
||||
fail("unexpected encoded array");
|
||||
free(result);
|
||||
|
||||
json_decref(object);
|
||||
json_decref(array);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_normal();
|
||||
test_indent();
|
||||
test_compact();
|
||||
test_compact_indent();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue