Normalize line endings

This commit is contained in:
jvelilla
2013-11-07 17:55:15 -03:00
parent 59b0d0d9fa
commit 8a96ed87b1
18 changed files with 3341 additions and 3341 deletions

View File

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

View File

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

View File

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

View File

@@ -1,28 +1,28 @@
<?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">
<target name="json">
<root all_classes="true"/>
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option trace="false" profile="false" debug="false" warning="true" full_class_checking="true" void_safety="none" syntax="standard" namespace="EJSON.Library">
<assertions/>
<warning name="export_class_missing" enabled="false"/>
<warning name="old_verbatim_strings" enabled="false"/>
<warning name="syntax" enabled="false"/>
<warning name="vjrv" enabled="false"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf" readonly="true"/>
<cluster name="json" location=".\" recursive="true">
<file_rule>
<exclude>^/gobo$</exclude>
<exclude>^/kernel$</exclude>
<exclude>^/extras$</exclude>
</file_rule>
<cluster name="kernel" location=".\kernel\" recursive="true"/>
<cluster name="extras" location=".\extras\" recursive="true"/>
</cluster>
</target>
</system>
<?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">
<target name="json">
<root all_classes="true"/>
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option trace="false" profile="false" debug="false" warning="true" full_class_checking="true" void_safety="none" syntax="standard" namespace="EJSON.Library">
<assertions/>
<warning name="export_class_missing" enabled="false"/>
<warning name="old_verbatim_strings" enabled="false"/>
<warning name="syntax" enabled="false"/>
<warning name="vjrv" enabled="false"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf" readonly="true"/>
<cluster name="json" location=".\" recursive="true">
<file_rule>
<exclude>^/gobo$</exclude>
<exclude>^/kernel$</exclude>
<exclude>^/extras$</exclude>
</file_rule>
<cluster name="kernel" location=".\kernel\" recursive="true"/>
<cluster name="extras" location=".\extras\" recursive="true"/>
</cluster>
</target>
</system>

View File

@@ -1 +1 @@

View File

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

View File

