This commit is contained in:
Jocelyn Fiat
2013-11-18 17:30:37 +00:00
26 changed files with 3782 additions and 3549 deletions

View File

@@ -0,0 +1,9 @@
# Set default behaviour, in case users don't have core.autocrlf set.
* text=auto
# Explicitly declare text files we want to always be normalized and converted
# to native line endings on checkout.
*.e text
*.ecf text
*.bat text
*.json text

View File

@@ -1,26 +1,26 @@
History file for EJSON History file for EJSON
====================== ======================
team: "" team: ""
date: "2011-07-06" date: "2011-07-06"
revision: "0.3.0" revision: "0.3.0"
+++++++++++++++++++++Important Changes since 0.2.0 version++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++Important Changes since 0.2.0 version++++++++++++++++++++++++++++++++++++++++++++++
*Updated skip_white_spaces, now check %U and %T codes *Updated skip_white_spaces, now check %U and %T codes
*Undo changes to is_a_valid_number, because it's doesn't follow the *Undo changes to is_a_valid_number, because it's doesn't follow the
JSON spec. Tests : fail13.json, fail29.json and fail30.json are valid JSON spec. Tests : fail13.json, fail29.json and fail30.json are valid
with this implementation, so we go back to the previous with this implementation, so we go back to the previous
implementation. implementation.
*Added autotest test suite *Added autotest test suite
*Added getest based test program *Added getest based test program
*Updated Eiffel configuration file, updated to the new clusters *Updated Eiffel configuration file, updated to the new clusters
*Added converters and factory classes *Added converters and factory classes
*Added new top level directories; library, test, build and example *Added new top level directories; library, test, build and example

View File

@@ -1,20 +1,20 @@
Copyright (c) 2010 Javier Velilla and others, http://ejson.origo.ethz.ch Copyright (c) 2010 Javier Velilla and others, http://ejson.origo.ethz.ch
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.

View File

@@ -1,97 +1,99 @@
Readme file for eJSON Readme file for eJSON
===================== =====================
team: "Javier Velilla,Jocelyn Fiat, Paul Cohen" team: "Javier Velilla,Jocelyn Fiat, Paul Cohen"
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
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. The objective of the library is to provide two basic
features Eiffel2JSON and JSON2Eiffel. features Eiffel2JSON and JSON2Eiffel.
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 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.
3. Versioning scheme 3. Versioning scheme
-------------------- --------------------
eJSON version numbers has the form: eJSON version numbers has the form:
«major number».«minor number».«patch level» «major number».«minor number».«patch level»
eJSON will retain the major number 0 as long as it has beta status. A change in eJSON will retain the major number 0 as long as it has beta status. A change in
major number indicates that a release is not backward compatible. A change in major number indicates that a release is not backward compatible. A change in
minor number indicates that a release is backward compatible (within that major minor number indicates that a release is backward compatible (within that major
number) but that new useful features may have been added. A change in patch number) but that new useful features may have been added. A change in patch
level simply indicates that the release contains bug fixes for the previous level simply indicates that the release contains bug fixes for the previous
release. Note that as long as eJSON is in beta status (0.Y.Z) backward release. Note that as long as eJSON is in beta status (0.Y.Z) backward
compatibility is not guranteed for changes in minor numbers! compatibility is not guranteed for changes in minor numbers!
4. Documentation 4. Documentation
--------------- ---------------
Currently the only documentation on eJSON is available at: Currently the only documentation on eJSON is available at:
https://github.com/eiffelhub/json/wiki/User-guide https://github.com/eiffelhub/json/wiki/User-guide
5. Requirements and installation 5. Requirements and installation
-------------------------------- --------------------------------
EJSON requires that you have: EJSON requires that you have:
1. Gobo 3.9 installed or later 1. Gobo 3.9 installed or later
2. One of the following compiler combinations installed: 2. One of the following compiler combinations installed:
* ISE Eiffel 6.5 or later. * ISE Eiffel 6.5 or later.
* gec [try to test] * gec [try to test]
* tecomp [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).
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.
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.
6. Contents of eJSON 6. Contents of eJSON
-------------------- --------------------
All directory names below are relative to the root directory of your ejson All directory names below are relative to the root directory of your ejson
installation. installation.
Directory Description Directory Description
--------- ----------- --------- -----------
doc Contains the eJSON.pdf documentation file. doc Contains the eJSON.pdf documentation file.
examples Contains the two example programs. examples Contains the two example programs.
ejson Contains the actual eJSON library classes. ejson Contains the actual eJSON library classes.
test Contains a test program for eJSON. test Contains a test program for eJSON.
7. Contacting the Team 7. Contacting the Team
---------------------- ----------------------
Contact the team: Contact the team:
Javier Velilla «javier.hector@gmail.com» Javier Velilla «javier.hector@gmail.com»
Paul Cohen «paco@seibostudios.se» Paul Cohen «paco@seibostudios.se»
Jocelyn Fiat «jfiat@eiffel.com» Jocelyn Fiat «jfiat@eiffel.com»
8. Releases 8. Releases
----------- -----------
For more information on what was changed in each release look in the file For more information on what was changed in each release look in the file
history.txt. history.txt.
Version Date Description Version Date Description
------- ---- ----------- ------- ---- -----------
0.3.0 2011-07-06 JSON Factory Converters 0.5.0 2013-11-dd Added JSON_ITERATOR, simplified JSON_OBJECT
0.2.0 2010-02-07 Adapted to EiffelStudio 6.4 or later, supports void-safety 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

View File

@@ -1,38 +1,37 @@
note note
description: "Objects that ..." description: "Objects that ..."
author: "" date: "$Date$"
date: "$Date$" revision: "$Revision$"
revision: "$Revision$"
class
class JSON_FILE_READER
JSON_FILE_READER
feature -- Access
feature -- Access
read_json_from (a_path: STRING): detachable STRING
read_json_from (a_path: STRING): detachable STRING local
local l_file: PLAIN_TEXT_FILE
l_file: PLAIN_TEXT_FILE template_content: STRING
template_content: STRING l_last_string: detachable STRING
l_last_string: detachable STRING do
do create l_file.make (a_path)
create l_file.make (a_path) -- We perform several checks until we make a real attempt to open the file.
-- We perform several checks until we make a real attempt to open the file. if not l_file.exists then
if not l_file.exists then print ("error: '" + a_path + "' does not exist%N")
print ("error: '" + a_path + "' does not exist%N") else
else if not l_file.is_readable then
if not l_file.is_readable then print ("error: '" + a_path + "' is not readable.%N")
print ("error: '" + a_path + "' is not readable.%N") else
else l_file.open_read
l_file.open_read create template_content.make_empty
create template_content.make_empty l_file.read_stream (l_file.count)
l_file.read_stream (l_file.count) l_last_string := l_file.last_string
l_last_string := l_file.last_string check l_last_string /= Void end -- implied by postcondition of `l_file.read_stream'
check l_last_string /= Void end -- implied by postcondition of `l_file.read_stream' template_content.append (l_last_string.string)
template_content.append (l_last_string.string) Result := template_content
Result := template_content l_file.close
l_file.close end
end end
end end
end
end
end

View File

@@ -0,0 +1,60 @@
note
description:
"JSON Iterator"
pattern: "Iterator visitor"
author: "Jocelyn Fiat"
license:"MIT (see http://www.opensource.org/licenses/mit-license.php)"
date: "2013/08/01"
revision: "Revision 0.1"
deferred class
JSON_ITERATOR
inherit
JSON_VISITOR
feature -- Visitor Pattern
visit_json_array (a_json_array: JSON_ARRAY)
-- Visit `a_json_array'.
do
across
a_json_array as c
loop
c.item.accept (Current)
end
end
visit_json_boolean (a_json_boolean: JSON_BOOLEAN)
-- Visit `a_json_boolean'.
do
end
visit_json_null (a_json_null: JSON_NULL)
-- Visit `a_json_null'.
do
end
visit_json_number (a_json_number: JSON_NUMBER)
-- Visit `a_json_number'.
do
end
visit_json_object (a_json_object: JSON_OBJECT)
-- Visit `a_json_object'.
do
across
a_json_object as c
loop
c.item.accept (Current)
end
end
visit_json_string (a_json_string: JSON_STRING)
-- Visit `a_json_string'.
do
end
end

View File

