-
Notifications
You must be signed in to change notification settings - Fork 25
/
README
142 lines (102 loc) · 5.52 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
NOTE!
The development in this version of the code is stalled. Please take the time and head over to paul's code at http://github.com/davisp/eep0018/tree
Thank you!
/eno
=============================================================================================
This module strives to prepare an EEP0018 implemenation. It implements most of the
functionality described there, with some additional features.
Compiling
=========
Adjust the Makefile's top section. After that, run
make
to compile everything. This results into
./bin/eep0018_drv.so
./bin/eep0018.beam.
Running
=======
The eep0018 module exports these functions:
* start/0 starts the driver.
* start/1 starts the driver; the parameter is the path to the eep0018_drv.so driver
* stop/0 stops the driver.
* json_to_term/1 parses a JSON text
* json_to_term/2 parses a JSON text, with some options (See below).
* term_to_json/1 creates a piece of JSON text.
Status/TODO
===========
Please consider this software as a ALPHA release! TODOs:
* Implement all missing json_to_term/2 options
json_to_term/2 Options - Differences to EEP 18
==============================================
EEP0018 states
| The {float,true} option says to convert all JSON numbers to
| Erlang floats, even if they look like integers.
| With this option, the result has type json(L, float()).
|
| The {float,false} option says to convert integers to integers;
| it is the default.
| With this option, the result has type json(L, number()).
|
| The {label,binary} option says to convert all JSON strings
| to Erlang binaries, even if they are keys in key:value pairs.
| With this option, the result has type json(binary(), N).
| This is the default.
|
| The {label,atom} option says to convert keys to atoms if
| possible, leaving other strings as binaries.
| With this option, the result has type json(json_label(), N).
|
| The {label,existing_atom} option says to convert keys to
| atoms if the atoms already exist, leaving other keys as
| binaries. All other strings remain binaries too.
| With this option, the result has type json(json_label(), N).
Instead of that we implement the following options
{parse,object}(*) ...... Parse only Erlang objects and arrays, i.e. parsing "123" would fail.
{parse,value} Parse all Erlang values, i.e. parsing "123" would succeed.
{objects,eep0018} ... (*) JSON objects will be mapped as laid out in EEP0018, i.e.
{} -> [{}]
{"a":"b","c":"d"} -> [{<<"a">>,<<"b">>},{<<"c">>,<<"d">>}]
{objects,compat} JSON objects will be mapped as in some other implementations, i.e.
{} -> {[]}
{"a":"b","c":"d"} -> {[{<<"a">>,<<"b">>},{<<"c">>,<<"d">>}]}
{labels,binary} ... (*) Labels will be mapped as binaries, i.e.
{"a":"b","c":"d"} -> {[{<<"a">>,<<"b">>},{<<"c">>,<<"d">>}]}
{labels,atom} Labels will be mapped as binaries, i.e.
{"a":"b","c":"d"} -> {[{a,<<"b">>},{c,<<"d">>}]}
Use this option only if you know that there is a limited range of
possible labels and that these labels can be converted to atoms.
The {labels,existing_atom} option is not implemented, because
a) it runs quite slow, and
b) the result of such an operation is unpredictable.
{number,exact} ... (*) Numbers are parsed exactly as they are in the JSON source code, i.e.
a JSON integer will be mapped as an Erlang integer, and a JSON float
will be mapped as an Erlang float, in the precision supported by the
current OTP runtime.
{number,number} Numbers are parsed exactly as they are in the JSON source code, i.e.
a JSON integer will be mapped as an Erlang integer, and a JSON float
will be mapped as an Erlang float, in the precision supported by the
C runtime and ei libraries, eg. signed 32-bit for integers and 64 bit
floating points.
{number,float} All numbers are parsed as an Erlang float, in the precision supported
by the C runtime (eg. 64 bit).
Performance considerations
==========================
Some of these options have a huge performance impact, as they are implemented on the Erlang side
and so require a two-step parsing process (one round in the driver and one extra round in Erlang):
* {number,exact} is implemented by transmitting the number value as a string
* {objects,compat} is currently implemented in Erlang. A final implementation -
after everyone agreed upon the Erlang mapping of JSON objects, would of
course be done in C.
YAJL
====
The parsing engine that drives behind that module is YAJL, see http://lloydforge.org/projects/yajl/.
The source tree contains a copy of that library, currently at version 0.4.0.
Implemenation Status
====================
The current development is done on OS/X 10.5, and is usually checked on Ubuntu/32 bit.
Other OSes might need a tuned Makefile.{uname -s}.
Critical Discussion
===================
For a critical discussion of JSON <-> Erlang interaction see here:
http://fullof.bs/prototype-eep-18-considered-harmful-the-problems-with-erlang-to-json-term-translation#more-402
and
http://sc.tri-bit.com/outgoing/scjson%20parser%20halp.html