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"
|
||||
revision: "0.3.0"
|
||||
|
||||
WARNING: THIS FILE IS NOT UP TO DATE
|
||||
|
||||
|
||||
+++++++++++++++++++++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 .
|
||||
|
||||
|
||||
|
||||
47
Readme.txt
47
Readme.txt
@@ -1,21 +1,26 @@
|
||||
Readme file for eJSON
|
||||
=====================
|
||||
|
||||
team: "Javier Velilla,Jocelyn Fiat, Paul Cohen"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
team: "Javier Velilla, Jocelyn Fiat"
|
||||
previous contributors: "Paul Cohen"
|
||||
date: "2014-nov-17"
|
||||
|
||||
1. Introduction
|
||||
---------------
|
||||
|
||||
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
|
||||
features Eiffel2JSON and JSON2Eiffel.
|
||||
with the JSON format. This library provides a JSON parser and visitors,
|
||||
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
|
||||
--------------
|
||||
|
||||
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
|
||||
readme file.
|
||||
|
||||
@@ -46,18 +51,18 @@ Currently the only documentation on eJSON is available at:
|
||||
|
||||
EJSON requires that you have:
|
||||
|
||||
1. Gobo 3.9 installed or later
|
||||
2. One of the following compiler combinations installed:
|
||||
* ISE Eiffel 6.5 or later.
|
||||
1. One of the following compiler combinations installed:
|
||||
* ISE Eiffel 13.11 or later.
|
||||
* gec [try to test]
|
||||
* tecomp [try to test]
|
||||
|
||||
eJSON probably works fine with other versions of the above compilers.
|
||||
There are no known platform dependencies (Windows, Linux).
|
||||
|
||||
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
|
||||
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
|
||||
the test program.
|
||||
@@ -70,18 +75,18 @@ installation.
|
||||
|
||||
Directory Description
|
||||
--------- -----------
|
||||
doc Contains the eJSON.pdf documentation file.
|
||||
examples Contains the two example programs.
|
||||
ejson Contains the actual eJSON library classes.
|
||||
test Contains a test program for eJSON.
|
||||
doc Contains documentation file.
|
||||
examples Contains example codes.
|
||||
library Contains the actual eJSON library classes.
|
||||
test Contains test suite for eJSON.
|
||||
|
||||
7. Contacting the Team
|
||||
----------------------
|
||||
|
||||
Contact the team:
|
||||
|
||||
https://github.com/eiffelhub/json/issues
|
||||
Javier Velilla «javier.hector@gmail.com»
|
||||
Paul Cohen «paco@seibostudios.se»
|
||||
Jocelyn Fiat «jfiat@eiffel.com»
|
||||
|
||||
8. Releases
|
||||
@@ -92,8 +97,16 @@ history.txt.
|
||||
|
||||
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.4.0 2012-12-12 Updated documentation URI
|
||||
0.3.0 2011-07-06 JSON Factory Converters
|
||||
0.2.0 2010-02-07 Adapted to EiffelStudio 6.4 or later, supports void-safety
|
||||
0.1.0 2010-02-07 First release, Adapted to SmartEiffel 1.2r7 and EiffelStudio 6.2 or previous
|
||||
0.1.0 2010-02-07 First release, Adapted to SmartEiffel 1.2r7 and EiffelStudio 6.2 or previous
|
||||
|
||||
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>/.svn$</exclude>
|
||||
</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/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf" readonly="true"/>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -10,7 +10,8 @@ inherit
|
||||
JSON_VISITOR
|
||||
|
||||
create
|
||||
make, make_custom
|
||||
make,
|
||||
make_custom
|
||||
|
||||
feature -- Initialization
|
||||
|
||||
@@ -32,14 +33,52 @@ feature -- Initialization
|
||||
|
||||
feature -- Access
|
||||
|
||||
output: STRING_32
|
||||
output: STRING_GENERAL
|
||||
-- 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
|
||||
do
|
||||
@@ -58,9 +97,7 @@ feature -- Access
|
||||
line_number := line_number + 1
|
||||
end
|
||||
|
||||
object_count_inlining: INTEGER
|
||||
|
||||
array_count_inlining: INTEGER
|
||||
line_number: INTEGER
|
||||
|
||||
feature -- Visitor Pattern
|
||||
|
||||
@@ -71,10 +108,14 @@ feature -- Visitor Pattern
|
||||
l_json_array: ARRAYED_LIST [JSON_VALUE]
|
||||
l_line: like line_number
|
||||
l_multiple_lines: BOOLEAN
|
||||
l_output: like output
|
||||
do
|
||||
l_output := output
|
||||
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
|
||||
output.append ("[")
|
||||
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_output.append_code (91) -- '[' : 91
|
||||
|
||||
l_line := line_number
|
||||
indent
|
||||
from
|
||||
@@ -89,14 +130,14 @@ feature -- Visitor Pattern
|
||||
value.accept (Current)
|
||||
l_json_array.forth
|
||||
if not l_json_array.after then
|
||||
output.append (", ")
|
||||
l_output.append (", ")
|
||||
end
|
||||
end
|
||||
exdent
|
||||
if line_number > l_line or l_json_array.count >= array_count_inlining then
|
||||
new_line
|
||||
end
|
||||
output.append ("]")
|
||||
l_output.append_code (93) -- ']' : 93
|
||||
end
|
||||
|
||||
visit_json_boolean (a_json_boolean: JSON_BOOLEAN)
|
||||
@@ -123,10 +164,12 @@ feature -- Visitor Pattern
|
||||
l_pairs: HASH_TABLE [JSON_VALUE, JSON_STRING]
|
||||
l_line: like line_number
|
||||
l_multiple_lines: BOOLEAN
|
||||
l_output: like output
|
||||
do
|
||||
l_output := output
|
||||
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
|
||||
output.append ("{")
|
||||
l_output.append_code (123) -- '{' : 123
|
||||
l_line := line_number
|
||||
indent
|
||||
from
|
||||
@@ -138,26 +181,29 @@ feature -- Visitor Pattern
|
||||
new_line
|
||||
end
|
||||
l_pairs.key_for_iteration.accept (Current)
|
||||
output.append (": ")
|
||||
l_output.append (": ")
|
||||
l_pairs.item_for_iteration.accept (Current)
|
||||
l_pairs.forth
|
||||
if not l_pairs.after then
|
||||
output.append (", ")
|
||||
l_output.append (", ")
|
||||
end
|
||||
end
|
||||
exdent
|
||||
if line_number > l_line or l_pairs.count >= object_count_inlining then
|
||||
new_line
|
||||
end
|
||||
output.append ("}")
|
||||
l_output.append_code (125) -- '}' : 125
|
||||
end
|
||||
|
||||
visit_json_string (a_json_string: JSON_STRING)
|
||||
-- Visit `a_json_string'.
|
||||
local
|
||||
l_output: like output
|
||||
do
|
||||
output.append ("%"")
|
||||
output.append (a_json_string.item)
|
||||
output.append ("%"")
|
||||
l_output := output
|
||||
l_output.append_code (34) -- '%"' : 34
|
||||
l_output.append (a_json_string.item)
|
||||
l_output.append_code (34) -- '%"' : 34
|
||||
end
|
||||
|
||||
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