This module strives to prepare an EEP0018 implemenation (for Erlang <-> json interaction)
C Erlang Shell
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
doc
src
tests
yajl
.gitignore
LICENSE
Makefile
Makefile.Darwin
Makefile.Linux
README

README

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