Encoding an empty array or object worked, but encoding it again
(possibly after adding some items) failed, because the visited flag
(used for detecting circular references) wasn't zeroed.
With this encoding flag, the object key-value pairs in output are in
the same order in which they were first inserted into the object.
To make this possible, a key of an object is now a serial number plus
a string. An object keeps an increasing counter which is used to
assign serial number to the keys. Hashing, comparison and public API
functions were changed to act only on the string part, i.e. the serial
number is ignored everywhere else but in the encoder, where it's used
to order object keys if JSON_PRESERVE_ORDER flag is used.
This patch changes the sprintf format from "%0.17f" to "%.17g", as the
f format specifier doesn't print the exponent at all. This caused
losing precision in all but the most simple cases.
Because the g specifier doesn't print the decimal fraction or exponent
if they're not needed, a ".0" has to be appended by hand in these
cases. Otherwise the value's type changes from real to integer when
decoding again.
Thanks to Philip Grandinetti for reporting this issue.
- 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
It's now an error to try to add an object or array to itself. The
encoder checks for circular references and fails with an error status
if one is detected.
Some day we will have ANSI C compatibility... This change doesn't make
the API backwards incompatible because uint32_t was only used in flags
to json_dump*() and the flags are meant to be used only by ORing
constants and macro output, and actually currently only JSON_INDENT
can be used.
Don't alloca() a whitespace buffer and fill it with spaces in each
call to dump_indent. Instead, use a static whitespace buffer.
As a bonus, this saves the use of poorly portable alloca().
Inside strings, All UTF-8 characters except for \, " and Unicode
control codes are dumped as-is. The control codes that have a special
one-character escape use that escape, and other control codes are
dumped using the \uXXXX escape.
Nothing was appended to strbuffer, so the buffer was left empty. An
empty strbuffer is not an empty string but NULL, so the result was a
segfault.
This patch fixes the problem by initializing strbuffer to an empty
string.
String buffer (strbuffer) is an object that resizes automatically when
data is added to it. It was implemented by generalizing the technique
used in json_dumps().