pboy / eep0018

This module strives to prepare an EEP0018 implemenation (for Erlang <-> json interaction)

This URL has Read+Write access

name age message
file .gitignore Sat Jan 03 09:21:18 -0800 2009 Add a deadsimple build system for Linux and OSX. [eno]
file LICENSE Sun May 17 09:38:49 -0700 2009 Major updates to eep0018 Switched the build sy... [davisp]
file Makefile Sat Jan 03 09:37:20 -0800 2009 OSX/Darwin builds ok again. [eno]
file Makefile.Darwin Sat Jan 03 09:21:18 -0800 2009 Add a deadsimple build system for Linux and OSX. [eno]
file Makefile.Linux Sat Jan 03 09:21:18 -0800 2009 Add a deadsimple build system for Linux and OSX. [eno]
file README Loading commit data...
directory doc/ Sat Dec 27 05:03:47 -0800 2008 Implemented most of the options according to EE... [eno]
directory src/
directory tests/
directory yajl/ Sun Jan 18 16:21:10 -0800 2009 Code deals with insufficient data. [eno]
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