Make real number encoding and decoding work under all locales
[jansson.git] / doc / conformance.rst
1 .. _rfc-conformance:
2
3 ***************
4 RFC Conformance
5 ***************
6
7 JSON is specified in :rfc:`4627`, *"The application/json Media Type
8 for JavaScript Object Notation (JSON)"*. This chapter discusses
9 Jansson's conformance to this specification.
10
11 Character Encoding
12 ==================
13
14 Jansson only supports UTF-8 encoded JSON texts. It does not support or
15 auto-detect any of the other encodings mentioned in the RFC, namely
16 UTF-16LE, UTF-16BE, UTF-32LE or UTF-32BE. Pure ASCII is supported, as
17 it's a subset of UTF-8.
18
19 Strings
20 =======
21
22 JSON strings are mapped to C-style null-terminated character arrays,
23 and UTF-8 encoding is used internally. Strings may not contain
24 embedded null characters, not even escaped ones.
25
26 For example, trying to decode the following JSON text leads to a parse
27 error::
28
29     ["this string contains the null character: \u0000"]
30
31 All other Unicode codepoints U+0001 through U+10FFFF are allowed.
32
33 Unicode normalization or any other transformation is never performed
34 on any strings (string values or object keys). When checking for
35 equivalence of strings or object keys, the comparison is performed
36 byte by byte between the original UTF-8 representations of the
37 strings.
38
39 Numbers
40 =======
41
42 Real vs. Integer
43 ----------------
44
45 JSON makes no distinction between real and integer numbers; Jansson
46 does. Real numbers are mapped to the ``double`` type and integers to
47 the ``json_int_t`` type, which is a typedef of ``long long`` or
48 ``long``, depending on whether ``long long`` is supported by your
49 compiler or not.
50
51 A JSON number is considered to be a real number if its lexical
52 representation includes one of ``e``, ``E``, or ``.``; regardless if
53 its actual numeric value is a true integer (e.g., all of ``1E6``,
54 ``3.0``, ``400E-2``, and ``3.14E3`` are mathematical integers, but
55 will be treated as real values).
56
57 All other JSON numbers are considered integers.
58
59 When encoding to JSON, real values are always represented
60 with a fractional part; e.g., the ``double`` value 3.0 will be
61 represented in JSON as ``3.0``, not ``3``.
62
63 Overflow, Underflow & Precision
64 -------------------------------
65
66 Real numbers whose absolute values are too small to be represented in
67 a C ``double`` will be silently estimated with 0.0. Thus, depending on
68 platform, JSON numbers very close to zero such as 1E-999 may result in
69 0.0.
70
71 Real numbers whose absolute values are too large to be represented in
72 a C ``double`` will result in an overflow error (a JSON decoding
73 error). Thus, depending on platform, JSON numbers like 1E+999 or
74 -1E+999 may result in a parsing error.
75
76 Likewise, integer numbers whose absolute values are too large to be
77 represented in the ``json_int_t`` type (see above) will result in an
78 overflow error (a JSON decoding error). Thus, depending on platform,
79 JSON numbers like 1000000000000000 may result in parsing error.
80
81 Parsing JSON real numbers may result in a loss of precision. As long
82 as overflow does not occur (i.e. a total loss of precision), the
83 rounded approximate value is silently used. Thus the JSON number
84 1.000000000000000005 may, depending on platform, result in the
85 ``double`` value 1.0.
86
87 Signed zeros
88 ------------
89
90 JSON makes no statement about what a number means; however Javascript
91 (ECMAscript) does state that +0.0 and -0.0 must be treated as being
92 distinct values, i.e. -0.0 |not-equal| 0.0. Jansson relies on the
93 underlying floating point library in the C environment in which it is
94 compiled. Therefore it is platform-dependent whether 0.0 and -0.0 will
95 be distinct values. Most platforms that use the IEEE 754
96 floating-point standard will support signed zeros.
97
98 Note that this only applies to floating-point; neither JSON, C, or
99 IEEE support the concept of signed integer zeros.
100
101 .. |not-equal| unicode:: U+2260
102
103 Types
104 -----
105
106 No support is provided in Jansson for any C numeric types other than
107 ``json_int_t`` and ``double``. This excludes things such as unsigned
108 types, ``long double``, etc. Obviously, shorter types like ``short``,
109 ``int``, ``long`` (if ``json_int_t`` is ``long long``) and ``float``
110 are implicitly handled via the ordinary C type coercion rules (subject
111 to overflow semantics). Also, no support or hooks are provided for any
112 supplemental "bignum" type add-on packages.
113
114
115 Locale
116 ======
117
118 Jansson works fine under any locale.
119
120 However, if the host program is multithreaded and uses ``setlocale()``
121 to switch the locale in one thread while Jansson is currently encoding
122 or decoding JSON data in another thread, the result may be wrong or
123 the program may even crash.
124
125 Jansson uses locale specific functions for certain string conversions
126 in the encoder and decoder, and then converts the locale specific
127 values to/from the JSON representation. This fails if the locale
128 changes between the string conversion and the locale-to-JSON
129 conversion. This can only happen in multithreaded programs that use
130 ``setlocale()``, that switches the locale for all running threads, not
131 only the thread that calls ``setlocale()``.
132
133 If your program uses ``setlocale()`` as described above, consider
134 using the thread-safe ``uselocale()`` instead.