@@ -1,59 +1,59 @@
note note
description: description:
"JSON Visitor" "JSON Visitor"
pattern: "Visitor" pattern: "Visitor"
author: "Javier Velilla" author: "Javier Velilla"
license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" license:"MIT (see http://www.opensource.org/licenses/mit-license.php)"
date: "2008/08/24" date: "2008/08/24"
revision: "Revision 0.1" revision: "Revision 0.1"
deferred class deferred class
JSON_VISITOR JSON_VISITOR
feature -- Visitor Pattern feature -- Visitor Pattern
visit_json_array (a_json_array: JSON_ARRAY) visit_json_array (a_json_array: JSON_ARRAY)
-- Visit `a_json_array'. -- Visit `a_json_array'.
require require
a_json_array_not_void: a_json_array /= Void a_json_array_not_void: a_json_array /= Void
deferred deferred
end end
visit_json_boolean (a_json_boolean: JSON_BOOLEAN) visit_json_boolean (a_json_boolean: JSON_BOOLEAN)
-- Visit `a_json_boolean'. -- Visit `a_json_boolean'.
require require
a_json_boolean_not_void: a_json_boolean /= Void a_json_boolean_not_void: a_json_boolean /= Void
deferred deferred
end end
visit_json_null (a_json_null: JSON_NULL) visit_json_null (a_json_null: JSON_NULL)
-- Visit `a_json_null'. -- Visit `a_json_null'.
require require
a_json_null_not_void: a_json_null /= Void a_json_null_not_void: a_json_null /= Void
deferred deferred
end end
visit_json_number (a_json_number: JSON_NUMBER) visit_json_number (a_json_number: JSON_NUMBER)
-- Visit `a_json_number'. -- Visit `a_json_number'.
require require
a_json_number_not_void: a_json_number /= Void a_json_number_not_void: a_json_number /= Void
deferred deferred
end end
visit_json_object (a_json_object: JSON_OBJECT) visit_json_object (a_json_object: JSON_OBJECT)
-- Visit `a_json_object'. -- Visit `a_json_object'.
require require
a_json_object_not_void: a_json_object /= Void a_json_object_not_void: a_json_object /= Void
deferred deferred
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'.
require require
a_json_string_not_void: a_json_string /= Void a_json_string_not_void: a_json_string /= Void
deferred deferred
end end
end end

View File

@@ -1,102 +1,102 @@
note note
description: "PRINT_JSON_VISITOR Generates the JSON-String for a JSON_VALUE" description: "PRINT_JSON_VISITOR Generates the JSON-String for a JSON_VALUE"
author: "jvelilla" author: "jvelilla"
date: "2008/08/24" date: "2008/08/24"
revision: "0.1" revision: "0.1"
class class
PRINT_JSON_VISITOR PRINT_JSON_VISITOR
inherit inherit
JSON_VISITOR JSON_VISITOR
create make create make
feature -- Initialization feature -- Initialization
make make
-- Create a new instance -- Create a new instance
do do
create to_json.make_empty create to_json.make_empty
end end
feature -- Access feature -- Access
to_json: STRING to_json: STRING
-- JSON representation -- JSON representation
feature -- Visitor Pattern feature -- Visitor Pattern
visit_json_array (a_json_array: JSON_ARRAY) visit_json_array (a_json_array: JSON_ARRAY)
-- Visit `a_json_array'. -- Visit `a_json_array'.
local local
value: JSON_VALUE value: JSON_VALUE
l_json_array: ARRAYED_LIST [JSON_VALUE] l_json_array: ARRAYED_LIST [JSON_VALUE]
do do
l_json_array:=a_json_array.array_representation l_json_array:=a_json_array.array_representation
to_json.append ("[") to_json.append ("[")
from from
l_json_array.start l_json_array.start
until until
l_json_array.off l_json_array.off
loop loop
value := l_json_array.item value := l_json_array.item
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
to_json.append(",") to_json.append(",")
end end
end end
to_json.append ("]") to_json.append ("]")
end end
visit_json_boolean (a_json_boolean: JSON_BOOLEAN) visit_json_boolean (a_json_boolean: JSON_BOOLEAN)
-- Visit `a_json_boolean'. -- Visit `a_json_boolean'.
do do
to_json.append (a_json_boolean.item.out) to_json.append (a_json_boolean.item.out)
end end
visit_json_null (a_json_null: JSON_NULL) visit_json_null (a_json_null: JSON_NULL)
-- Visit `a_json_null'. -- Visit `a_json_null'.
do do
to_json.append ("null") to_json.append ("null")
end end
visit_json_number (a_json_number: JSON_NUMBER) visit_json_number (a_json_number: JSON_NUMBER)
-- Visit `a_json_number'. -- Visit `a_json_number'.
do do
to_json.append (a_json_number.item) to_json.append (a_json_number.item)
end end
visit_json_object (a_json_object: JSON_OBJECT) visit_json_object (a_json_object: JSON_OBJECT)
-- Visit `a_json_object'. -- Visit `a_json_object'.
local local
l_pairs: HASH_TABLE[JSON_VALUE,JSON_STRING] l_pairs: HASH_TABLE[JSON_VALUE,JSON_STRING]
do do
l_pairs := a_json_object.map_representation l_pairs := a_json_object.map_representation
to_json.append ("{") to_json.append ("{")
from from
l_pairs.start l_pairs.start
until until
l_pairs.off l_pairs.off
loop loop
l_pairs.key_for_iteration.accept (Current) l_pairs.key_for_iteration.accept (Current)
to_json.append (":") to_json.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
to_json.append (",") to_json.append (",")
end end
end end
to_json.append ("}") to_json.append ("}")
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'.
do do
to_json.append ("%"") to_json.append ("%"")
to_json.append (a_json_string.item) to_json.append (a_json_string.item)
to_json.append ("%"") to_json.append ("%"")
end end
end end

View File

@@ -1,85 +1,85 @@
note note
description: "A JSON converter for DS_HASH_TABLE [ANY, HASHABLE]" description: "A JSON converter for DS_HASH_TABLE [ANY, HASHABLE]"
author: "Paul Cohen" author: "Paul Cohen"
date: "$Date: $" date: "$Date: $"
revision: "$Revision: $" revision: "$Revision: $"
file: "$HeadURL: $" file: "$HeadURL: $"
class JSON_DS_HASH_TABLE_CONVERTER class JSON_DS_HASH_TABLE_CONVERTER
inherit inherit
JSON_CONVERTER JSON_CONVERTER
create create
make make
feature {NONE} -- Initialization feature {NONE} -- Initialization
make make
do do
create object.make (0) create object.make (0)
end end
feature -- Access feature -- Access
value: JSON_OBJECT value: JSON_OBJECT
object: DS_HASH_TABLE [ANY, HASHABLE] object: DS_HASH_TABLE [ANY, HASHABLE]
feature -- Conversion feature -- Conversion
from_json (j: like value): detachable like object from_json (j: like value): detachable like object
local local
keys: ARRAY [JSON_STRING] keys: ARRAY [JSON_STRING]
i: INTEGER i: INTEGER
h: HASHABLE h: HASHABLE
a: ANY a: ANY
do do
keys := j.current_keys keys := j.current_keys
create Result.make (keys.count) create Result.make (keys.count)
from from
i := 1 i := 1
until until
i > keys.count i > keys.count
loop loop
h ?= json.object (keys [i], void) h ?= json.object (keys [i], void)
check h /= Void end check h /= Void end
a := json.object (j.item (keys [i]), Void) a := json.object (j.item (keys [i]), Void)
Result.put (a, h) Result.put (a, h)
i := i + 1 i := i + 1
end end
end end
to_json (o: like object): like value to_json (o: like object): like value
local local
c: DS_HASH_TABLE_CURSOR [ANY, HASHABLE] c: DS_HASH_TABLE_CURSOR [ANY, HASHABLE]
js: JSON_STRING js: JSON_STRING
jv: JSON_VALUE jv: JSON_VALUE
failed: BOOLEAN failed: BOOLEAN
do do
create Result.make create Result.make
from from
c := o.new_cursor c := o.new_cursor
c.start c.start
until until
c.after c.after
loop loop
if attached {JSON_STRING} json.value (c.key) as l_key then if attached {JSON_STRING} json.value (c.key) as l_key then
js := l_key js := l_key
else else
create js.make_json (c.key.out) create js.make_json (c.key.out)
end end
jv := json.value (c.item) jv := json.value (c.item)
if jv /= Void then if jv /= Void then
Result.put (jv, js) Result.put (jv, js)
else else
failed := True failed := True
end end
c.forth c.forth
end end
if failed then if failed then
Result := Void Result := Void
end end
end end
end -- class JSON_DS_HASH_TABLE_CONVERTER end -- class JSON_DS_HASH_TABLE_CONVERTER

View File

@@ -1,62 +1,62 @@
note note
description: "A JSON converter for DS_LINKED_LIST [ANY]" description: "A JSON converter for DS_LINKED_LIST [ANY]"
author: "Paul Cohen" author: "Paul Cohen"
date: "$Date: $" date: "$Date: $"
revision: "$Revision: $" revision: "$Revision: $"
file: "$HeadURL: $" file: "$HeadURL: $"
class JSON_DS_LINKED_LIST_CONVERTER class JSON_DS_LINKED_LIST_CONVERTER
inherit inherit
JSON_CONVERTER JSON_CONVERTER
create create
make make
feature {NONE} -- Initialization feature {NONE} -- Initialization
make make
do do
create object.make create object.make
end end
feature -- Access feature -- Access
value: JSON_ARRAY value: JSON_ARRAY
object: DS_LINKED_LIST [ANY] object: DS_LINKED_LIST [ANY]
feature -- Conversion feature -- Conversion
from_json (j: like value): detachable like object from_json (j: like value): detachable like object
local local
i: INTEGER i: INTEGER
do do
create Result.make create Result.make
from from
i := 1 i := 1
until until
i > j.count i > j.count
loop loop
Result.put_last (json.object (j [i], Void)) Result.put_last (json.object (j [i], Void))
i := i + 1 i := i + 1
end end
end end
to_json (o: like object): like value to_json (o: like object): like value
local local
c: DS_LIST_CURSOR [ANY] c: DS_LIST_CURSOR [ANY]
do do
create Result.make_array create Result.make_array
from from
c := o.new_cursor c := o.new_cursor
c.start c.start
until until
c.after c.after
loop loop
Result.add (json.value (c.item)) Result.add (json.value (c.item))
c.forth c.forth
end end
end end
end -- class JSON_DS_LINKED_LIST_CONVERTER end -- class JSON_DS_LINKED_LIST_CONVERTER

View File

@@ -1,28 +1,28 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="json" uuid="4E21C3BD-7951-4C6E-A673-431E762D7414" library_target="json"> <system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="json" uuid="4E21C3BD-7951-4C6E-A673-431E762D7414" library_target="json">
<target name="json"> <target name="json">
<root all_classes="true"/> <root all_classes="true"/>
<file_rule> <file_rule>
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
<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" void_safety="none" syntax="standard" namespace="EJSON.Library"> <option trace="false" profile="false" debug="false" warning="true" full_class_checking="true" void_safety="none" syntax="standard" namespace="EJSON.Library">
<assertions/> <assertions/>
<warning name="export_class_missing" enabled="false"/> <warning name="export_class_missing" enabled="false"/>
<warning name="old_verbatim_strings" enabled="false"/> <warning name="old_verbatim_strings" enabled="false"/>
<warning name="syntax" enabled="false"/> <warning name="syntax" enabled="false"/>
<warning name="vjrv" enabled="false"/> <warning name="vjrv" enabled="false"/>
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf" readonly="true"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf" readonly="true"/>
<cluster name="json" location=".\" recursive="true"> <cluster name="json" location=".\" recursive="true">
<file_rule> <file_rule>
<exclude>^/gobo$</exclude> <exclude>^/gobo$</exclude>
<exclude>^/kernel$</exclude> <exclude>^/kernel$</exclude>
<exclude>^/extras$</exclude> <exclude>^/extras$</exclude>
</file_rule> </file_rule>
<cluster name="kernel" location=".\kernel\" recursive="true"/> <cluster name="kernel" location=".\kernel\" recursive="true"/>
<cluster name="extras" location=".\extras\" recursive="true"/> <cluster name="extras" location=".\extras\" recursive="true"/>
</cluster> </cluster>
</target> </target>
</system> </system>

View File

@@ -1,268 +1,268 @@
note note
description: "Core factory class for creating JSON objects and corresponding Eiffel objects." description: "Core factory class for creating JSON objects and corresponding Eiffel objects."
author: "Paul Cohen" author: "Paul Cohen"
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
file: "$HeadURL: $" file: "$HeadURL: $"
class EJSON class EJSON
inherit inherit
EXCEPTIONS EXCEPTIONS
feature -- Access feature -- Access
value (an_object: detachable ANY): detachable JSON_VALUE value (an_object: detachable ANY): detachable JSON_VALUE
-- JSON value from Eiffel object. Raises an "eJSON exception" if -- JSON value from Eiffel object. Raises an "eJSON exception" if
-- unable to convert value. -- unable to convert value.
local local
i: INTEGER i: INTEGER
ja: JSON_ARRAY ja: JSON_ARRAY
do do
-- Try to convert from basic Eiffel types. Note that we check with -- Try to convert from basic Eiffel types. Note that we check with
-- `conforms_to' since the client may have subclassed the base class -- `conforms_to' since the client may have subclassed the base class
-- that these basic types are derived from. -- that these basic types are derived from.
if an_object = Void then if an_object = Void then
create {JSON_NULL} Result create {JSON_NULL} Result
elseif attached {BOOLEAN} an_object as b then elseif attached {BOOLEAN} an_object as b then
create {JSON_BOOLEAN} Result.make_boolean (b) create {JSON_BOOLEAN} Result.make_boolean (b)
elseif attached {INTEGER_8} an_object as i8 then elseif attached {INTEGER_8} an_object as i8 then
create {JSON_NUMBER} Result.make_integer (i8) create {JSON_NUMBER} Result.make_integer (i8)
elseif attached {INTEGER_16} an_object as i16 then elseif attached {INTEGER_16} an_object as i16 then
create {JSON_NUMBER} Result.make_integer (i16) create {JSON_NUMBER} Result.make_integer (i16)
elseif attached {INTEGER_32} an_object as i32 then elseif attached {INTEGER_32} an_object as i32 then
create {JSON_NUMBER} Result.make_integer (i32) create {JSON_NUMBER} Result.make_integer (i32)
elseif attached {INTEGER_64} an_object as i64 then elseif attached {INTEGER_64} an_object as i64 then
create {JSON_NUMBER} Result.make_integer (i64) create {JSON_NUMBER} Result.make_integer (i64)
elseif attached {NATURAL_8} an_object as n8 then elseif attached {NATURAL_8} an_object as n8 then
create {JSON_NUMBER} Result.make_natural (n8) create {JSON_NUMBER} Result.make_natural (n8)
elseif attached {NATURAL_16} an_object as n16 then elseif attached {NATURAL_16} an_object as n16 then
create {JSON_NUMBER} Result.make_natural (n16) create {JSON_NUMBER} Result.make_natural (n16)
elseif attached {NATURAL_32} an_object as n32 then elseif attached {NATURAL_32} an_object as n32 then
create {JSON_NUMBER} Result.make_natural (n32) create {JSON_NUMBER} Result.make_natural (n32)
elseif attached {NATURAL_64} an_object as n64 then elseif attached {NATURAL_64} an_object as n64 then
create {JSON_NUMBER} Result.make_natural (n64) create {JSON_NUMBER} Result.make_natural (n64)
elseif attached {REAL_32} an_object as r32 then elseif attached {REAL_32} an_object as r32 then
create {JSON_NUMBER} Result.make_real (r32) create {JSON_NUMBER} Result.make_real (r32)
elseif attached {REAL_64} an_object as r64 then elseif attached {REAL_64} an_object as r64 then
create {JSON_NUMBER} Result.make_real (r64) create {JSON_NUMBER} Result.make_real (r64)
elseif attached {ARRAY [detachable ANY]} an_object as a then elseif attached {ARRAY [detachable ANY]} an_object as a then
create ja.make_array create ja.make_array
from from
i := a.lower i := a.lower
until until
i > a.upper i > a.upper
loop loop
if attached value (a @ i) as v then if attached value (a @ i) as v then
ja.add (v) ja.add (v)
else else
check value_attached: False end check value_attached: False end
end end
i := i + 1 i := i + 1
end end
Result := ja Result := ja
elseif attached {CHARACTER_8} an_object as c8 then elseif attached {CHARACTER_8} an_object as c8 then
create {JSON_STRING} Result.make_json (c8.out) create {JSON_STRING} Result.make_json (c8.out)
elseif attached {CHARACTER_32} an_object as c32 then elseif attached {CHARACTER_32} an_object as c32 then
create {JSON_STRING} Result.make_json (c32.out) create {JSON_STRING} Result.make_json (c32.out)
elseif attached {STRING_8} an_object as s8 then elseif attached {STRING_8} an_object as s8 then
create {JSON_STRING} Result.make_json (s8) create {JSON_STRING} Result.make_json (s8)
elseif attached {STRING_32} an_object as s32 then elseif attached {STRING_32} an_object as s32 then
create {JSON_STRING} Result.make_json_from_string_32 (s32) create {JSON_STRING} Result.make_json_from_string_32 (s32)
end end
if Result = Void then if Result = Void then
-- Now check the converters -- Now check the converters
if an_object /= Void and then attached converter_for (an_object) as jc then if an_object /= Void and then attached converter_for (an_object) as jc then
Result := jc.to_json (an_object) Result := jc.to_json (an_object)
else else
raise (exception_failed_to_convert_to_json (an_object)) raise (exception_failed_to_convert_to_json (an_object))
end end
end end
end end
object (a_value: detachable JSON_VALUE; base_class: detachable STRING): detachable ANY object (a_value: detachable JSON_VALUE; base_class: detachable STRING): detachable ANY
-- Eiffel object from JSON value. If `base_class' /= Void an eiffel -- Eiffel object from JSON value. If `base_class' /= Void an eiffel
-- object based on `base_class' will be returned. Raises an "eJSON -- object based on `base_class' will be returned. Raises an "eJSON
-- exception" if unable to convert value. -- exception" if unable to convert value.
local local
i: INTEGER i: INTEGER
ll: LINKED_LIST [detachable ANY] ll: LINKED_LIST [detachable ANY]
t: HASH_TABLE [detachable ANY, STRING_GENERAL] t: HASH_TABLE [detachable ANY, STRING_GENERAL]
keys: ARRAY [JSON_STRING] keys: ARRAY [JSON_STRING]
do do
if a_value = Void then if a_value = Void then
Result := Void Result := Void
else else
if base_class = Void then if base_class = Void then
if a_value = Void then if a_value = Void then
Result := Void Result := Void
elseif attached {JSON_NULL} a_value then elseif attached {JSON_NULL} a_value then
Result := Void Result := Void
elseif attached {JSON_BOOLEAN} a_value as jb then elseif attached {JSON_BOOLEAN} a_value as jb then
Result := jb.item Result := jb.item
elseif attached {JSON_NUMBER} a_value as jn then elseif attached {JSON_NUMBER} a_value as jn then
if jn.item.is_integer_8 then if jn.item.is_integer_8 then
Result := jn.item.to_integer_8 Result := jn.item.to_integer_8
elseif jn.item.is_integer_16 then elseif jn.item.is_integer_16 then
Result := jn.item.to_integer_16 Result := jn.item.to_integer_16
elseif jn.item.is_integer_32 then elseif jn.item.is_integer_32 then
Result := jn.item.to_integer_32 Result := jn.item.to_integer_32
elseif jn.item.is_integer_64 then elseif jn.item.is_integer_64 then
Result := jn.item.to_integer_64 Result := jn.item.to_integer_64
elseif jn.item.is_natural_64 then elseif jn.item.is_natural_64 then
Result := jn.item.to_natural_64 Result := jn.item.to_natural_64
elseif jn.item.is_double then elseif jn.item.is_double then
Result := jn.item.to_double Result := jn.item.to_double
end end
elseif attached {JSON_STRING} a_value as js then elseif attached {JSON_STRING} a_value as js then
create {STRING_32} Result.make_from_string (js.unescaped_string_32) create {STRING_32} Result.make_from_string (js.unescaped_string_32)
elseif attached {JSON_ARRAY} a_value as ja then elseif attached {JSON_ARRAY} a_value as ja then
from from
create ll.make create ll.make
i := 1 i := 1
until until
i > ja.count i > ja.count
loop loop
ll.extend (object (ja [i], Void)) ll.extend (object (ja [i], Void))
i := i + 1 i := i + 1
end end
Result := ll Result := ll
elseif attached {JSON_OBJECT} a_value as jo then elseif attached {JSON_OBJECT} a_value as jo then
keys := jo.current_keys keys := jo.current_keys
create t.make (keys.count) create t.make (keys.count)
from from
i := keys.lower i := keys.lower
until until
i > keys.upper i > keys.upper
loop loop
if attached {STRING_GENERAL} object (keys [i], Void) as s then if attached {STRING_GENERAL} object (keys [i], Void) as s then
t.put (object (jo.item (keys [i]), Void), s) t.put (object (jo.item (keys [i]), Void), s)
end end
i := i + 1 i := i + 1
end end
Result := t Result := t
end end
else else
if converters.has_key (base_class) and then attached converters.found_item as jc then if converters.has_key (base_class) and then attached converters.found_item as jc then
Result := jc.from_json (a_value) Result := jc.from_json (a_value)
else else
raise (exception_failed_to_convert_to_eiffel (a_value, base_class)) raise (exception_failed_to_convert_to_eiffel (a_value, base_class))
end end
end end
end end
end end
object_from_json (json: STRING; base_class: detachable STRING): detachable ANY object_from_json (json: STRING; base_class: detachable STRING): detachable ANY
-- Eiffel object from JSON representation. If `base_class' /= Void an -- Eiffel object from JSON representation. If `base_class' /= Void an
-- Eiffel object based on `base_class' will be returned. Raises an -- Eiffel object based on `base_class' will be returned. Raises an
-- "eJSON exception" if unable to convert value. -- "eJSON exception" if unable to convert value.
require require
json_not_void: json /= Void json_not_void: json /= Void
local local
jv: detachable JSON_VALUE jv: detachable JSON_VALUE
do do
json_parser.set_representation (json) json_parser.set_representation (json)
jv := json_parser.parse jv := json_parser.parse
if jv /= Void then if jv /= Void then
Result := object (jv, base_class) Result := object (jv, base_class)
end end
end end
converter_for (an_object: ANY): detachable JSON_CONVERTER converter_for (an_object: ANY): detachable JSON_CONVERTER
-- Converter for objects. Returns Void if none found. -- Converter for objects. Returns Void if none found.
require require
an_object_not_void: an_object /= Void an_object_not_void: an_object /= Void
do do
if converters.has_key (an_object.generator) then if converters.has_key (an_object.generator) then
Result := converters.found_item Result := converters.found_item
end end
end end
json_reference (s: STRING): JSON_OBJECT json_reference (s: STRING): JSON_OBJECT
-- A JSON (Dojo style) reference object using `s' as the -- A JSON (Dojo style) reference object using `s' as the
-- reference value. The caller is responsable for ensuring -- reference value. The caller is responsable for ensuring
-- the validity of `s' as a json reference. -- the validity of `s' as a json reference.
require require
s_not_void: s /= Void s_not_void: s /= Void
local local
js_key, js_value: JSON_STRING js_key, js_value: JSON_STRING
do do
create Result.make create Result.make
create js_key.make_json ("$ref") create js_key.make_json ("$ref")
create js_value.make_json (s) create js_value.make_json (s)
Result.put (js_value, js_key) Result.put (js_value, js_key)
end end
json_references (l: LIST [STRING]): JSON_ARRAY json_references (l: LIST [STRING]): JSON_ARRAY
-- A JSON array of JSON (Dojo style) reference objects using the -- A JSON array of JSON (Dojo style) reference objects using the
-- strings in `l' as reference values. The caller is responsable -- strings in `l' as reference values. The caller is responsable
-- for ensuring the validity of all strings in `l' as json -- for ensuring the validity of all strings in `l' as json
-- references. -- references.
require require
l_not_void: l /= Void l_not_void: l /= Void
local local
c: ITERATION_CURSOR [STRING] c: ITERATION_CURSOR [STRING]
do do
create Result.make_array create Result.make_array
from from
c := l.new_cursor c := l.new_cursor
until until
c.after c.after
loop loop
Result.add (json_reference (c.item)) Result.add (json_reference (c.item))
c.forth c.forth
end end
end end
feature -- Change feature -- Change
add_converter (jc: JSON_CONVERTER) add_converter (jc: JSON_CONVERTER)
-- Add the converter `jc'. -- Add the converter `jc'.
require require
jc_not_void: jc /= Void jc_not_void: jc /= Void
do do
converters.force (jc, jc.object.generator) converters.force (jc, jc.object.generator)
ensure ensure
has_converter: converter_for (jc.object) /= Void has_converter: converter_for (jc.object) /= Void
end end
feature {NONE} -- Implementation feature {NONE} -- Implementation
converters: HASH_TABLE [JSON_CONVERTER, STRING] converters: HASH_TABLE [JSON_CONVERTER, STRING]
-- Converters hashed by generator (base class) -- Converters hashed by generator (base class)
once once
create Result.make (10) create Result.make (10)
end end
feature {NONE} -- Implementation (Exceptions) feature {NONE} -- Implementation (Exceptions)
exception_prefix: STRING = "eJSON exception: " exception_prefix: STRING = "eJSON exception: "
exception_failed_to_convert_to_eiffel (a_value: JSON_VALUE; base_class: detachable STRING): STRING exception_failed_to_convert_to_eiffel (a_value: JSON_VALUE; base_class: detachable STRING): STRING
-- Exception message for failing to convert a JSON_VALUE to an instance of `a'. -- Exception message for failing to convert a JSON_VALUE to an instance of `a'.
do do
Result := exception_prefix + "Failed to convert JSON_VALUE to an Eiffel object: " + a_value.generator Result := exception_prefix + "Failed to convert JSON_VALUE to an Eiffel object: " + a_value.generator
if base_class /= Void then if base_class /= Void then
Result.append (" -> {" + base_class + "}") Result.append (" -> {" + base_class + "}")
end end
end end
exception_failed_to_convert_to_json (an_object: detachable ANY): STRING exception_failed_to_convert_to_json (an_object: detachable ANY): STRING
-- Exception message for failing to convert `a' to a JSON_VALUE. -- Exception message for failing to convert `a' to a JSON_VALUE.
do do
Result := exception_prefix + "Failed to convert Eiffel object to a JSON_VALUE" Result := exception_prefix + "Failed to convert Eiffel object to a JSON_VALUE"
if an_object /= Void then if an_object /= Void then
Result.append (" : {" + an_object.generator + "}") Result.append (" : {" + an_object.generator + "}")
end end
end end
feature {NONE} -- Implementation (JSON parser) feature {NONE} -- Implementation (JSON parser)
json_parser: JSON_PARSER json_parser: JSON_PARSER
once once
create Result.make_parser ("") create Result.make_parser ("")
end end
end -- class EJSON end -- class EJSON

View File

@@ -1,141 +1,178 @@
note note
description: "[ description: "[
JSON_ARRAY represent an array in JSON. JSON_ARRAY represent an array in JSON.
An array in JSON is an ordered set of names. An array in JSON is an ordered set of names.
Examples Examples
array array
[] []
[elements] [elements]
]" ]"
author: "Javier Velilla" author: "Javier Velilla"
date: "2008/08/24" date: "2008/08/24"
revision: "Revision 0.1" revision: "Revision 0.1"
class class
JSON_ARRAY JSON_ARRAY
inherit inherit
JSON_VALUE JSON_VALUE
DEBUG_OUTPUT ITERABLE [JSON_VALUE]
create DEBUG_OUTPUT
make_array
create
feature {NONE} -- Initialization make_array
make_array feature {NONE} -- Initialization
-- Initialize JSON Array
do make_array
create values.make (10) -- Initialize JSON Array
end do
create values.make (10)
feature -- Access end
i_th alias "[]" (i: INTEGER): JSON_VALUE feature -- Access
-- Item at `i'-th position
require i_th alias "[]" (i: INTEGER): JSON_VALUE
is_valid_index: valid_index (i) -- Item at `i'-th position
do require
Result := values.i_th (i) is_valid_index: valid_index (i)
end do
Result := values.i_th (i)
representation: STRING end
local
i: INTEGER representation: STRING
do local
Result := "[" i: INTEGER
from do
i := 1 Result := "["
until from
i > count i := 1
loop until
Result.append (i_th (i).representation) i > count
i := i + 1 loop
if i <= count then Result.append (i_th (i).representation)
Result.append_character (',') i := i + 1
end if i <= count then
end Result.append_character (',')
Result.append_character (']') end
end end
Result.append_character (']')
feature -- Visitor pattern end
accept (a_visitor: JSON_VISITOR) feature -- Visitor pattern
-- Accept `a_visitor'.
-- (Call `visit_json_array' procedure on `a_visitor'.) accept (a_visitor: JSON_VISITOR)
do -- Accept `a_visitor'.
a_visitor.visit_json_array (Current) -- (Call `visit_json_array' procedure on `a_visitor'.)
end do
a_visitor.visit_json_array (Current)
feature -- Mesurement end
count: INTEGER feature -- Access
-- Number of items.
do new_cursor: ITERATION_CURSOR [JSON_VALUE]
Result := values.count -- Fresh cursor associated with current structure
end do
Result := values.new_cursor
feature -- Status report end
valid_index (i: INTEGER): BOOLEAN feature -- Mesurement
-- Is `i' a valid index?
do count: INTEGER
Result := (1 <= i) and (i <= count) -- Number of items.
end do
Result := values.count
feature -- Change Element end
add (value: JSON_VALUE) feature -- Status report
require
value_not_null: value /= void valid_index (i: INTEGER): BOOLEAN
do -- Is `i' a valid index?
values.extend (value) do
ensure Result := (1 <= i) and (i <= count)
has_new_value: old values.count + 1 = values.count and end
values.has (value)
end feature -- Change Element
feature -- Report put_front (v: JSON_VALUE)
require
hash_code: INTEGER v_not_void: v /= Void
-- Hash code value do
do values.put_front (v)
from ensure
values.start has_new_value: old values.count + 1 = values.count and
Result := values.item.hash_code values.first = v
until end
values.off
loop add, extend (v: JSON_VALUE)
Result:= ((Result \\ 8388593) |<< 8) + values.item.hash_code require
values.forth v_not_void: v /= Void
end do
Result := Result \\ values.count values.extend (v)
end ensure
has_new_value: old values.count + 1 = values.count and
feature -- Conversion values.has (v)
end
array_representation: ARRAYED_LIST [JSON_VALUE]
-- Representation as a sequences of values prune_all (v: JSON_VALUE)
do -- Remove all occurrences of `v'.
Result := values require
end v_not_void: v /= Void
do
feature -- Status report values.prune_all (v)
ensure
debug_output: STRING not_has_new_value: not values.has (v)
-- String that should be displayed in debugger to represent `Current'. end
do
Result := count.out wipe_out
end -- Remove all items.
do
feature {NONE} -- Implementation values.wipe_out
end
values: ARRAYED_LIST [JSON_VALUE]
-- Value container feature -- Report
invariant hash_code: INTEGER
value_not_void: values /= Void -- Hash code value
do
end from
values.start
Result := values.item.hash_code
until
values.off
loop
Result:= ((Result \\ 8388593) |<< 8) + values.item.hash_code
values.forth
end
Result := Result \\ values.count
end
feature -- Conversion
array_representation: ARRAYED_LIST [JSON_VALUE]
-- Representation as a sequences of values
-- be careful, modifying the return object may have impact on the original JSON_ARRAY object
do
Result := values
end
feature -- Status report
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
Result := count.out + " item(s)"
end
feature {NONE} -- Implementation
values: ARRAYED_LIST [JSON_VALUE]
-- Value container
invariant
value_not_void: values /= Void
end

