Converted ecf file to complete void-safe.
Improved JSON_PRETTY_STRING_VISITOR to support STRING_8 or STRING_32 output. Added examples. Added doc in the folder "doc". Updated Readme and other files. Added package.iron file.
This commit is contained in:
@@ -5,6 +5,8 @@ team: ""
|
|||||||
date: "2011-07-06"
|
date: "2011-07-06"
|
||||||
revision: "0.3.0"
|
revision: "0.3.0"
|
||||||
|
|
||||||
|
WARNING: THIS FILE IS NOT UP TO DATE
|
||||||
|
|
||||||
|
|
||||||
+++++++++++++++++++++Important Changes since 0.2.0 version++++++++++++++++++++++++++++++++++++++++++++++
|
+++++++++++++++++++++Important Changes since 0.2.0 version++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2010-2014 Javier Velilla and others,
|
Copyright (c) 2010-2014 Javier Velilla, Jocelyn Fiat and others,
|
||||||
https://github.com/eiffelhub/json .
|
https://github.com/eiffelhub/json .
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
43
Readme.txt
43
Readme.txt
@@ -1,21 +1,26 @@
|
|||||||
Readme file for eJSON
|
Readme file for eJSON
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
team: "Javier Velilla,Jocelyn Fiat, Paul Cohen"
|
team: "Javier Velilla, Jocelyn Fiat"
|
||||||
date: "$Date$"
|
previous contributors: "Paul Cohen"
|
||||||
revision: "$Revision$"
|
date: "2014-nov-17"
|
||||||
|
|
||||||
1. Introduction
|
1. Introduction
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
eJSON stands for Eiffel JSON library and is a small Eiffel library for dealing
|
eJSON stands for Eiffel JSON library and is a small Eiffel library for dealing
|
||||||
with the JSON format. The objective of the library is to provide two basic
|
with the JSON format. This library provides a JSON parser and visitors,
|
||||||
features Eiffel2JSON and JSON2Eiffel.
|
including a pretty printer.
|
||||||
|
|
||||||
|
The converters part is now obsolete and not recommended (remember: the
|
||||||
|
objective of converters were to provide two basic features Eiffel2JSON and
|
||||||
|
JSON2Eiffel). There will be a new design for converters as a standalone
|
||||||
|
library on top of Current json library.
|
||||||
|
|
||||||
2. Legal stuff
|
2. Legal stuff
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
eJSON is copyrighted by the author Javier Velilla and others. It is licensed
|
eJSON is copyrighted by the author Javier Velilla, Jocelyn Fiat and others. It is licensed
|
||||||
under the MIT License. See the file license.txt in the same directory as this
|
under the MIT License. See the file license.txt in the same directory as this
|
||||||
readme file.
|
readme file.
|
||||||
|
|
||||||
@@ -46,11 +51,9 @@ Currently the only documentation on eJSON is available at:
|
|||||||
|
|
||||||
EJSON requires that you have:
|
EJSON requires that you have:
|
||||||
|
|
||||||
1. Gobo 3.9 installed or later
|
1. One of the following compiler combinations installed:
|
||||||
2. One of the following compiler combinations installed:
|
* ISE Eiffel 13.11 or later.
|
||||||
* ISE Eiffel 6.5 or later.
|
|
||||||
* gec [try to test]
|
* gec [try to test]
|
||||||
* tecomp [try to test]
|
|
||||||
|
|
||||||
eJSON probably works fine with other versions of the above compilers.
|
eJSON probably works fine with other versions of the above compilers.
|
||||||
There are no known platform dependencies (Windows, Linux).
|
There are no known platform dependencies (Windows, Linux).
|
||||||
@@ -58,6 +61,8 @@ There are no known platform dependencies (Windows, Linux).
|
|||||||
To install eJSON simply extract the ejson-X.Y.Z.zip file to some appropriate
|
To install eJSON simply extract the ejson-X.Y.Z.zip file to some appropriate
|
||||||
place on your hard disk. There are no requirements on environment variables or
|
place on your hard disk. There are no requirements on environment variables or
|
||||||
registry variables.
|
registry variables.
|
||||||
|
Note eJSON is also delivered within EiffelStudio release, under
|
||||||
|
$ISE_LIBRARY/contrib/library/text/parser/json
|
||||||
|
|
||||||
To verify that everything works you should compile the example programs and/or
|
To verify that everything works you should compile the example programs and/or
|
||||||
the test program.
|
the test program.
|
||||||
@@ -70,18 +75,18 @@ installation.
|
|||||||
|
|
||||||
Directory Description
|
Directory Description
|
||||||
--------- -----------
|
--------- -----------
|
||||||
doc Contains the eJSON.pdf documentation file.
|
doc Contains documentation file.
|
||||||
examples Contains the two example programs.
|
examples Contains example codes.
|
||||||
ejson Contains the actual eJSON library classes.
|
library Contains the actual eJSON library classes.
|
||||||
test Contains a test program for eJSON.
|
test Contains test suite for eJSON.
|
||||||
|
|
||||||
7. Contacting the Team
|
7. Contacting the Team
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
Contact the team:
|
Contact the team:
|
||||||
|
|
||||||
|
https://github.com/eiffelhub/json/issues
|
||||||
Javier Velilla «javier.hector@gmail.com»
|
Javier Velilla «javier.hector@gmail.com»
|
||||||
Paul Cohen «paco@seibostudios.se»
|
|
||||||
Jocelyn Fiat «jfiat@eiffel.com»
|
Jocelyn Fiat «jfiat@eiffel.com»
|
||||||
|
|
||||||
8. Releases
|
8. Releases
|
||||||
@@ -92,6 +97,14 @@ history.txt.
|
|||||||
|
|
||||||
Version Date Description
|
Version Date Description
|
||||||
------- ---- -----------
|
------- ---- -----------
|
||||||
|
0.6.0 2014-11-17 Fixed various issue with parsing string (such as \t and related),
|
||||||
|
Implemented escaping of slash '/' only in case of '</' to avoid
|
||||||
|
potential issue with javascript and </script>
|
||||||
|
Many feature renaming to match Eiffel style and naming convention,
|
||||||
|
kept previous feature as obsolete.
|
||||||
|
Restructured the library to make easy extraction of "converter"
|
||||||
|
classes if needed in the future.
|
||||||
|
Marked converters classes as obsolete.
|
||||||
0.5.0 2013-11-dd Added JSON_ITERATOR, simplified JSON_OBJECT
|
0.5.0 2013-11-dd Added JSON_ITERATOR, simplified JSON_OBJECT
|
||||||
0.4.0 2012-12-12 Updated documentation URI
|
0.4.0 2012-12-12 Updated documentation URI
|
||||||
0.3.0 2011-07-06 JSON Factory Converters
|
0.3.0 2011-07-06 JSON Factory Converters
|
||||||
|
|||||||
295
doc/user_guide.mediawiki
Normal file
295
doc/user_guide.mediawiki
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
== 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:
|
||||||
|
- Javier Velilla
|
||||||
|
- Jocelyn Fiat
|
||||||
|
|
||||||
|
The formal name of the project is “eJSON”.
|
||||||
|
|
||||||
|
For questions regarding eJSON please contact
|
||||||
|
- <javier.hector at gmail.com>
|
||||||
|
- <jfiat at eiffel.com>
|
||||||
|
- or directly on [https://github.com/eiffelhub/json/issues]
|
||||||
|
|
||||||
|
=== Current version and status ===
|
||||||
|
|
||||||
|
The latest release is 0.6.0. eJSON has been improved and cleaned.
|
||||||
|
The converters are not obsolete.
|
||||||
|
|
||||||
|
|
||||||
|
== 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 13.11
|
||||||
|
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 go to the [http://ejson.origo.ethz.ch/download download page].
|
||||||
|
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 <code>$ISE_LIBRARY/contrib/library/text/parser/json</code>.
|
||||||
|
|
||||||
|
|
||||||
|
=== 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
|
||||||
|
converters/ (JSON core converter classes !OBSOLETE!)
|
||||||
|
json_converter.e
|
||||||
|
json_hash_table_converter.e
|
||||||
|
json_list_converter.e
|
||||||
|
json_linked_list_converter.e
|
||||||
|
json_arrayed_list_converter.e
|
||||||
|
support/
|
||||||
|
ejson.e
|
||||||
|
shared_ejson.e
|
||||||
|
gobo_converters/ (JSON core converter classes support for GOBO !OBSOLETE!)
|
||||||
|
converters/
|
||||||
|
json_ds_hash_table_converter.e
|
||||||
|
json_ds_linked_list_converter.e
|
||||||
|
shared_gobo_ejson.e
|
||||||
|
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.
|
||||||
|
* Ongoing: Provide a JSON_FACTORY class for easy conversion between arbitrary JSON and Eiffel values.
|
||||||
|
* Ongoing: Provide a mechanism for users to add custom converters between JSON values and user space Eiffel classes.
|
||||||
|
* Ongoing: Implement a full test framework for 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:
|
||||||
|
|
||||||
|
== A simple example ==
|
||||||
|
|
||||||
|
There are two basic approaches to using eJSON; either you use the basic JSON_VALUE classes, converting to and from JSON values to corresponding Eiffel instances or you use the high level eJSON interface class SHARED_EJSON. Of course you can use a mix of both approaches if you find it appropriate!
|
||||||
|
|
||||||
|
Here is an example of how to create a JSON number value from an INTEGER and then obtain the JSON representation for that value.
|
||||||
|
|
||||||
|
simple_example is
|
||||||
|
local
|
||||||
|
i: INTEGER
|
||||||
|
jn: JSON_NUMBER
|
||||||
|
s: STRING
|
||||||
|
do
|
||||||
|
i := 42
|
||||||
|
create jn.make_integer (i)
|
||||||
|
s := jn.representation -- s.is_equal ("42")
|
||||||
|
end
|
||||||
|
|
||||||
|
== 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.
|
||||||
|
|
||||||
|
eiffel_to_json_null_representation is
|
||||||
|
local
|
||||||
|
a: ANY
|
||||||
|
jn: JSON_NULL
|
||||||
|
do
|
||||||
|
create jn
|
||||||
|
print ("JSON representation for JSON null value: '")
|
||||||
|
print (jn.representation)
|
||||||
|
print ("'%N")
|
||||||
|
a := Void
|
||||||
|
if attached {JSON_NULL} json.value (a) as l_jn then -- json from SHARED_EJSON!
|
||||||
|
print ("JSON representation of Eiffel Void reference: '")
|
||||||
|
print (l_jn.representation)
|
||||||
|
print ("'%N")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
The output of the above code will be:
|
||||||
|
|
||||||
|
JSON representation for JSON null value: 'null'
|
||||||
|
JSON representation of Eiffel Void reference: 'null'
|
||||||
|
|
||||||
|
=== 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.
|
||||||
|
|
||||||
83
examples/basic/basic.e
Normal file
83
examples/basic/basic.e
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
class
|
||||||
|
BASIC
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make
|
||||||
|
-- Initialize `Current'.
|
||||||
|
local
|
||||||
|
parser: JSON_PARSER
|
||||||
|
printer: JSON_PRETTY_STRING_VISITOR
|
||||||
|
s: STRING_32
|
||||||
|
do
|
||||||
|
-- Create parser for content `json_content'
|
||||||
|
create parser.make_with_string (json_content)
|
||||||
|
-- Parse the content
|
||||||
|
parser.parse_content
|
||||||
|
if
|
||||||
|
parser.is_valid and then
|
||||||
|
attached parser.parsed_json_value as jv
|
||||||
|
then
|
||||||
|
-- Json content is valid, and well parser.
|
||||||
|
-- and the parsed json value is `jv'
|
||||||
|
|
||||||
|
-- Let's access the glossary/title value
|
||||||
|
if
|
||||||
|
attached {JSON_OBJECT} jv as j_object and then
|
||||||
|
attached {JSON_OBJECT} j_object.item ("glossary") as j_glossary and then
|
||||||
|
attached {JSON_STRING} j_glossary.item ("title") as j_title
|
||||||
|
then
|
||||||
|
print ("The glossary title is %"" + j_title.unescaped_string_8 + "%".%N")
|
||||||
|
else
|
||||||
|
print ("The glossary title was not found!%N")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Pretty print the parsed JSON
|
||||||
|
create s.make_empty
|
||||||
|
create printer.make (s)
|
||||||
|
jv.accept (printer)
|
||||||
|
print ("The JSON formatted using a pretty printer:%N")
|
||||||
|
print (s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
json_content: STRING = "[
|
||||||
|
{
|
||||||
|
"glossary": {
|
||||||
|
"title": "example glossary",
|
||||||
|
"GlossDiv": {
|
||||||
|
"title": "S",
|
||||||
|
"GlossList": {
|
||||||
|
"GlossEntry": {
|
||||||
|
"ID": "SGML",
|
||||||
|
"SortAs": "SGML",
|
||||||
|
"GlossTerm": "Standard Generalized Markup Language",
|
||||||
|
"Acronym": "SGML",
|
||||||
|
"Abbrev": "ISO 8879:1986",
|
||||||
|
"GlossDef": {
|
||||||
|
"para": "A meta-markup language, used to create markup languages such as DocBook.",
|
||||||
|
"GlossSeeAlso": ["GML", "XML"]
|
||||||
|
},
|
||||||
|
"GlossSee": "markup"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
|
||||||
|
feature -- Change
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
invariant
|
||||||
|
-- invariant_clause: True
|
||||||
|
|
||||||
|
end
|
||||||
10
examples/basic/basic.ecf
Normal file
10
examples/basic/basic.ecf
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="basic" uuid="5156B9EE-0436-42A3-BDA1-74710DF05A35">
|
||||||
|
<target name="basic">
|
||||||
|
<root class="BASIC" feature="make"/>
|
||||||
|
<setting name="console_application" value="true"/>
|
||||||
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
|
<library name="json" location="..\..\library\json-safe.ecf" readonly="false"/>
|
||||||
|
<cluster name="basic" location=".\"/>
|
||||||
|
</target>
|
||||||
|
</system>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<exclude>/CVS$</exclude>
|
<exclude>/CVS$</exclude>
|
||||||
<exclude>/.svn$</exclude>
|
<exclude>/.svn$</exclude>
|
||||||
</file_rule>
|
</file_rule>
|
||||||
<option trace="false" profile="false" debug="false" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="transitional" syntax="standard" namespace="EJSON.Library">
|
<option trace="false" profile="false" debug="false" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard" namespace="EJSON.Library">
|
||||||
<assertions/>
|
<assertions/>
|
||||||
</option>
|
</option>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf" readonly="true"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf" readonly="true"/>
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
@@ -10,7 +10,8 @@ inherit
|
|||||||
JSON_VISITOR
|
JSON_VISITOR
|
||||||
|
|
||||||
create
|
create
|
||||||
make, make_custom
|
make,
|
||||||
|
make_custom
|
||||||
|
|
||||||
feature -- Initialization
|
feature -- Initialization
|
||||||
|
|
||||||
@@ -32,14 +33,52 @@ feature -- Initialization
|
|||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
output: STRING_32
|
output: STRING_GENERAL
|
||||||
-- JSON representation
|
-- JSON representation
|
||||||
|
|
||||||
indentation: like output
|
feature -- Settings
|
||||||
|
|
||||||
indentation_step: like indentation
|
indentation_step: STRING
|
||||||
|
-- Text used for indentation.
|
||||||
|
--| by default a tabulation "%T"
|
||||||
|
|
||||||
line_number: INTEGER
|
object_count_inlining: INTEGER
|
||||||
|
-- Inline where object item count is under `object_count_inlining'.
|
||||||
|
--| ex 3:
|
||||||
|
--| { "a", "b", "c" }
|
||||||
|
--| ex 2:
|
||||||
|
--| {
|
||||||
|
--| "a",
|
||||||
|
--| "b",
|
||||||
|
--| "c"
|
||||||
|
--| }
|
||||||
|
|
||||||
|
array_count_inlining: INTEGER
|
||||||
|
-- Inline where array item count is under `object_count_inlining'.
|
||||||
|
|
||||||
|
feature -- Element change
|
||||||
|
|
||||||
|
set_indentation_step (a_step: STRING)
|
||||||
|
-- Set `indentation_step' to `a_step'.
|
||||||
|
do
|
||||||
|
indentation_step := a_step
|
||||||
|
end
|
||||||
|
|
||||||
|
set_object_count_inlining (a_nb: INTEGER)
|
||||||
|
-- Set `object_count_inlining' to `a_nb'.
|
||||||
|
do
|
||||||
|
object_count_inlining := a_nb
|
||||||
|
end
|
||||||
|
|
||||||
|
set_array_count_inlining (a_nb: INTEGER)
|
||||||
|
-- Set `array_count_inlining' to `a_nb'.
|
||||||
|
do
|
||||||
|
array_count_inlining := a_nb
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
indentation: STRING
|
||||||
|
|
||||||
indent
|
indent
|
||||||
do
|
do
|
||||||
@@ -58,9 +97,7 @@ feature -- Access
|
|||||||
line_number := line_number + 1
|
line_number := line_number + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
object_count_inlining: INTEGER
|
line_number: INTEGER
|
||||||
|
|
||||||
array_count_inlining: INTEGER
|
|
||||||
|
|
||||||
feature -- Visitor Pattern
|
feature -- Visitor Pattern
|
||||||
|
|
||||||
@@ -71,10 +108,14 @@ feature -- Visitor Pattern
|
|||||||
l_json_array: ARRAYED_LIST [JSON_VALUE]
|
l_json_array: ARRAYED_LIST [JSON_VALUE]
|
||||||
l_line: like line_number
|
l_line: like line_number
|
||||||
l_multiple_lines: BOOLEAN
|
l_multiple_lines: BOOLEAN
|
||||||
|
l_output: like output
|
||||||
do
|
do
|
||||||
|
l_output := output
|
||||||
l_json_array := a_json_array.array_representation
|
l_json_array := a_json_array.array_representation
|
||||||
l_multiple_lines := l_json_array.count >= array_count_inlining or across l_json_array as p some attached {JSON_OBJECT} p.item or attached {JSON_ARRAY} p.item end
|
l_multiple_lines := l_json_array.count >= array_count_inlining
|
||||||
output.append ("[")
|
or across l_json_array as p some attached {JSON_OBJECT} p.item or attached {JSON_ARRAY} p.item end
|
||||||
|
l_output.append_code (91) -- '[' : 91
|
||||||
|
|
||||||
l_line := line_number
|
l_line := line_number
|
||||||
indent
|
indent
|
||||||
from
|
from
|
||||||
@@ -89,14 +130,14 @@ feature -- Visitor Pattern
|
|||||||
value.accept (Current)
|
value.accept (Current)
|
||||||
l_json_array.forth
|
l_json_array.forth
|
||||||
if not l_json_array.after then
|
if not l_json_array.after then
|
||||||
output.append (", ")
|
l_output.append (", ")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
exdent
|
exdent
|
||||||
if line_number > l_line or l_json_array.count >= array_count_inlining then
|
if line_number > l_line or l_json_array.count >= array_count_inlining then
|
||||||
new_line
|
new_line
|
||||||
end
|
end
|
||||||
output.append ("]")
|
l_output.append_code (93) -- ']' : 93
|
||||||
end
|
end
|
||||||
|
|
||||||
visit_json_boolean (a_json_boolean: JSON_BOOLEAN)
|
visit_json_boolean (a_json_boolean: JSON_BOOLEAN)
|
||||||
@@ -123,10 +164,12 @@ feature -- Visitor Pattern
|
|||||||
l_pairs: HASH_TABLE [JSON_VALUE, JSON_STRING]
|
l_pairs: HASH_TABLE [JSON_VALUE, JSON_STRING]
|
||||||
l_line: like line_number
|
l_line: like line_number
|
||||||
l_multiple_lines: BOOLEAN
|
l_multiple_lines: BOOLEAN
|
||||||
|
l_output: like output
|
||||||
do
|
do
|
||||||
|
l_output := output
|
||||||
l_pairs := a_json_object.map_representation
|
l_pairs := a_json_object.map_representation
|
||||||
l_multiple_lines := l_pairs.count >= object_count_inlining or across l_pairs as p some attached {JSON_OBJECT} p.item or attached {JSON_ARRAY} p.item end
|
l_multiple_lines := l_pairs.count >= object_count_inlining or across l_pairs as p some attached {JSON_OBJECT} p.item or attached {JSON_ARRAY} p.item end
|
||||||
output.append ("{")
|
l_output.append_code (123) -- '{' : 123
|
||||||
l_line := line_number
|
l_line := line_number
|
||||||
indent
|
indent
|
||||||
from
|
from
|
||||||
@@ -138,26 +181,29 @@ feature -- Visitor Pattern
|
|||||||
new_line
|
new_line
|
||||||
end
|
end
|
||||||
l_pairs.key_for_iteration.accept (Current)
|
l_pairs.key_for_iteration.accept (Current)
|
||||||
output.append (": ")
|
l_output.append (": ")
|
||||||
l_pairs.item_for_iteration.accept (Current)
|
l_pairs.item_for_iteration.accept (Current)
|
||||||
l_pairs.forth
|
l_pairs.forth
|
||||||
if not l_pairs.after then
|
if not l_pairs.after then
|
||||||
output.append (", ")
|
l_output.append (", ")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
exdent
|
exdent
|
||||||
if line_number > l_line or l_pairs.count >= object_count_inlining then
|
if line_number > l_line or l_pairs.count >= object_count_inlining then
|
||||||
new_line
|
new_line
|
||||||
end
|
end
|
||||||
output.append ("}")
|
l_output.append_code (125) -- '}' : 125
|
||||||
end
|
end
|
||||||
|
|
||||||
visit_json_string (a_json_string: JSON_STRING)
|
visit_json_string (a_json_string: JSON_STRING)
|
||||||
-- Visit `a_json_string'.
|
-- Visit `a_json_string'.
|
||||||
|
local
|
||||||
|
l_output: like output
|
||||||
do
|
do
|
||||||
output.append ("%"")
|
l_output := output
|
||||||
output.append (a_json_string.item)
|
l_output.append_code (34) -- '%"' : 34
|
||||||
output.append ("%"")
|
l_output.append (a_json_string.item)
|
||||||
|
l_output.append_code (34) -- '%"' : 34
|
||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
|
|||||||
16
package.iron
Normal file
16
package.iron
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package json
|
||||||
|
|
||||||
|
project
|
||||||
|
json_safe = "library/json-safe.ecf"
|
||||||
|
json = "library/json.ecf"
|
||||||
|
json_gobo_extension = "library/json_gobo_extension.ecf"
|
||||||
|
|
||||||
|
note
|
||||||
|
title: Eiffel JSON
|
||||||
|
description: Eiffel JSON parser and visitors
|
||||||
|
tags: json,parser,text
|
||||||
|
license: MIT
|
||||||
|
copyright: Copyright (c) 2010-2014 Javier Velilla, Jocelyn Fiat and others,
|
||||||
|
link[github]: "project" https://github.com/eiffelhub/json
|
||||||
|
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user