@@ -1,176 +1,176 @@
note
description: "[
JSON_ARRAY represent an array in JSON.
An array in JSON is an ordered set of names.
Examples
array
[]
[elements]
]"
author: "Javier Velilla"
date: "2008/08/24"
revision: "Revision 0.1"
class
JSON_ARRAY
inherit
JSON_VALUE
ITERABLE [JSON_VALUE]
create
make_array
feature {NONE} -- Initialization
make_array
-- Initialize JSON Array
do
create values.make (10)
end
feature -- Access
i_th alias "[]" (i: INTEGER): JSON_VALUE
-- Item at `i'-th position
require
is_valid_index: valid_index (i)
do
Result := values.i_th (i)
end
representation: STRING
local
i: INTEGER
do
Result := "["
from
i := 1
until
i > count
loop
Result.append (i_th (i).representation)
i := i + 1
if i <= count then
Result.append_character (',')
end
end
Result.append_character (']')
end
feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR)
-- Accept `a_visitor'.
-- (Call `visit_json_array' procedure on `a_visitor'.)
do
a_visitor.visit_json_array (Current)
end
feature -- Access
new_cursor: ITERATION_CURSOR [JSON_VALUE]
-- Fresh cursor associated with current structure
do
Result := values.new_cursor
end
feature -- Mesurement
count: INTEGER
-- Number of items.
do
Result := values.count
end
feature -- Status report
valid_index (i: INTEGER): BOOLEAN
-- Is `i' a valid index?
do
Result := (1 <= i) and (i <= count)
end
feature -- Change Element
put_front (v: JSON_VALUE)
require
v_not_void: v /= Void
do
values.put_front (v)
ensure
has_new_value: old values.count + 1 = values.count and
values.first = v
end
add, extend (v: JSON_VALUE)
require
v_not_void: v /= Void
do
values.extend (v)
ensure
has_new_value: old values.count + 1 = values.count and
values.has (v)
end
prune_all (v: JSON_VALUE)
-- Remove all occurrences of `v'.
require
v_not_void: v /= Void
do
values.prune_all (v)
ensure
not_has_new_value: not values.has (v)
end
wipe_out
-- Remove all items.
do
values.wipe_out
end
feature -- Report
hash_code: INTEGER
-- Hash code value
do
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
note
description: "[
JSON_ARRAY represent an array in JSON.
An array in JSON is an ordered set of names.
Examples
array
[]
[elements]
]"
author: "Javier Velilla"
date: "2008/08/24"
revision: "Revision 0.1"
class
JSON_ARRAY
inherit
JSON_VALUE
ITERABLE [JSON_VALUE]
create
make_array
feature {NONE} -- Initialization
make_array
-- Initialize JSON Array
do
create values.make (10)
end
feature -- Access
i_th alias "[]" (i: INTEGER): JSON_VALUE
-- Item at `i'-th position
require
is_valid_index: valid_index (i)
do
Result := values.i_th (i)
end
representation: STRING
local
i: INTEGER
do
Result := "["
from
i := 1
until
i > count
loop
Result.append (i_th (i).representation)
i := i + 1
if i <= count then
Result.append_character (',')
end
end
Result.append_character (']')
end
feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR)
-- Accept `a_visitor'.
-- (Call `visit_json_array' procedure on `a_visitor'.)
do
a_visitor.visit_json_array (Current)
end
feature -- Access
new_cursor: ITERATION_CURSOR [JSON_VALUE]
-- Fresh cursor associated with current structure
do
Result := values.new_cursor
end
feature -- Mesurement
count: INTEGER
-- Number of items.
do
Result := values.count
end
feature -- Status report
valid_index (i: INTEGER): BOOLEAN
-- Is `i' a valid index?
do
Result := (1 <= i) and (i <= count)
end
feature -- Change Element
put_front (v: JSON_VALUE)
require
v_not_void: v /= Void
do
values.put_front (v)
ensure
has_new_value: old values.count + 1 = values.count and
values.first = v
end
add, extend (v: JSON_VALUE)
require
v_not_void: v /= Void
do
values.extend (v)
ensure
has_new_value: old values.count + 1 = values.count and
values.has (v)
end
prune_all (v: JSON_VALUE)
-- Remove all occurrences of `v'.
require
v_not_void: v /= Void
do
values.prune_all (v)
ensure
not_has_new_value: not values.has (v)
end
wipe_out
-- Remove all items.
do
values.wipe_out
end
feature -- Report
hash_code: INTEGER
-- Hash code value
do
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
description: "JSON Truth values"
author: "Javier Velilla"
date: "2008/08/24"
revision: "Revision 0.1"
class
JSON_BOOLEAN
inherit
JSON_VALUE
create
make_boolean
feature {NONE} -- Initialization
make_boolean (an_item: BOOLEAN)
--Initialize.
do
item := an_item
end
feature -- Access
item: BOOLEAN
-- Content
hash_code: INTEGER
-- Hash code value
do
Result := item.hash_code
end
representation: STRING
do
if item then
Result := "true"
else
Result := "false"
end
end
feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR)
-- Accept `a_visitor'.
-- (Call `visit_json_boolean' procedure on `a_visitor'.)
do
a_visitor.visit_json_boolean (Current)
end
feature -- Status report
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
Result := item.out
end
end
note
description: "JSON Truth values"
author: "Javier Velilla"
date: "2008/08/24"
revision: "Revision 0.1"
class
JSON_BOOLEAN
inherit
JSON_VALUE
create
make_boolean
feature {NONE} -- Initialization
make_boolean (an_item: BOOLEAN)
--Initialize.
do
item := an_item
end
feature -- Access
item: BOOLEAN
-- Content
hash_code: INTEGER
-- Hash code value
do
Result := item.hash_code
end
representation: STRING
do
if item then
Result := "true"
else
Result := "false"
end
end
feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR)
-- Accept `a_visitor'.
-- (Call `visit_json_boolean' procedure on `a_visitor'.)
do
a_visitor.visit_json_boolean (Current)
end
feature -- Status report
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
Result := item.out
end
end

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,18 @@
<?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">
<target name="test_suite">
<root cluster="test_suite" class="APPLICATION" feature="make"/>
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<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"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="json" location="..\..\..\library\json-safe.ecf"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
<cluster name="test_suite" location=".\" recursive="true"/>
</target>
</system>
<?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">
<target name="test_suite">
<root cluster="test_suite" class="APPLICATION" feature="make"/>
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<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"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="json" location="..\..\..\library\json-safe.ecf"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
<cluster name="test_suite" location=".\" recursive="true"/>
</target>
</system>