View File

@@ -1,61 +1,61 @@
note note
description: "JSON Truth values" description: "JSON Truth values"
author: "Javier Velilla" author: "Javier Velilla"
date: "2008/08/24" date: "2008/08/24"
revision: "Revision 0.1" revision: "Revision 0.1"
class class
JSON_BOOLEAN JSON_BOOLEAN
inherit inherit
JSON_VALUE JSON_VALUE
create create
make_boolean make_boolean
feature {NONE} -- Initialization feature {NONE} -- Initialization
make_boolean (an_item: BOOLEAN) make_boolean (an_item: BOOLEAN)
--Initialize. --Initialize.
do do
item := an_item item := an_item
end end
feature -- Access feature -- Access
item: BOOLEAN item: BOOLEAN
-- Content -- Content
hash_code: INTEGER hash_code: INTEGER
-- Hash code value -- Hash code value
do do
Result := item.hash_code Result := item.hash_code
end end
representation: STRING representation: STRING
do do
if item then if item then
Result := "true" Result := "true"
else else
Result := "false" Result := "false"
end end
end end
feature -- Visitor pattern feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR) accept (a_visitor: JSON_VISITOR)
-- Accept `a_visitor'. -- Accept `a_visitor'.
-- (Call `visit_json_boolean' procedure on `a_visitor'.) -- (Call `visit_json_boolean' procedure on `a_visitor'.)
do do
a_visitor.visit_json_boolean (Current) a_visitor.visit_json_boolean (Current)
end end
feature -- Status report feature -- Status report
debug_output: STRING debug_output: STRING
-- String that should be displayed in debugger to represent `Current'. -- String that should be displayed in debugger to represent `Current'.
do do
Result := item.out Result := item.out
end end
end end

View File

@@ -1,47 +1,47 @@
note note
description: "JSON Null Values" description: "JSON Null Values"
author: "Javier Velilla" author: "Javier Velilla"
date: "2008/08/24" date: "2008/08/24"
revision: "Revision 0.1" revision: "Revision 0.1"
class class
JSON_NULL JSON_NULL
inherit inherit
JSON_VALUE JSON_VALUE
feature --Access feature --Access
hash_code: INTEGER hash_code: INTEGER
-- Hash code value -- Hash code value
do do
Result := null_value.hash_code Result := null_value.hash_code
end end
representation: STRING representation: STRING
do do
Result := "null" Result := "null"
end end
feature -- Visitor pattern feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR) accept (a_visitor: JSON_VISITOR)
-- Accept `a_visitor'. -- Accept `a_visitor'.
-- (Call `visit_element_a' procedure on `a_visitor'.) -- (Call `visit_element_a' procedure on `a_visitor'.)
do do
a_visitor.visit_json_null (Current) a_visitor.visit_json_null (Current)
end end
feature -- Status report feature -- Status report
debug_output: STRING debug_output: STRING
-- String that should be displayed in debugger to represent `Current'. -- String that should be displayed in debugger to represent `Current'.
do do
Result := null_value Result := null_value
end end
feature {NONE}-- Implementation feature {NONE}-- Implementation
null_value: STRING = "null" null_value: STRING = "null"
end end

View File

@@ -1,99 +1,99 @@
note note
description: "JSON Numbers, octal and hexadecimal formats are not used." description: "JSON Numbers, octal and hexadecimal formats are not used."
author: "Javier Velilla" author: "Javier Velilla"
date: "2008/08/24" date: "2008/08/24"
revision: "Revision 0.1" revision: "Revision 0.1"
license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" license:"MIT (see http://www.opensource.org/licenses/mit-license.php)"
class class
JSON_NUMBER JSON_NUMBER
inherit inherit
JSON_VALUE JSON_VALUE
redefine redefine
is_equal is_equal
end end
create create
make_integer, make_integer,
make_natural, make_natural,
make_real make_real
feature {NONE} -- initialization feature {NONE} -- initialization
make_integer (an_argument: INTEGER_64) make_integer (an_argument: INTEGER_64)
-- Initialize an instance of JSON_NUMBER from the integer value of `an_argument'. -- Initialize an instance of JSON_NUMBER from the integer value of `an_argument'.
do do
item := an_argument.out item := an_argument.out
numeric_type := INTEGER_TYPE numeric_type := INTEGER_TYPE
end end
make_natural (an_argument: NATURAL_64) make_natural (an_argument: NATURAL_64)
-- Initialize an instance of JSON_NUMBER from the unsigned integer value of `an_argument'. -- Initialize an instance of JSON_NUMBER from the unsigned integer value of `an_argument'.
do do
item := an_argument.out item := an_argument.out
numeric_type := NATURAL_TYPE numeric_type := NATURAL_TYPE
end end
make_real (an_argument: DOUBLE) make_real (an_argument: DOUBLE)
-- Initialize an instance of JSON_NUMBER from the floating point value of `an_argument'. -- Initialize an instance of JSON_NUMBER from the floating point value of `an_argument'.
do do
item := an_argument.out item := an_argument.out
numeric_type := DOUBLE_TYPE numeric_type := DOUBLE_TYPE
end end
feature -- Access feature -- Access
item: STRING item: STRING
-- Content -- Content
hash_code: INTEGER hash_code: INTEGER
--Hash code value --Hash code value
do do
Result := item.hash_code Result := item.hash_code
end end
representation: STRING representation: STRING
do do
Result := item Result := item
end end
feature -- Visitor pattern feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR) accept (a_visitor: JSON_VISITOR)
-- Accept `a_visitor'. -- Accept `a_visitor'.
-- (Call `visit_json_number' procedure on `a_visitor'.) -- (Call `visit_json_number' procedure on `a_visitor'.)
do do
a_visitor.visit_json_number (Current) a_visitor.visit_json_number (Current)
end end
feature -- Status feature -- Status
is_equal (other: like Current): BOOLEAN is_equal (other: like Current): BOOLEAN
-- Is `other' attached to an object of the same type -- Is `other' attached to an object of the same type
-- as current object and identical to it? -- as current object and identical to it?
do do
Result := item.is_equal (other.item) Result := item.is_equal (other.item)
end end
feature -- Status report feature -- Status report
debug_output: STRING debug_output: STRING
-- String that should be displayed in debugger to represent `Current'. -- String that should be displayed in debugger to represent `Current'.
do do
Result := item Result := item
end end
feature -- Implementation feature -- Implementation
INTEGER_TYPE: INTEGER = 1 INTEGER_TYPE: INTEGER = 1
DOUBLE_TYPE: INTEGER = 2 DOUBLE_TYPE: INTEGER = 2
NATURAL_TYPE: INTEGER = 3 NATURAL_TYPE: INTEGER = 3
numeric_type: INTEGER numeric_type: INTEGER
invariant invariant
item_not_void: item /= Void item_not_void: item /= Void
end end

View File

@@ -8,7 +8,7 @@ note
object object
{} {}
{"key","value"} {"key": "value"}
]" ]"
author: "Javier Velilla" author: "Javier Velilla"
@@ -22,7 +22,9 @@ class
inherit inherit
JSON_VALUE JSON_VALUE
TABLE_ITERABLE [JSON_VALUE, JSON_STRING] TABLE_ITERABLE [JSON_VALUE, JSON_STRING]
DEBUG_OUTPUT
create create
make make
@@ -52,6 +54,67 @@ feature -- Change Element
object.extend (l_value, key) object.extend (l_value, key)
end end
put_string (value: READABLE_STRING_GENERAL; key: JSON_STRING)
-- Assuming there is no item of key `key',
-- insert `value' with `key'.
require
key_not_present: not has_key (key)
local
l_value: JSON_STRING
do
create l_value.make_json_from_string_32 (value.as_string_32)
put (l_value, key)
end
put_integer (value: INTEGER_64; key: JSON_STRING)
-- Assuming there is no item of key `key',
-- insert `value' with `key'.
require
key_not_present: not has_key (key)
local
l_value: JSON_NUMBER
do
create l_value.make_integer (value)
put (l_value, key)
end
put_natural (value: NATURAL_64; key: JSON_STRING)
-- Assuming there is no item of key `key',
-- insert `value' with `key'.
require
key_not_present: not has_key (key)
local
l_value: JSON_NUMBER
do
create l_value.make_natural (value)
put (l_value, key)
end
put_real (value: DOUBLE; key: JSON_STRING)
-- Assuming there is no item of key `key',
-- insert `value' with `key'.
require
key_not_present: not has_key (key)
local
l_value: JSON_NUMBER
do
create l_value.make_real (value)
put (l_value, key)
end
put_boolean (value: BOOLEAN; key: JSON_STRING)
-- Assuming there is no item of key `key',
-- insert `value' with `key'.
require
key_not_present: not has_key (key)
local
l_value: JSON_BOOLEAN
do
create l_value.make_boolean (value)
put (l_value, key)
end
replace (value: detachable JSON_VALUE; key: JSON_STRING) replace (value: detachable JSON_VALUE; key: JSON_STRING)
-- Assuming there is no item of key `key', -- Assuming there is no item of key `key',
-- insert `value' with `key'. -- insert `value' with `key'.
@@ -65,6 +128,68 @@ feature -- Change Element
object.force (l_value, key) object.force (l_value, key)
end end
replace_with_string (value: READABLE_STRING_GENERAL; key: JSON_STRING)
-- Assuming there is no item of key `key',
-- insert `value' with `key'.
local
l_value: JSON_STRING
do
create l_value.make_json_from_string_32 (value.as_string_32)
replace (l_value, key)
end
replace_with_integer (value: INTEGER_64; key: JSON_STRING)
-- Assuming there is no item of key `key',
-- insert `value' with `key'.
local
l_value: JSON_NUMBER
do
create l_value.make_integer (value)
replace (l_value, key)
end
replace_with_with_natural (value: NATURAL_64; key: JSON_STRING)
-- Assuming there is no item of key `key',
-- insert `value' with `key'.
local
l_value: JSON_NUMBER
do
create l_value.make_natural (value)
replace (l_value, key)
end
replace_with_real (value: DOUBLE; key: JSON_STRING)
-- Assuming there is no item of key `key',
-- insert `value' with `key'.
local
l_value: JSON_NUMBER
do
create l_value.make_real (value)
replace (l_value, key)
end
replace_with_boolean (value: BOOLEAN; key: JSON_STRING)
-- Assuming there is no item of key `key',
-- insert `value' with `key'.
local
l_value: JSON_BOOLEAN
do
create l_value.make_boolean (value)
replace (l_value, key)
end
remove (key: JSON_STRING)
-- Remove item indexed by `key' if any.
do
object.remove (key)
end
wipe_out
-- Reset all items to default values; reset status.
do
object.wipe_out
end
feature -- Access feature -- Access
has_key (key: JSON_STRING): BOOLEAN has_key (key: JSON_STRING): BOOLEAN
@@ -95,7 +220,8 @@ feature -- Access
local local
t: HASH_TABLE [JSON_VALUE, JSON_STRING] t: HASH_TABLE [JSON_VALUE, JSON_STRING]
do do
Result := "{" create Result.make (2)
Result.append_character ('{')
from from
t := map_representation t := map_representation
t.start t.start
@@ -103,7 +229,7 @@ feature -- Access
t.after t.after
loop loop
Result.append (t.key_for_iteration.representation) Result.append (t.key_for_iteration.representation)
Result.append (":") Result.append_character (':')
Result.append (t.item_for_iteration.representation) Result.append (t.item_for_iteration.representation)
t.forth t.forth
if not t.after then if not t.after then
@@ -177,7 +303,7 @@ feature -- Status report
debug_output: STRING debug_output: STRING
-- String that should be displayed in debugger to represent `Current'. -- String that should be displayed in debugger to represent `Current'.
do do
Result := object.count.out Result := count.out + " item(s)"
end end
feature {NONE} -- Implementation feature {NONE} -- Implementation
@@ -186,6 +312,6 @@ feature {NONE} -- Implementation
-- Value container -- Value container
invariant invariant
object_not_null: object /= Void object_not_void: object /= Void
end end

View File

@@ -1,329 +1,329 @@
note note
description: "[ description: "[
A JSON_STRING represent a string in JSON. A JSON_STRING represent a string in JSON.
A string is a collection of zero or more Unicodes characters, wrapped in double A string is a collection of zero or more Unicodes characters, wrapped in double
quotes, using blackslash espaces. quotes, using blackslash espaces.
]" ]"
author: "Javier Velilla" author: "Javier Velilla"
date: "2008/08/24" date: "2008/08/24"
revision: "Revision 0.1" revision: "Revision 0.1"
license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" license:"MIT (see http://www.opensource.org/licenses/mit-license.php)"
class class
JSON_STRING JSON_STRING
inherit inherit
JSON_VALUE JSON_VALUE
redefine redefine
is_equal is_equal
end end
create create
make_json, make_json,
make_json_from_string_32, make_json_from_string_32,
make_with_escaped_json make_with_escaped_json
convert convert
make_json ({READABLE_STRING_8, STRING_8, IMMUTABLE_STRING_8}), make_json ({READABLE_STRING_8, STRING_8, IMMUTABLE_STRING_8}),
make_json_from_string_32 ({READABLE_STRING_32, STRING_32, IMMUTABLE_STRING_32}) make_json_from_string_32 ({READABLE_STRING_32, STRING_32, IMMUTABLE_STRING_32})
feature {NONE} -- Initialization feature {NONE} -- Initialization
make_json (s: READABLE_STRING_8) make_json (s: READABLE_STRING_8)
-- Initialize. -- Initialize.
require require
item_not_void: s /= Void item_not_void: s /= Void
do do
make_with_escaped_json (escaped_json_string (s)) make_with_escaped_json (escaped_json_string (s))
end end
make_json_from_string_32 (s: READABLE_STRING_32) make_json_from_string_32 (s: READABLE_STRING_32)
-- Initialize from STRING_32 `s'. -- Initialize from STRING_32 `s'.
require require
item_not_void: s /= Void item_not_void: s /= Void
do do
make_with_escaped_json (escaped_json_string_32 (s)) make_with_escaped_json (escaped_json_string_32 (s))
end end
make_with_escaped_json (s: READABLE_STRING_8) make_with_escaped_json (s: READABLE_STRING_8)
-- Initialize with an_item already escaped -- Initialize with an_item already escaped
require require
item_not_void: s /= Void item_not_void: s /= Void
do do
item := s item := s
end end
feature -- Access feature -- Access
item: STRING item: STRING
-- Contents with escaped entities if any -- Contents with escaped entities if any
unescaped_string_8: STRING_8 unescaped_string_8: STRING_8
-- Unescaped string from `item' -- Unescaped string from `item'
local local
s: like item s: like item
i, n: INTEGER i, n: INTEGER
c: CHARACTER c: CHARACTER
do do
s := item s := item
n := s.count n := s.count
create Result.make (n) create Result.make (n)
from i := 1 until i > n loop from i := 1 until i > n loop
c := s[i] c := s[i]
if c = '\' then if c = '\' then
if i < n then if i < n then
inspect s[i+1] inspect s[i+1]
when '\' then when '\' then
Result.append_character ('\') Result.append_character ('\')
i := i + 2 i := i + 2
when '%"' then when '%"' then
Result.append_character ('%"') Result.append_character ('%"')
i := i + 2 i := i + 2
when 'n' then when 'n' then
Result.append_character ('%N') Result.append_character ('%N')
i := i + 2 i := i + 2
when 'r' then when 'r' then
Result.append_character ('%R') Result.append_character ('%R')
i := i + 2 i := i + 2
when 'u' then when 'u' then
--| Leave unicode \uXXXX unescaped --| Leave Unicode \uXXXX unescaped
Result.append_character ('\') Result.append_character ('\')
i := i + 1 i := i + 1
else else
Result.append_character ('\') Result.append_character ('\')
i := i + 1 i := i + 1
end end
else else
Result.append_character ('\') Result.append_character ('\')
i := i + 1 i := i + 1
end end
else else
Result.append_character (c) Result.append_character (c)
i := i + 1 i := i + 1
end end
end end
end end
unescaped_string_32: STRING_32 unescaped_string_32: STRING_32
-- Unescaped string 32 from `item' -- Unescaped string 32 from `item'
local local
s: like item s: like item
i, n: INTEGER i, n: INTEGER
c: CHARACTER c: CHARACTER
hex: STRING hex: STRING
do do
s := item s := item
n := s.count n := s.count
create Result.make (n) create Result.make (n)
from i := 1 until i > n loop from i := 1 until i > n loop
c := s[i] c := s[i]
if c = '\' then if c = '\' then
if i < n then if i < n then
inspect s[i+1] inspect s[i+1]
when '\' then when '\' then
Result.append_character ('\') Result.append_character ('\')
i := i + 2 i := i + 2
when '%"' then when '%"' then
Result.append_character ('%"') Result.append_character ('%"')
i := i + 2 i := i + 2
when 'n' then when 'n' then
Result.append_character ('%N') Result.append_character ('%N')
i := i + 2 i := i + 2
when 'r' then when 'r' then
Result.append_character ('%R') Result.append_character ('%R')
i := i + 2 i := i + 2
when 'u' then when 'u' then
hex := s.substring (i+2, i+2+4 - 1) hex := s.substring (i+2, i+2+4 - 1)
if hex.count = 4 then if hex.count = 4 then
Result.append_code (hexadecimal_to_natural_32 (hex)) Result.append_code (hexadecimal_to_natural_32 (hex))
end end
i := i + 2 + 4 i := i + 2 + 4
else else
Result.append_character ('\') Result.append_character ('\')
i := i + 1 i := i + 1
end end
else else
Result.append_character ('\') Result.append_character ('\')
i := i + 1 i := i + 1
end end
else else
Result.append_character (c.to_character_32) Result.append_character (c.to_character_32)
i := i + 1 i := i + 1
end end
end end
end end
representation: STRING representation: STRING
-- String representation of `item' with escaped entities if any -- String representation of `item' with escaped entities if any
do do
create Result.make (item.count + 2) create Result.make (item.count + 2)
Result.append_character ('%"') Result.append_character ('%"')
Result.append (item) Result.append (item)
Result.append_character ('%"') Result.append_character ('%"')
end end
feature -- Visitor pattern feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR) accept (a_visitor: JSON_VISITOR)
-- Accept `a_visitor'. -- Accept `a_visitor'.
-- (Call `visit_json_string' procedure on `a_visitor'.) -- (Call `visit_json_string' procedure on `a_visitor'.)
do do
a_visitor.visit_json_string (Current) a_visitor.visit_json_string (Current)
end end
feature -- Comparison feature -- Comparison
is_equal (other: like Current): BOOLEAN is_equal (other: like Current): BOOLEAN
-- Is JSON_STRING made of same character sequence as `other' -- Is JSON_STRING made of same character sequence as `other'
-- (possibly with a different capacity)? -- (possibly with a different capacity)?
do do
Result := item.same_string (other.item) Result := item.same_string (other.item)
end end
feature -- Change Element feature -- Change Element
append (a_string: STRING) append (a_string: STRING)
-- Add a_string -- Add a_string
require require
a_string_not_void: a_string /= Void a_string_not_void: a_string /= Void
do do
item.append_string (a_string) item.append_string (a_string)
end end
feature -- Status report feature -- Status report
hash_code: INTEGER hash_code: INTEGER
-- Hash code value -- Hash code value
do do
Result := item.hash_code Result := item.hash_code
end end
feature -- Status report feature -- Status report
debug_output: STRING debug_output: STRING
-- String that should be displayed in debugger to represent `Current'. -- String that should be displayed in debugger to represent `Current'.
do do
Result := item Result := item
end end
feature {NONE} -- Implementation feature {NONE} -- Implementation
is_hexadecimal (s: READABLE_STRING_8): BOOLEAN is_hexadecimal (s: READABLE_STRING_8): BOOLEAN
-- Is `s' an hexadecimal value? -- Is `s' an hexadecimal value?
do do
Result := across s as scur all scur.item.is_hexa_digit end Result := across s as scur all scur.item.is_hexa_digit end
end end
hexadecimal_to_natural_32 (s: READABLE_STRING_8): NATURAL_32 hexadecimal_to_natural_32 (s: READABLE_STRING_8): NATURAL_32
-- Hexadecimal string `s' converted to NATURAL_32 value -- Hexadecimal string `s' converted to NATURAL_32 value
require require
s_not_void: s /= Void s_not_void: s /= Void
is_hexadecimal: is_hexadecimal (s) is_hexadecimal: is_hexadecimal (s)
local local
i, nb: INTEGER i, nb: INTEGER
char: CHARACTER char: CHARACTER
do do
nb := s.count nb := s.count
if nb >= 2 and then s.item (2) = 'x' then if nb >= 2 and then s.item (2) = 'x' then
i := 3 i := 3
else else
i := 1 i := 1
end end
from from
until until
i > nb i > nb
loop loop
Result := Result * 16 Result := Result * 16
char := s.item (i) char := s.item (i)
if char >= '0' and then char <= '9' then if char >= '0' and then char <= '9' then
Result := Result + (char |-| '0').to_natural_32 Result := Result + (char |-| '0').to_natural_32
else else
Result := Result + (char.lower |-| 'a' + 10).to_natural_32 Result := Result + (char.lower |-| 'a' + 10).to_natural_32
end end
i := i + 1 i := i + 1
end end
end end
escaped_json_string (s: READABLE_STRING_8): STRING_8 escaped_json_string (s: READABLE_STRING_8): STRING_8
-- JSON string with '"' and '\' characters escaped -- JSON string with '"' and '\' characters escaped
require require
s_not_void: s /= Void s_not_void: s /= Void
local local
i, n: INTEGER i, n: INTEGER
c: CHARACTER_8 c: CHARACTER_8
do do
n := s.count n := s.count
create Result.make (n + n // 10) create Result.make (n + n // 10)
from i := 1 until i > n loop from i := 1 until i > n loop
c := s.item (i) c := s.item (i)
inspect c inspect c
when '%"' then Result.append_string ("\%"") when '%"' then Result.append_string ("\%"")
when '\' then Result.append_string ("\\") when '\' then Result.append_string ("\\")
when '%R' then Result.append_string ("\r") when '%R' then Result.append_string ("\r")
when '%N' then Result.append_string ("\n") when '%N' then Result.append_string ("\n")
else else
Result.extend (c) Result.extend (c)
end end
i := i + 1 i := i + 1
end end
end end
escaped_json_string_32 (s: READABLE_STRING_32): STRING_8 escaped_json_string_32 (s: READABLE_STRING_32): STRING_8
-- JSON string with '"' and '\' characters and unicode escaped -- JSON string with '"' and '\' characters and Unicode escaped
require require
s_not_void: s /= Void s_not_void: s /= Void
local local
i, j, n: INTEGER i, j, n: INTEGER
uc: CHARACTER_32 uc: CHARACTER_32
c: CHARACTER_8 c: CHARACTER_8
h: STRING_8 h: STRING_8
do do
n := s.count n := s.count
create Result.make (n + n // 10) create Result.make (n + n // 10)
from i := 1 until i > n loop from i := 1 until i > n loop
uc := s.item (i) uc := s.item (i)
if uc.is_character_8 then if uc.is_character_8 then
c := uc.to_character_8 c := uc.to_character_8
inspect c inspect c
when '%"' then Result.append_string ("\%"") when '%"' then Result.append_string ("\%"")
when '\' then Result.append_string ("\\") when '\' then Result.append_string ("\\")
when '%R' then Result.append_string ("\r") when '%R' then Result.append_string ("\r")
when '%N' then Result.append_string ("\n") when '%N' then Result.append_string ("\n")
else else
Result.extend (c) Result.extend (c)
end end
else else
Result.append ("\u") Result.append ("\u")
h := uc.code.to_hex_string h := uc.code.to_hex_string
-- Remove first 0 and keep 4 hexa digit -- Remove first 0 and keep 4 hexa digit
from from
j := 1 j := 1
until until
h.count = 4 or (j <= h.count and then h.item (j) /= '0') h.count = 4 or (j <= h.count and then h.item (j) /= '0')
loop loop
j := j + 1 j := j + 1
end end
h := h.substring (j, h.count) h := h.substring (j, h.count)
from from
until until
h.count >= 4 h.count >= 4
loop loop
h.prepend_integer (0) h.prepend_integer (0)
end end
check h.count = 4 end check h.count = 4 end
Result.append (h) Result.append (h)
end end
i := i + 1 i := i + 1
end end
end end
invariant invariant
item_not_void: item /= Void item_not_void: item /= Void
end end

View File

@@ -1,118 +1,118 @@
note note
description: "Objects that ..." description: "Objects that ..."
author: "jvelilla" author: "jvelilla"
date: "2008/08/24" date: "2008/08/24"
revision: "0.1" revision: "0.1"
class class
JSON_READER JSON_READER
create create
make make
feature {NONE} -- Initialization feature {NONE} -- Initialization
make (a_json: STRING) make (a_json: STRING)
-- Initialize Reader -- Initialize Reader
do do
set_representation (a_json) set_representation (a_json)
end end
feature -- Commands feature -- Commands
set_representation (a_json: STRING) set_representation (a_json: STRING)
-- Set `representation'. -- Set `representation'.
do do
a_json.left_adjust a_json.left_adjust
a_json.right_adjust a_json.right_adjust
representation := a_json representation := a_json
index := 1 index := 1
end end
read: CHARACTER read: CHARACTER
-- Read character -- Read character
do do
if not representation.is_empty then if not representation.is_empty then
Result := representation.item (index) Result := representation.item (index)
end end
end end
next next
-- Move to next index -- Move to next index
require require
has_more_elements: has_next has_more_elements: has_next
do do
index := index + 1 index := index + 1
ensure ensure
incremented: old index + 1 = index incremented: old index + 1 = index
end end
previous previous
-- Move to previous index -- Move to previous index
require require
not_is_first: has_previous not_is_first: has_previous
do do
index := index - 1 index := index - 1
ensure ensure
incremented: old index - 1 = index incremented: old index - 1 = index
end end
skip_white_spaces skip_white_spaces
-- Remove white spaces -- Remove white spaces
local local
c: like actual c: like actual
do do
from from
c := actual c := actual
until until
(c /= ' ' and c /= '%N' and c /= '%R' and c /= '%U' and c /= '%T' ) or not has_next (c /= ' ' and c /= '%N' and c /= '%R' and c /= '%U' and c /= '%T' ) or not has_next
loop loop
next next
c := actual c := actual
end end
end end
json_substring (start_index, end_index: INTEGER_32): STRING json_substring (start_index, end_index: INTEGER_32): STRING
-- JSON representation between `start_index' and `end_index' -- JSON representation between `start_index' and `end_index'
do do
Result := representation.substring (start_index, end_index) Result := representation.substring (start_index, end_index)
end end
feature -- Status report feature -- Status report
has_next: BOOLEAN has_next: BOOLEAN
-- Has a next character? -- Has a next character?
do do
Result := index <= representation.count Result := index <= representation.count
end end
has_previous: BOOLEAN has_previous: BOOLEAN
-- Has a previous character? -- Has a previous character?
do do
Result := index >= 1 Result := index >= 1
end end
feature -- Access feature -- Access
representation: STRING representation: STRING
-- Serialized representation of the original JSON string -- Serialized representation of the original JSON string
feature {NONE} -- Implementation feature {NONE} -- Implementation
actual: CHARACTER actual: CHARACTER
-- Current character or '%U' if none -- Current character or '%U' if none
do do
if index > representation.count then if index > representation.count then
Result := '%U' Result := '%U'
else else
Result := representation.item (index) Result := representation.item (index)
end end
end end
index: INTEGER index: INTEGER
-- Actual index -- Actual index
invariant invariant
representation_not_void: representation /= Void representation_not_void: representation /= Void
end end

View File

@@ -1,77 +1,77 @@
note note
description: "" description: ""
author: "jvelilla" author: "jvelilla"
date: "2008/08/24" date: "2008/08/24"
revision: "0.1" revision: "0.1"
class class
JSON_TOKENS JSON_TOKENS
feature -- Access feature -- Access
j_OBJECT_OPEN: CHARACTER = '{' j_OBJECT_OPEN: CHARACTER = '{'
j_ARRAY_OPEN: CHARACTER = '[' j_ARRAY_OPEN: CHARACTER = '['
j_OBJECT_CLOSE: CHARACTER = '}' j_OBJECT_CLOSE: CHARACTER = '}'
j_ARRAY_CLOSE: CHARACTER = ']' j_ARRAY_CLOSE: CHARACTER = ']'
j_STRING: CHARACTER = '"' j_STRING: CHARACTER = '"'
j_PLUS: CHARACTER = '+' j_PLUS: CHARACTER = '+'
j_MINUS: CHARACTER = '-' j_MINUS: CHARACTER = '-'
j_DOT: CHARACTER = '.' j_DOT: CHARACTER = '.'
feature -- Status report feature -- Status report
is_open_token (c: CHARACTER): BOOLEAN is_open_token (c: CHARACTER): BOOLEAN
-- Characters which open a type -- Characters which open a type
do do
inspect c inspect c
when j_OBJECT_OPEN, j_ARRAY_OPEN, j_STRING, j_PLUS, j_MINUS, j_DOT then when j_OBJECT_OPEN, j_ARRAY_OPEN, j_STRING, j_PLUS, j_MINUS, j_DOT then
Result := True Result := True
else else
end end
end end
is_close_token (c: CHARACTER): BOOLEAN is_close_token (c: CHARACTER): BOOLEAN
-- Characters which close a type -- Characters which close a type
do do
inspect c inspect c
when j_OBJECT_CLOSE, j_ARRAY_CLOSE, j_STRING then when j_OBJECT_CLOSE, j_ARRAY_CLOSE, j_STRING then
Result := True Result := True
else else
end end
end end
is_special_character (c: CHARACTER): BOOLEAN is_special_character (c: CHARACTER): BOOLEAN
-- Control Characters -- Control Characters
-- %F Form feed -- %F Form feed
-- %H backslasH -- %H backslasH
-- %N Newline -- %N Newline
-- %R carriage Return -- %R carriage Return
-- %T horizontal Tab -- %T horizontal Tab
-- %B Backspace -- %B Backspace
-- / Solidus -- / Solidus
-- " Quotation -- " Quotation
do do
inspect c inspect c
when '%F', '%H', '%N', '%R', '%T', '%B', '/', '"' then when '%F', '%H', '%N', '%R', '%T', '%B', '/', '"' then
Result := True Result := True
else else
end end
end end
is_special_control (c: CHARACTER): BOOLEAN is_special_control (c: CHARACTER): BOOLEAN
--Control Characters --Control Characters
-- \b\f\n\r\t -- \b\f\n\r\t
do do
inspect c inspect c
when 'b', 'f', 'n', 'r', 't' then when 'b', 'f', 'n', 'r', 't' then
Result := True Result := True
else else
end end
end end
end end

View File

@@ -1,11 +1,11 @@
{"menu": { { "menu": {
"id": "file", "id": "file",
"value": "File", "value": "File",
"popup": { "popup": {
"menuitem": [ "menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"}, {"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"}, {"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"} {"value": "Close", "onclick": "CloseDoc()"}
] ]
} }
}} }}

View File

@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="test_suite" uuid="EA141B17-6A21-4781-8B5F-E9939BAE968A"> <system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="test_suite" uuid="EA141B17-6A21-4781-8B5F-E9939BAE968A">
<target name="test_suite"> <target name="test_suite">
<root cluster="test_suite" class="APPLICATION" feature="make"/> <root cluster="test_suite" class="APPLICATION" feature="make"/>
<file_rule> <file_rule>
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude> <exclude>/CVS$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
</file_rule> </file_rule>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="standard"> <option warning="true" is_attached_by_default="true" void_safety="all" syntax="standard">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="json" location="..\..\..\library\json-safe.ecf"/> <library name="json" location="..\..\..\library\json-safe.ecf"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/> <library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
<cluster name="test_suite" location=".\" recursive="true"/> <cluster name="test_suite" location=".\" recursive="true"/>
</target> </target>
</system> </system>