== Preface == This document is a living document! As always read and try out the code to understand what's really going on. === About the project === The eJSON project was started by Javier Velilla in 2008. The aim was simply to provide JSON support to Eiffel programmers. A couple of other people have been involved to various extent since the start; Berend de Boer, Jocelyn Fiat and Manu Stapf. In 2009 Paul Cohen joined the project as an active developer and later Jocelyn Fiat. The current active maintainers: - Jocelyn Fiat - Javier Velilla The formal name of the project is "eJSON". For questions regarding eJSON please contact - - - or directly on [https://github.com/eiffelhub/json/issues] === Current version and status === The latest release is 0.8.0. eJSON has been improved and cleaned. The converters are now obsolete and are replaced by the "serialization" interfaces. == Introduction == === What is JSON? === JSON (JavaScript Object Notation) is a lightweight computer data interchange format. It is a text-based, human-readable format for representing simple data structures and associative arrays (called objects). See the [http://en.wikipedia.org/wiki/JSON Wikipedia article on JSON], [http://www.json.org www.json.org] and [http://www.json.com www.json.com] for more information. The JSON format is specified in [http://www.ietf.org/rfc/rfc4627.txt IETF RFC 4627] by Douglas Crockford. The official [http://www.iana.org/assignments/media-types Internet MIME media type] for JSON is "application/json". The recommended file name extension for JSON files is ".json". === Advantages === 1. Lightweight data-interchange format. 2. Easy for humans to read and write. 3. Enables easy integration with AJAX/JavaScript web applications. See the article [http://www.developer.com/lang/jscript/article.php/3596836 Speeding Up AJAX with JSON] for a good short discussion on this subject. 4. JSON data structures translate with ease into the native data structures universal to almost all programming languages used today. === Use in Eiffel applications === JSON can be used as a general serialization format for Eiffel objects. As such it could be used as a: * Data representation format in REST-based web service applications written in Eiffel. * Serialization format for Eiffel objects in persistence solutions. * File format for configuration files in Eiffel systems. === Prerequisites === eJSON works today with EiffelStudio 17.05 There is an optional extension that requires the latest snapshot of the Gobo Eiffel libraries (a working snapshot is distributed with EiffelStudio). The depencencies on Gobo are on Gobo's unicode and regex libraries and for some of the extra features in eJSON, on Gobos structure classes DS_HASH_TABLE and DS_LINKED_LIST. eJSON is intended to work with all ECMA compliant Eiffel compilers. === Installation === You can either download a given release and install on your machine or you can get the latest snapshot of the code. To download latest source code: [https://github.com/eiffelhub/json/archive/master.zip master archive file]. To get the latest snapshot of the code do: : $ git clone https://github.com/eiffelhub/json.git json *[https://github.com/eiffelhub/json/releases download page] *[https://github.com/eiffelhub/json github project] Note that the latest json release is also delivered with EiffelStudio installation under $ISE_LIBRARY/contrib/library/text/parser/json. === Cluster and directory layout === json/ library/ (Root directory for eJSON library classes) kernel/ (All classes in this cluster should eventually only depend on ECMA Eiffel and FreeELKS). json_array.e json_boolean.e json_null.e json_number.e json_object.e json_string.e json_value.e parser/ json_parser.e json_parser_access.e json_reader.e json_tokens.e utility/ file/ json_file_reader.e visitor/ json_visitor.e json_iterator.e json_pretty_string_visitor.e print_json_visitor.e serialization/ deserializer/... serializer/... ... converters/ (JSON core converter classes !OBSOLETE!) gobo_converters/ (JSON core converter classes support for GOBO !OBSOLETE!) test/ (Contains autotest suite) autotest/ (AutoTest based unit test). examples/ (Example code) === Future development === Here is a list of suggestions for future development of eJSON. * Suggestion: Investigate performance and improve it if neccessary. * Suggestion: Support JSON references. See [http://www.json.com/2007/10/19/json-referencing-proposal-and-library JSON Referencing Proposal and Library] and [http://www.sitepen.com/blog/2008/06/17/json-referencing-in-dojo JSON referencing in Dojo] for more information. * Suggestion: Support JSON path. See [http://goessner.net/articles/JsonPath JSONPath - XPath for JSON] for more information. * Suggestion: Support JSON schema validation. See [http://json-schema.org JSON Schema Proposal] for more information. * Suggestion: Support RDF JSON serialization. See [http://n2.talis.com/wiki/RDF_JSON_Specification RDF JSON Specification] for more information. * Suggestion: Add support to JSON classes for conversion from Eiffel manifest values. So one can write things like: == Mapping of JSON values to Eiffel values == === JSON number === JSON numbers are represented by the class JSON_NUMBER. JSON number values can be converted to/from NATURAL_*, INTEGER_* and REAL_64 values. For floating point values REAL_* is used. The complete mapping is as follows: JSON number -> Eiffel: * -128 <= n <= +127 -> INTEGER_8 * n can't be represented by INTEGER_8 and -32768 <= n <= +32767 -> INTEGER_16 * n can't be represented by INTEGER_16 and -2147483648 <= n <= +2147483647 -> INTEGER_32 * n can't be represented by INTEGER_32 and -9223372036854775808 <= n <= +9223372036854775807 -> INTEGER_64 * n can't be represented by INTEGER_64 and 9223372036854775808 <= n <= 18446744073709551615 -> NATURAL_64 * n has fractional dot '.' -> REAL_64. * n -> eJSON exception if number can't be represented by a INTEGER_64, NATURAL_64 or REAL_64. Eiffel -> JSON number: * NATURAL_8, NATURAL_16, NATURAL_32, NATURAL_64, NATURAL -> JSON number * INTEGER_8, INTEGER_16, INTEGER_32, INTEGER_64, INTEGER -> JSON number * REAL_32, REAL_64, REAL -> JSON number You can use the following creation routines to create JSON_NUMBER instances: * JSON_NUMBER.make_integer * JSON_NUMBER.make_real * JSON_NUMBER.make_natural eiffel_to_json_number_representation is local i: INTEGER r: REAL jn: JSON_NUMBER do print ("JSON representation of Eiffel INTEGER: '") i := 123 create jn.make_integer (i) print (jn.representation) print ("'%N") print ("JSON representation of Eiffel REAL: '") r := 12.3 create jn.make_real (r) print (jn.representation) print ("'%N") end The output of the above code will be: JSON representation of Eiffel INTEGER: '123' JSON representation of Eiffel REAL: '12.300000190734863' === JSON boolean === JSON boolean values are represented by the class JSON_BOOLEAN. The JSON boolean value "true" is converted to/from the BOOLEAN value "True" and the JSON boolean value "false is converted to/from the BOOLEAN value "False". eiffel_to_json_boolean_representation is local b: BOOLEAN jb: JSON_BOOLEAN do print ("JSON representation of Eiffel BOOLEAN: '") b := True create jb.make (b) print (jb.representation) print ("'%N") print("JSON representation of Eiffel BOOLEAN: '") b := False create jb.make (b) print (jb.representation) print ("'%N") end The output of the above code will be: JSON representation of Eiffel BOOLEAN: 'true' JSON representation of Eiffel BOOLEAN: 'false' === JSON string === JSON strings are represented by the class JSON_STRING. JSON string values can be converted to/from STRING_32, STRING and CHARACTER values. The complete mapping is as follows: JSON string -> Eiffel: * All JSON strings -> STRING or STRING_32 Eiffel -> JSON string: * STRING_32 -> JSON string * STRING -> JSON string * CHARACTER -> JSON string eiffel_to_json_string_representation is local s: STRING js: JSON_STRING do print ("JSON representation of Eiffel STRING: '") s := "JSON rocks!" create js.make_from_string (s) print (js.representation) print ("'%N") end The output of the above code will be: JSON representation of Eiffel STRING: '"JSON rocks!"' Note: JSON escape unicode characters, as well a other specific characters, to get the unescaped string value, use either 'unescaped_string_8' or 'unescaped_string_32'. === JSON null === The JSON null value is represented by the class JSON_NULL. The JSON null value can be converted to/from Void. === JSON array === JSON array is represented by the class JSON_ARRAY. === JSON object === JSON object is represented by the class JSON_OBJECT. == The eJSON visitor pattern == TBD. See examples. == The eJSON file reader class == TBD. == The serialization interfaces == - JSON_SERIALIZER: convert Eiffel object to JSON string - JSON_DESERIALIZER: convert JSON string to Eiffel object - JSON_SERIALIZATION: convert in both way, serializer and deserializer - JSON_*_CONTEXT: used to register custom (de)serializer, and set various settings.