From c5e1b1ee697bd865c755fae9e8209ca561c1a012 Mon Sep 17 00:00:00 2001 From: Conaclos Date: Mon, 30 Jun 2014 18:28:13 +0200 Subject: [PATCH 01/11] Syntax update. Replace assigment attempt with object test. --- test/autotest/test_suite/test_ds.e | 94 +++---- test/autotest/test_suite/test_json_core.e | 230 +++++++++--------- .../test_suite/test_json_custom_classes.e | 43 ++-- 3 files changed, 192 insertions(+), 175 deletions(-) diff --git a/test/autotest/test_suite/test_ds.e b/test/autotest/test_suite/test_ds.e index 1cccd4b1..5b3f28f8 100644 --- a/test/autotest/test_suite/test_ds.e +++ b/test/autotest/test_suite/test_ds.e @@ -1,74 +1,76 @@ -class TEST_DS + +note + description: "Linked list and hash table converters test." + date: "$Date$" + revision: "$Revision$" + +class + TEST_DS inherit SHARED_EJSON - rename default_create as shared_default_create end - EQA_TEST_SET - select default_create end + undefine + default_create + end + EQA_TEST_SET feature -- Test test_linked_list_converter + -- Convert a linked list to a json value and + -- convert this one to a linked list. local - jc: JSON_LINKED_LIST_CONVERTER l: LINKED_LIST [STRING] - l2: detachable LINKED_LIST [detachable ANY] s: STRING - jv: detachable JSON_VALUE do - create jc.make - json.add_converter (jc) create l.make - s := "foo" - l.force (s) - s := "bar" - l.force (s) - jv := json.value (l) - assert ("jv /= Void", jv /= Void) - if attached jv as l_jv then - s := jv.representation - l2 ?= json.object (jv, "LINKED_LIST") - assert ("l2 /= Void", l2 /= Void) + l.force ("foo") + l.force ("bar") + + if attached json.value (l) as l_value then + s := l_value.representation + assert ("JSON array converted to LINKED_LIST", attached {LINKED_LIST [detachable ANY]} json.object (l_value, "LINKED_LIST")) + else + assert ("LINKED_LIST converted to a JSON value", False) end end test_hash_table_converter + -- Convert a hash table to a json value and + -- convert this one to a hash table. local - tc: JSON_HASH_TABLE_CONVERTER t: HASH_TABLE [STRING, STRING] - t2: detachable HASH_TABLE [ANY, HASHABLE] s: STRING - ucs_key, ucs_value: detachable STRING_32 - jv: detachable JSON_VALUE + l_ucs_key: detachable STRING_32 do - create tc.make - json.add_converter (tc) create t.make (2) t.put ("foo", "1") t.put ("bar", "2") - jv := json.value (t) - assert ("jv /= Void", jv /= Void) - if attached jv as l_jv then - s := l_jv.representation - t2 ?= json.object (l_jv, "HASH_TABLE") - assert ("t2 /= Void", t2 /= Void) - end - create ucs_key.make_from_string ("1") - if attached t2 as l_t2 then - ucs_value ?= t2 @ ucs_key - assert ("ucs_value /= Void", ucs_value /= Void) - if attached ucs_value as l_ucs_value then - assert ("ucs_value.string.is_equal (%"foo%")", l_ucs_value.string.is_equal ("foo")) - end - create ucs_key.make_from_string ("2") - ucs_value ?= t2 @ ucs_key - assert ("ucs_value /= Void", ucs_value /= Void) - if attached ucs_value as l_ucs_value then - assert ("ucs_value.string.is_equal (%"bar%")", l_ucs_value.string.is_equal ("bar")) - end - end + if attached json.value (t) as l_value then + s := l_value.representation + if attached {HASH_TABLE [ANY, HASHABLE]} json.object (l_value, "HASH_TABLE") as t2 then + + create l_ucs_key.make_from_string ("1") + if attached {STRING_32} t2 [l_ucs_key] as l_ucs_value then + assert ("ucs_value.string.is_equal (%"foo%")", l_ucs_value.string.is_equal ("foo")) + else + assert ("ucs_value /= Void", False) + end + + create l_ucs_key.make_from_string ("2") + if attached {STRING_32} t2 [l_ucs_key] as l_ucs_value then + assert ("ucs_value.string.is_equal (%"bar%")", l_ucs_value.string.is_equal ("bar")) + else + assert ("ucs_value /= Void", False) + end + else + assert ("JSON object converted to HASH_TABLE", False); + end + else + assert ("HASH_TABLE converted to a JSON value", False) + end end end -- class TEST_DS diff --git a/test/autotest/test_suite/test_json_core.e b/test/autotest/test_suite/test_json_core.e index 9c2febac..61b68b39 100644 --- a/test/autotest/test_suite/test_json_core.e +++ b/test/autotest/test_suite/test_json_core.e @@ -1,10 +1,13 @@ -class TEST_JSON_CORE +class + TEST_JSON_CORE inherit SHARED_EJSON - rename default_create as shared_default_create end + undefine + default_create + end + EQA_TEST_SET - select default_create end feature -- Test @@ -21,7 +24,7 @@ feature -- Test assert ("jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) -- Eiffel value -> JSON value -> JSON representation with factory if attached {JSON_NUMBER} json.value (i) as l_jn then - assert ("l_jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) + assert ("l_jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) else assert ("json.value (i) is a JSON_NUMBER", False) end @@ -477,64 +480,60 @@ feature -- Test test_json_null local - a: detachable ANY - dummy_object: STRING - jn: detachable JSON_NULL jrep: STRING + jn: JSON_NULL parser: JSON_PARSER do -- Eiffel value -> JSON value -> JSON representation create jn - assert ("jn /= Void", jn /= Void) - assert ("jn.representation.is_equal (%"%"null%"%")", jn.representation.is_equal ("null")) + jrep := "null" + + assert ("jn.representation.is_equal (%"%"null%"%")", jn.representation.is_equal (jrep)) -- Eiffel value -> JSON value -> JSON representation with factory - jn ?= json.value (Void) - assert ("jn /= Void", jn /= Void) - if attached jn as l_jn then - assert ("jn.representation.is_equal (%"null%")", l_jn.representation.is_equal ("null")) + if attached {JSON_NULL} json.value (Void) as l_json_null then + assert ("jn.representation.is_equal (%"null%")", l_json_null.representation.is_equal ("null")) + else + assert ("json.value (Void) /= Void", False) end -- JSON representation -> JSON value -> Eiffel value - jrep := "null" create parser.make_parser (jrep) - jn := Void - jn ?= parser.parse - assert ("jn /= Void", jn /= Void) - create dummy_object.make_empty - a := dummy_object - a ?= json.object (jn, Void) - assert ("a = Void", a = Void) + if attached parser.parse as l_json_null then + assert ("a = Void", json.object (l_json_null, Void) = Void) + else + assert ("parser.parse /= Void", False) + end end test_json_string_and_character local c: CHARACTER - js: detachable JSON_STRING jrep: STRING + js: JSON_STRING parser: JSON_PARSER do c := 'a' -- Eiffel value -> JSON value -> JSON representation create js.make_json (c.out) - assert ("js /= Void", js /= Void) + assert ("js.representation.is_equal (%"%"a%"%")", js.representation.is_equal ("%"a%"")) -- Eiffel value -> JSON value -> JSON representation with factory - js ?= json.value (c) - assert ("js /= Void", js /= Void) - if attached js as l_js then - assert ("js.representation.is_equal (%"%"a%"%")", l_js.representation.is_equal ("%"a%"")) + if attached {JSON_STRING} json.value (c) as l_json_str then + assert ("js.representation.is_equal (%"%"a%"%")", l_json_str.representation.is_equal ("%"a%"")) + else + assert ("json.value (c) /= Void", False) end -- JSON representation -> JSON value -> Eiffel value jrep := "%"a%"" create parser.make_parser (jrep) - js := Void - js ?= parser.parse - assert ("js /= Void", js /= Void) - if attached {STRING_32} json.object (js, Void) as ucs then - assert ("ucs.string.is_equal (%"a%")", ucs.string.is_equal ("a")) - end - + if attached {JSON_STRING} parser.parse as l_json_str then + if attached {STRING_32} json.object (l_json_str, Void) as ucs then + assert ("ucs.string.is_equal (%"a%")", ucs.string.is_equal ("a")) + end + else + assert ("parser.parse /= Void", False) + end end test_json_string_and_string @@ -545,94 +544,101 @@ feature -- Test parser: JSON_PARSER do s := "foobar" + jrep := "%"foobar%"" + -- Eiffel value -> JSON value -> JSON representation create js.make_json (s) - assert ("js /= Void", js /= Void) - assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal (jrep)) -- Eiffel value -> JSON value -> JSON representation with factory - js ?= json.value (s) - assert ("js /= Void", js /= Void) - if attached js as l_js then - assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) + if attached {JSON_STRING} json.value (s) as l_js then + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal (jrep)) + else + assert ("json.value (s) /= Void", False) end -- JSON representation -> JSON value -> Eiffel value - jrep := "%"foobar%"" create parser.make_parser (jrep) - js := Void - js ?= parser.parse - assert ("js /= Void", js /= Void) - if attached {STRING_32} json.object (js, Void) as l_ucs then - assert ("ucs.string.is_equal (%"foobar%")", l_ucs.string.is_equal ("foobar")) - end + if attached {JSON_STRING} parser.parse as l_js then + if attached {STRING_32} json.object (l_js, Void) as l_ucs then + assert ("ucs.string.is_equal (%"foobar%")", l_ucs.string.is_equal (s)) + end + else + assert ("parser.parse /= Void", False) + end end test_json_string_and_uc_string local js: detachable JSON_STRING ucs: detachable STRING_32 - jrep: STRING + jrep, s: STRING parser: JSON_PARSER do - create ucs.make_from_string ("foobar") + s := "foobar" + jrep := "%"foobar%"" + create ucs.make_from_string (s) + -- Eiffel value -> JSON value -> JSON representation create js.make_json (ucs) - assert ("js /= Void", js /= Void) - assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal ("%"foobar%"")) + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal (jrep)) + -- Eiffel value -> JSON value -> JSON representation with factory - js ?= json.value (ucs) - assert ("js /= Void", js /= Void) - if attached js as l_js then - assert ("js.representation.is_equal (%"%"foobar%"%")", l_js.representation.is_equal ("%"foobar%"")) + if attached {JSON_STRING} json.value (ucs) as l_js then + assert ("js.representation.is_equal (%"%"foobar%"%")", l_js.representation.is_equal (jrep)) + else + assert ("json.value (ucs) /= Void", False) end -- JSON representation -> JSON value -> Eiffel value - jrep := "%"foobar%"" create parser.make_parser (jrep) - js := Void - js ?= parser.parse - assert ("js /= Void", js /= Void) - ucs := Void - ucs ?= json.object (js, Void) - if attached ucs as l_ucs then - assert ("ucs.string.is_equal (%"foobar%")", l_ucs.string.is_equal ("foobar")) - end + if attached {JSON_STRING} parser.parse as l_js then + if attached {STRING_32} json.object (l_js, Void) as l_ucs then + assert ("ucs.string.is_equal (%"foobar%")", l_ucs.string.is_equal (s)) + else + assert ("json.object (js, Void) /= Void", False) + end + else + assert ("parser.parse /= Void", False) + end end test_json_string_and_special_characters local js: detachable JSON_STRING s: detachable STRING_8 - ucs: detachable STRING_32 jrep: STRING parser: JSON_PARSER do + jrep := "%"foo\\bar%"" create s.make_from_string ("foo\bar") create js.make_json (s) - assert ("js.representation.same_string (%"%"foo\\bar%"%")", js.representation.same_string ("%"foo\\bar%"")) + assert ("js.representation.same_string (%"%"foo\\bar%"%")", js.representation.same_string (jrep)) -- Eiffel value -> JSON value -> JSON representation with factory - js ?= json.value (s) - assert ("js /= Void", js /= Void) - if js /= Void then - assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.same_string ("%"foo\\bar%"")) + if attached {JSON_STRING} json.value (s) as l_js then + assert ("js.representation.is_equal (%"%"foobar%"%")", l_js.representation.same_string (jrep)) + else + assert ("json.value (s) /= Void", False) end -- JSON representation -> JSON value -> Eiffel value - jrep := "%"foo\\bar%"" create parser.make_parser (jrep) - js ?= parser.parse - assert ("js /= Void", js /= Void) - ucs ?= json.object (js, Void) - if ucs /= Void then - assert ("ucs.same_string (%"foo\bar%")", ucs.same_string ("foo\bar")) - end + if attached {JSON_STRING} parser.parse as l_js then + if attached {STRING_32} json.object (l_js, Void) as l_ucs then + assert ("ucs.same_string (%"foo\bar%")", l_ucs.same_string ("foo\bar")) + end + else + assert ("parser.parse /= Void", False) + end + jrep := "%"foo\\bar%"" create parser.make_parser (jrep) if attached {JSON_STRING} parser.parse as jstring then assert ("unescaped string %"foo\\bar%" to %"foo\bar%"", jstring.unescaped_string_8.same_string ("foo\bar")) + else + assert ("parser.parse /= Void", False) end create js.make_json_from_string_32 ({STRING_32}"%/20320/%/22909/") @@ -642,13 +648,14 @@ feature -- Test create parser.make_parser (jrep) if attached {JSON_STRING} parser.parse as jstring then assert ("same unicode string32 %"%%/20320/%%/22909/%"", jstring.unescaped_string_32.same_string ({STRING_32}"%/20320/%/22909/")) + else + assert ("parser.parse /= Void", False) end end test_json_array local ll: LINKED_LIST [INTEGER_8] - ll2: detachable LINKED_LIST [detachable ANY] ja: detachable JSON_ARRAY jn: JSON_NUMBER jrep: STRING @@ -677,11 +684,10 @@ feature -- Test assert ("ja /= Void", ja /= Void) assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", ja.representation.is_equal ("[0,1,1,2,3,5]")) -- Eiffel value -> JSON value -> JSON representation with factory - ja := Void - ja ?= json.value (ll) - assert ("ja /= Void", ja /= Void) - if attached ja as l_ja then + if attached {JSON_ARRAY} json.value (ll) as l_ja then assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", l_ja.representation.is_equal ("[0,1,1,2,3,5]")) + else + assert ("json.value (ll) /= Void", False) end -- JSON representation -> JSON value -> Eiffel value @@ -691,22 +697,20 @@ feature -- Test -- values 0, 1, 1, 2, 3, 5 jrep := "[0,1,1,2,3,5]" create parser.make_parser (jrep) - ja := Void - ja ?= parser.parse - assert ("ja /= Void", ja /= Void) - ll2 ?= json.object (ja, Void) - assert ("ll2 /= Void", ll2 /= Void) - --ll.compare_objects - --ll2.compare_objects - if attached ll2 as l_ll2 then - assert ("ll2.is_equal (ll)", l_ll2.is_equal (ll)) + if attached {JSON_ARRAY} parser.parse as l_ja then + if attached {LINKED_LIST [detachable ANY]} json.object (ja, Void) as l_ll2 then + assert ("ll2.is_equal (ll)", l_ll2.is_equal (ll)) + else + assert ("json.object (ja, Void) /= Void", False) + end + else + assert ("parser.parse /= Void", False) end - end test_json_object local - t, t2: detachable HASH_TABLE [detachable ANY, STRING_GENERAL] + t: detachable HASH_TABLE [detachable ANY, STRING_GENERAL] i: INTEGER ucs_key, ucs: STRING_32 a: ARRAY [INTEGER] @@ -745,6 +749,7 @@ feature -- Test jo.put (ja, js_key) assert ("jo /= Void", jo /= Void) assert ("jo.representation.is_equal (%"{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}%")", jo.representation.is_equal ("{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}")) + -- Eiffel value -> JSON value -> JSON representation with factory create t.make (3) create ucs_key.make_from_string ("name") @@ -756,26 +761,28 @@ feature -- Test create ucs_key.make_from_string ("contents") a := <<0, 1, 1, 2, 3, 5>> t.put (a, ucs_key) - jo := Void - jo ?= json.value (t) - assert ("jo /= Void", jo /= Void) - if attached jo as l_jo then + if attached {JSON_OBJECT} json.value (t) as l_jo then assert ("jo.representation.is_equal (%"{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}%")", l_jo.representation.is_equal ("{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}")) + else + assert ("json.value (t) /= Void", False) end + -- JSON representation -> JSON value -> Eiffel value -> JSON value -> JSON representation jrep := "{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}" create parser.make_parser (jrep) - jo := Void - jo ?= parser.parse - assert ("jo /= Void", jo /= Void) - t2 ?= json.object (jo, Void) - assert ("t2 /= Void", t2 /= Void) - jo ?= json.value (t2) - assert ("jo /= Void", jo /= Void) - if attached jo as l_jo then - assert ("jrep.is_equal (jo.representation)", jrep.is_equal (jo.representation)) - end - + if attached {JSON_OBJECT} parser.parse as l_jo then + if attached {HASH_TABLE [detachable ANY, STRING_GENERAL]} json.object (l_jo, Void) as l_t2 then + if attached json.value (l_t2) as l_jo_2 then + assert ("jrep.is_equal (jo.representation)", jrep.is_equal (l_jo_2.representation)) + else + assert ("json.value (t2) /= Void", False) + end + else + assert ("json.object (jo, Void) /= Void", False) + end + else + assert ("parser.parse /= Void", jo /= Void) + end end test_json_object_hash_code @@ -802,7 +809,6 @@ feature -- Test jv := json.value (gv) else assert ("exceptions.is_developer_exception", json.is_developer_exception) --- assert ("exceptions.is_developer_exception_of_name", json.is_developer_exception_of_name ("eJSON exception: Failed to convert Eiffel object to a JSON_VALUE: OPERATING_ENVIRONMENT")) end rescue exception := True @@ -813,17 +819,15 @@ feature -- Test -- Test converting from a JSON value to an Eiffel object based on a -- class for which no JSON converter has been registered. local - gv : detachable OPERATING_ENVIRONMENT + gv : detachable ANY jo: JSON_OBJECT exception: BOOLEAN do if not exception then create jo.make - gv ?= json.object (jo, "OPERATING_ENVIRONMENT") + gv := json.object (jo, "OPERATING_ENVIRONMENT") else assert ("exceptions.is_developer_exception", json.is_developer_exception) --- assert ("exceptions.is_developer_exception_of_name", json.is_developer_exception_of_name ("eJSON exception: Failed to convert JSON_VALUE to an Eiffel object: JSON_OBJECT -> OPERATING_ENVIRONMENT")) - end rescue exception := True diff --git a/test/autotest/test_suite/test_json_custom_classes.e b/test/autotest/test_suite/test_json_custom_classes.e index fc7957bc..0b0b0715 100644 --- a/test/autotest/test_suite/test_json_custom_classes.e +++ b/test/autotest/test_suite/test_json_custom_classes.e @@ -1,19 +1,28 @@ -class TEST_JSON_CUSTOM_CLASSES + +note + description: "Parsing and converter of book collection test." + date: "$Date$" + revision: "$Revision$" + +class + TEST_JSON_CUSTOM_CLASSES inherit SHARED_EJSON - rename default_create as shared_default_create end + undefine + default_create + end + EQA_TEST_SET - select default_create end + feature -- Test test_custom_classes + -- Parse JSON representation to JSON_OBJECT and test book collection converter. local - bc: detachable BOOK_COLLECTION jbc: JSON_BOOK_CONVERTER jbcc: JSON_BOOK_COLLECTION_CONVERTER jac: JSON_AUTHOR_CONVERTER - jo: detachable JSON_OBJECT parser: JSON_PARSER jrep: STRING do @@ -25,18 +34,20 @@ feature -- Test json.add_converter (jac) jrep := "{%"name%":%"Test collection%",%"books%":[{%"title%":%"eJSON: The Definitive Guide%",%"isbn%":%"123123-413243%",%"author%":{%"name%":%"Foo Bar%"}}]}" create parser.make_parser (jrep) - jo := Void - jo ?= parser.parse - assert ("jo /= Void", jo /= Void) - bc := Void - bc ?= json.object (jo, "BOOK_COLLECTION") - assert ("bc /= Void", bc /= Void) - jo ?= json.value (bc) - assert ("jo /= Void", jo /= Void) - if attached jo as l_jo then - assert ("JSON representation is correct", l_jo.representation.same_string ("{%"name%":%"Test collection%",%"books%":[{%"title%":%"eJSON: The Definitive Guide%",%"isbn%":%"123123-413243%",%"author%":{%"name%":%"Foo Bar%"}}]}")) - end + if attached {JSON_OBJECT} parser.parse as l_json_object then + if attached {BOOK_COLLECTION} json.object (l_json_object, "BOOK_COLLECTION") as l_collection then + if attached {JSON_OBJECT} json.value (l_collection) as l_json_object_2 then + assert ("JSON representation is correct", l_json_object_2.representation.same_string (jrep)) + else + assert ("BOOK_COLLECTION converted to JSON_OBJECT", False) + end + else + assert ("JSON_OBJECT converted to BOOK_COLLECTION", False) + end + else + assert ("JSON object representation to JSON_OBJECT", False) + end end end -- class TEST_JSON_CUSTOM_CLASS From 052860b62cd803092d7b5f939d61b483af5bfaa4 Mon Sep 17 00:00:00 2001 From: Conaclos Date: Mon, 30 Jun 2014 18:31:42 +0200 Subject: [PATCH 02/11] Improve converters. Replace old syntax with new one and improve implementation. --- .../test_suite/json_author_converter.e | 14 ++--- .../json_book_collection_converter.e | 51 ++++++++++--------- .../autotest/test_suite/json_book_converter.e | 25 ++++----- 3 files changed, 48 insertions(+), 42 deletions(-) diff --git a/test/autotest/test_suite/json_author_converter.e b/test/autotest/test_suite/json_author_converter.e index c8f9e6d0..6375a01a 100644 --- a/test/autotest/test_suite/json_author_converter.e +++ b/test/autotest/test_suite/json_author_converter.e @@ -4,7 +4,8 @@ note date: "$Date$" revision: "$Revision$" -class JSON_AUTHOR_CONVERTER +class + JSON_AUTHOR_CONVERTER inherit JSON_CONVERTER @@ -29,12 +30,10 @@ feature -- Access feature -- Conversion from_json (j: like to_json): detachable like object - local - ucs: detachable STRING_32 do - ucs ?= json.object (j.item (name_key), Void) - check ucs /= Void end - create Result.make (ucs) + if attached {STRING_32} json.object (j.item (name_key), Void) as l_name then + create Result.make (l_name) + end end to_json (o: like object): JSON_OBJECT @@ -43,9 +42,10 @@ feature -- Conversion Result.put (json.value (o.name), name_key) end -feature {NONE} -- Implementation +feature {NONE} -- Implementation name_key: JSON_STRING + -- Author's name label. once create Result.make_json ("name") end diff --git a/test/autotest/test_suite/json_book_collection_converter.e b/test/autotest/test_suite/json_book_collection_converter.e index 1c569ce3..e78b070e 100644 --- a/test/autotest/test_suite/json_book_collection_converter.e +++ b/test/autotest/test_suite/json_book_collection_converter.e @@ -4,7 +4,8 @@ note date: "$Date$" revision: "$Revision$" -class JSON_BOOK_COLLECTION_CONVERTER +class + JSON_BOOK_COLLECTION_CONVERTER inherit JSON_CONVERTER @@ -30,30 +31,32 @@ feature -- Conversion from_json (j: like to_json): detachable like object local - ucs: detachable STRING_32 - ll: LINKED_LIST [BOOK] - b: detachable BOOK - ja: detachable JSON_ARRAY - i: INTEGER + l_books: LINKED_LIST [BOOK] do - ucs ?= json.object (j.item (name_key), Void) - check ucs /= Void end - create Result.make (ucs) - ja ?= j.item (books_key) - check ja /= Void end - from - i := 1 - create ll.make - until - i > ja.count - loop - b ?= json.object (ja [i], "BOOK") - check b /= Void end - ll.force (b) - i := i + 1 + if + attached {STRING_32} json.object (j.item (name_key), Void) as l_name and + attached {JSON_ARRAY} j.item (books_key) as l_json_array + then + create Result.make (l_name) + create l_books.make + + across + l_json_array as it + until + Result = Void + loop + if attached {BOOK} json.object (it.item, "BOOK") as l_book then + l_books.extend (l_book) + else + Result := Void + -- Failed + end + end + + if Result /= Void then + Result.add_books (l_books) + end end - check ll /= Void end - Result.add_books (ll) end to_json (o: like object): JSON_OBJECT @@ -66,11 +69,13 @@ feature -- Conversion feature {NONE} -- Implementation name_key: JSON_STRING + -- Collection's name label. once create Result.make_json ("name") end books_key: JSON_STRING + -- Book list label. once create Result.make_json ("books") end diff --git a/test/autotest/test_suite/json_book_converter.e b/test/autotest/test_suite/json_book_converter.e index de31f79e..9da210a5 100644 --- a/test/autotest/test_suite/json_book_converter.e +++ b/test/autotest/test_suite/json_book_converter.e @@ -4,7 +4,8 @@ note date: "$Date$" revision: "$Revision$" -class JSON_BOOK_CONVERTER +class + JSON_BOOK_CONVERTER inherit JSON_CONVERTER @@ -31,17 +32,14 @@ feature -- Access feature -- Conversion from_json (j: like to_json): detachable like object - local - ucs1, ucs2: detachable STRING_32 - a: detachable AUTHOR do - ucs1 ?= json.object (j.item (title_key), Void) - check ucs1 /= Void end - ucs2 ?= json.object (j.item (isbn_key), Void) - check ucs2 /= Void end - a ?= json.object (j.item (author_key), "AUTHOR") - check a /= Void end - create Result.make (ucs1, a, ucs2) + if + attached {STRING_32} json.object (j.item (title_key), Void) as l_title and + attached {STRING_32} json.object (j.item (isbn_key), Void) as l_isbn and + attached {AUTHOR} json.object (j.item (author_key), "AUTHOR") as l_author + then + create Result.make (l_title, l_author, l_isbn) + end end to_json (o: like object): JSON_OBJECT @@ -52,19 +50,22 @@ feature -- Conversion Result.put (json.value (o.author), author_key) end -feature {NONE} -- Implementation +feature {NONE} -- Implementation title_key: JSON_STRING + -- Book's title label. once create Result.make_json ("title") end isbn_key: JSON_STRING + -- Book ISBN label. once create Result.make_json ("isbn") end author_key: JSON_STRING + -- Author label. once create Result.make_json ("author") end From 361773101ebee208787db9120f379a6860be8954 Mon Sep 17 00:00:00 2001 From: Conaclos Date: Mon, 30 Jun 2014 18:32:14 +0200 Subject: [PATCH 03/11] Add documentation and contracts for domain types. --- test/autotest/test_suite/author.e | 13 +++++- test/autotest/test_suite/book.e | 38 +++++++++++---- test/autotest/test_suite/book_collection.e | 54 +++++++++++----------- 3 files changed, 66 insertions(+), 39 deletions(-) diff --git a/test/autotest/test_suite/author.e b/test/autotest/test_suite/author.e index 9df55bf7..235cae9f 100644 --- a/test/autotest/test_suite/author.e +++ b/test/autotest/test_suite/author.e @@ -1,4 +1,6 @@ -class AUTHOR + +class + AUTHOR create make @@ -6,19 +8,26 @@ create feature {NONE} -- Initialization make (a_name: STRING_32) + -- Create an author with `a_name' as `name'. do set_name (a_name) + ensure + name_set: name = a_name end feature -- Access name: STRING_32 + -- Author name -feature -- Status setting +feature -- Change set_name (a_name: STRING_32) + -- Set `name' with `a_name'. do name := a_name + ensure + name_set: name = a_name end end -- class AUTHOR diff --git a/test/autotest/test_suite/book.e b/test/autotest/test_suite/book.e index 414036db..cd2c2764 100644 --- a/test/autotest/test_suite/book.e +++ b/test/autotest/test_suite/book.e @@ -1,40 +1,60 @@ -class BOOK + +class + BOOK create make feature {NONE} -- Initialization - make (a_title: STRING_32; an_author: AUTHOR; an_isbn: STRING_32) + make (a_title: STRING_32; a_author: AUTHOR; a_isbn: STRING_32) + -- Create a book with `a_title' as `title', + -- `a_author' as `author', and `a_isbn' as `isbn', do set_title (a_title) - set_author (an_author) - set_isbn (an_isbn) + set_author (a_author) + set_isbn (a_isbn) + ensure + title_set: title = a_title + author_set: author = a_author + isbn_set: isbn = a_isbn end feature -- Access title: STRING_32 + -- Main title. isbn: STRING_32 + -- ISBN. author: AUTHOR + -- Author. -feature -- Status setting +feature -- Change set_title (a_title: STRING_32) + -- Set `title' with `a_title'. do title := a_title + ensure + title_set: title = a_title end - set_author (an_author: AUTHOR) + set_author (a_author: AUTHOR) + -- Set `author' with `a_author'. do - author := an_author + author := a_author + ensure + author_set: author = a_author end - set_isbn (an_isbn: STRING_32) + set_isbn (a_isbn: STRING_32) + -- Set `isbn' with `a_isbn'. do - isbn := an_isbn + isbn := a_isbn + ensure + isbn_set: isbn = a_isbn end end -- class BOOK diff --git a/test/autotest/test_suite/book_collection.e b/test/autotest/test_suite/book_collection.e index 5ee0b0dd..4813d9ea 100644 --- a/test/autotest/test_suite/book_collection.e +++ b/test/autotest/test_suite/book_collection.e @@ -1,4 +1,5 @@ -class BOOK_COLLECTION +class + BOOK_COLLECTION create make @@ -6,75 +7,72 @@ create feature {NONE} -- Initialization make (a_name: STRING_32) + -- Create a collection of book with `a_name' as `name' do set_name (a_name) create book_index.make (10) + ensure + name_set: name = a_name end feature -- Access name: STRING_32 + -- Name. books: LIST [BOOK] + -- collection of book. do - from - create {LINKED_LIST [BOOK]} Result.make - book_index.start - until - book_index.after - loop - Result.append (book_index.item_for_iteration) - book_index.forth + create {LINKED_LIST [BOOK]} Result.make + across book_index as it loop + Result.append (it.item) end end - books_by_author (an_author: STRING_32): detachable LIST [BOOK] + books_by_author (a_author: STRING_32): LIST [BOOK] + -- Books wrote by `a_author' in this collection. do - if book_index.has (an_author) then - Result := book_index @ an_author + if attached book_index [a_author] as l_result then + Result := l_result else create {LINKED_LIST [BOOK]} Result.make end end -feature -- Status setting +feature -- Change set_name (a_name: STRING_32) + -- Set `name' with `a_name'. do name := a_name + ensure + name_set: name = a_name end add_book (a_book: BOOK) + -- Extend collection with `a_book'. local l: detachable LIST [BOOK] do - if book_index.has (a_book.author.name) then - l := book_index.at ( a_book.author.name ) - else + l := book_index.at (a_book.author.name ) + if l = Void then create {LINKED_LIST [BOOK]} l.make book_index.put (l, a_book.author.name) end - if attached l as la then - la.force (a_book) - end - + l.force (a_book) end add_books (book_list: like books) - + -- Append collection with `book_list'. do - from - book_list.start - until - book_list.after - loop - add_book (book_list.item) - book_list.forth + across book_list as it loop + add_book (it.item) end end feature {NONE} -- Implementation book_index: HASH_TABLE [LIST [BOOK], STRING_32] + -- Association of author name and its books. end -- class BOOK_COLLECTION From 20e704604a297d28ddfe88378e2d8e7a5b827a87 Mon Sep 17 00:00:00 2001 From: Conaclos Date: Fri, 4 Jul 2014 17:59:05 +0200 Subject: [PATCH 04/11] Apply pretty print tool. Apply on each class in test suite and library. --- library/extras/file/json_file_reader.e | 4 +- library/extras/visitor/json_iterator.e | 10 +- .../visitor/json_pretty_string_visitor.e | 30 +- library/extras/visitor/json_visitor.e | 9 +- library/extras/visitor/print_json_visitor.e | 14 +- .../converters/json_arrayed_list_converter.e | 10 +- library/kernel/converters/json_converter.e | 32 +- .../converters/json_hash_table_converter.e | 110 +- .../converters/json_linked_list_converter.e | 10 +- .../kernel/converters/json_list_converter.e | 86 +- library/kernel/ejson.e | 20 +- library/kernel/json_array.e | 230 ++- library/kernel/json_boolean.e | 79 +- library/kernel/json_null.e | 59 +- library/kernel/json_number.e | 132 +- library/kernel/json_object.e | 458 +++--- library/kernel/json_string.e | 283 ++-- library/kernel/json_value.e | 60 +- library/kernel/scanner/json_parser.e | 161 +- library/kernel/scanner/json_reader.e | 26 +- library/kernel/scanner/json_tokens.e | 24 +- library/kernel/shared_ejson.e | 58 +- test/autotest/test_suite/application.e | 9 +- test/autotest/test_suite/author.e | 27 +- test/autotest/test_suite/book.e | 55 +- test/autotest/test_suite/book_collection.e | 94 +- .../test_suite/json_author_converter.e | 57 +- .../json_book_collection_converter.e | 77 +- .../autotest/test_suite/json_book_converter.e | 83 +- test/autotest/test_suite/test_ds.e | 106 +- test/autotest/test_suite/test_json_core.e | 1310 ++++++++--------- .../test_suite/test_json_custom_classes.e | 49 +- test/autotest/test_suite/test_json_suite.e | 216 ++- 33 files changed, 2005 insertions(+), 1983 deletions(-) diff --git a/library/extras/file/json_file_reader.e b/library/extras/file/json_file_reader.e index a7c60481..9537a547 100644 --- a/library/extras/file/json_file_reader.e +++ b/library/extras/file/json_file_reader.e @@ -26,7 +26,9 @@ feature -- Access create template_content.make_empty l_file.read_stream (l_file.count) 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) Result := template_content l_file.close diff --git a/library/extras/visitor/json_iterator.e b/library/extras/visitor/json_iterator.e index dae48dd1..3489ce85 100644 --- a/library/extras/visitor/json_iterator.e +++ b/library/extras/visitor/json_iterator.e @@ -1,11 +1,8 @@ note - description: - - "JSON Iterator" - + description: "JSON Iterator" pattern: "Iterator visitor" author: "Jocelyn Fiat" - license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" + license: "MIT (see http://www.opensource.org/licenses/mit-license.php)" date: "2013/08/01" revision: "Revision 0.1" @@ -13,6 +10,7 @@ deferred class JSON_ITERATOR inherit + JSON_VISITOR feature -- Visitor Pattern @@ -52,7 +50,7 @@ feature -- Visitor Pattern end end - visit_json_string (a_json_string: JSON_STRING) + visit_json_string (a_json_string: JSON_STRING) -- Visit `a_json_string'. do end diff --git a/library/extras/visitor/json_pretty_string_visitor.e b/library/extras/visitor/json_pretty_string_visitor.e index 98b17c81..3ac76617 100644 --- a/library/extras/visitor/json_pretty_string_visitor.e +++ b/library/extras/visitor/json_pretty_string_visitor.e @@ -6,11 +6,11 @@ class JSON_PRETTY_STRING_VISITOR inherit + JSON_VISITOR create - make, - make_custom + make, make_custom feature -- Initialization @@ -26,7 +26,6 @@ feature -- Initialization output := a_output create indentation.make_empty indentation_step := "%T" - object_count_inlining := a_object_count_inlining array_count_inlining := a_array_count_inlining end @@ -34,7 +33,7 @@ feature -- Initialization feature -- Access output: STRING_32 - -- JSON representation + -- JSON representation indentation: like output @@ -60,6 +59,7 @@ feature -- Access end object_count_inlining: INTEGER + array_count_inlining: INTEGER feature -- Visitor Pattern @@ -82,10 +82,7 @@ feature -- Visitor Pattern until l_json_array.off loop - if - line_number > l_line or - l_multiple_lines - then + if line_number > l_line or l_multiple_lines then new_line end value := l_json_array.item @@ -96,10 +93,7 @@ feature -- Visitor Pattern end end exdent - if - line_number > l_line or - l_json_array.count >= array_count_inlining - then + if line_number > l_line or l_json_array.count >= array_count_inlining then new_line end output.append ("]") @@ -140,10 +134,7 @@ feature -- Visitor Pattern until l_pairs.off loop - if - line_number > l_line or - l_multiple_lines - then + if line_number > l_line or l_multiple_lines then new_line end l_pairs.key_for_iteration.accept (Current) @@ -155,16 +146,13 @@ feature -- Visitor Pattern end end exdent - if - line_number > l_line or - l_pairs.count >= object_count_inlining - then + if line_number > l_line or l_pairs.count >= object_count_inlining then new_line end output.append ("}") end - visit_json_string (a_json_string: JSON_STRING) + visit_json_string (a_json_string: JSON_STRING) -- Visit `a_json_string'. do output.append ("%"") diff --git a/library/extras/visitor/json_visitor.e b/library/extras/visitor/json_visitor.e index f032b564..a4fc6d3f 100644 --- a/library/extras/visitor/json_visitor.e +++ b/library/extras/visitor/json_visitor.e @@ -1,11 +1,8 @@ note - description: - - "JSON Visitor" - + description: "JSON Visitor" pattern: "Visitor" 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" revision: "Revision 0.1" @@ -49,7 +46,7 @@ feature -- Visitor Pattern deferred end - visit_json_string (a_json_string: JSON_STRING) + visit_json_string (a_json_string: JSON_STRING) -- Visit `a_json_string'. require a_json_string_not_void: a_json_string /= Void diff --git a/library/extras/visitor/print_json_visitor.e b/library/extras/visitor/print_json_visitor.e index 6072769b..4dcd08a3 100644 --- a/library/extras/visitor/print_json_visitor.e +++ b/library/extras/visitor/print_json_visitor.e @@ -8,9 +8,11 @@ class PRINT_JSON_VISITOR inherit + JSON_VISITOR -create make +create + make feature -- Initialization @@ -23,7 +25,7 @@ feature -- Initialization feature -- Access to_json: STRING - -- JSON representation + -- JSON representation feature -- Visitor Pattern @@ -33,7 +35,7 @@ feature -- Visitor Pattern value: JSON_VALUE l_json_array: ARRAYED_LIST [JSON_VALUE] do - l_json_array:=a_json_array.array_representation + l_json_array := a_json_array.array_representation to_json.append ("[") from l_json_array.start @@ -44,7 +46,7 @@ feature -- Visitor Pattern value.accept (Current) l_json_array.forth if not l_json_array.after then - to_json.append(",") + to_json.append (",") end end to_json.append ("]") @@ -71,7 +73,7 @@ feature -- Visitor Pattern visit_json_object (a_json_object: JSON_OBJECT) -- Visit `a_json_object'. local - l_pairs: HASH_TABLE[JSON_VALUE,JSON_STRING] + l_pairs: HASH_TABLE [JSON_VALUE, JSON_STRING] do l_pairs := a_json_object.map_representation to_json.append ("{") @@ -91,7 +93,7 @@ feature -- Visitor Pattern to_json.append ("}") end - visit_json_string (a_json_string: JSON_STRING) + visit_json_string (a_json_string: JSON_STRING) -- Visit `a_json_string'. do to_json.append ("%"") diff --git a/library/kernel/converters/json_arrayed_list_converter.e b/library/kernel/converters/json_arrayed_list_converter.e index da089f7b..21bcd4d4 100644 --- a/library/kernel/converters/json_arrayed_list_converter.e +++ b/library/kernel/converters/json_arrayed_list_converter.e @@ -5,20 +5,22 @@ note revision: "$Revision$" file: "$HeadURL: $" -class JSON_ARRAYED_LIST_CONVERTER +class + JSON_ARRAYED_LIST_CONVERTER inherit - JSON_LIST_CONVERTER + + JSON_LIST_CONVERTER redefine object end create - make + make feature -- Access - object: ARRAYED_LIST [detachable ANY] + object: ARRAYED_LIST [detachable ANY] feature {NONE} -- Factory diff --git a/library/kernel/converters/json_converter.e b/library/kernel/converters/json_converter.e index 796ef4eb..b4d78a66 100644 --- a/library/kernel/converters/json_converter.e +++ b/library/kernel/converters/json_converter.e @@ -5,32 +5,34 @@ note revision: "$Revision$" file: "$HeadURL: $" -deferred class JSON_CONVERTER +deferred class + JSON_CONVERTER inherit - SHARED_EJSON + + SHARED_EJSON feature -- Access - object: ANY - -- Eiffel object - deferred - end + object: ANY + -- Eiffel object + deferred + end feature -- Conversion - from_json (j: attached like to_json): detachable like object - -- Convert from JSON value. + from_json (j: attached like to_json): detachable like object + -- Convert from JSON value. -- Returns Void if unable to convert - deferred - end + deferred + end - to_json (o: like object): detachable JSON_VALUE - -- Convert to JSON value - deferred - end + to_json (o: like object): detachable JSON_VALUE + -- Convert to JSON value + deferred + end invariant - has_eiffel_object: object /= Void -- An empty object must be created at creation time! + has_eiffel_object: object /= Void -- An empty object must be created at creation time! end diff --git a/library/kernel/converters/json_hash_table_converter.e b/library/kernel/converters/json_hash_table_converter.e index e1264de7..00b87374 100644 --- a/library/kernel/converters/json_hash_table_converter.e +++ b/library/kernel/converters/json_hash_table_converter.e @@ -1,76 +1,82 @@ note - description: "A JSON converter for HASH_TABLE [ANY, HASHABLE]" - author: "Paul Cohen" + description: "A JSON converter for HASH_TABLE [ANY, HASHABLE]" + author: "Paul Cohen" date: "$Date: 2014-01-30 15:27:41 +0100 (jeu., 30 janv. 2014) $" revision: "$Revision: 94128 $" - file: "$HeadURL: $" + file: "$HeadURL: $" -class JSON_HASH_TABLE_CONVERTER +class + JSON_HASH_TABLE_CONVERTER inherit - JSON_CONVERTER + + JSON_CONVERTER create - make + make feature {NONE} -- Initialization - make - do - create object.make (0) - end + make + do + create object.make (0) + end feature -- Access - object: HASH_TABLE [ANY, HASHABLE] + object: HASH_TABLE [ANY, HASHABLE] feature -- Conversion - from_json (j: attached like to_json): like object - do - create Result.make (j.count) - across - j as ic - loop - if attached json.object (ic.item, Void) as l_object then + from_json (j: attached like to_json): like object + do + create Result.make (j.count) + across + j as ic + loop + if attached json.object (ic.item, Void) as l_object then if attached {HASHABLE} json.object (ic.key, Void) as h then Result.put (l_object, h) else - check key_is_hashable: False end + check + key_is_hashable: False + end end - else - check object_attached: False end - end - end - end + else + check + object_attached: False + end + end + end + end - to_json (o: like object): detachable JSON_OBJECT - local - c: HASH_TABLE_ITERATION_CURSOR [ANY, HASHABLE] - js: JSON_STRING - failed: BOOLEAN - do - create Result.make - from - c := o.new_cursor - 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 - if attached json.value (c.item) as jv then - Result.put (jv, js) - else - failed := True - end - c.forth - end - if failed then - Result := Void - end - end + to_json (o: like object): detachable JSON_OBJECT + local + c: HASH_TABLE_ITERATION_CURSOR [ANY, HASHABLE] + js: JSON_STRING + failed: BOOLEAN + do + create Result.make + from + c := o.new_cursor + 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 + if attached json.value (c.item) as jv then + Result.put (jv, js) + else + failed := True + end + c.forth + end + if failed then + Result := Void + end + end end -- class JSON_HASH_TABLE_CONVERTER diff --git a/library/kernel/converters/json_linked_list_converter.e b/library/kernel/converters/json_linked_list_converter.e index 42a1c2c4..1edb6bf8 100644 --- a/library/kernel/converters/json_linked_list_converter.e +++ b/library/kernel/converters/json_linked_list_converter.e @@ -5,20 +5,22 @@ note revision: "$Revision$" file: "$HeadURL: $" -class JSON_LINKED_LIST_CONVERTER +class + JSON_LINKED_LIST_CONVERTER inherit - JSON_LIST_CONVERTER + + JSON_LIST_CONVERTER redefine object end create - make + make feature -- Access - object: LINKED_LIST [detachable ANY] + object: LINKED_LIST [detachable ANY] feature {NONE} -- Factory diff --git a/library/kernel/converters/json_list_converter.e b/library/kernel/converters/json_list_converter.e index 75e0f848..7872756b 100644 --- a/library/kernel/converters/json_list_converter.e +++ b/library/kernel/converters/json_list_converter.e @@ -1,25 +1,27 @@ note - description: "A JSON converter for LIST [ANY]" - author: "Paul Cohen" - date: "$Date$" - revision: "$Revision$" - file: "$HeadURL: $" + description: "A JSON converter for LIST [ANY]" + author: "Paul Cohen" + date: "$Date$" + revision: "$Revision$" + file: "$HeadURL: $" -deferred class JSON_LIST_CONVERTER +deferred class + JSON_LIST_CONVERTER inherit - JSON_CONVERTER + + JSON_CONVERTER feature {NONE} -- Initialization - make + make do object := new_object (0) - end + end feature -- Access - object: LIST [detachable ANY] + object: LIST [detachable ANY] feature {NONE} -- Factory @@ -31,44 +33,44 @@ feature {NONE} -- Factory feature -- Conversion - from_json (j: attached like to_json): detachable like object - local - i: INTEGER - do - Result := new_object (j.count) - from - i := 1 - until - i > j.count - loop - Result.extend (json.object (j [i], Void)) - i := i + 1 - end - end + from_json (j: attached like to_json): detachable like object + local + i: INTEGER + do + Result := new_object (j.count) + from + i := 1 + until + i > j.count + loop + Result.extend (json.object (j [i], Void)) + i := i + 1 + end + end - to_json (o: like object): detachable JSON_ARRAY - local - c: ITERATION_CURSOR [detachable ANY] - jv: detachable JSON_VALUE + to_json (o: like object): detachable JSON_ARRAY + local + c: ITERATION_CURSOR [detachable ANY] + jv: detachable JSON_VALUE failed: BOOLEAN - do - create Result.make_array - from - c := o.new_cursor - until - c.after - loop - jv := json.value (c.item) - if jv /= Void then - Result.add (jv) - else + do + create Result.make_array + from + c := o.new_cursor + until + c.after + loop + jv := json.value (c.item) + if jv /= Void then + Result.add (jv) + else failed := True - end + end c.forth - end + end if failed then Result := Void end - end + end end -- class JSON_ARRAYED_LIST_CONVERTER diff --git a/library/kernel/ejson.e b/library/kernel/ejson.e index cb5ed967..86f114ee 100644 --- a/library/kernel/ejson.e +++ b/library/kernel/ejson.e @@ -5,9 +5,11 @@ note revision: "$Revision$" file: "$HeadURL: $" -class EJSON +class + EJSON inherit + EXCEPTIONS feature -- Access @@ -19,9 +21,9 @@ feature -- Access 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. + -- 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 @@ -56,7 +58,9 @@ feature -- Access if attached value (a @ i) as v then ja.add (v) else - check value_attached: False end + check + value_attached: False + end end i := i + 1 end @@ -65,15 +69,13 @@ feature -- Access 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 + -- 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 @@ -84,7 +86,7 @@ feature -- Access 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 + -- object based on `base_class' will be returned. Raises an "eJSON -- exception" if unable to convert value. local i: INTEGER diff --git a/library/kernel/json_array.e b/library/kernel/json_array.e index cd693f5c..0f2e50ef 100644 --- a/library/kernel/json_array.e +++ b/library/kernel/json_array.e @@ -1,75 +1,75 @@ 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" + 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 + JSON_ARRAY inherit - JSON_VALUE + + JSON_VALUE ITERABLE [JSON_VALUE] DEBUG_OUTPUT create - make_array + make_array feature {NONE} -- Initialization - make_array - -- Initialize JSON Array - do - create values.make (10) - end + 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 + 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 + 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 + 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 @@ -81,98 +81,96 @@ feature -- Access feature -- Mesurement - count: INTEGER - -- Number of items. - do - Result := values.count - end + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + values: ARRAYED_LIST [JSON_VALUE] + -- Value container invariant - value_not_void: values /= Void + value_not_void: values /= Void end diff --git a/library/kernel/json_boolean.e b/library/kernel/json_boolean.e index cc17681c..4e1a24a7 100644 --- a/library/kernel/json_boolean.e +++ b/library/kernel/json_boolean.e @@ -1,61 +1,62 @@ note - description: "JSON Truth values" - author: "Javier Velilla" - date: "2008/08/24" - revision: "Revision 0.1" + description: "JSON Truth values" + author: "Javier Velilla" + date: "2008/08/24" + revision: "Revision 0.1" class - JSON_BOOLEAN + JSON_BOOLEAN inherit - JSON_VALUE + + JSON_VALUE create - make_boolean + make_boolean feature {NONE} -- Initialization - make_boolean (an_item: BOOLEAN) - --Initialize. - do - item := an_item - end + make_boolean (an_item: BOOLEAN) + --Initialize. + do + item := an_item + end feature -- Access - item: BOOLEAN - -- Content + item: BOOLEAN + -- Content - hash_code: INTEGER - -- Hash code value - do - Result := item.hash_code - end + 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 - 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 + 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 + debug_output: STRING + -- String that should be displayed in debugger to represent `Current'. + do + Result := item.out + end end diff --git a/library/kernel/json_null.e b/library/kernel/json_null.e index 9c6f4ed7..04130ce5 100644 --- a/library/kernel/json_null.e +++ b/library/kernel/json_null.e @@ -1,47 +1,48 @@ note - description: "JSON Null Values" - author: "Javier Velilla" - date: "2008/08/24" - revision: "Revision 0.1" + description: "JSON Null Values" + author: "Javier Velilla" + date: "2008/08/24" + revision: "Revision 0.1" class - JSON_NULL + JSON_NULL inherit - JSON_VALUE + + JSON_VALUE feature --Access - hash_code: INTEGER - -- Hash code value - do - Result := null_value.hash_code - end + hash_code: INTEGER + -- Hash code value + do + Result := null_value.hash_code + end + + representation: STRING + do + Result := "null" + 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 + 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 + debug_output: STRING + -- String that should be displayed in debugger to represent `Current'. + do + Result := null_value + end -feature {NONE}-- Implementation +feature {NONE} -- Implementation - null_value: STRING = "null" + null_value: STRING = "null" end diff --git a/library/kernel/json_number.e b/library/kernel/json_number.e index 5f8ea60f..213a32e2 100644 --- a/library/kernel/json_number.e +++ b/library/kernel/json_number.e @@ -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)" + 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 + JSON_NUMBER inherit - JSON_VALUE - redefine - is_equal - end + + JSON_VALUE + redefine + is_equal + end create - make_integer, - make_natural, - make_real + 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_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_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 + 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 + item: STRING + -- Content - hash_code: INTEGER - --Hash code value - do - Result := item.hash_code - end + hash_code: INTEGER + --Hash code value + do + Result := item.hash_code + end + + representation: STRING + do + Result := item + 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 + 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 + 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 + 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 + INTEGER_TYPE: INTEGER = 1 - numeric_type: INTEGER + DOUBLE_TYPE: INTEGER = 2 + + NATURAL_TYPE: INTEGER = 3 + + numeric_type: INTEGER invariant - item_not_void: item /= Void + item_not_void: item /= Void end diff --git a/library/kernel/json_object.e b/library/kernel/json_object.e index 8a13c64c..8cff2589 100644 --- a/library/kernel/json_object.e +++ b/library/kernel/json_object.e @@ -1,182 +1,180 @@ note - - description: "[ - An JSON_OBJECT represent an object in JSON. - An object is an unordered set of name/value pairs - - Examples: - - object - {} - {"key": "value"} - - ]" - author: "Javier Velilla" - date: "2008/08/24" - revision: "Revision 0.1" - license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" + description: "[ + An JSON_OBJECT represent an object in JSON. + An object is an unordered set of name/value pairs + + Examples: + + object + {} + {"key": "value"} + ]" + author: "Javier Velilla" + date: "2008/08/24" + revision: "Revision 0.1" + license: "MIT (see http://www.opensource.org/licenses/mit-license.php)" class - JSON_OBJECT + JSON_OBJECT inherit - JSON_VALUE - TABLE_ITERABLE [JSON_VALUE, JSON_STRING] + JSON_VALUE - DEBUG_OUTPUT + TABLE_ITERABLE [JSON_VALUE, JSON_STRING] + + DEBUG_OUTPUT create - make + make feature {NONE} -- Initialization - make - -- Initialize - do - create object.make (10) - end + make + -- Initialize + do + create object.make (10) + end feature -- Change Element - put (value: detachable JSON_VALUE; 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: like value - do - l_value := value - if l_value = Void then - create {JSON_NULL} l_value - end - object.extend (l_value, key) - end + put (value: detachable JSON_VALUE; 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: like value + do + l_value := value + if l_value = Void then + create {JSON_NULL} l_value + end + object.extend (l_value, key) + 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_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_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_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_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 - 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) + -- Assuming there is no item of key `key', + -- insert `value' with `key'. + local + l_value: like value + do + l_value := value + if l_value = Void then + create {JSON_NULL} l_value + end + object.force (l_value, key) + end - replace (value: detachable JSON_VALUE; key: JSON_STRING) - -- Assuming there is no item of key `key', - -- insert `value' with `key'. - local - l_value: like value - do - l_value := value - if l_value = Void then - create {JSON_NULL} l_value - end - object.force (l_value, key) - 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_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_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_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_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 + 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. @@ -185,59 +183,59 @@ feature -- Change Element end wipe_out - -- Reset all items to default values; reset status. + -- Reset all items to default values; reset status. do object.wipe_out end feature -- Access - has_key (key: JSON_STRING): BOOLEAN - -- has the JSON_OBJECT contains a specific key 'key'. - do - Result := object.has (key) - end + has_key (key: JSON_STRING): BOOLEAN + -- has the JSON_OBJECT contains a specific key 'key'. + do + Result := object.has (key) + end - has_item (value: JSON_VALUE): BOOLEAN - -- has the JSON_OBJECT contain a specfic item 'value' - do - Result := object.has_item (value) - end + has_item (value: JSON_VALUE): BOOLEAN + -- has the JSON_OBJECT contain a specfic item 'value' + do + Result := object.has_item (value) + end - item (key: JSON_STRING): detachable JSON_VALUE - -- the json_value associated with a key. - do - Result := object.item (key) - end + item (key: JSON_STRING): detachable JSON_VALUE + -- the json_value associated with a key. + do + Result := object.item (key) + end - current_keys: ARRAY [JSON_STRING] - -- array containing actually used keys - do - Result := object.current_keys - end + current_keys: ARRAY [JSON_STRING] + -- array containing actually used keys + do + Result := object.current_keys + end - representation: STRING - local - t: HASH_TABLE [JSON_VALUE, JSON_STRING] - do - create Result.make (2) - Result.append_character ('{') - from - t := map_representation - t.start - until - t.after - loop - Result.append (t.key_for_iteration.representation) - Result.append_character (':') - Result.append (t.item_for_iteration.representation) - t.forth - if not t.after then - Result.append_character (',') - end - end - Result.append_character ('}') - end + representation: STRING + local + t: HASH_TABLE [JSON_VALUE, JSON_STRING] + do + create Result.make (2) + Result.append_character ('{') + from + t := map_representation + t.start + until + t.after + loop + Result.append (t.key_for_iteration.representation) + Result.append_character (':') + Result.append (t.item_for_iteration.representation) + t.forth + if not t.after then + Result.append_character (',') + end + end + Result.append_character ('}') + end feature -- Mesurement @@ -265,53 +263,53 @@ feature -- Status report feature -- Visitor pattern - accept (a_visitor: JSON_VISITOR) - -- Accept `a_visitor'. - -- (Call `visit_json_object' procedure on `a_visitor'.) - do - a_visitor.visit_json_object (Current) - end + accept (a_visitor: JSON_VISITOR) + -- Accept `a_visitor'. + -- (Call `visit_json_object' procedure on `a_visitor'.) + do + a_visitor.visit_json_object (Current) + end feature -- Conversion - map_representation: HASH_TABLE [JSON_VALUE, JSON_STRING] - --A representation that maps keys to values - do - Result := object - end + map_representation: HASH_TABLE [JSON_VALUE, JSON_STRING] + --A representation that maps keys to values + do + Result := object + end feature -- Report - hash_code: INTEGER - -- Hash code value - do - from - object.start - Result := object.out.hash_code - until - object.off - loop - Result := ((Result \\ 8388593) |<< 8) + object.item_for_iteration.hash_code - object.forth - end - -- Ensure it is a positive value. - Result := Result.hash_code - end + hash_code: INTEGER + -- Hash code value + do + from + object.start + Result := object.out.hash_code + until + object.off + loop + Result := ((Result \\ 8388593) |<< 8) + object.item_for_iteration.hash_code + object.forth + end + -- Ensure it is a positive value. + Result := Result.hash_code + end feature -- Status report - debug_output: STRING - -- String that should be displayed in debugger to represent `Current'. - do - Result := count.out + " item(s)" - end + debug_output: STRING + -- String that should be displayed in debugger to represent `Current'. + do + Result := count.out + " item(s)" + end feature {NONE} -- Implementation - object: HASH_TABLE [JSON_VALUE, JSON_STRING] - -- Value container + object: HASH_TABLE [JSON_VALUE, JSON_STRING] + -- Value container invariant - object_not_void: object /= Void + object_not_void: object /= Void end diff --git a/library/kernel/json_string.e b/library/kernel/json_string.e index 89ec4648..f8d051c0 100644 --- a/library/kernel/json_string.e +++ b/library/kernel/json_string.e @@ -1,30 +1,26 @@ 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)" - + 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 + JSON_STRING inherit - JSON_VALUE - redefine - is_equal - end + + JSON_VALUE + redefine + is_equal + end create - make_json, - make_json_from_string_32, - make_with_escaped_json + make_json, make_json_from_string_32, make_with_escaped_json convert make_json ({READABLE_STRING_8, STRING_8, IMMUTABLE_STRING_8}), @@ -32,34 +28,34 @@ convert 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 (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_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 + 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 + item: STRING + -- Contents with escaped entities if any feature -- Conversion @@ -86,14 +82,14 @@ feature -- Conversion unescape_to_string_32 (Result) end - representation: STRING + 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 + do + create Result.make (item.count + 2) + Result.append_character ('%"') + Result.append (item) + Result.append_character ('%"') + end unescape_to_string_8 (a_output: STRING_8) -- Unescape string `item' into `a_output'. @@ -105,11 +101,15 @@ feature -- Conversion do s := item n := s.count - from i := 1 until i > n loop - c := s[i] + from + i := 1 + until + i > n + loop + c := s [i] if c = '\' then if i < n then - inspect s[i+1] + inspect s [i + 1] when '\' then a_output.append_character ('\') i := i + 2 @@ -132,7 +132,7 @@ feature -- Conversion a_output.append_character ('%T') i := i + 2 when 'u' then - --| Leave Unicode \uXXXX unescaped + --| Leave Unicode \uXXXX unescaped a_output.append_character ('\') i := i + 1 else @@ -153,7 +153,7 @@ feature -- Conversion unescape_to_string_32 (a_output: STRING_32) -- Unescape string `item' into `a_output' string 32. --| some encoders uses UTF-8 , and not the recommended pure json encoding - --| thus, let's support the UTF-8 encoding during decoding. + --| thus, let's support the UTF-8 encoding during decoding. local s: READABLE_STRING_8 i, n: INTEGER @@ -163,11 +163,15 @@ feature -- Conversion do s := item n := s.count - from i := 1 until i > n loop + from + i := 1 + until + i > n + loop ch := s.item (i) if ch = '\' then if i < n then - inspect s[i+1] + inspect s [i + 1] when '\' then a_output.append_character ('\') i := i + 2 @@ -207,37 +211,27 @@ feature -- Conversion c := ch.natural_32_code if c <= 0x7F then -- 0xxxxxxx - check ch = c.to_character_32 end + check + ch = c.to_character_32 + end a_output.append_character (ch) elseif c <= 0xDF then -- 110xxxxx 10xxxxxx i := i + 1 if i <= n then - a_output.append_code ( - ((c & 0x1F) |<< 6) | - (s.code (i) & 0x3F) - ) + a_output.append_code (((c & 0x1F) |<< 6) | (s.code (i) & 0x3F)) end elseif c <= 0xEF then -- 1110xxxx 10xxxxxx 10xxxxxx i := i + 2 if i <= n then - a_output.append_code ( - ((c & 0xF) |<< 12) | - ((s.code (i - 1) & 0x3F) |<< 6) | - (s.code (i) & 0x3F) - ) + a_output.append_code (((c & 0xF) |<< 12) | ((s.code (i - 1) & 0x3F) |<< 6) | (s.code (i) & 0x3F)) end elseif c <= 0xF7 then -- 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx i := i + 3 if i <= n then - a_output.append_code ( - ((c & 0x7) |<< 18) | - ((s.code (i - 2) & 0x3F) |<< 12) | - ((s.code (i - 1) & 0x3F) |<< 6) | - (s.code (i) & 0x3F) - ) + a_output.append_code (((c & 0x7) |<< 18) | ((s.code (i - 2) & 0x3F) |<< 12) | ((s.code (i - 1) & 0x3F) |<< 6) | (s.code (i) & 0x3F)) end end i := i + 1 @@ -247,52 +241,52 @@ feature -- Conversion 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 + 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 + 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 + 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 + 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 + 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? + -- Is `s' an hexadecimal value? local i: INTEGER do @@ -302,7 +296,7 @@ feature {NONE} -- Implementation until i > s.count or not Result loop - Result := s[i].is_hexa_digit + Result := s [i].is_hexa_digit i := i + 1 end end @@ -317,13 +311,11 @@ feature {NONE} -- Implementation 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 @@ -339,26 +331,37 @@ feature {NONE} -- Implementation end end - escaped_json_string (s: READABLE_STRING_8): STRING_8 - -- JSON string with '"' and '\' characters escaped - require - s_not_void: s /= Void + 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 + from + i := 1 + until + i > n + loop c := s.item (i) inspect c - when '%"' then Result.append_string ("\%"") - when '\' then Result.append_string ("\\") - when '%B' then Result.append_string ("\b") - when '%F' then Result.append_string ("\f") - when '%N' then Result.append_string ("\n") - when '%R' then Result.append_string ("\r") - when '%T' then Result.append_string ("\t") + when '%"' then + Result.append_string ("\%"") + when '\' then + Result.append_string ("\\") + when '%B' then + Result.append_string ("\b") + when '%F' then + Result.append_string ("\f") + when '%N' then + Result.append_string ("\n") + when '%R' then + Result.append_string ("\r") + when '%T' then + Result.append_string ("\t") else Result.extend (c) end @@ -366,10 +369,10 @@ feature {NONE} -- Implementation 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 + 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 @@ -378,25 +381,36 @@ feature {NONE} -- Implementation do n := s.count create Result.make (n + n // 10) - from i := 1 until i > n loop + 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 '%B' then Result.append_string ("\b") - when '%F' then Result.append_string ("\f") - when '%N' then Result.append_string ("\n") - when '%R' then Result.append_string ("\r") - when '%T' then Result.append_string ("\t") + when '%"' then + Result.append_string ("\%"") + when '\' then + Result.append_string ("\\") + when '%B' then + Result.append_string ("\b") + when '%F' then + Result.append_string ("\f") + when '%N' then + Result.append_string ("\n") + when '%R' then + Result.append_string ("\r") + when '%T' then + Result.append_string ("\t") else Result.extend (c) end else Result.append ("\u") h := uc.code.to_hex_string - -- Remove first 0 and keep 4 hexa digit + -- Remove first 0 and keep 4 hexa digit from j := 1 until @@ -405,14 +419,15 @@ feature {NONE} -- Implementation 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 + check + h.count = 4 + end Result.append (h) end i := i + 1 @@ -420,6 +435,6 @@ feature {NONE} -- Implementation end invariant - item_not_void: item /= Void + item_not_void: item /= Void end diff --git a/library/kernel/json_value.e b/library/kernel/json_value.e index bbf47c7c..f5a5fccf 100644 --- a/library/kernel/json_value.e +++ b/library/kernel/json_value.e @@ -1,43 +1,43 @@ note - description:"[ - JSON_VALUE represent a value in JSON. - A value can be - * a string in double quotes - * a number - * boolean value(true, false ) - * null - * an object - * an array - ]" - author: "Javier Velilla" - date: "2008/05/19" - revision: "Revision 0.1" - license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" - + description: "[ + JSON_VALUE represent a value in JSON. + A value can be + * a string in double quotes + * a number + * boolean value(true, false ) + * null + * an object + * an array + ]" + author: "Javier Velilla" + date: "2008/05/19" + revision: "Revision 0.1" + license: "MIT (see http://www.opensource.org/licenses/mit-license.php)" deferred class - JSON_VALUE + JSON_VALUE inherit - HASHABLE - DEBUG_OUTPUT - + HASHABLE + + DEBUG_OUTPUT + feature -- Access - representation: STRING - -- UTF-8 encoded Unicode string representation of Current - deferred - end + representation: STRING + -- UTF-8 encoded Unicode string representation of Current + deferred + end feature -- Visitor pattern - accept (a_visitor: JSON_VISITOR) - -- Accept `a_visitor'. - -- (Call `visit_*' procedure on `a_visitor'.) - require - a_visitor_not_void: a_visitor /= Void - deferred - end + accept (a_visitor: JSON_VISITOR) + -- Accept `a_visitor'. + -- (Call `visit_*' procedure on `a_visitor'.) + require + a_visitor_not_void: a_visitor /= Void + deferred + end end diff --git a/library/kernel/scanner/json_parser.e b/library/kernel/scanner/json_parser.e index a3bf29f3..1df4ff39 100644 --- a/library/kernel/scanner/json_parser.e +++ b/library/kernel/scanner/json_parser.e @@ -1,5 +1,4 @@ note - description: "Parse serialized JSON data" author: "jvelilla" date: "2008/08/24" @@ -9,7 +8,9 @@ class JSON_PARSER inherit + JSON_READER + JSON_TOKENS create @@ -62,18 +63,18 @@ feature -- Element change feature -- Commands parse_json: detachable JSON_VALUE - -- Parse JSON data `representation' - -- start ::= object | array + -- Parse JSON data `representation' + -- start ::= object | array do - if is_valid_start_symbol then - Result := parse - if extra_elements then - is_parsed := False - end - else - is_parsed := False - report_error ("Syntax error unexpected token, expecting `{' or `['") - end + if is_valid_start_symbol then + Result := parse + if extra_elements then + is_parsed := False + end + else + is_parsed := False + report_error ("Syntax error unexpected token, expecting `{' or `['") + end end parse: detachable JSON_VALUE @@ -92,7 +93,7 @@ feature -- Commands when j_ARRAY_OPEN then Result := parse_array else - if c.is_digit or c = j_MINUS then + if c.is_digit or c = j_MINUS then Result := parse_number elseif is_null then Result := create {JSON_NULL} @@ -131,15 +132,19 @@ feature -- Commands l_value: detachable JSON_VALUE do create Result.make - -- check if is an empty object {} + -- check if is an empty object {} next skip_white_spaces if actual = j_OBJECT_CLOSE then - --is an empty object + --is an empty object else - -- a complex object {"key" : "value"} + -- a complex object {"key" : "value"} previous - from has_more := True until not has_more loop + from + has_more := True + until + not has_more + loop next skip_white_spaces l_json_string := parse_string @@ -153,7 +158,6 @@ feature -- Commands report_error ("%N Input string is a not well formed JSON, expected: : found: " + actual.out) has_more := False end - l_value := parse if is_parsed and then (l_value /= Void and l_json_string /= Void) then Result.put (l_value, l_json_string) @@ -168,7 +172,7 @@ feature -- Commands end else has_more := False - -- explain the error + -- explain the error end end end @@ -241,11 +245,11 @@ feature -- Commands c: like actual do create Result.make_array - --check if is an empty array [] + --check if is an empty array [] next skip_white_spaces if actual = j_array_close then - --is an empty array + --is an empty array else previous from @@ -263,7 +267,7 @@ feature -- Commands c := actual if c = j_ARRAY_CLOSE then flag := False - elseif c /= ',' then + elseif c /= ',' then flag := False is_parsed := False report_error ("Array is not well formed JSON, found [" + c.out + " ]") @@ -286,7 +290,6 @@ feature -- Commands do create sb.make_empty sb.append_character (actual) - from flag := True until @@ -294,16 +297,13 @@ feature -- Commands loop next c := actual - if not has_next or is_close_token (c) - or c = ',' or c = '%N' or c = '%R' - then + if not has_next or is_close_token (c) or c = ',' or c = '%N' or c = '%R' then flag := False previous else sb.append_character (c) end end - if is_valid_number (sb) then if sb.is_integer then create Result.make_integer (sb.to_integer) @@ -313,7 +313,7 @@ feature -- Commands end else is_parsed := False - report_error ("Expected a number, found: [ " + sb + " ]") + report_error ("Expected a number, found: [ " + sb + " ]") end end @@ -324,7 +324,7 @@ feature -- Commands l_string: STRING do l_null := null_id - l_string := json_substring (index,index + l_null.count - 1) + l_string := json_substring (index, index + l_null.count - 1) if l_string.is_equal (l_null) then Result := True end @@ -350,7 +350,7 @@ feature -- Commands l_string: STRING do l_true := true_id - l_string := json_substring (index,index + l_true.count - 1) + l_string := json_substring (index, index + l_true.count - 1) if l_string.is_equal (l_true) then Result := True end @@ -376,12 +376,12 @@ feature -- Commands feature {NONE} -- Implementation is_valid_number (a_number: STRING): BOOLEAN - -- is 'a_number' a valid number based on this regular expression - -- "-?(?: 0|[1-9]\d+)(?: \.\d+)?(?: [eE][+-]?\d+)?\b"? + -- is 'a_number' a valid number based on this regular expression + -- "-?(?: 0|[1-9]\d+)(?: \.\d+)?(?: [eE][+-]?\d+)?\b"? local s: detachable STRING c: CHARACTER - i,n: INTEGER + i, n: INTEGER do create s.make_empty n := a_number.count @@ -390,34 +390,52 @@ feature {NONE} -- Implementation else Result := True i := 1 - --| "-?" - c := a_number[i] + --| "-?" + c := a_number [i] if c = '-' then - s.extend (c); i := i + 1; c := a_number[i] + s.extend (c); + i := i + 1; + c := a_number [i] end - --| "0|[1-9]\d* + --| "0|[1-9]\d* if c.is_digit then if c = '0' then - --| "0" - s.extend (c); i := i + 1; c := a_number[i] + --| "0" + s.extend (c); + i := i + 1; + c := a_number [i] else - --| "[1-9]" - s.extend (c); i := i + 1; c := a_number[i] - --| "\d*" - from until i > n or not c.is_digit loop - s.extend (c); i := i + 1; c := a_number[i] + --| "[1-9]" + s.extend (c); + i := i + 1; + c := a_number [i] + --| "\d*" + from + until + i > n or not c.is_digit + loop + s.extend (c); + i := i + 1; + c := a_number [i] end end end end if Result then - --| "(\.\d+)?" + --| "(\.\d+)?" if c = '.' then - --| "\.\d+" = "\.\d\d*" - s.extend (c); i := i + 1; c := a_number[i] + --| "\.\d+" = "\.\d\d*" + s.extend (c); + i := i + 1; + c := a_number [i] if c.is_digit then - from until i > n or not c.is_digit loop - s.extend (c); i := i + 1; c := a_number[i] + from + until + i > n or not c.is_digit + loop + s.extend (c); + i := i + 1; + c := a_number [i] end else Result := False --| expecting digit @@ -426,23 +444,37 @@ feature {NONE} -- Implementation end if Result then --| "(?:[eE][+-]?\d+)?\b" if c = 'e' or c = 'E' then - --| "[eE][+-]?\d+" - s.extend (c); i := i + 1; c := a_number[i] + --| "[eE][+-]?\d+" + s.extend (c); + i := i + 1; + c := a_number [i] if c = '+' or c = '-' then - s.extend (c); i := i + 1; c := a_number[i] + s.extend (c); + i := i + 1; + c := a_number [i] end if c.is_digit then - from until i > n or not c.is_digit loop - s.extend (c); i := i + 1; c := a_number[i] + from + until + i > n or not c.is_digit + loop + s.extend (c); + i := i + 1; + c := a_number [i] end else - Result := False --| expecting digit + Result := False --| expecting digit end end end if Result then --| "\b" - from until i > n or not c.is_space loop - s.extend (c); i := i + 1; c := a_number[i] + from + until + i > n or not c.is_space + loop + s.extend (c); + i := i + 1; + c := a_number [i] end Result := i > n and then s.same_string (a_number) end @@ -454,19 +486,15 @@ feature {NONE} -- Implementation local i: INTEGER do - if - a_unicode.count = 6 and then - a_unicode[1] = '\' and then - a_unicode[2] = 'u' - then + if a_unicode.count = 6 and then a_unicode [1] = '\' and then a_unicode [2] = 'u' then from Result := True i := 3 until i > 6 or Result = False loop - inspect a_unicode[i] - when '0'..'9', 'a'..'f', 'A'..'F' then + inspect a_unicode [i] + when '0'..'9', 'a'..'f', 'A'..'F' then else Result := False end @@ -493,11 +521,11 @@ feature {NONE} -- Implementation Result := has_next end - is_valid_start_symbol : BOOLEAN + is_valid_start_symbol: BOOLEAN -- expecting `{' or `[' as start symbol do if attached representation as s and then s.count > 0 then - Result := s[1] = '{' or s[1] = '[' + Result := s [1] = '{' or s [1] = '[' end end @@ -509,5 +537,4 @@ feature {NONE} -- Constants null_id: STRING = "null" - end diff --git a/library/kernel/scanner/json_reader.e b/library/kernel/scanner/json_reader.e index 977e91ae..7700285b 100644 --- a/library/kernel/scanner/json_reader.e +++ b/library/kernel/scanner/json_reader.e @@ -12,22 +12,22 @@ create feature {NONE} -- Initialization - make (a_json: STRING) - -- Initialize Reader - do - set_representation (a_json) - end + 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 + set_representation (a_json: STRING) + -- Set `representation'. + do + a_json.left_adjust + a_json.right_adjust representation := a_json - index := 1 - end + index := 1 + end read: CHARACTER -- Read character @@ -65,7 +65,7 @@ feature -- Commands from c := actual 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 next c := actual diff --git a/library/kernel/scanner/json_tokens.e b/library/kernel/scanner/json_tokens.e index 86f86ba3..be35d1e5 100644 --- a/library/kernel/scanner/json_tokens.e +++ b/library/kernel/scanner/json_tokens.e @@ -10,36 +10,40 @@ class 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 + -- 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 + -- Characters which close a type do inspect c when j_OBJECT_CLOSE, j_ARRAY_CLOSE, j_STRING then Result := True else - end end @@ -51,26 +55,24 @@ feature -- Status report -- %R carriage Return -- %T horizontal Tab -- %B Backspace - -- / Solidus - -- " Quotation + -- / 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 + 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 diff --git a/library/kernel/shared_ejson.e b/library/kernel/shared_ejson.e index 421b83a4..eda0ecb2 100644 --- a/library/kernel/shared_ejson.e +++ b/library/kernel/shared_ejson.e @@ -1,38 +1,36 @@ note - description: "[ - Shared factory class for creating JSON objects. Maps JSON - objects to ELKS HASH_TABLEs and JSON arrays to ELKS - LINKED_LISTs. Use non-conforming inheritance from this - class to ensure that your classes share the same - JSON_FACTORY instance. - ]" - author: "Paul Cohen" - date: "$Date$" - revision: "$Revision: 89185 $" - file: "$HeadURL: $" + description: "[ + Shared factory class for creating JSON objects. Maps JSON + objects to ELKS HASH_TABLEs and JSON arrays to ELKS + LINKED_LISTs. Use non-conforming inheritance from this + class to ensure that your classes share the same + JSON_FACTORY instance. + ]" + author: "Paul Cohen" + date: "$Date$" + revision: "$Revision: 89185 $" + file: "$HeadURL: $" -class SHARED_EJSON +class + SHARED_EJSON feature - json: EJSON - -- A shared EJSON instance with default converters for - --LINKED_LIST [ANY] and HASH_TABLE [ANY, HASHABLE] - local + json: EJSON + -- A shared EJSON instance with default converters for + --LINKED_LIST [ANY] and HASH_TABLE [ANY, HASHABLE] + local jalc: JSON_ARRAYED_LIST_CONVERTER - jllc: JSON_LINKED_LIST_CONVERTER - jhtc: JSON_HASH_TABLE_CONVERTER - once - create Result + jllc: JSON_LINKED_LIST_CONVERTER + jhtc: JSON_HASH_TABLE_CONVERTER + once + create Result + create jalc.make + Result.add_converter (jalc) + create jllc.make + Result.add_converter (jllc) + create jhtc.make + Result.add_converter (jhtc) + end - create jalc.make - Result.add_converter (jalc) - - create jllc.make - Result.add_converter (jllc) - - create jhtc.make - Result.add_converter (jhtc) - end - end -- class SHARED_EJSON diff --git a/test/autotest/test_suite/application.e b/test/autotest/test_suite/application.e index 77d42fe7..01160cbe 100644 --- a/test/autotest/test_suite/application.e +++ b/test/autotest/test_suite/application.e @@ -1,12 +1,13 @@ note - description : "test_suite application root class" - date : "$Date$" - revision : "$Revision$" + description: "test_suite application root class" + date: "$Date$" + revision: "$Revision$" class APPLICATION inherit + ARGUMENTS create @@ -17,7 +18,7 @@ feature {NONE} -- Initialization make -- Run application. do - --| Add your code here + --| Add your code here print ("Hello Eiffel World!%N") end diff --git a/test/autotest/test_suite/author.e b/test/autotest/test_suite/author.e index 235cae9f..35118404 100644 --- a/test/autotest/test_suite/author.e +++ b/test/autotest/test_suite/author.e @@ -1,33 +1,32 @@ - class AUTHOR create - make + make feature {NONE} -- Initialization - make (a_name: STRING_32) + make (a_name: STRING_32) -- Create an author with `a_name' as `name'. - do - set_name (a_name) - ensure + do + set_name (a_name) + ensure name_set: name = a_name - end + end feature -- Access - name: STRING_32 - -- Author name + name: STRING_32 + -- Author name feature -- Change - set_name (a_name: STRING_32) + set_name (a_name: STRING_32) -- Set `name' with `a_name'. - do - name := a_name - ensure + do + name := a_name + ensure name_set: name = a_name - end + end end -- class AUTHOR diff --git a/test/autotest/test_suite/book.e b/test/autotest/test_suite/book.e index cd2c2764..96670f16 100644 --- a/test/autotest/test_suite/book.e +++ b/test/autotest/test_suite/book.e @@ -1,60 +1,59 @@ - class BOOK create - make + make feature {NONE} -- Initialization - make (a_title: STRING_32; a_author: AUTHOR; a_isbn: STRING_32) + make (a_title: STRING_32; a_author: AUTHOR; a_isbn: STRING_32) -- Create a book with `a_title' as `title', - -- `a_author' as `author', and `a_isbn' as `isbn', - do - set_title (a_title) - set_author (a_author) - set_isbn (a_isbn) - ensure + -- `a_author' as `author', and `a_isbn' as `isbn'. + do + set_title (a_title) + set_author (a_author) + set_isbn (a_isbn) + ensure title_set: title = a_title author_set: author = a_author isbn_set: isbn = a_isbn - end + end feature -- Access - title: STRING_32 + title: STRING_32 -- Main title. - isbn: STRING_32 + isbn: STRING_32 -- ISBN. - author: AUTHOR + author: AUTHOR -- Author. feature -- Change - set_title (a_title: STRING_32) + set_title (a_title: STRING_32) -- Set `title' with `a_title'. - do - title := a_title - ensure + do + title := a_title + ensure title_set: title = a_title - end + end - set_author (a_author: AUTHOR) + set_author (a_author: AUTHOR) -- Set `author' with `a_author'. - do - author := a_author - ensure + do + author := a_author + ensure author_set: author = a_author - end + end - set_isbn (a_isbn: STRING_32) + set_isbn (a_isbn: STRING_32) -- Set `isbn' with `a_isbn'. - do - isbn := a_isbn - ensure + do + isbn := a_isbn + ensure isbn_set: isbn = a_isbn - end + end end -- class BOOK diff --git a/test/autotest/test_suite/book_collection.e b/test/autotest/test_suite/book_collection.e index 4813d9ea..8959455a 100644 --- a/test/autotest/test_suite/book_collection.e +++ b/test/autotest/test_suite/book_collection.e @@ -2,77 +2,81 @@ class BOOK_COLLECTION create - make + make feature {NONE} -- Initialization - make (a_name: STRING_32) - -- Create a collection of book with `a_name' as `name' - do - set_name (a_name) - create book_index.make (10) - ensure + make (a_name: STRING_32) + -- Create a book collection with `a_name' as `name'. + do + set_name (a_name) + create book_index.make (10) + ensure name_set: name = a_name - end + end feature -- Access - name: STRING_32 + name: STRING_32 -- Name. - books: LIST [BOOK] + books: LIST [BOOK] -- collection of book. - do - create {LINKED_LIST [BOOK]} Result.make - across book_index as it loop + do + create {LINKED_LIST [BOOK]} Result.make + across + book_index as it + loop Result.append (it.item) - end - end + end + end - books_by_author (a_author: STRING_32): LIST [BOOK] + books_by_author (a_author: STRING_32): LIST [BOOK] -- Books wrote by `a_author' in this collection. - do - if attached book_index [a_author] as l_result then - Result := l_result - else - create {LINKED_LIST [BOOK]} Result.make - end - end + do + if attached book_index [a_author] as l_result then + Result := l_result + else + create {LINKED_LIST [BOOK]} Result.make + end + end feature -- Change - set_name (a_name: STRING_32) + set_name (a_name: STRING_32) -- Set `name' with `a_name'. - do - name := a_name - ensure + do + name := a_name + ensure name_set: name = a_name - end + end - add_book (a_book: BOOK) + add_book (a_book: BOOK) -- Extend collection with `a_book'. - local - l: detachable LIST [BOOK] - do - l := book_index.at (a_book.author.name ) - if l = Void then - create {LINKED_LIST [BOOK]} l.make - book_index.put (l, a_book.author.name) - end - l.force (a_book) - end + local + l: detachable LIST [BOOK] + do + l := book_index.at (a_book.author.name) + if l = Void then + create {LINKED_LIST [BOOK]} l.make + book_index.put (l, a_book.author.name) + end + l.force (a_book) + end - add_books (book_list: like books) + add_books (book_list: like books) -- Append collection with `book_list'. - do - across book_list as it loop + do + across + book_list as it + loop add_book (it.item) - end - end + end + end feature {NONE} -- Implementation - book_index: HASH_TABLE [LIST [BOOK], STRING_32] + book_index: HASH_TABLE [LIST [BOOK], STRING_32] -- Association of author name and its books. end -- class BOOK_COLLECTION diff --git a/test/autotest/test_suite/json_author_converter.e b/test/autotest/test_suite/json_author_converter.e index 6375a01a..1eafac8e 100644 --- a/test/autotest/test_suite/json_author_converter.e +++ b/test/autotest/test_suite/json_author_converter.e @@ -1,53 +1,54 @@ note - description: "A JSON converter for AUTHOR" - author: "Paul Cohen" - date: "$Date$" - revision: "$Revision$" + description: "A JSON converter for AUTHOR" + author: "Paul Cohen" + date: "$Date$" + revision: "$Revision$" class JSON_AUTHOR_CONVERTER inherit - JSON_CONVERTER + + JSON_CONVERTER create - make + make feature {NONE} -- Initialization - make - local - ucs: STRING_32 - do - create ucs.make_from_string ("") - create object.make (ucs) - end + make + local + ucs: STRING_32 + do + create ucs.make_from_string ("") + create object.make (ucs) + end feature -- Access - object: AUTHOR + object: AUTHOR feature -- Conversion - from_json (j: like to_json): detachable like object - do - if attached {STRING_32} json.object (j.item (name_key), Void) as l_name then + from_json (j: like to_json): detachable like object + do + if attached {STRING_32} json.object (j.item (name_key), Void) as l_name then create Result.make (l_name) - end - end + end + end - to_json (o: like object): JSON_OBJECT - do - create Result.make - Result.put (json.value (o.name), name_key) - end + to_json (o: like object): JSON_OBJECT + do + create Result.make + Result.put (json.value (o.name), name_key) + end feature {NONE} -- Implementation - name_key: JSON_STRING + name_key: JSON_STRING -- Author's name label. - once - create Result.make_json ("name") - end + once + create Result.make_json ("name") + end end -- class JSON_AUTHOR_CONVERTER diff --git a/test/autotest/test_suite/json_book_collection_converter.e b/test/autotest/test_suite/json_book_collection_converter.e index e78b070e..0ba713f2 100644 --- a/test/autotest/test_suite/json_book_collection_converter.e +++ b/test/autotest/test_suite/json_book_collection_converter.e @@ -1,45 +1,45 @@ note - description: "A JSON converter for BOOK_COLLECTION" - author: "Paul Cohen" - date: "$Date$" - revision: "$Revision$" + description: "A JSON converter for BOOK_COLLECTION" + author: "Paul Cohen" + date: "$Date$" + revision: "$Revision$" class JSON_BOOK_COLLECTION_CONVERTER inherit - JSON_CONVERTER + + JSON_CONVERTER create - make + make feature {NONE} -- Initialization - make - local - ucs: STRING_32 - do - create ucs.make_from_string ("") - create object.make (ucs) - end + make + local + ucs: STRING_32 + do + create ucs.make_from_string ("") + create object.make (ucs) + end feature -- Access - object: BOOK_COLLECTION + object: BOOK_COLLECTION feature -- Conversion - from_json (j: like to_json): detachable like object - local - l_books: LINKED_LIST [BOOK] - do - if + from_json (j: like to_json): detachable like object + local + l_books: LINKED_LIST [BOOK] + do + if attached {STRING_32} json.object (j.item (name_key), Void) as l_name and attached {JSON_ARRAY} j.item (books_key) as l_json_array - then + then create Result.make (l_name) create l_books.make - across l_json_array as it until @@ -52,32 +52,31 @@ feature -- Conversion -- Failed end end - if Result /= Void then Result.add_books (l_books) end - end - end + end + end - to_json (o: like object): JSON_OBJECT - do - create Result.make - Result.put (json.value (o.name), name_key) - Result.put (json.value (o.books), books_key) - end + to_json (o: like object): JSON_OBJECT + do + create Result.make + Result.put (json.value (o.name), name_key) + Result.put (json.value (o.books), books_key) + end -feature {NONE} -- Implementation +feature {NONE} -- Implementation - name_key: JSON_STRING + name_key: JSON_STRING -- Collection's name label. - once - create Result.make_json ("name") - end + once + create Result.make_json ("name") + end - books_key: JSON_STRING + books_key: JSON_STRING -- Book list label. - once - create Result.make_json ("books") - end + once + create Result.make_json ("books") + end end -- class JSON_BOOK_COLLECTION_CONVERTER diff --git a/test/autotest/test_suite/json_book_converter.e b/test/autotest/test_suite/json_book_converter.e index 9da210a5..8711420c 100644 --- a/test/autotest/test_suite/json_book_converter.e +++ b/test/autotest/test_suite/json_book_converter.e @@ -1,73 +1,74 @@ note - description: "A JSON converter for BOOK" - author: "Paul Cohen" - date: "$Date$" - revision: "$Revision$" + description: "A JSON converter for BOOK" + author: "Paul Cohen" + date: "$Date$" + revision: "$Revision$" class JSON_BOOK_CONVERTER inherit - JSON_CONVERTER + + JSON_CONVERTER create - make + make feature {NONE} -- Initialization - make - local - ucs: STRING_32 - a: AUTHOR - do - create ucs.make_from_string ("") - create a.make (ucs) - create object.make (ucs, a, ucs) - end + make + local + ucs: STRING_32 + a: AUTHOR + do + create ucs.make_from_string ("") + create a.make (ucs) + create object.make (ucs, a, ucs) + end feature -- Access - object: BOOK + object: BOOK feature -- Conversion - from_json (j: like to_json): detachable like object - do - if + from_json (j: like to_json): detachable like object + do + if attached {STRING_32} json.object (j.item (title_key), Void) as l_title and attached {STRING_32} json.object (j.item (isbn_key), Void) as l_isbn and attached {AUTHOR} json.object (j.item (author_key), "AUTHOR") as l_author - then + then create Result.make (l_title, l_author, l_isbn) - end - end + end + end - to_json (o: like object): JSON_OBJECT - do - create Result.make - Result.put (json.value (o.title), title_key) - Result.put (json.value (o.isbn), isbn_key) - Result.put (json.value (o.author), author_key) - end + to_json (o: like object): JSON_OBJECT + do + create Result.make + Result.put (json.value (o.title), title_key) + Result.put (json.value (o.isbn), isbn_key) + Result.put (json.value (o.author), author_key) + end feature {NONE} -- Implementation - title_key: JSON_STRING + title_key: JSON_STRING -- Book's title label. - once - create Result.make_json ("title") - end + once + create Result.make_json ("title") + end - isbn_key: JSON_STRING + isbn_key: JSON_STRING -- Book ISBN label. - once - create Result.make_json ("isbn") - end + once + create Result.make_json ("isbn") + end - author_key: JSON_STRING + author_key: JSON_STRING -- Author label. - once - create Result.make_json ("author") - end + once + create Result.make_json ("author") + end end -- class JSON_BOOK_CONVERTER diff --git a/test/autotest/test_suite/test_ds.e b/test/autotest/test_suite/test_ds.e index 5b3f28f8..5f737ea8 100644 --- a/test/autotest/test_suite/test_ds.e +++ b/test/autotest/test_suite/test_ds.e @@ -1,14 +1,14 @@ - note - description: "Linked list and hash table converters test." - date: "$Date$" - revision: "$Revision$" + description: "Linked list and hash table converters test." + date: "$Date$" + revision: "$Revision$" class TEST_DS inherit - SHARED_EJSON + + SHARED_EJSON undefine default_create end @@ -17,60 +17,56 @@ inherit feature -- Test - test_linked_list_converter + test_linked_list_converter -- Convert a linked list to a json value and -- convert this one to a linked list. - local - l: LINKED_LIST [STRING] - s: STRING - do - create l.make - l.force ("foo") - l.force ("bar") + local + l: LINKED_LIST [STRING] + s: STRING + do + create l.make + l.force ("foo") + l.force ("bar") + if attached json.value (l) as l_value then + s := l_value.representation + assert ("JSON array converted to LINKED_LIST", attached {LINKED_LIST [detachable ANY]} json.object (l_value, "LINKED_LIST")) + else + assert ("LINKED_LIST converted to a JSON value", False) + end + end - if attached json.value (l) as l_value then - s := l_value.representation - assert ("JSON array converted to LINKED_LIST", attached {LINKED_LIST [detachable ANY]} json.object (l_value, "LINKED_LIST")) - else - assert ("LINKED_LIST converted to a JSON value", False) - end - end - - test_hash_table_converter + test_hash_table_converter -- Convert a hash table to a json value and -- convert this one to a hash table. - local - t: HASH_TABLE [STRING, STRING] - s: STRING - l_ucs_key: detachable STRING_32 - do - create t.make (2) - t.put ("foo", "1") - t.put ("bar", "2") - - if attached json.value (t) as l_value then - s := l_value.representation - if attached {HASH_TABLE [ANY, HASHABLE]} json.object (l_value, "HASH_TABLE") as t2 then - - create l_ucs_key.make_from_string ("1") - if attached {STRING_32} t2 [l_ucs_key] as l_ucs_value then - assert ("ucs_value.string.is_equal (%"foo%")", l_ucs_value.string.is_equal ("foo")) - else - assert ("ucs_value /= Void", False) - end - - create l_ucs_key.make_from_string ("2") - if attached {STRING_32} t2 [l_ucs_key] as l_ucs_value then - assert ("ucs_value.string.is_equal (%"bar%")", l_ucs_value.string.is_equal ("bar")) - else - assert ("ucs_value /= Void", False) - end - else - assert ("JSON object converted to HASH_TABLE", False); - end - else - assert ("HASH_TABLE converted to a JSON value", False) - end - end + local + t: HASH_TABLE [STRING, STRING] + s: STRING + l_ucs_key: detachable STRING_32 + do + create t.make (2) + t.put ("foo", "1") + t.put ("bar", "2") + if attached json.value (t) as l_value then + s := l_value.representation + if attached {HASH_TABLE [ANY, HASHABLE]} json.object (l_value, "HASH_TABLE") as t2 then + create l_ucs_key.make_from_string ("1") + if attached {STRING_32} t2 [l_ucs_key] as l_ucs_value then + assert ("ucs_value.string.is_equal (%"foo%")", l_ucs_value.string.is_equal ("foo")) + else + assert ("ucs_value /= Void", False) + end + create l_ucs_key.make_from_string ("2") + if attached {STRING_32} t2 [l_ucs_key] as l_ucs_value then + assert ("ucs_value.string.is_equal (%"bar%")", l_ucs_value.string.is_equal ("bar")) + else + assert ("ucs_value /= Void", False) + end + else + assert ("JSON object converted to HASH_TABLE", False); + end + else + assert ("HASH_TABLE converted to a JSON value", False) + end + end end -- class TEST_DS diff --git a/test/autotest/test_suite/test_json_core.e b/test/autotest/test_suite/test_json_core.e index 61b68b39..7db16c2c 100644 --- a/test/autotest/test_suite/test_json_core.e +++ b/test/autotest/test_suite/test_json_core.e @@ -1,8 +1,9 @@ -class +class TEST_JSON_CORE inherit - SHARED_EJSON + + SHARED_EJSON undefine default_create end @@ -11,32 +12,32 @@ inherit feature -- Test - test_json_number_and_integer - local - i: INTEGER - jn: JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - i := 42 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_integer (i) - assert ("jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_NUMBER} json.value (i) as l_jn then + test_json_number_and_integer + local + i: INTEGER + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i := 42 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i) + assert ("jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (i) as l_jn then assert ("l_jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) else assert ("json.value (i) is a JSON_NUMBER", False) - end + end - -- JSON representation-> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_8 since the value is 42 - jrep := "42" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then - if attached {INTEGER_8} json.object (jn, Void) as l_i8 then + -- JSON representation-> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_8 since the value is 42 + jrep := "42" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_8} json.object (jn, Void) as l_i8 then assert ("l_i8 = 42", l_i8 = 42) else assert ("json.object (jn, Void) is a INTEGER_8", False) @@ -44,34 +45,34 @@ feature -- Test else assert ("parser.parse is a JSON_NUMBER", False) end - end + end - test_json_number_and_integer_8 - local - i8: INTEGER_8 - jn: JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - i8 := 42 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_integer (i8) - assert ("jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_NUMBER} json.value (i8) as l_jn then - assert ("l_jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) + test_json_number_and_integer_8 + local + i8: INTEGER_8 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i8 := 42 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i8) + assert ("jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (i8) as l_jn then + assert ("l_jn.representation.same_string (%"42%")", jn.representation.same_string ("42")) else assert ("json.value (i8) is a JSON_NUMBER", False) - end + end - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_8 since the value is 42 - jrep := "42" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then - if attached {INTEGER_8} json.object (jn, Void) as l_i8 then + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_8 since the value is 42 + jrep := "42" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_8} json.object (jn, Void) as l_i8 then assert ("l_i8 = 42", l_i8 = 42) else assert ("json.object (jn, Void) is a INTEGER_8", False) @@ -79,34 +80,34 @@ feature -- Test else assert ("parser.parse is a JSON_NUMBER", False) end - end + end - test_json_number_and_integer_16 - local - i16: INTEGER_16 - jn: JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - i16 := 300 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_integer (i16) - assert ("jn.representation.same_string (%"300%")", jn.representation.same_string ("300")) - -- Eiffel value -> JSON with factory - if attached {JSON_NUMBER} json.value (i16) as l_jn then - assert ("l_jn.representation.same_string (%"300%")", l_jn.representation.same_string ("300")) + test_json_number_and_integer_16 + local + i16: INTEGER_16 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i16 := 300 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i16) + assert ("jn.representation.same_string (%"300%")", jn.representation.same_string ("300")) + -- Eiffel value -> JSON with factory + if attached {JSON_NUMBER} json.value (i16) as l_jn then + assert ("l_jn.representation.same_string (%"300%")", l_jn.representation.same_string ("300")) else assert ("json.value (i16) is a JSON_NUMBER", False) - end + end - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_16 since the value is 300 - jrep := "300" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then - if attached {INTEGER_16} json.object (jn, Void) as l_i16 then + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_16 since the value is 300 + jrep := "300" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_16} json.object (jn, Void) as l_i16 then assert ("l_i16 = 300", l_i16 = 300) else assert ("json.object (jn, Void) is a INTEGER_16", False) @@ -114,34 +115,34 @@ feature -- Test else assert ("parser.parse is a JSON_NUMBER", False) end - end + end - test_json_number_and_integer_32 - local - i32: INTEGER_32 - jn: JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - i32 := 100000 - -- Eiffel value -> JSON representation -> JSON value - create jn.make_integer (i32) - assert ("jn.representation.same_string (%"100000%")", jn.representation.same_string ("100000")) - -- Eiffel value -> JSON representation -> JSON value with factory - if attached {JSON_NUMBER} json.value (i32) as l_jn then - assert ("l_jn.representation.same_string (%"100000%")", l_jn.representation.same_string ("100000")) + test_json_number_and_integer_32 + local + i32: INTEGER_32 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i32 := 100000 + -- Eiffel value -> JSON representation -> JSON value + create jn.make_integer (i32) + assert ("jn.representation.same_string (%"100000%")", jn.representation.same_string ("100000")) + -- Eiffel value -> JSON representation -> JSON value with factory + if attached {JSON_NUMBER} json.value (i32) as l_jn then + assert ("l_jn.representation.same_string (%"100000%")", l_jn.representation.same_string ("100000")) else assert ("json.value (i32) is a JSON_NUMBER", False) - end + end - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_32 since the value is 100000 - jrep := "100000" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then - if attached {INTEGER_32} json.object (jn, Void) as l_i32 then + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 100000 + jrep := "100000" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_32} json.object (jn, Void) as l_i32 then assert ("l_i32 = 100000", l_i32 = 100000) else assert ("json.object (jn, Void) is a INTEGER_32", False) @@ -149,34 +150,34 @@ feature -- Test else assert ("parser.parse is a JSON_NUMBER", False) end - end + end - test_json_number_and_integer_64 - local - i64: INTEGER_64 - jn: JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - i64 := 42949672960 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_integer (i64) - assert ("jn.representation.same_string (%"42949672960%")", jn.representation.same_string ("42949672960")) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_NUMBER} json.value (i64) as l_jn then - assert ("l_jn.representation.same_string (%"42949672960%")", l_jn.representation.same_string ("42949672960")) + test_json_number_and_integer_64 + local + i64: INTEGER_64 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + i64 := 42949672960 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_integer (i64) + assert ("jn.representation.same_string (%"42949672960%")", jn.representation.same_string ("42949672960")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (i64) as l_jn then + assert ("l_jn.representation.same_string (%"42949672960%")", l_jn.representation.same_string ("42949672960")) else assert ("json.value (i64) is a JSON_NUMBER", False) - end + end - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_32 since the value is 42949672960 - jrep := "42949672960" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then - if attached {INTEGER_64} json.object (jn, Void) as l_i64 then + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 42949672960 + jrep := "42949672960" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_64} json.object (jn, Void) as l_i64 then assert ("l_i64 = 42949672960", l_i64 = 42949672960) else assert ("json.object (jn, Void) is a INTEGER_64", False) @@ -184,69 +185,69 @@ feature -- Test else assert ("parser.parse is a JSON_NUMBER", False) end - end + end - test_json_number_and_natural_8 - local - n8: NATURAL_8 - jn: JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - n8 := 200 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_natural (n8) - assert ("jn.representation.same_string (%"200%")", jn.representation.same_string ("200")) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_NUMBER} json.value (n8) as l_jn then - assert ("l_jn.representation.same_string (%"200%")", l_jn.representation.same_string ("200")) - else - assert ("json.value (n8) is a JSON_NUMBER}", False) - end + test_json_number_and_natural_8 + local + n8: NATURAL_8 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + n8 := 200 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n8) + assert ("jn.representation.same_string (%"200%")", jn.representation.same_string ("200")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (n8) as l_jn then + assert ("l_jn.representation.same_string (%"200%")", l_jn.representation.same_string ("200")) + else + assert ("json.value (n8) is a JSON_NUMBER}", False) + end - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_16 since the value is 200 - jrep := "200" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then - if attached {INTEGER_16} json.object (jn, Void) as i16 then - assert ("i16 = 200", i16 = 200) - else - assert ("json.object (jn, Void) is an INTEGER_16", False) - end + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_16 since the value is 200 + jrep := "200" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_16} json.object (jn, Void) as i16 then + assert ("i16 = 200", i16 = 200) + else + assert ("json.object (jn, Void) is an INTEGER_16", False) + end else assert ("parser.parse is a JSON_NUMBER", False) - end - end + end + end - test_json_number_and_natural_16 - local - n16: NATURAL_16 - jn: JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - n16 := 32768 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_natural (n16) - assert ("jn.representation.same_string (%"32768%")", jn.representation.same_string ("32768")) - -- Eiffel value -> JSON value -> JSON representation with factory + test_json_number_and_natural_16 + local + n16: NATURAL_16 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + n16 := 32768 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n16) + assert ("jn.representation.same_string (%"32768%")", jn.representation.same_string ("32768")) + -- Eiffel value -> JSON value -> JSON representation with factory if attached {JSON_NUMBER} json.value (n16) as l_jn then - assert ("l_jn.representation.same_string (%"32768%")", l_jn.representation.same_string ("32768")) - else - assert ("json.value (n16) is a JSON_NUMBER", False) - end + assert ("l_jn.representation.same_string (%"32768%")", l_jn.representation.same_string ("32768")) + else + assert ("json.value (n16) is a JSON_NUMBER", False) + end - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_32 since the value is 32768 - jrep := "32768" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then - if attached {INTEGER_32} json.object (jn, Void) as i32 then + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 32768 + jrep := "32768" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_32} json.object (jn, Void) as i32 then assert ("i32 = 32768", i32 = 32768) else assert ("json.object (jn, Void) is a INTEGER_32", False) @@ -254,310 +255,308 @@ feature -- Test else assert ("parser.parse is a JSON_NUMBER", False) end - end + end - test_json_number_and_natural_32 - local - n32: NATURAL_32 - jn: JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - n32 := 2147483648 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_natural (n32) - assert ("jn.representation.same_string (%"2147483648%")", jn.representation.same_string ("2147483648")) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached json.value (n32) as l_jn then - assert ("l_jn.representation.same_string (%"2147483648%")", l_jn.representation.same_string ("2147483648")) - else - assert ("json.value (n32) is a JSON_NUMBER", False) - end - - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_64 since the value is 2147483648 - jrep := "2147483648" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then - if attached {INTEGER_64} json.object (jn, Void) as i64 then - assert ("i64 = 2147483648", i64 = 2147483648) - else - assert ("json.object (jn, Void) is a INTEGER_64", False) - end - else - assert ("parser.parse is a JSON_NUMBER", False) - end - end - - test_json_number_and_large_integers - local - jrep: STRING - n64: NATURAL_64 - jn: JSON_NUMBER - parser: JSON_PARSER - do - n64 := 9223372036854775808 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_natural (n64) - assert ("jn.representation.same_string (%"9223372036854775808%")", jn.representation.same_string ("9223372036854775808")) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_NUMBER} json.value (n64) as l_jn then - assert ("l_jn.representation.same_string (%"9223372036854775808%")", l_jn.representation.same_string ("9223372036854775808")) - else - assert ("json.value (n64) is a JSON_NUMBER", False) - end - - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- we know it is INTEGER_32 since the value is 42949672960 - jrep := "9223372036854775808" -- 1 higher than largest positive number that can be represented by INTEGER 64 - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then - if attached {NATURAL_64} json.object (jn, Void) as l_n64 then - assert ("l_n64 = 9223372036854775808", l_n64 = 9223372036854775808) - else - assert ("json.object (jn, Void) is a NATURAL_64", False) - end - else - assert ("parser.parse is a JSON_NUMBER", False) - end - end - - test_json_number_and_eiffel_real - local - r: REAL - jn: JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - r := 3.14 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_real (r) - assert ("jn.representation.same_string (%"3.1400001049041748%")", jn.representation.same_string ("3.1400001049041748")) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_NUMBER} json.value (r) as l_jn then - assert ("l_jn.representation.same_string (%"3.1400001049041748%")", l_jn.representation.same_string ("3.1400001049041748")) - else - assert ("json.value (r) is a JSON_NUMBER", False) - end - - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will always return a REAL_64 if the value - -- of the JSON number is a floating point number - jrep := "3.14" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then - if attached {REAL_64} json.object (jn, Void) as r64 then - assert ("3.14 <= r64 and r64 <= 3.141", 3.14 <= r64 and r64 <= 3.141) - else - assert ("json.object (jn, Void) is a REAL_64", False) - end - else - assert ("parser.parse is a JSON_NUMBER", False) - end - end - - test_json_number_and_eiffel_real_32 - local - r32: REAL_32 - jn: JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - r32 := 3.14 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_real (r32) - assert ("jn.representation.same_string (%"3.1400001049041748%")", jn.representation.same_string ("3.1400001049041748")) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_NUMBER} json.value (r32) as l_jn then - assert ("l_jn.representation.same_string (%"3.1400001049041748%")", l_jn.representation.same_string ("3.1400001049041748")) + test_json_number_and_natural_32 + local + n32: NATURAL_32 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + n32 := 2147483648 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n32) + assert ("jn.representation.same_string (%"2147483648%")", jn.representation.same_string ("2147483648")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached json.value (n32) as l_jn then + assert ("l_jn.representation.same_string (%"2147483648%")", l_jn.representation.same_string ("2147483648")) else - assert ("json.value (r32) is a JSON_NUMBER", False) - end + assert ("json.value (n32) is a JSON_NUMBER", False) + end - -- JSON representation -> JSON value -> Eiffel value - jrep := "3.1400001049041748" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then - if attached {REAL_64} json.object (l_jn, Void) as r64 then - assert ("r64 = 3.1400001049041748", r64 = 3.1400001049041748) - else - assert ("json.object (l_jn, Void) is a REAL_64", False) - end + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_64 since the value is 2147483648 + jrep := "2147483648" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {INTEGER_64} json.object (jn, Void) as i64 then + assert ("i64 = 2147483648", i64 = 2147483648) + else + assert ("json.object (jn, Void) is a INTEGER_64", False) + end else assert ("parser.parse is a JSON_NUMBER", False) - end - end + end + end - test_json_number_and_eiffel_real_64 - local - r64: REAL_64 - jn: JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - r64 := 3.1415926535897931 - -- Eiffel value -> JSON value -> JSON representation - create jn.make_real (r64) - assert ("jn.representation.same_string (%"3.1415926535897931%")", jn.representation.same_string ("3.1415926535897931")) - - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_NUMBER} json.value (r64) as l_jn then - assert ("l_jn.representation.same_string (%"3.1415926535897931%")", l_jn.representation.same_string ("3.1415926535897931")) - else - assert ("json.value (r64) is a JSON_NUMBER", False) - end - - -- JSON representation -> JSON value -> Eiffel value - jrep := "3.1415926535897931" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then - if attached {REAL_64} json.object (jn, Void) as l_r64 then - assert ("l_r64 = 3.1415926535897931", l_r64 = 3.1415926535897931) - else - assert ("json.object (jn, Void) is a REAL_64", False) - end - else - assert ("parser.parse is a JSON_NUMBER", False) - end - end - - test_json_boolean - local - parser: JSON_PARSER - jb: JSON_BOOLEAN - b: BOOLEAN - do - -- Eiffel value -> JSON value -> JSON representation - b := True - create jb.make_boolean (b) - assert ("jb.representation.is_equal (%"true%")", jb.representation.is_equal ("true")) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_BOOLEAN} json.value (b) as l_jb then - assert ("l_jb.representation.same_string (%"true%")", l_jb.representation.same_string ("true")) - else - assert ("l_jb /= Void", False) - end - - -- JSON representation -> JSON value -> Eiffel value - create parser.make_parser ("true") - if attached {JSON_BOOLEAN} parser.parse as l_jb then - if attached {BOOLEAN} json.object (l_jb, Void) as l_b then - assert ("l_b = True", l_b = True) - else - assert ("json.object (l_jb, Void) is BOOLEAN", False) - end + test_json_number_and_large_integers + local + jrep: STRING + n64: NATURAL_64 + jn: JSON_NUMBER + parser: JSON_PARSER + do + n64 := 9223372036854775808 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_natural (n64) + assert ("jn.representation.same_string (%"9223372036854775808%")", jn.representation.same_string ("9223372036854775808")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (n64) as l_jn then + assert ("l_jn.representation.same_string (%"9223372036854775808%")", l_jn.representation.same_string ("9223372036854775808")) else - assert ("parser.parse is a JSON_BOOLEAN", False) - end + assert ("json.value (n64) is a JSON_NUMBER", False) + end - -- Eiffel value -> JSON value -> JSON representation - b := False - create jb.make_boolean (b) - assert ("jb.representation.same_string (%"false%")", jb.representation.same_string ("false")) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_BOOLEAN} json.value (b) as l_jb then - assert ("l_jb.representation.same_string (%"false%")", l_jb.representation.same_string ("false")) - else - assert ("json.value (b) is a JSON_BOOLEAN", False) - end + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- we know it is INTEGER_32 since the value is 42949672960 + jrep := "9223372036854775808" -- 1 higher than largest positive number that can be represented by INTEGER 64 + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {NATURAL_64} json.object (jn, Void) as l_n64 then + assert ("l_n64 = 9223372036854775808", l_n64 = 9223372036854775808) + else + assert ("json.object (jn, Void) is a NATURAL_64", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end - -- JSON representation -> JSON value -> Eiffel value - create parser.make_parser ("false") - if attached {JSON_BOOLEAN} parser.parse as l_jb then - if attached {BOOLEAN} json.object (l_jb, Void) as l_b then - assert ("l_b = False", l_b = False) + test_json_number_and_eiffel_real + local + r: REAL + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + r := 3.14 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_real (r) + assert ("jn.representation.same_string (%"3.1400001049041748%")", jn.representation.same_string ("3.1400001049041748")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (r) as l_jn then + assert ("l_jn.representation.same_string (%"3.1400001049041748%")", l_jn.representation.same_string ("3.1400001049041748")) + else + assert ("json.value (r) is a JSON_NUMBER", False) + end + + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will always return a REAL_64 if the value + -- of the JSON number is a floating point number + jrep := "3.14" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {REAL_64} json.object (jn, Void) as r64 then + assert ("3.14 <= r64 and r64 <= 3.141", 3.14 <= r64 and r64 <= 3.141) + else + assert ("json.object (jn, Void) is a REAL_64", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_number_and_eiffel_real_32 + local + r32: REAL_32 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + r32 := 3.14 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_real (r32) + assert ("jn.representation.same_string (%"3.1400001049041748%")", jn.representation.same_string ("3.1400001049041748")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (r32) as l_jn then + assert ("l_jn.representation.same_string (%"3.1400001049041748%")", l_jn.representation.same_string ("3.1400001049041748")) + else + assert ("json.value (r32) is a JSON_NUMBER", False) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "3.1400001049041748" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {REAL_64} json.object (l_jn, Void) as r64 then + assert ("r64 = 3.1400001049041748", r64 = 3.1400001049041748) + else + assert ("json.object (l_jn, Void) is a REAL_64", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_number_and_eiffel_real_64 + local + r64: REAL_64 + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + r64 := 3.1415926535897931 + -- Eiffel value -> JSON value -> JSON representation + create jn.make_real (r64) + assert ("jn.representation.same_string (%"3.1415926535897931%")", jn.representation.same_string ("3.1415926535897931")) + + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NUMBER} json.value (r64) as l_jn then + assert ("l_jn.representation.same_string (%"3.1415926535897931%")", l_jn.representation.same_string ("3.1415926535897931")) + else + assert ("json.value (r64) is a JSON_NUMBER", False) + end + + -- JSON representation -> JSON value -> Eiffel value + jrep := "3.1415926535897931" + create parser.make_parser (jrep) + if attached {JSON_NUMBER} parser.parse as l_jn then + if attached {REAL_64} json.object (jn, Void) as l_r64 then + assert ("l_r64 = 3.1415926535897931", l_r64 = 3.1415926535897931) + else + assert ("json.object (jn, Void) is a REAL_64", False) + end + else + assert ("parser.parse is a JSON_NUMBER", False) + end + end + + test_json_boolean + local + parser: JSON_PARSER + jb: JSON_BOOLEAN + b: BOOLEAN + do + -- Eiffel value -> JSON value -> JSON representation + b := True + create jb.make_boolean (b) + assert ("jb.representation.is_equal (%"true%")", jb.representation.is_equal ("true")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_BOOLEAN} json.value (b) as l_jb then + assert ("l_jb.representation.same_string (%"true%")", l_jb.representation.same_string ("true")) + else + assert ("l_jb /= Void", False) + end + + -- JSON representation -> JSON value -> Eiffel value + create parser.make_parser ("true") + if attached {JSON_BOOLEAN} parser.parse as l_jb then + if attached {BOOLEAN} json.object (l_jb, Void) as l_b then + assert ("l_b = True", l_b = True) + else + assert ("json.object (l_jb, Void) is BOOLEAN", False) + end + else + assert ("parser.parse is a JSON_BOOLEAN", False) + end + + -- Eiffel value -> JSON value -> JSON representation + b := False + create jb.make_boolean (b) + assert ("jb.representation.same_string (%"false%")", jb.representation.same_string ("false")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_BOOLEAN} json.value (b) as l_jb then + assert ("l_jb.representation.same_string (%"false%")", l_jb.representation.same_string ("false")) + else + assert ("json.value (b) is a JSON_BOOLEAN", False) + end + + -- JSON representation -> JSON value -> Eiffel value + create parser.make_parser ("false") + if attached {JSON_BOOLEAN} parser.parse as l_jb then + if attached {BOOLEAN} json.object (l_jb, Void) as l_b then + assert ("l_b = False", l_b = False) else assert ("json.object (l_jb, Void) is a BOOLEAN", False) end - else - assert ("parser.parse is a JSON_BOOLEAN", False) - end - end + else + assert ("parser.parse is a JSON_BOOLEAN", False) + end + end - test_json_null - local - jrep: STRING - jn: JSON_NULL - parser: JSON_PARSER - do - -- Eiffel value -> JSON value -> JSON representation - create jn - jrep := "null" - - assert ("jn.representation.is_equal (%"%"null%"%")", jn.representation.is_equal (jrep)) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_NULL} json.value (Void) as l_json_null then + test_json_null + local + jrep: STRING + jn: JSON_NULL + parser: JSON_PARSER + do + -- Eiffel value -> JSON value -> JSON representation + create jn + jrep := "null" + assert ("jn.representation.is_equal (%"%"null%"%")", jn.representation.is_equal (jrep)) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_NULL} json.value (Void) as l_json_null then assert ("jn.representation.is_equal (%"null%")", l_json_null.representation.is_equal ("null")) - else - assert ("json.value (Void) /= Void", False) - end + else + assert ("json.value (Void) /= Void", False) + end - -- JSON representation -> JSON value -> Eiffel value - create parser.make_parser (jrep) - if attached parser.parse as l_json_null then - assert ("a = Void", json.object (l_json_null, Void) = Void) - else - assert ("parser.parse /= Void", False) - end - end + -- JSON representation -> JSON value -> Eiffel value + create parser.make_parser (jrep) + if attached parser.parse as l_json_null then + assert ("a = Void", json.object (l_json_null, Void) = Void) + else + assert ("parser.parse /= Void", False) + end + end - test_json_string_and_character - local - c: CHARACTER - jrep: STRING - js: JSON_STRING - parser: JSON_PARSER - do - c := 'a' - -- Eiffel value -> JSON value -> JSON representation - create js.make_json (c.out) - - assert ("js.representation.is_equal (%"%"a%"%")", js.representation.is_equal ("%"a%"")) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_STRING} json.value (c) as l_json_str then + test_json_string_and_character + local + c: CHARACTER + jrep: STRING + js: JSON_STRING + parser: JSON_PARSER + do + c := 'a' + -- Eiffel value -> JSON value -> JSON representation + create js.make_json (c.out) + assert ("js.representation.is_equal (%"%"a%"%")", js.representation.is_equal ("%"a%"")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_STRING} json.value (c) as l_json_str then assert ("js.representation.is_equal (%"%"a%"%")", l_json_str.representation.is_equal ("%"a%"")) - else - assert ("json.value (c) /= Void", False) - end + else + assert ("json.value (c) /= Void", False) + end - -- JSON representation -> JSON value -> Eiffel value - jrep := "%"a%"" - create parser.make_parser (jrep) - if attached {JSON_STRING} parser.parse as l_json_str then + -- JSON representation -> JSON value -> Eiffel value + jrep := "%"a%"" + create parser.make_parser (jrep) + if attached {JSON_STRING} parser.parse as l_json_str then if attached {STRING_32} json.object (l_json_str, Void) as ucs then assert ("ucs.string.is_equal (%"a%")", ucs.string.is_equal ("a")) end else assert ("parser.parse /= Void", False) end - end + end - test_json_string_and_string - local - s: STRING - js: detachable JSON_STRING - jrep: STRING - parser: JSON_PARSER - do - s := "foobar" - jrep := "%"foobar%"" + test_json_string_and_string + local + s: STRING + js: detachable JSON_STRING + jrep: STRING + parser: JSON_PARSER + do + s := "foobar" + jrep := "%"foobar%"" - -- Eiffel value -> JSON value -> JSON representation - create js.make_json (s) - assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal (jrep)) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_STRING} json.value (s) as l_js then + -- Eiffel value -> JSON value -> JSON representation + create js.make_json (s) + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal (jrep)) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_STRING} json.value (s) as l_js then assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal (jrep)) - else + else assert ("json.value (s) /= Void", False) - end + end - -- JSON representation -> JSON value -> Eiffel value - create parser.make_parser (jrep) + -- JSON representation -> JSON value -> Eiffel value + create parser.make_parser (jrep) if attached {JSON_STRING} parser.parse as l_js then if attached {STRING_32} json.object (l_js, Void) as l_ucs then assert ("ucs.string.is_equal (%"foobar%")", l_ucs.string.is_equal (s)) @@ -565,34 +564,34 @@ feature -- Test else assert ("parser.parse /= Void", False) end - end + end - test_json_string_and_uc_string - local - js: detachable JSON_STRING - ucs: detachable STRING_32 - jrep, s: STRING - parser: JSON_PARSER - do - s := "foobar" - jrep := "%"foobar%"" - create ucs.make_from_string (s) + test_json_string_and_uc_string + local + js: detachable JSON_STRING + ucs: detachable STRING_32 + jrep, s: STRING + parser: JSON_PARSER + do + s := "foobar" + jrep := "%"foobar%"" + create ucs.make_from_string (s) - -- Eiffel value -> JSON value -> JSON representation - create js.make_json (ucs) - assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal (jrep)) + -- Eiffel value -> JSON value -> JSON representation + create js.make_json (ucs) + assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal (jrep)) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_STRING} json.value (ucs) as l_js then + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_STRING} json.value (ucs) as l_js then assert ("js.representation.is_equal (%"%"foobar%"%")", l_js.representation.is_equal (jrep)) - else + else assert ("json.value (ucs) /= Void", False) - end + end - -- JSON representation -> JSON value -> Eiffel value - create parser.make_parser (jrep) - if attached {JSON_STRING} parser.parse as l_js then - if attached {STRING_32} json.object (l_js, Void) as l_ucs then + -- JSON representation -> JSON value -> Eiffel value + create parser.make_parser (jrep) + if attached {JSON_STRING} parser.parse as l_js then + if attached {STRING_32} json.object (l_js, Void) as l_ucs then assert ("ucs.string.is_equal (%"foobar%")", l_ucs.string.is_equal (s)) else assert ("json.object (js, Void) /= Void", False) @@ -600,104 +599,99 @@ feature -- Test else assert ("parser.parse /= Void", False) end - end + end - test_json_string_and_special_characters - local - js: detachable JSON_STRING - s: detachable STRING_8 - jrep: STRING - parser: JSON_PARSER - do - jrep := "%"foo\\bar%"" - create s.make_from_string ("foo\bar") - create js.make_json (s) + test_json_string_and_special_characters + local + js: detachable JSON_STRING + s: detachable STRING_8 + jrep: STRING + parser: JSON_PARSER + do + jrep := "%"foo\\bar%"" + create s.make_from_string ("foo\bar") + create js.make_json (s) + assert ("js.representation.same_string (%"%"foo\\bar%"%")", js.representation.same_string (jrep)) - assert ("js.representation.same_string (%"%"foo\\bar%"%")", js.representation.same_string (jrep)) - - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_STRING} json.value (s) as l_js then - assert ("js.representation.is_equal (%"%"foobar%"%")", l_js.representation.same_string (jrep)) - else + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_STRING} json.value (s) as l_js then + assert ("js.representation.is_equal (%"%"foobar%"%")", l_js.representation.same_string (jrep)) + else assert ("json.value (s) /= Void", False) - end + end - -- JSON representation -> JSON value -> Eiffel value - create parser.make_parser (jrep) - if attached {JSON_STRING} parser.parse as l_js then - if attached {STRING_32} json.object (l_js, Void) as l_ucs then + -- JSON representation -> JSON value -> Eiffel value + create parser.make_parser (jrep) + if attached {JSON_STRING} parser.parse as l_js then + if attached {STRING_32} json.object (l_js, Void) as l_ucs then assert ("ucs.same_string (%"foo\bar%")", l_ucs.same_string ("foo\bar")) - end - else + end + else assert ("parser.parse /= Void", False) - end - - - jrep := "%"foo\\bar%"" + end + jrep := "%"foo\\bar%"" create parser.make_parser (jrep) if attached {JSON_STRING} parser.parse as jstring then assert ("unescaped string %"foo\\bar%" to %"foo\bar%"", jstring.unescaped_string_8.same_string ("foo\bar")) else assert ("parser.parse /= Void", False) end - - create js.make_json_from_string_32 ({STRING_32}"%/20320/%/22909/") - assert ("escaping unicode string32 %"%%/20320/%%/22909/%" %"\u4F60\u597D%"", js.item.same_string ("\u4F60\u597D")) - - jrep := "%"\u4F60\u597D%"" --| Ni hao + create js.make_json_from_string_32 ({STRING_32} "你好") + assert ("escaping unicode string32 %"%%/20320/%%/22909/%" %"\u4F60\u597D%"", js.item.same_string ("\u4F60\u597D")) + jrep := "%"\u4F60\u597D%"" --| Ni hao create parser.make_parser (jrep) if attached {JSON_STRING} parser.parse as jstring then - assert ("same unicode string32 %"%%/20320/%%/22909/%"", jstring.unescaped_string_32.same_string ({STRING_32}"%/20320/%/22909/")) + assert ("same unicode string32 %"%%/20320/%%/22909/%"", jstring.unescaped_string_32.same_string ({STRING_32} "你好")) else assert ("parser.parse /= Void", False) end - end + end - test_json_array - local - ll: LINKED_LIST [INTEGER_8] - ja: detachable JSON_ARRAY - jn: JSON_NUMBER - jrep: STRING - parser: JSON_PARSER - do - -- Eiffel value -> JSON value -> JSON representation - create ll.make - ll.extend (0) - ll.extend (1) - ll.extend (1) - ll.extend (2) - ll.extend (3) - ll.extend (5) - -- Note: Currently there is no simple way of creating a JSON_ARRAY - -- from an LINKED_LIST. - create ja.make_array - from - ll.start - until - ll.after - loop - create jn.make_integer (ll.item) - ja.add (jn) - ll.forth - end - assert ("ja /= Void", ja /= Void) - assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", ja.representation.is_equal ("[0,1,1,2,3,5]")) - -- Eiffel value -> JSON value -> JSON representation with factory - if attached {JSON_ARRAY} json.value (ll) as l_ja then - assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", l_ja.representation.is_equal ("[0,1,1,2,3,5]")) - else + test_json_array + local + ll: LINKED_LIST [INTEGER_8] + ja: detachable JSON_ARRAY + jn: JSON_NUMBER + jrep: STRING + parser: JSON_PARSER + do + -- Eiffel value -> JSON value -> JSON representation + create ll.make + ll.extend (0) + ll.extend (1) + ll.extend (1) + ll.extend (2) + ll.extend (3) + ll.extend (5) + -- Note: Currently there is no simple way of creating a JSON_ARRAY + -- from an LINKED_LIST. + create ja.make_array + from + ll.start + until + ll.after + loop + create jn.make_integer (ll.item) + ja.add (jn) + ll.forth + end + assert ("ja /= Void", ja /= Void) + assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", ja.representation.is_equal ("[0,1,1,2,3,5]")) + -- Eiffel value -> JSON value -> JSON representation with factory + if attached {JSON_ARRAY} json.value (ll) as l_ja then + assert ("ja.representation.is_equal (%"[0,1,1,2,3,5]%")", l_ja.representation.is_equal ("[0,1,1,2,3,5]")) + else assert ("json.value (ll) /= Void", False) - end + end - -- JSON representation -> JSON value -> Eiffel value - -- Note: The JSON_FACTORY will return the smallest INTEGER_* object - -- that can represent the value of the JSON number, in this case - -- it means we will get an LINKED_LIST [ANY] containing the INTEGER_8 - -- values 0, 1, 1, 2, 3, 5 - jrep := "[0,1,1,2,3,5]" - create parser.make_parser (jrep) - if attached {JSON_ARRAY} parser.parse as l_ja then + -- JSON representation -> JSON value -> Eiffel value + -- Note: The JSON_FACTORY will return the smallest INTEGER_* object + -- that can represent the value of the JSON number, in this case + -- it means we will get an LINKED_LIST [ANY] containing the INTEGER_8 + -- values 0, 1, 1, 2, 3, 5 + jrep := "[0,1,1,2,3,5]" + create parser.make_parser (jrep) + if attached {JSON_ARRAY} parser.parse as l_ja then if attached {LINKED_LIST [detachable ANY]} json.object (ja, Void) as l_ll2 then assert ("ll2.is_equal (ll)", l_ll2.is_equal (ll)) else @@ -705,71 +699,71 @@ feature -- Test end else assert ("parser.parse /= Void", False) - end - end + end + end - test_json_object - local - t: detachable HASH_TABLE [detachable ANY, STRING_GENERAL] - i: INTEGER - ucs_key, ucs: STRING_32 - a: ARRAY [INTEGER] - jo: detachable JSON_OBJECT - jn: JSON_NUMBER - js_key, js: JSON_STRING - ja: JSON_ARRAY - jrep: STRING - parser: JSON_PARSER - do - -- Eiffel value -> JSON value -> JSON representation - -- Note: Currently there is now way of creating a JSON_OBJECT from - -- a HASH_TABLE, so we do it manually. - -- t = {"name": "foobar", "size": 42, "contents", [0, 1, 1, 2, 3, 5]} - create jo.make - create js_key.make_json ("name") - create js.make_json ("foobar") - jo.put (js, js_key) - create js_key.make_json ("size") - create jn.make_integer (42) - jo.put (jn, js_key) - create js_key.make_json ("contents") - create ja.make_array - create jn.make_integer (0) - ja.add (jn) - create jn.make_integer (1) - ja.add (jn) - create jn.make_integer (1) - ja.add (jn) - create jn.make_integer (2) - ja.add (jn) - create jn.make_integer (3) - ja.add (jn) - create jn.make_integer (5) - ja.add (jn) - jo.put (ja, js_key) - assert ("jo /= Void", jo /= Void) - assert ("jo.representation.is_equal (%"{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}%")", jo.representation.is_equal ("{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}")) + test_json_object + local + t: detachable HASH_TABLE [detachable ANY, STRING_GENERAL] + i: INTEGER + ucs_key, ucs: STRING_32 + a: ARRAY [INTEGER] + jo: detachable JSON_OBJECT + jn: JSON_NUMBER + js_key, js: JSON_STRING + ja: JSON_ARRAY + jrep: STRING + parser: JSON_PARSER + do + -- Eiffel value -> JSON value -> JSON representation + -- Note: Currently there is now way of creating a JSON_OBJECT from + -- a HASH_TABLE, so we do it manually. + -- t = {"name": "foobar", "size": 42, "contents", [0, 1, 1, 2, 3, 5]} + create jo.make + create js_key.make_json ("name") + create js.make_json ("foobar") + jo.put (js, js_key) + create js_key.make_json ("size") + create jn.make_integer (42) + jo.put (jn, js_key) + create js_key.make_json ("contents") + create ja.make_array + create jn.make_integer (0) + ja.add (jn) + create jn.make_integer (1) + ja.add (jn) + create jn.make_integer (1) + ja.add (jn) + create jn.make_integer (2) + ja.add (jn) + create jn.make_integer (3) + ja.add (jn) + create jn.make_integer (5) + ja.add (jn) + jo.put (ja, js_key) + assert ("jo /= Void", jo /= Void) + assert ("jo.representation.is_equal (%"{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}%")", jo.representation.is_equal ("{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}")) - -- Eiffel value -> JSON value -> JSON representation with factory - create t.make (3) - create ucs_key.make_from_string ("name") - create ucs.make_from_string ("foobar") - t.put (ucs, ucs_key) - create ucs_key.make_from_string ("size") - i := 42 - t.put (i, ucs_key) - create ucs_key.make_from_string ("contents") - a := <<0, 1, 1, 2, 3, 5>> - t.put (a, ucs_key) - if attached {JSON_OBJECT} json.value (t) as l_jo then + -- Eiffel value -> JSON value -> JSON representation with factory + create t.make (3) + create ucs_key.make_from_string ("name") + create ucs.make_from_string ("foobar") + t.put (ucs, ucs_key) + create ucs_key.make_from_string ("size") + i := 42 + t.put (i, ucs_key) + create ucs_key.make_from_string ("contents") + a := <<0, 1, 1, 2, 3, 5>> + t.put (a, ucs_key) + if attached {JSON_OBJECT} json.value (t) as l_jo then assert ("jo.representation.is_equal (%"{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}%")", l_jo.representation.is_equal ("{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}")) - else + else assert ("json.value (t) /= Void", False) - end + end - -- JSON representation -> JSON value -> Eiffel value -> JSON value -> JSON representation - jrep := "{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}" - create parser.make_parser (jrep) + -- JSON representation -> JSON value -> Eiffel value -> JSON value -> JSON representation + jrep := "{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}" + create parser.make_parser (jrep) if attached {JSON_OBJECT} parser.parse as l_jo then if attached {HASH_TABLE [detachable ANY, STRING_GENERAL]} json.object (l_jo, Void) as l_t2 then if attached json.value (l_t2) as l_jo_2 then @@ -783,55 +777,55 @@ feature -- Test else assert ("parser.parse /= Void", jo /= Void) end - end + end - test_json_object_hash_code - local - ht: HASH_TABLE [ANY, JSON_VALUE] - jo: JSON_OBJECT - do - create ht.make (1) - create jo.make - ht.force ("", jo) - assert ("ht.has_key (jo)", ht.has_key (jo)) - end + test_json_object_hash_code + local + ht: HASH_TABLE [ANY, JSON_VALUE] + jo: JSON_OBJECT + do + create ht.make (1) + create jo.make + ht.force ("", jo) + assert ("ht.has_key (jo)", ht.has_key (jo)) + end - test_json_failed_json_conversion - -- Test converting an Eiffel object to JSON that is based on a class - -- for which no JSON converter has been registered. - local - gv: OPERATING_ENVIRONMENT - jv: detachable JSON_VALUE - exception: BOOLEAN - do - if not exception then - create gv - jv := json.value (gv) - else - assert ("exceptions.is_developer_exception", json.is_developer_exception) - end - rescue - exception := True - retry - end + test_json_failed_json_conversion + -- Test converting an Eiffel object to JSON that is based on a class + -- for which no JSON converter has been registered. + local + gv: OPERATING_ENVIRONMENT + jv: detachable JSON_VALUE + exception: BOOLEAN + do + if not exception then + create gv + jv := json.value (gv) + else + assert ("exceptions.is_developer_exception", json.is_developer_exception) + end + rescue + exception := True + retry + end - test_json_failed_eiffel_conversion - -- Test converting from a JSON value to an Eiffel object based on a - -- class for which no JSON converter has been registered. - local - gv : detachable ANY - jo: JSON_OBJECT - exception: BOOLEAN - do - if not exception then - create jo.make - gv := json.object (jo, "OPERATING_ENVIRONMENT") - else - assert ("exceptions.is_developer_exception", json.is_developer_exception) - end - rescue - exception := True - retry - end + test_json_failed_eiffel_conversion + -- Test converting from a JSON value to an Eiffel object based on a + -- class for which no JSON converter has been registered. + local + gv: detachable ANY + jo: JSON_OBJECT + exception: BOOLEAN + do + if not exception then + create jo.make + gv := json.object (jo, "OPERATING_ENVIRONMENT") + else + assert ("exceptions.is_developer_exception", json.is_developer_exception) + end + rescue + exception := True + retry + end end -- class TEST_JSON_CORE diff --git a/test/autotest/test_suite/test_json_custom_classes.e b/test/autotest/test_suite/test_json_custom_classes.e index 0b0b0715..7db1df10 100644 --- a/test/autotest/test_suite/test_json_custom_classes.e +++ b/test/autotest/test_suite/test_json_custom_classes.e @@ -1,14 +1,14 @@ - note - description: "Parsing and converter of book collection test." - date: "$Date$" - revision: "$Revision$" + description: "Parsing and converter of book collection test." + date: "$Date$" + revision: "$Revision$" class TEST_JSON_CUSTOM_CLASSES inherit - SHARED_EJSON + + SHARED_EJSON undefine default_create end @@ -17,25 +17,24 @@ inherit feature -- Test - test_custom_classes + test_custom_classes -- Parse JSON representation to JSON_OBJECT and test book collection converter. - local - jbc: JSON_BOOK_CONVERTER - jbcc: JSON_BOOK_COLLECTION_CONVERTER - jac: JSON_AUTHOR_CONVERTER - parser: JSON_PARSER - jrep: STRING - do - create jbc.make - json.add_converter (jbc) - create jbcc.make - json.add_converter (jbcc) - create jac.make - json.add_converter (jac) - jrep := "{%"name%":%"Test collection%",%"books%":[{%"title%":%"eJSON: The Definitive Guide%",%"isbn%":%"123123-413243%",%"author%":{%"name%":%"Foo Bar%"}}]}" - create parser.make_parser (jrep) - - if attached {JSON_OBJECT} parser.parse as l_json_object then + local + jbc: JSON_BOOK_CONVERTER + jbcc: JSON_BOOK_COLLECTION_CONVERTER + jac: JSON_AUTHOR_CONVERTER + parser: JSON_PARSER + jrep: STRING + do + create jbc.make + json.add_converter (jbc) + create jbcc.make + json.add_converter (jbcc) + create jac.make + json.add_converter (jac) + jrep := "{%"name%":%"Test collection%",%"books%":[{%"title%":%"eJSON: The Definitive Guide%",%"isbn%":%"123123-413243%",%"author%":{%"name%":%"Foo Bar%"}}]}" + create parser.make_parser (jrep) + if attached {JSON_OBJECT} parser.parse as l_json_object then if attached {BOOK_COLLECTION} json.object (l_json_object, "BOOK_COLLECTION") as l_collection then if attached {JSON_OBJECT} json.value (l_collection) as l_json_object_2 then assert ("JSON representation is correct", l_json_object_2.representation.same_string (jrep)) @@ -47,7 +46,7 @@ feature -- Test end else assert ("JSON object representation to JSON_OBJECT", False) - end - end + end + end end -- class TEST_JSON_CUSTOM_CLASS diff --git a/test/autotest/test_suite/test_json_suite.e b/test/autotest/test_suite/test_json_suite.e index c2a66b71..096a8db2 100644 --- a/test/autotest/test_suite/test_json_suite.e +++ b/test/autotest/test_suite/test_json_suite.e @@ -11,6 +11,7 @@ class TEST_JSON_SUITE inherit + EQA_TEST_SET redefine on_prepare @@ -27,38 +28,38 @@ feature {NONE} -- Events feature -- Tests Pass test_json_pass1 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("pass1.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("pass1.json",parse_json.is_parsed = True) + assert ("pass1.json", parse_json.is_parsed = True) end end test_json_pass2 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("pass2.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("pass2.json",parse_json.is_parsed = True) + assert ("pass2.json", parse_json.is_parsed = True) end end - test_json_pass3 - -- + test_json_pass3 + -- local parse_json: like new_json_parser do if attached json_file_from ("pass3.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("pass3.json",parse_json.is_parsed = True) + assert ("pass3.json", parse_json.is_parsed = True) end end @@ -69,14 +70,10 @@ feature -- Tests Pass s: READABLE_STRING_32 do s := {STRING_32} "{ %"nihaoma%": %"你好吗\t?%" }" - parse_json := new_json_parser (utf.string_32_to_utf_8_string_8 (s)) json_value := parse_json.parse_json assert ("utf8.pass1.json", parse_json.is_parsed = True) - if - attached {JSON_OBJECT} json_value as jo and then - attached {JSON_STRING} jo.item ("nihaoma") as js - then + if attached {JSON_OBJECT} json_value as jo and then attached {JSON_STRING} jo.item ("nihaoma") as js then assert ("utf8.nihaoma", js.unescaped_string_32.same_string ({STRING_32} "你好吗%T?")) else assert ("utf8.nihaoma", False) @@ -84,408 +81,400 @@ feature -- Tests Pass end feature -- Tests Failures - test_json_fail1 - -- + + test_json_fail1 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail1.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail1.json",parse_json.is_parsed = False) + assert ("fail1.json", parse_json.is_parsed = False) end end - test_json_fail2 - -- + test_json_fail2 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail2.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail2.json",parse_json.is_parsed = False) + assert ("fail2.json", parse_json.is_parsed = False) end end test_json_fail3 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail3.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail3.json",parse_json.is_parsed = False) + assert ("fail3.json", parse_json.is_parsed = False) end end test_json_fail4 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail4.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail4.json",parse_json.is_parsed = False) + assert ("fail4.json", parse_json.is_parsed = False) end end - test_json_fail5 - -- + test_json_fail5 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail5.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail5.json",parse_json.is_parsed = False) + assert ("fail5.json", parse_json.is_parsed = False) end end - test_json_fail6 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail6.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail6.json",parse_json.is_parsed = False ) + assert ("fail6.json", parse_json.is_parsed = False) end end - test_json_fail7 - -- + test_json_fail7 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail7.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail7.json",parse_json.is_parsed = False) + assert ("fail7.json", parse_json.is_parsed = False) end end - test_json_fail8 - -- + test_json_fail8 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail8.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail8.json",parse_json.is_parsed = False ) + assert ("fail8.json", parse_json.is_parsed = False) end end - test_json_fail9 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail9.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail9.json",parse_json.is_parsed = False) + assert ("fail9.json", parse_json.is_parsed = False) end end - test_json_fail10 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail10.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail10.json",parse_json.is_parsed = False) + assert ("fail10.json", parse_json.is_parsed = False) end end - test_json_fail11 - -- + test_json_fail11 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail11.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail11.json",parse_json.is_parsed = False) + assert ("fail11.json", parse_json.is_parsed = False) end end test_json_fail12 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail12.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail12.json",parse_json.is_parsed = False) + assert ("fail12.json", parse_json.is_parsed = False) end end - test_json_fail13 - -- + test_json_fail13 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail13.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail13.json",parse_json.is_parsed = False) + assert ("fail13.json", parse_json.is_parsed = False) end end - test_json_fail14 - -- + test_json_fail14 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail14.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail14.json",parse_json.is_parsed = False) + assert ("fail14.json", parse_json.is_parsed = False) end end test_json_fail15 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail15.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail15.json",parse_json.is_parsed = False) + assert ("fail15.json", parse_json.is_parsed = False) end end test_json_fail16 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail16.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail16.json",parse_json.is_parsed = False) + assert ("fail16.json", parse_json.is_parsed = False) end end test_json_fail17 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail17.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail17.json",parse_json.is_parsed = False) + assert ("fail17.json", parse_json.is_parsed = False) end end test_json_fail18 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail18.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail18.json",parse_json.is_parsed = True) + assert ("fail18.json", parse_json.is_parsed = True) end end test_json_fail19 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail19.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail19.json",parse_json.is_parsed = False) + assert ("fail19.json", parse_json.is_parsed = False) end end test_json_fail20 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail20.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail20.json",parse_json.is_parsed = False) + assert ("fail20.json", parse_json.is_parsed = False) end end - test_json_fail21 - -- + test_json_fail21 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail21.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail21.json",parse_json.is_parsed = False) + assert ("fail21.json", parse_json.is_parsed = False) end end - - test_json_fail22 - -- + test_json_fail22 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail22.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail22.json",parse_json.is_parsed = False) + assert ("fail22.json", parse_json.is_parsed = False) end end - test_json_fail23 - -- + test_json_fail23 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail23.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail23.json",parse_json.is_parsed = False) + assert ("fail23.json", parse_json.is_parsed = False) end end - test_json_fail24 - -- + test_json_fail24 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail24.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail24.json",parse_json.is_parsed = False) + assert ("fail24.json", parse_json.is_parsed = False) end end test_json_fail25 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail25.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail25.json",parse_json.is_parsed = False) + assert ("fail25.json", parse_json.is_parsed = False) end end - - test_json_fail26 - -- + test_json_fail26 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail26.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail26.json",parse_json.is_parsed = False) + assert ("fail26.json", parse_json.is_parsed = False) end end - - test_json_fail27 - -- + test_json_fail27 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail27.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail27.json",parse_json.is_parsed = False) + assert ("fail27.json", parse_json.is_parsed = False) end end - - test_json_fail28 - -- + test_json_fail28 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail28.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail28.json",parse_json.is_parsed = False) + assert ("fail28.json", parse_json.is_parsed = False) end end - - test_json_fail29 - -- + test_json_fail29 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail29.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail29.json",parse_json.is_parsed = False ) + assert ("fail29.json", parse_json.is_parsed = False) end end - - test_json_fail30 - -- + test_json_fail30 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail30.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail30.json",parse_json.is_parsed = False) + assert ("fail30.json", parse_json.is_parsed = False) end end test_json_fail31 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail31.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail31.json",parse_json.is_parsed = False) + assert ("fail31.json", parse_json.is_parsed = False) end end - test_json_fail32 - -- + test_json_fail32 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail32.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail32.json",parse_json.is_parsed = False) + assert ("fail32.json", parse_json.is_parsed = False) end end - test_json_fail33 - -- + test_json_fail33 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail33.json") as json_file then parse_json := new_json_parser (json_file) json_value := parse_json.parse_json - assert ("fail33.json",parse_json.is_parsed = False) + assert ("fail33.json", parse_json.is_parsed = False) end end @@ -495,23 +484,22 @@ feature -- JSON_FROM_FILE json_value: detachable JSON_VALUE - json_file_from (fn: STRING): detachable STRING - local - f: RAW_FILE - l_path: STRING + json_file_from (fn: STRING): detachable STRING + local + f: RAW_FILE + l_path: STRING test_dir: STRING i: INTEGER do test_dir := (create {EXECUTION_ENVIRONMENT}).current_working_directory test_dir.append_character ((create {OPERATING_ENVIRONMENT}).directory_separator) - l_path := test_dir + fn create f.make_with_name (l_path) if f.exists then -- Found json file else - -- before EiffelStudio 7.3 , the current dir of autotest execution was not the parent dir of ecf but something like - -- ..json\test\autotest\test_suite\EIFGENs\test_suite\Testing\execution\TEST_JSON_SUITE.test_json_fail1\..\..\..\..\..\fail1.json + -- before EiffelStudio 7.3 , the current dir of autotest execution was not the parent dir of ecf but something like + -- ..json\test\autotest\test_suite\EIFGENs\test_suite\Testing\execution\TEST_JSON_SUITE.test_json_fail1\..\..\..\..\..\fail1.json from i := 5 until @@ -536,9 +524,7 @@ feature -- JSON_FROM_FILE create Result.make_parser (a_string) end - invariant file_reader /= Void end - From 19dbbf89e75e62ec01ea189b8757387c3105e426 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Wed, 24 Sep 2014 20:08:12 +0200 Subject: [PATCH 05/11] Fixed various issue with parsing string (such as \t and related), Implemented escaping of slash '/' only in case of ' Many feature renaming to match Eiffel style and naming convention, kept previous feature as obsolete. Restructured the library to make easy extraction of "converter" classes if needed in the future. Updated part of the code to use new feature names. --- .gitattributes | 1 + .gitignore | 2 +- History.txt | 4 +- License.txt | 8 +- .../json_arrayed_list_converter.e | 0 .../converters => converter}/json_converter.e | 0 .../json_hash_table_converter.e | 14 +- .../json_linked_list_converter.e | 0 .../json_list_converter.e | 6 +- library/{kernel => converter/support}/ejson.e | 26 +- .../support}/shared_ejson.e | 2 +- library/extras/file/json_file_reader.e | 39 --- .../converters/json_ds_hash_table_converter.e | 0 .../json_ds_linked_list_converter.e | 0 .../shared_gobo_ejson.e | 0 library/json-safe.ecf | 19 +- library/json.ecf | 17 +- library/json_gobo_extension.ecf | 2 +- library/kernel/json_array.e | 87 +++-- library/kernel/json_boolean.e | 36 +- library/kernel/json_number.e | 71 +++- library/kernel/json_object.e | 279 +++++++-------- library/kernel/json_string.e | 221 +++++++----- library/kernel/scanner/json_tokens.e | 79 ----- .../{kernel/scanner => parser}/json_parser.e | 282 +++++++++++----- library/parser/json_parser_access.e | 9 + .../{kernel/scanner => parser}/json_reader.e | 8 +- library/parser/json_tokens.e | 87 +++++ library/utility/file/json_file_reader.e | 46 +++ .../visitor/json_iterator.e | 0 .../visitor/json_pretty_string_visitor.e | 0 .../visitor/json_visitor.e | 0 .../visitor/print_json_visitor.e | 0 .../test_suite/json_author_converter.e | 2 +- .../json_book_collection_converter.e | 6 +- .../autotest/test_suite/json_book_converter.e | 8 +- test/autotest/test_suite/test_ds.e | 4 +- test/autotest/test_suite/test_json_core.e | 221 +++++++----- test/autotest/test_suite/test_json_suite.e | 317 +++++++++--------- test/autotest/test_suite/test_suite-safe.ecf | 6 +- 40 files changed, 1121 insertions(+), 788 deletions(-) rename library/{kernel/converters => converter}/json_arrayed_list_converter.e (100%) rename library/{kernel/converters => converter}/json_converter.e (100%) rename library/{kernel/converters => converter}/json_hash_table_converter.e (86%) rename library/{kernel/converters => converter}/json_linked_list_converter.e (100%) rename library/{kernel/converters => converter}/json_list_converter.e (90%) rename library/{kernel => converter/support}/ejson.e (92%) rename library/{kernel => converter/support}/shared_ejson.e (97%) delete mode 100644 library/extras/file/json_file_reader.e rename library/{gobo => gobo_converter}/converters/json_ds_hash_table_converter.e (100%) rename library/{gobo => gobo_converter}/converters/json_ds_linked_list_converter.e (100%) rename library/{gobo => gobo_converter}/shared_gobo_ejson.e (100%) delete mode 100644 library/kernel/scanner/json_tokens.e rename library/{kernel/scanner => parser}/json_parser.e (64%) create mode 100644 library/parser/json_parser_access.e rename library/{kernel/scanner => parser}/json_reader.e (97%) create mode 100644 library/parser/json_tokens.e create mode 100644 library/utility/file/json_file_reader.e rename library/{extras => utility}/visitor/json_iterator.e (100%) rename library/{extras => utility}/visitor/json_pretty_string_visitor.e (100%) rename library/{extras => utility}/visitor/json_visitor.e (100%) rename library/{extras => utility}/visitor/print_json_visitor.e (100%) diff --git a/.gitattributes b/.gitattributes index 98d61a9f..14347263 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7,3 +7,4 @@ *.ecf text *.bat text *.json text +*.txt text diff --git a/.gitignore b/.gitignore index a1ff1e86..3702d5e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ *.swp -EIFGENs +EIFGENs/ diff --git a/History.txt b/History.txt index 5cf7f2ec..02fd7cb6 100644 --- a/History.txt +++ b/History.txt @@ -1,4 +1,4 @@ -History file for EJSON +History file for EJSON ====================== team: "" @@ -23,4 +23,4 @@ implementation. *Added converters and factory classes -*Added new top level directories; library, test, build and example \ No newline at end of file +*Added new top level directories; library, test, build and example diff --git a/License.txt b/License.txt index 1c17b708..8bf6765c 100644 --- a/License.txt +++ b/License.txt @@ -1,4 +1,4 @@ -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 @@ -6,10 +6,10 @@ of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 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 -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 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -17,4 +17,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 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 -THE SOFTWARE. \ No newline at end of file +THE SOFTWARE. diff --git a/library/kernel/converters/json_arrayed_list_converter.e b/library/converter/json_arrayed_list_converter.e similarity index 100% rename from library/kernel/converters/json_arrayed_list_converter.e rename to library/converter/json_arrayed_list_converter.e diff --git a/library/kernel/converters/json_converter.e b/library/converter/json_converter.e similarity index 100% rename from library/kernel/converters/json_converter.e rename to library/converter/json_converter.e diff --git a/library/kernel/converters/json_hash_table_converter.e b/library/converter/json_hash_table_converter.e similarity index 86% rename from library/kernel/converters/json_hash_table_converter.e rename to library/converter/json_hash_table_converter.e index 00b87374..c3b2c724 100644 --- a/library/kernel/converters/json_hash_table_converter.e +++ b/library/converter/json_hash_table_converter.e @@ -52,27 +52,27 @@ feature -- Conversion to_json (o: like object): detachable JSON_OBJECT local - c: HASH_TABLE_ITERATION_CURSOR [ANY, HASHABLE] js: JSON_STRING failed: BOOLEAN do create Result.make - from - c := o.new_cursor - until - c.after + across + o as c loop if attached {JSON_STRING} json.value (c.key) as l_key then js := l_key else - create js.make_json (c.key.out) + if attached {READABLE_STRING_GENERAL} c.key as s_key then + create js.make_from_string_general (s_key) + else + create js.make_from_string (c.key.out) + end end if attached json.value (c.item) as jv then Result.put (jv, js) else failed := True end - c.forth end if failed then Result := Void diff --git a/library/kernel/converters/json_linked_list_converter.e b/library/converter/json_linked_list_converter.e similarity index 100% rename from library/kernel/converters/json_linked_list_converter.e rename to library/converter/json_linked_list_converter.e diff --git a/library/kernel/converters/json_list_converter.e b/library/converter/json_list_converter.e similarity index 90% rename from library/kernel/converters/json_list_converter.e rename to library/converter/json_list_converter.e index 7872756b..343851c9 100644 --- a/library/kernel/converters/json_list_converter.e +++ b/library/converter/json_list_converter.e @@ -51,17 +51,15 @@ feature -- Conversion to_json (o: like object): detachable JSON_ARRAY local c: ITERATION_CURSOR [detachable ANY] - jv: detachable JSON_VALUE failed: BOOLEAN do - create Result.make_array + create Result.make (o.count) from c := o.new_cursor until c.after loop - jv := json.value (c.item) - if jv /= Void then + if attached json.value (c.item) as jv then Result.add (jv) else failed := True diff --git a/library/kernel/ejson.e b/library/converter/support/ejson.e similarity index 92% rename from library/kernel/ejson.e rename to library/converter/support/ejson.e index 86f114ee..1ea6c8c1 100644 --- a/library/kernel/ejson.e +++ b/library/converter/support/ejson.e @@ -27,7 +27,7 @@ feature -- Access if an_object = Void then create {JSON_NULL} Result elseif attached {BOOLEAN} an_object as b then - create {JSON_BOOLEAN} Result.make_boolean (b) + create {JSON_BOOLEAN} Result.make (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 @@ -49,7 +49,7 @@ feature -- Access 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 + create ja.make (a.count) from i := a.lower until @@ -66,13 +66,13 @@ feature -- Access end Result := ja elseif attached {CHARACTER_8} an_object as c8 then - create {JSON_STRING} Result.make_json (c8.out) + create {JSON_STRING} Result.make_from_string (c8.out) elseif attached {CHARACTER_32} an_object as c32 then - create {JSON_STRING} Result.make_json (c32.out) + create {JSON_STRING} Result.make_from_string_32 (create {STRING_32}.make_filled (c32, 1)) elseif attached {STRING_8} an_object as s8 then - create {JSON_STRING} Result.make_json (s8) + create {JSON_STRING} Result.make_from_string (s8) elseif attached {STRING_32} an_object as s32 then - create {JSON_STRING} Result.make_json_from_string_32 (s32) + create {JSON_STRING} Result.make_from_string_32 (s32) end if Result = Void then -- Now check the converters @@ -162,12 +162,10 @@ feature -- Access -- "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 + json_parser.parse_content + if json_parser.is_valid and then attached json_parser.parsed_json_value as jv then Result := object (jv, base_class) end end @@ -192,8 +190,8 @@ feature -- Access js_key, js_value: JSON_STRING do create Result.make - create js_key.make_json ("$ref") - create js_value.make_json (s) + create js_key.make_from_string ("$ref") + create js_value.make_from_string (s) Result.put (js_value, js_key) end @@ -207,7 +205,7 @@ feature -- Access local c: ITERATION_CURSOR [STRING] do - create Result.make_array + create Result.make (l.count) from c := l.new_cursor until @@ -264,7 +262,7 @@ feature {NONE} -- Implementation (JSON parser) json_parser: JSON_PARSER once - create Result.make_parser ("") + create Result.make_with_string ("{}") end end -- class EJSON diff --git a/library/kernel/shared_ejson.e b/library/converter/support/shared_ejson.e similarity index 97% rename from library/kernel/shared_ejson.e rename to library/converter/support/shared_ejson.e index eda0ecb2..066bad88 100644 --- a/library/kernel/shared_ejson.e +++ b/library/converter/support/shared_ejson.e @@ -14,7 +14,7 @@ note class SHARED_EJSON -feature +feature -- Access json: EJSON -- A shared EJSON instance with default converters for diff --git a/library/extras/file/json_file_reader.e b/library/extras/file/json_file_reader.e deleted file mode 100644 index 9537a547..00000000 --- a/library/extras/file/json_file_reader.e +++ /dev/null @@ -1,39 +0,0 @@ -note - description: "Objects that ..." - date: "$Date$" - revision: "$Revision$" - -class - JSON_FILE_READER - -feature -- Access - - read_json_from (a_path: STRING): detachable STRING - local - l_file: PLAIN_TEXT_FILE - template_content: STRING - l_last_string: detachable STRING - do - create l_file.make_with_name (a_path) - -- We perform several checks until we make a real attempt to open the file. - if not l_file.exists then - print ("error: '" + a_path + "' does not exist%N") - else - if not l_file.is_readable then - print ("error: '" + a_path + "' is not readable.%N") - else - l_file.open_read - create template_content.make_empty - l_file.read_stream (l_file.count) - l_last_string := l_file.last_string - check - l_last_string /= Void - end -- implied by postcondition of `l_file.read_stream' - template_content.append (l_last_string.string) - Result := template_content - l_file.close - end - end - end - -end diff --git a/library/gobo/converters/json_ds_hash_table_converter.e b/library/gobo_converter/converters/json_ds_hash_table_converter.e similarity index 100% rename from library/gobo/converters/json_ds_hash_table_converter.e rename to library/gobo_converter/converters/json_ds_hash_table_converter.e diff --git a/library/gobo/converters/json_ds_linked_list_converter.e b/library/gobo_converter/converters/json_ds_linked_list_converter.e similarity index 100% rename from library/gobo/converters/json_ds_linked_list_converter.e rename to library/gobo_converter/converters/json_ds_linked_list_converter.e diff --git a/library/gobo/shared_gobo_ejson.e b/library/gobo_converter/shared_gobo_ejson.e similarity index 100% rename from library/gobo/shared_gobo_ejson.e rename to library/gobo_converter/shared_gobo_ejson.e diff --git a/library/json-safe.ecf b/library/json-safe.ecf index 0eb6cc52..f3a3bb52 100644 --- a/library/json-safe.ecf +++ b/library/json-safe.ecf @@ -1,5 +1,5 @@ - + @@ -9,20 +9,13 @@ - - - ^/gobo$ - ^/kernel$ - ^/extras$ - - - + + + + + diff --git a/library/json.ecf b/library/json.ecf index 8d6dc612..e9e114fd 100644 --- a/library/json.ecf +++ b/library/json.ecf @@ -9,20 +9,13 @@ - - - ^/gobo$ - ^/kernel$ - ^/extras$ - - - + + + + + diff --git a/library/json_gobo_extension.ecf b/library/json_gobo_extension.ecf index dd5f9b75..48449915 100644 --- a/library/json_gobo_extension.ecf +++ b/library/json_gobo_extension.ecf @@ -12,6 +12,6 @@ - + diff --git a/library/kernel/json_array.e b/library/kernel/json_array.e index 0f2e50ef..2006c1e1 100644 --- a/library/kernel/json_array.e +++ b/library/kernel/json_array.e @@ -7,9 +7,9 @@ note [] [elements] ]" - author: "Javier Velilla" - date: "2008/08/24" - revision: "Revision 0.1" + author: "$Author$" + date: "$date$" + revision: "$Revision$" class JSON_ARRAY @@ -23,14 +23,29 @@ inherit DEBUG_OUTPUT create + make, make_empty, make_array feature {NONE} -- Initialization + make (nb: INTEGER) + -- Initialize JSON array with capacity of `nb' items. + do + create items.make (nb) + end + + make_empty + -- Initialize empty JSON array. + do + make (0) + end + make_array -- Initialize JSON Array + obsolete + "Use `make' Sept/2014" do - create values.make (10) + make (10) end feature -- Access @@ -40,24 +55,19 @@ feature -- Access require is_valid_index: valid_index (i) do - Result := values.i_th (i) + Result := items.i_th (i) end representation: STRING - local - i: INTEGER do Result := "[" - from - i := 1 - until - i > count + across + items as ic loop - Result.append (i_th (i).representation) - i := i + 1 - if i <= count then + if Result.count > 1 then Result.append_character (',') end + Result.append (ic.item.representation) end Result.append_character (']') end @@ -76,7 +86,7 @@ feature -- Access new_cursor: ITERATION_CURSOR [JSON_VALUE] -- Fresh cursor associated with current structure do - Result := values.new_cursor + Result := items.new_cursor end feature -- Mesurement @@ -84,7 +94,7 @@ feature -- Mesurement count: INTEGER -- Number of items. do - Result := values.count + Result := items.count end feature -- Status report @@ -101,18 +111,18 @@ feature -- Change Element require v_not_void: v /= Void do - values.put_front (v) + items.put_front (v) ensure - has_new_value: old values.count + 1 = values.count and values.first = v + has_new_value: old items.count + 1 = items.count and items.first = v end add, extend (v: JSON_VALUE) require v_not_void: v /= Void do - values.extend (v) + items.extend (v) ensure - has_new_value: old values.count + 1 = values.count and values.has (v) + has_new_value: old items.count + 1 = items.count and items.has (v) end prune_all (v: JSON_VALUE) @@ -120,41 +130,44 @@ feature -- Change Element require v_not_void: v /= Void do - values.prune_all (v) + items.prune_all (v) ensure - not_has_new_value: not values.has (v) + not_has_new_value: not items.has (v) end wipe_out -- Remove all items. do - values.wipe_out - end + items.wipe_out + end feature -- Report hash_code: INTEGER -- Hash code value + local + l_started: BOOLEAN do - from - values.start - Result := values.item.hash_code - until - values.off + across + items as ic loop - Result := ((Result \\ 8388593) |<< 8) + values.item.hash_code - values.forth + if l_started then + Result := ((Result \\ 8388593) |<< 8) + ic.item.hash_code + else + Result := ic.item.hash_code + l_started := True + end end - Result := Result \\ values.count + Result := Result \\ items.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 + -- Representation as a sequences of values. + -- be careful, modifying the return object may have impact on the original JSON_ARRAY object. do - Result := values + Result := items end feature -- Status report @@ -167,10 +180,10 @@ feature -- Status report feature {NONE} -- Implementation - values: ARRAYED_LIST [JSON_VALUE] + items: ARRAYED_LIST [JSON_VALUE] -- Value container invariant - value_not_void: values /= Void + items_not_void: items /= Void end diff --git a/library/kernel/json_boolean.e b/library/kernel/json_boolean.e index 4e1a24a7..e642ed48 100644 --- a/library/kernel/json_boolean.e +++ b/library/kernel/json_boolean.e @@ -1,8 +1,8 @@ note - description: "JSON Truth values" - author: "Javier Velilla" - date: "2008/08/24" - revision: "Revision 0.1" + description: "JSON Boolean values" + author: "$Author$" + date: "$Date$" + revision: "$Revision$" class JSON_BOOLEAN @@ -12,14 +12,36 @@ inherit JSON_VALUE create + make, + make_true, make_false, make_boolean feature {NONE} -- Initialization - make_boolean (an_item: BOOLEAN) - --Initialize. + make (a_value: BOOLEAN) + -- Initialize Current JSON boolean with `a_boolean'. do - item := an_item + item := a_value + end + + make_true + -- Initialize Current JSON boolean with True. + do + make (True) + end + + make_false + -- Initialize Current JSON boolean with False. + do + make (False) + end + + make_boolean (a_item: BOOLEAN) + -- Initialize. + obsolete + "Use `make' Sept/2014" + do + make (a_item) end feature -- Access diff --git a/library/kernel/json_number.e b/library/kernel/json_number.e index 213a32e2..ea72cf4c 100644 --- a/library/kernel/json_number.e +++ b/library/kernel/json_number.e @@ -1,8 +1,8 @@ note description: "JSON Numbers, octal and hexadecimal formats are not used." - author: "Javier Velilla" - date: "2008/08/24" - revision: "Revision 0.1" + author: "$Author$" + date: "$Date$" + revision: "$Revision$" license: "MIT (see http://www.opensource.org/licenses/mit-license.php)" class @@ -24,21 +24,21 @@ feature {NONE} -- initialization -- Initialize an instance of JSON_NUMBER from the integer value of `an_argument'. do item := an_argument.out - numeric_type := INTEGER_TYPE + 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 + numeric_type := natural_type end - make_real (an_argument: DOUBLE) + make_real (an_argument: REAL_64) -- Initialize an instance of JSON_NUMBER from the floating point value of `an_argument'. do item := an_argument.out - numeric_type := DOUBLE_TYPE + numeric_type := double_type end feature -- Access @@ -46,6 +46,9 @@ feature -- Access item: STRING -- Content + numeric_type: INTEGER + -- Type of number (integer, natural or real). + hash_code: INTEGER --Hash code value do @@ -57,6 +60,52 @@ feature -- Access Result := item end +feature -- Conversion + + integer_64_item: INTEGER_64 + -- Associated integer value. + require + is_integer: is_integer + do + Result := item.to_integer_64 + end + + natural_64_item: NATURAL_64 + -- Associated natural value. + require + is_natural: is_natural + do + Result := item.to_natural_64 + end + + double_item, real_64_item: REAL_64 + -- Associated real value. + require + is_real: is_real + do + Result := item.to_real_64 + end + +feature -- Status report + + is_integer: BOOLEAN + -- Is Current an integer number? + do + Result := numeric_type = integer_type + end + + is_natural: BOOLEAN + -- Is Current a natural number? + do + Result := numeric_type = natural_type + end + + is_double, is_real: BOOLEAN + -- Is Current a real number? + do + Result := numeric_type = real_type + end + feature -- Visitor pattern accept (a_visitor: JSON_VISITOR) @@ -85,13 +134,11 @@ feature -- Status report feature -- Implementation - INTEGER_TYPE: INTEGER = 1 + integer_type: INTEGER = 1 - DOUBLE_TYPE: INTEGER = 2 + double_type, real_type: INTEGER = 2 - NATURAL_TYPE: INTEGER = 3 - - numeric_type: INTEGER + natural_type: INTEGER = 3 invariant item_not_void: item /= Void diff --git a/library/kernel/json_object.e b/library/kernel/json_object.e index 8cff2589..b5a0d44b 100644 --- a/library/kernel/json_object.e +++ b/library/kernel/json_object.e @@ -3,15 +3,15 @@ note An JSON_OBJECT represent an object in JSON. An object is an unordered set of name/value pairs - Examples: - - object - {} - {"key": "value"} + Examples: + object + {} + {"key": value} + {"key": "value"} ]" - author: "Javier Velilla" - date: "2008/08/24" - revision: "Revision 0.1" + author: "$Author$" + date: "$Date$" + revision: "$Revision$" license: "MIT (see http://www.opensource.org/licenses/mit-license.php)" class @@ -26,213 +26,226 @@ inherit DEBUG_OUTPUT create - make + make_empty, make_with_capacity, make feature {NONE} -- Initialization - make - -- Initialize + make_with_capacity (nb: INTEGER) + -- Initialize with a capacity of `nb' items. do - create object.make (10) + create items.make (nb) + end + + make_empty + -- Initialize as empty object. + do + make_with_capacity (0) + end + + make + -- Initialize with default capacity. + do + make_with_capacity (3) end feature -- Change Element - put (value: detachable JSON_VALUE; key: JSON_STRING) - -- Assuming there is no item of key `key', - -- insert `value' with `key'. + put (a_value: detachable JSON_VALUE; a_key: JSON_STRING) + -- Assuming there is no item of key `a_key', + -- insert `a_value' with `a_key'. require - key_not_present: not has_key (key) - local - l_value: like value + a_key_not_present: not has_key (a_key) do - l_value := value - if l_value = Void then - create {JSON_NULL} l_value + if a_value = Void then + items.extend (create {JSON_NULL}, a_key) + else + items.extend (a_value, a_key) end - object.extend (l_value, key) end - put_string (value: READABLE_STRING_GENERAL; key: JSON_STRING) - -- Assuming there is no item of key `key', - -- insert `value' with `key'. + put_string (a_value: READABLE_STRING_GENERAL; a_key: JSON_STRING) + -- Assuming there is no item of key `a_key', + -- insert `a_value' with `a_key'. require - key_not_present: not has_key (key) + key_not_present: not has_key (a_key) local l_value: JSON_STRING do - create l_value.make_json_from_string_32 (value.as_string_32) - put (l_value, key) + if attached {READABLE_STRING_8} a_value as s then + create l_value.make_from_string (s) + else + create l_value.make_from_string_32 (a_value.as_string_32) + end + put (l_value, a_key) end - put_integer (value: INTEGER_64; key: JSON_STRING) - -- Assuming there is no item of key `key', - -- insert `value' with `key'. + put_integer (a_value: INTEGER_64; a_key: JSON_STRING) + -- Assuming there is no item of key `a_key', + -- insert `a_value' with `a_key'. require - key_not_present: not has_key (key) + key_not_present: not has_key (a_key) local l_value: JSON_NUMBER do - create l_value.make_integer (value) - put (l_value, key) + create l_value.make_integer (a_value) + put (l_value, a_key) end - put_natural (value: NATURAL_64; key: JSON_STRING) - -- Assuming there is no item of key `key', - -- insert `value' with `key'. + put_natural (a_value: NATURAL_64; a_key: JSON_STRING) + -- Assuming there is no item of key `a_key', + -- insert `a_value' with `a_key'. require - key_not_present: not has_key (key) + key_not_present: not has_key (a_key) local l_value: JSON_NUMBER do - create l_value.make_natural (value) - put (l_value, key) + create l_value.make_natural (a_value) + put (l_value, a_key) end - put_real (value: DOUBLE; key: JSON_STRING) - -- Assuming there is no item of key `key', - -- insert `value' with `key'. + put_real (a_value: DOUBLE; a_key: JSON_STRING) + -- Assuming there is no item of key `a_key', + -- insert `a_value' with `a_key'. require - key_not_present: not has_key (key) + key_not_present: not has_key (a_key) local l_value: JSON_NUMBER do - create l_value.make_real (value) - put (l_value, key) + create l_value.make_real (a_value) + put (l_value, a_key) end - put_boolean (value: BOOLEAN; key: JSON_STRING) - -- Assuming there is no item of key `key', - -- insert `value' with `key'. + put_boolean (a_value: BOOLEAN; a_key: JSON_STRING) + -- Assuming there is no item of key `a_key', + -- insert `a_value' with `a_key'. require - key_not_present: not has_key (key) + key_not_present: not has_key (a_key) local l_value: JSON_BOOLEAN do - create l_value.make_boolean (value) - put (l_value, key) + create l_value.make (a_value) + put (l_value, a_key) end - replace (value: detachable JSON_VALUE; key: JSON_STRING) - -- Assuming there is no item of key `key', - -- insert `value' with `key'. - local - l_value: like value + replace (a_value: detachable JSON_VALUE; a_key: JSON_STRING) + -- Assuming there is no item of key `a_key', + -- insert `a_value' with `a_key'. do - l_value := value - if l_value = Void then - create {JSON_NULL} l_value + if a_value = Void then + items.force (create {JSON_NULL}, a_key) + else + items.force (a_value, a_key) end - object.force (l_value, key) end - replace_with_string (value: READABLE_STRING_GENERAL; key: JSON_STRING) - -- Assuming there is no item of key `key', - -- insert `value' with `key'. + replace_with_string (a_value: READABLE_STRING_GENERAL; a_key: JSON_STRING) + -- Assuming there is no item of key `a_key', + -- insert `a_value' with `a_key'. local l_value: JSON_STRING do - create l_value.make_json_from_string_32 (value.as_string_32) - replace (l_value, key) + if attached {READABLE_STRING_8} a_value as s then + create l_value.make_from_string (s) + else + create l_value.make_from_string_32 (a_value.as_string_32) + end + replace (l_value, a_key) end - replace_with_integer (value: INTEGER_64; key: JSON_STRING) - -- Assuming there is no item of key `key', - -- insert `value' with `key'. + replace_with_integer (a_value: INTEGER_64; a_key: JSON_STRING) + -- Assuming there is no item of key `a_key', + -- insert `a_value' with `a_key'. local l_value: JSON_NUMBER do - create l_value.make_integer (value) - replace (l_value, key) + create l_value.make_integer (a_value) + replace (l_value, a_key) end - replace_with_with_natural (value: NATURAL_64; key: JSON_STRING) - -- Assuming there is no item of key `key', - -- insert `value' with `key'. + replace_with_with_natural (a_value: NATURAL_64; a_key: JSON_STRING) + -- Assuming there is no item of key `a_key', + -- insert `a_value' with `a_key'. local l_value: JSON_NUMBER do - create l_value.make_natural (value) - replace (l_value, key) + create l_value.make_natural (a_value) + replace (l_value, a_key) end - replace_with_real (value: DOUBLE; key: JSON_STRING) - -- Assuming there is no item of key `key', - -- insert `value' with `key'. + replace_with_real (a_value: DOUBLE; a_key: JSON_STRING) + -- Assuming there is no item of key `a_key', + -- insert `a_value' with `a_key'. local l_value: JSON_NUMBER do - create l_value.make_real (value) - replace (l_value, key) + create l_value.make_real (a_value) + replace (l_value, a_key) end - replace_with_boolean (value: BOOLEAN; key: JSON_STRING) - -- Assuming there is no item of key `key', - -- insert `value' with `key'. + replace_with_boolean (a_value: BOOLEAN; a_key: JSON_STRING) + -- Assuming there is no item of key `a_key', + -- insert `a_value' with `a_key'. local l_value: JSON_BOOLEAN do - create l_value.make_boolean (value) - replace (l_value, key) + create l_value.make (a_value) + replace (l_value, a_key) end - remove (key: JSON_STRING) - -- Remove item indexed by `key' if any. + remove (a_key: JSON_STRING) + -- Remove item indexed by `a_key' if any. do - object.remove (key) + items.remove (a_key) end wipe_out -- Reset all items to default values; reset status. do - object.wipe_out + items.wipe_out + end + +feature -- Status report + + has_key (a_key: JSON_STRING): BOOLEAN + -- has the JSON_OBJECT contains a specific key `a_key'. + do + Result := items.has (a_key) + end + + has_item (a_value: JSON_VALUE): BOOLEAN + -- has the JSON_OBJECT contain a specfic item `a_value' + do + Result := items.has_item (a_value) end feature -- Access - has_key (key: JSON_STRING): BOOLEAN - -- has the JSON_OBJECT contains a specific key 'key'. + item (a_key: JSON_STRING): detachable JSON_VALUE + -- the json_value associated with a key `a_key'. do - Result := object.has (key) - end - - has_item (value: JSON_VALUE): BOOLEAN - -- has the JSON_OBJECT contain a specfic item 'value' - do - Result := object.has_item (value) - end - - item (key: JSON_STRING): detachable JSON_VALUE - -- the json_value associated with a key. - do - Result := object.item (key) + Result := items.item (a_key) end current_keys: ARRAY [JSON_STRING] - -- array containing actually used keys + -- Array containing actually used keys. do - Result := object.current_keys + Result := items.current_keys end representation: STRING - local - t: HASH_TABLE [JSON_VALUE, JSON_STRING] + -- do create Result.make (2) Result.append_character ('{') - from - t := map_representation - t.start - until - t.after + across + items as ic loop - Result.append (t.key_for_iteration.representation) - Result.append_character (':') - Result.append (t.item_for_iteration.representation) - t.forth - if not t.after then + if Result.count > 1 then Result.append_character (',') end + Result.append (ic.key.representation) + Result.append_character (':') + Result.append (ic.item.representation) end Result.append_character ('}') end @@ -240,9 +253,9 @@ feature -- Access feature -- Mesurement count: INTEGER - -- Number of field + -- Number of field. do - Result := object.count + Result := items.count end feature -- Access @@ -250,7 +263,7 @@ feature -- Access new_cursor: TABLE_ITERATION_CURSOR [JSON_VALUE, JSON_STRING] -- Fresh cursor associated with current structure do - Result := object.new_cursor + Result := items.new_cursor end feature -- Status report @@ -258,7 +271,7 @@ feature -- Status report is_empty: BOOLEAN -- Is empty object? do - Result := object.is_empty + Result := items.is_empty end feature -- Visitor pattern @@ -273,9 +286,9 @@ feature -- Visitor pattern feature -- Conversion map_representation: HASH_TABLE [JSON_VALUE, JSON_STRING] - --A representation that maps keys to values + -- A representation that maps keys to values do - Result := object + Result := items end feature -- Report @@ -284,13 +297,13 @@ feature -- Report -- Hash code value do from - object.start - Result := object.out.hash_code + items.start + Result := items.out.hash_code until - object.off + items.off loop - Result := ((Result \\ 8388593) |<< 8) + object.item_for_iteration.hash_code - object.forth + Result := ((Result \\ 8388593) |<< 8) + items.item_for_iteration.hash_code + items.forth end -- Ensure it is a positive value. Result := Result.hash_code @@ -301,15 +314,15 @@ feature -- Status report debug_output: STRING -- String that should be displayed in debugger to represent `Current'. do - Result := count.out + " item(s)" + Result := count.out + "item(s)" end feature {NONE} -- Implementation - object: HASH_TABLE [JSON_VALUE, JSON_STRING] + items: HASH_TABLE [JSON_VALUE, JSON_STRING] -- Value container invariant - object_not_void: object /= Void + items_not_void: items /= Void end diff --git a/library/kernel/json_string.e b/library/kernel/json_string.e index f8d051c0..1359c4bb 100644 --- a/library/kernel/json_string.e +++ b/library/kernel/json_string.e @@ -4,9 +4,9 @@ note 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" + author: "$Author$" + date: "$Date$" + revision: "$Revision$" license: "MIT (see http://www.opensource.org/licenses/mit-license.php)" class @@ -20,16 +20,73 @@ inherit end create - make_json, make_json_from_string_32, make_with_escaped_json + make_from_string, make_from_string_32, make_from_string_general, + make_from_escaped_json_string, + make_with_escaped_json, make_json, make_json_from_string_32 convert - make_json ({READABLE_STRING_8, STRING_8, IMMUTABLE_STRING_8}), - make_json_from_string_32 ({READABLE_STRING_32, STRING_32, IMMUTABLE_STRING_32}) + make_from_string ({READABLE_STRING_8, STRING_8, IMMUTABLE_STRING_8}), + make_from_string_32 ({READABLE_STRING_32, STRING_32, IMMUTABLE_STRING_32}), + make_from_string_general ({READABLE_STRING_GENERAL, STRING_GENERAL, IMMUTABLE_STRING_GENERAL}) feature {NONE} -- Initialization + make_from_string (s: READABLE_STRING_8) + -- Initialize from ascii string `s'. + require + s_not_void: s /= Void + do + make_from_escaped_json_string (escaped_json_string (s)) + end + + make_from_string_32 (s: READABLE_STRING_32) + -- Initialize from unicode string `s'. + require + s_not_void: s /= Void + do + make_from_escaped_json_string (escaped_json_string (s)) + end + + make_from_string_general (s: READABLE_STRING_GENERAL) + -- Initialize from string `s'. + require + s_not_void: s /= Void + do + if attached {READABLE_STRING_8} s as s8 then + make_from_string (s8) + else + make_from_string_32 (s.as_string_32) + end + end + + make_from_escaped_json_string (a_escaped_string: READABLE_STRING_8) + -- Initialize with `a_escaped_string' already JSON escaped. + require + a_escaped_string_not_void: a_escaped_string /= Void + do + item := a_escaped_string + end + + make_with_escaped_json (a_escaped_string: READABLE_STRING_8) + -- Initialize with `a_escaped_string' already JSON escaped. + obsolete + "Use `make_from_escaped_json_string' Sept/2014" + require + a_escaped_string_not_void: a_escaped_string /= Void + do + make_from_escaped_json_string (a_escaped_string) + end + + make_from_json_string (a_json: JSON_STRING) + -- Initialize with `a_json' string value. + do + make_from_escaped_json_string (a_json.item) + end + make_json (s: READABLE_STRING_8) -- Initialize. + obsolete + "Use `make_from_string' Sept/2014" require item_not_void: s /= Void do @@ -38,18 +95,12 @@ feature {NONE} -- Initialization make_json_from_string_32 (s: READABLE_STRING_32) -- Initialize from STRING_32 `s'. + obsolete + "Use `make_from_string_32' Sept/2014" 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 + make_with_escaped_json (escaped_json_string (s)) end feature -- Access @@ -60,7 +111,7 @@ feature -- Access feature -- Conversion unescaped_string_8: STRING_8 - -- Unescaped string from `item'. + -- Unescaped ascii string from `item'. --| note: valid only if `item' does not encode any unicode character. local s: like item @@ -71,7 +122,7 @@ feature -- Conversion end unescaped_string_32: STRING_32 - -- Unescaped string 32 from `item' + -- Unescaped uncode string from `item' --| some encoders uses UTF-8 , and not the recommended pure json encoding --| thus, let's support the UTF-8 encoding during decoding. local @@ -83,7 +134,7 @@ feature -- Conversion end representation: STRING - -- String representation of `item' with escaped entities if any + -- String representation of `item' with escaped entities if any. do create Result.make (item.count + 2) Result.append_character ('%"') @@ -110,11 +161,14 @@ feature -- Conversion if c = '\' then if i < n then inspect s [i + 1] + when '%"' then + a_output.append_character ('%"') + i := i + 2 when '\' then a_output.append_character ('\') i := i + 2 - when '%"' then - a_output.append_character ('%"') + when '/' then + a_output.append_character ('/') i := i + 2 when 'b' then a_output.append_character ('%B') @@ -132,15 +186,15 @@ feature -- Conversion a_output.append_character ('%T') i := i + 2 when 'u' then - --| Leave Unicode \uXXXX unescaped - a_output.append_character ('\') + --| Leave unicode \uXXXX unescaped + a_output.append_character (c) -- '\' i := i + 1 else - a_output.append_character ('\') + a_output.append_character (c) -- '\' i := i + 1 end else - a_output.append_character ('\') + a_output.append_character (c) -- '\' i := i + 1 end else @@ -153,7 +207,7 @@ feature -- Conversion unescape_to_string_32 (a_output: STRING_32) -- Unescape string `item' into `a_output' string 32. --| some encoders uses UTF-8 , and not the recommended pure json encoding - --| thus, let's support the UTF-8 encoding during decoding. + --| thus, let's support the UTF-8 encoding during decoding. local s: READABLE_STRING_8 i, n: INTEGER @@ -172,11 +226,14 @@ feature -- Conversion if ch = '\' then if i < n then inspect s [i + 1] + when '%"' then + a_output.append_character ('%"') + i := i + 2 when '\' then a_output.append_character ('\') i := i + 2 - when '%"' then - a_output.append_character ('%"') + when '/' then + a_output.append_character ('/') i := i + 2 when 'b' then a_output.append_character ('%B') @@ -198,13 +255,13 @@ feature -- Conversion if hex.count = 4 then a_output.append_code (hexadecimal_to_natural_32 (hex)) end - i := i + 6 -- i +2 +4 + i := i + 6 -- i+2+4 else - a_output.append_character ('\') + a_output.append_character (ch) -- '\' i := i + 1 end else - a_output.append_character ('\') + a_output.append_character (ch) -- '\' i := i + 1 end else @@ -259,12 +316,48 @@ feature -- Comparison feature -- Change Element - append (a_string: STRING) - -- Add a_string + append (a_escaped_string: READABLE_STRING_8) + -- Add JSON escaped string `a_escaped_string' require - a_string_not_void: a_string /= Void + a_escaped_string_not_void: a_escaped_string /= Void do - item.append_string (a_string) + item.append_string (a_escaped_string) + end + + append_json_string (a_json_string: JSON_STRING) + -- Add JSON string `a_json_string' + require + a_json_string_not_void: a_json_string /= Void + do + append (a_json_string.item) + end + + append_string (s: READABLE_STRING_8) + -- Add ascii string `s' + require + s_not_void: s /= Void + do + append (escaped_json_string (s)) + end + + append_string_32 (s: READABLE_STRING_32) + -- Add unicode string `s' + require + s_not_void: s /= Void + do + append (escaped_json_string (s)) + end + + append_string_general (s: READABLE_STRING_GENERAL) + -- Add unicode string `s' + require + s_not_void: s /= Void + do + if attached {READABLE_STRING_8} s as s8 then + append_string (s.as_string_8) + else + append_string_32 (s.as_string_32) + end end feature -- Status report @@ -285,11 +378,11 @@ feature -- Status report feature {NONE} -- Implementation - is_hexadecimal (s: READABLE_STRING_8): BOOLEAN - -- Is `s' an hexadecimal value? + is_hexadecimal (s: READABLE_STRING_8): BOOLEAN + -- Is `s' an hexadecimal value? local i: INTEGER - do + do from Result := True i := 1 @@ -299,7 +392,7 @@ feature {NONE} -- Implementation Result := s [i].is_hexa_digit i := i + 1 end - end + end hexadecimal_to_natural_32 (s: READABLE_STRING_8): NATURAL_32 -- Hexadecimal string `s' converted to NATURAL_32 value @@ -331,46 +424,8 @@ feature {NONE} -- Implementation 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 '%B' then - Result.append_string ("\b") - when '%F' then - Result.append_string ("\f") - when '%N' then - Result.append_string ("\n") - when '%R' then - Result.append_string ("\r") - when '%T' then - Result.append_string ("\t") - 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 + escaped_json_string (s: READABLE_STRING_GENERAL): STRING_8 + -- JSON string with '"' and '\' characters and unicode escaped require s_not_void: s /= Void local @@ -394,6 +449,14 @@ feature {NONE} -- Implementation Result.append_string ("\%"") when '\' then Result.append_string ("\\") + when '/' then + -- To avoid issue with Javascript ... + -- escape only n or not c.is_digit loop - s.extend (c); - i := i + 1; + s.extend (c) + i := i + 1 c := a_number [i] end end @@ -423,18 +524,18 @@ feature {NONE} -- Implementation end if Result then --| "(\.\d+)?" - if c = '.' then + if c = token_dot then --| "\.\d+" = "\.\d\d*" - s.extend (c); - i := i + 1; + s.extend (c) + i := i + 1 c := a_number [i] if c.is_digit then from until i > n or not c.is_digit loop - s.extend (c); - i := i + 1; + s.extend (c) + i := i + 1 c := a_number [i] end else @@ -443,14 +544,14 @@ feature {NONE} -- Implementation end end if Result then --| "(?:[eE][+-]?\d+)?\b" - if c = 'e' or c = 'E' then + if is_exp_token (c) then --| "[eE][+-]?\d+" - s.extend (c); - i := i + 1; + s.extend (c) + i := i + 1 c := a_number [i] - if c = '+' or c = '-' then - s.extend (c); - i := i + 1; + if c = token_plus or c = token_minus then + s.extend (c) + i := i + 1 c := a_number [i] end if c.is_digit then @@ -458,8 +559,8 @@ feature {NONE} -- Implementation until i > n or not c.is_digit loop - s.extend (c); - i := i + 1; + s.extend (c) + i := i + 1 c := a_number [i] end else @@ -472,8 +573,8 @@ feature {NONE} -- Implementation until i > n or not c.is_space loop - s.extend (c); - i := i + 1; + s.extend (c) + i := i + 1 c := a_number [i] end Result := i > n and then s.same_string (a_number) @@ -481,8 +582,7 @@ feature {NONE} -- Implementation end is_valid_unicode (a_unicode: STRING): BOOLEAN - -- is 'a_unicode' a valid Unicode based on this regular expression - -- "\\u[0-9a-fA-F]{4}" + -- is 'a_unicode' a valid unicode based on the regular expression "\\u[0-9a-fA-F]{4}" . local i: INTEGER do @@ -525,7 +625,7 @@ feature {NONE} -- Implementation -- expecting `{' or `[' as start symbol do if attached representation as s and then s.count > 0 then - Result := s [1] = '{' or s [1] = '[' + Result := s [1] = token_object_open or s [1] = token_array_open end end diff --git a/library/parser/json_parser_access.e b/library/parser/json_parser_access.e new file mode 100644 index 00000000..19b8e815 --- /dev/null +++ b/library/parser/json_parser_access.e @@ -0,0 +1,9 @@ +note + description: "Inherit to access restricted feature from {JSON_PARSER}." + date: "$Date$" + revision: "$Revision$" + +deferred class + JSON_PARSER_ACCESS + +end diff --git a/library/kernel/scanner/json_reader.e b/library/parser/json_reader.e similarity index 97% rename from library/kernel/scanner/json_reader.e rename to library/parser/json_reader.e index 7700285b..9cd3c2b0 100644 --- a/library/kernel/scanner/json_reader.e +++ b/library/parser/json_reader.e @@ -20,13 +20,19 @@ feature {NONE} -- Initialization feature -- Commands + reset + -- Reset reader + do + index := 1 + end + set_representation (a_json: STRING) -- Set `representation'. do a_json.left_adjust a_json.right_adjust representation := a_json - index := 1 + reset end read: CHARACTER diff --git a/library/parser/json_tokens.e b/library/parser/json_tokens.e new file mode 100644 index 00000000..7286f2b3 --- /dev/null +++ b/library/parser/json_tokens.e @@ -0,0 +1,87 @@ +note + description: "Token used by the JSON_PARSER" + author: "$Author$" + date: "$Date$" + revision: "$Revision$" + +class + JSON_TOKENS + +feature -- Access + + token_object_open: CHARACTER = '{' + token_object_close: CHARACTER = '}' + + token_array_open: CHARACTER = '[' + token_array_close: CHARACTER = ']' + + token_double_quote: CHARACTER = '"' + token_plus: CHARACTER = '+' + token_minus: CHARACTER = '-' + token_dot: CHARACTER = '.' + token_exp: CHARACTER = 'e' + token_comma: CHARACTER = ',' + token_colon: CHARACTER = ':' + +feature -- Status report + + is_open_token (c: CHARACTER): BOOLEAN + -- Characters which open a type + do + inspect c + when token_object_open, token_array_open, token_double_quote, token_plus, token_minus, token_dot then + Result := True + else + + end + end + + is_close_token (c: CHARACTER): BOOLEAN + -- Characters which close a type + do + inspect c + when token_object_close, token_array_close, token_double_quote 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 '"', '%H' , '/', '%B', '%F', '%N', '%R', '%T' then -- '%H' = '\' = reverse solidus + 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 + + is_exp_token (c: CHARACTER): BOOLEAN + -- Is number exposant token? + do + Result := c = token_exp or else c.as_lower = token_exp + end + +end diff --git a/library/utility/file/json_file_reader.e b/library/utility/file/json_file_reader.e new file mode 100644 index 00000000..cd3f4de3 --- /dev/null +++ b/library/utility/file/json_file_reader.e @@ -0,0 +1,46 @@ +note + description: "Objects that ..." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + JSON_FILE_READER + +feature -- Access + + read_json_from (a_path: READABLE_STRING_GENERAL): detachable STRING + local + l_file: PLAIN_TEXT_FILE + l_last_string: detachable STRING + l_file_count: INTEGER + l_fetch_done: BOOLEAN + do + create l_file.make_with_name (a_path) + -- We perform several checks until we make a real attempt to open the file. + if not l_file.exists then + print ("error: '" + a_path.out + "' does not exist%N") -- FIXME: unicode may be truncated + else + if not l_file.is_readable then + print ("error: '" + a_path.out + "' is not readable.%N") -- FIXME: unicode may be truncated + else + l_file_count := l_file.count + l_file.open_read + from + create Result.make (l_file_count) + until + l_fetch_done + loop + l_file.read_stream (1_024) + l_last_string := l_file.last_string + l_fetch_done := l_file.exhausted or l_file.end_of_file or l_last_string.count < 1_024 + if not l_last_string.is_empty then + Result.append (l_last_string) + end + end + l_file.close + end + end + end + +end diff --git a/library/extras/visitor/json_iterator.e b/library/utility/visitor/json_iterator.e similarity index 100% rename from library/extras/visitor/json_iterator.e rename to library/utility/visitor/json_iterator.e diff --git a/library/extras/visitor/json_pretty_string_visitor.e b/library/utility/visitor/json_pretty_string_visitor.e similarity index 100% rename from library/extras/visitor/json_pretty_string_visitor.e rename to library/utility/visitor/json_pretty_string_visitor.e diff --git a/library/extras/visitor/json_visitor.e b/library/utility/visitor/json_visitor.e similarity index 100% rename from library/extras/visitor/json_visitor.e rename to library/utility/visitor/json_visitor.e diff --git a/library/extras/visitor/print_json_visitor.e b/library/utility/visitor/print_json_visitor.e similarity index 100% rename from library/extras/visitor/print_json_visitor.e rename to library/utility/visitor/print_json_visitor.e diff --git a/test/autotest/test_suite/json_author_converter.e b/test/autotest/test_suite/json_author_converter.e index 1eafac8e..c097b8b3 100644 --- a/test/autotest/test_suite/json_author_converter.e +++ b/test/autotest/test_suite/json_author_converter.e @@ -48,7 +48,7 @@ feature {NONE} -- Implementation name_key: JSON_STRING -- Author's name label. once - create Result.make_json ("name") + create Result.make_from_string ("name") end end -- class JSON_AUTHOR_CONVERTER diff --git a/test/autotest/test_suite/json_book_collection_converter.e b/test/autotest/test_suite/json_book_collection_converter.e index 0ba713f2..0a36de26 100644 --- a/test/autotest/test_suite/json_book_collection_converter.e +++ b/test/autotest/test_suite/json_book_collection_converter.e @@ -60,7 +60,7 @@ feature -- Conversion to_json (o: like object): JSON_OBJECT do - create Result.make + create Result.make_with_capacity (2) Result.put (json.value (o.name), name_key) Result.put (json.value (o.books), books_key) end @@ -70,13 +70,13 @@ feature {NONE} -- Implementation name_key: JSON_STRING -- Collection's name label. once - create Result.make_json ("name") + create Result.make_from_string ("name") end books_key: JSON_STRING -- Book list label. once - create Result.make_json ("books") + create Result.make_from_string ("books") end end -- class JSON_BOOK_COLLECTION_CONVERTER diff --git a/test/autotest/test_suite/json_book_converter.e b/test/autotest/test_suite/json_book_converter.e index 8711420c..dec02971 100644 --- a/test/autotest/test_suite/json_book_converter.e +++ b/test/autotest/test_suite/json_book_converter.e @@ -45,7 +45,7 @@ feature -- Conversion to_json (o: like object): JSON_OBJECT do - create Result.make + create Result.make_with_capacity (3) Result.put (json.value (o.title), title_key) Result.put (json.value (o.isbn), isbn_key) Result.put (json.value (o.author), author_key) @@ -56,19 +56,19 @@ feature {NONE} -- Implementation title_key: JSON_STRING -- Book's title label. once - create Result.make_json ("title") + create Result.make_from_string ("title") end isbn_key: JSON_STRING -- Book ISBN label. once - create Result.make_json ("isbn") + create Result.make_from_string ("isbn") end author_key: JSON_STRING -- Author label. once - create Result.make_json ("author") + create Result.make_from_string ("author") end end -- class JSON_BOOK_CONVERTER diff --git a/test/autotest/test_suite/test_ds.e b/test/autotest/test_suite/test_ds.e index 5f737ea8..34d8f0aa 100644 --- a/test/autotest/test_suite/test_ds.e +++ b/test/autotest/test_suite/test_ds.e @@ -51,13 +51,13 @@ feature -- Test if attached {HASH_TABLE [ANY, HASHABLE]} json.object (l_value, "HASH_TABLE") as t2 then create l_ucs_key.make_from_string ("1") if attached {STRING_32} t2 [l_ucs_key] as l_ucs_value then - assert ("ucs_value.string.is_equal (%"foo%")", l_ucs_value.string.is_equal ("foo")) + assert ("ucs_value.string.is_equal (%"foo%")", l_ucs_value.same_string_general ("foo")) else assert ("ucs_value /= Void", False) end create l_ucs_key.make_from_string ("2") if attached {STRING_32} t2 [l_ucs_key] as l_ucs_value then - assert ("ucs_value.string.is_equal (%"bar%")", l_ucs_value.string.is_equal ("bar")) + assert ("ucs_value.string.is_equal (%"bar%")", l_ucs_value.same_string_general ("bar")) else assert ("ucs_value /= Void", False) end diff --git a/test/autotest/test_suite/test_json_core.e b/test/autotest/test_suite/test_json_core.e index 7db16c2c..93eeb4fc 100644 --- a/test/autotest/test_suite/test_json_core.e +++ b/test/autotest/test_suite/test_json_core.e @@ -10,6 +10,11 @@ inherit EQA_TEST_SET + JSON_PARSER_ACCESS + undefine + default_create + end + feature -- Test test_json_number_and_integer @@ -35,15 +40,15 @@ feature -- Test -- that can represent the value of the JSON number, in this case -- we know it is INTEGER_8 since the value is 42 jrep := "42" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then + create parser.make_with_string (jrep) + if attached {JSON_NUMBER} parser.next_parsed_json_value as l_jn then if attached {INTEGER_8} json.object (jn, Void) as l_i8 then assert ("l_i8 = 42", l_i8 = 42) else assert ("json.object (jn, Void) is a INTEGER_8", False) end else - assert ("parser.parse is a JSON_NUMBER", False) + assert ("parser.next_parsed_json_value is a JSON_NUMBER", False) end end @@ -70,15 +75,15 @@ feature -- Test -- that can represent the value of the JSON number, in this case -- we know it is INTEGER_8 since the value is 42 jrep := "42" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then + create parser.make_with_string (jrep) + if attached {JSON_NUMBER} parser.next_parsed_json_value as l_jn then if attached {INTEGER_8} json.object (jn, Void) as l_i8 then assert ("l_i8 = 42", l_i8 = 42) else assert ("json.object (jn, Void) is a INTEGER_8", False) end else - assert ("parser.parse is a JSON_NUMBER", False) + assert ("parser.next_parsed_json_value is a JSON_NUMBER", False) end end @@ -105,15 +110,15 @@ feature -- Test -- that can represent the value of the JSON number, in this case -- we know it is INTEGER_16 since the value is 300 jrep := "300" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then + create parser.make_with_string (jrep) + if attached {JSON_NUMBER} parser.next_parsed_json_value as l_jn then if attached {INTEGER_16} json.object (jn, Void) as l_i16 then assert ("l_i16 = 300", l_i16 = 300) else assert ("json.object (jn, Void) is a INTEGER_16", False) end else - assert ("parser.parse is a JSON_NUMBER", False) + assert ("parser.next_parsed_json_value is a JSON_NUMBER", False) end end @@ -140,15 +145,15 @@ feature -- Test -- that can represent the value of the JSON number, in this case -- we know it is INTEGER_32 since the value is 100000 jrep := "100000" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then + create parser.make_with_string (jrep) + if attached {JSON_NUMBER} parser.next_parsed_json_value as l_jn then if attached {INTEGER_32} json.object (jn, Void) as l_i32 then assert ("l_i32 = 100000", l_i32 = 100000) else assert ("json.object (jn, Void) is a INTEGER_32", False) end else - assert ("parser.parse is a JSON_NUMBER", False) + assert ("parser.next_parsed_json_value is a JSON_NUMBER", False) end end @@ -175,15 +180,15 @@ feature -- Test -- that can represent the value of the JSON number, in this case -- we know it is INTEGER_32 since the value is 42949672960 jrep := "42949672960" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then + create parser.make_with_string (jrep) + if attached {JSON_NUMBER} parser.next_parsed_json_value as l_jn then if attached {INTEGER_64} json.object (jn, Void) as l_i64 then assert ("l_i64 = 42949672960", l_i64 = 42949672960) else assert ("json.object (jn, Void) is a INTEGER_64", False) end else - assert ("parser.parse is a JSON_NUMBER", False) + assert ("parser.next_parsed_json_value is a JSON_NUMBER", False) end end @@ -210,15 +215,15 @@ feature -- Test -- that can represent the value of the JSON number, in this case -- we know it is INTEGER_16 since the value is 200 jrep := "200" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then + create parser.make_with_string (jrep) + if attached {JSON_NUMBER} parser.next_parsed_json_value as l_jn then if attached {INTEGER_16} json.object (jn, Void) as i16 then assert ("i16 = 200", i16 = 200) else assert ("json.object (jn, Void) is an INTEGER_16", False) end else - assert ("parser.parse is a JSON_NUMBER", False) + assert ("parser.next_parsed_json_value is a JSON_NUMBER", False) end end @@ -245,15 +250,15 @@ feature -- Test -- that can represent the value of the JSON number, in this case -- we know it is INTEGER_32 since the value is 32768 jrep := "32768" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then + create parser.make_with_string (jrep) + if attached {JSON_NUMBER} parser.next_parsed_json_value as l_jn then if attached {INTEGER_32} json.object (jn, Void) as i32 then assert ("i32 = 32768", i32 = 32768) else assert ("json.object (jn, Void) is a INTEGER_32", False) end else - assert ("parser.parse is a JSON_NUMBER", False) + assert ("parser.next_parsed_json_value is a JSON_NUMBER", False) end end @@ -280,15 +285,15 @@ feature -- Test -- that can represent the value of the JSON number, in this case -- we know it is INTEGER_64 since the value is 2147483648 jrep := "2147483648" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then + create parser.make_with_string (jrep) + if attached {JSON_NUMBER} parser.next_parsed_json_value as l_jn then if attached {INTEGER_64} json.object (jn, Void) as i64 then assert ("i64 = 2147483648", i64 = 2147483648) else assert ("json.object (jn, Void) is a INTEGER_64", False) end else - assert ("parser.parse is a JSON_NUMBER", False) + assert ("parser.next_parsed_json_value is a JSON_NUMBER", False) end end @@ -315,15 +320,15 @@ feature -- Test -- that can represent the value of the JSON number, in this case -- we know it is INTEGER_32 since the value is 42949672960 jrep := "9223372036854775808" -- 1 higher than largest positive number that can be represented by INTEGER 64 - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then + create parser.make_with_string (jrep) + if attached {JSON_NUMBER} parser.next_parsed_json_value as l_jn then if attached {NATURAL_64} json.object (jn, Void) as l_n64 then assert ("l_n64 = 9223372036854775808", l_n64 = 9223372036854775808) else assert ("json.object (jn, Void) is a NATURAL_64", False) end else - assert ("parser.parse is a JSON_NUMBER", False) + assert ("parser.next_parsed_json_value is a JSON_NUMBER", False) end end @@ -349,15 +354,15 @@ feature -- Test -- Note: The JSON_FACTORY will always return a REAL_64 if the value -- of the JSON number is a floating point number jrep := "3.14" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then + create parser.make_with_string (jrep) + if attached {JSON_NUMBER} parser.next_parsed_json_value as l_jn then if attached {REAL_64} json.object (jn, Void) as r64 then assert ("3.14 <= r64 and r64 <= 3.141", 3.14 <= r64 and r64 <= 3.141) else assert ("json.object (jn, Void) is a REAL_64", False) end else - assert ("parser.parse is a JSON_NUMBER", False) + assert ("parser.next_parsed_json_value is a JSON_NUMBER", False) end end @@ -381,15 +386,15 @@ feature -- Test -- JSON representation -> JSON value -> Eiffel value jrep := "3.1400001049041748" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then + create parser.make_with_string (jrep) + if attached {JSON_NUMBER} parser.next_parsed_json_value as l_jn then if attached {REAL_64} json.object (l_jn, Void) as r64 then assert ("r64 = 3.1400001049041748", r64 = 3.1400001049041748) else assert ("json.object (l_jn, Void) is a REAL_64", False) end else - assert ("parser.parse is a JSON_NUMBER", False) + assert ("parser.next_parsed_json_value is a JSON_NUMBER", False) end end @@ -414,15 +419,15 @@ feature -- Test -- JSON representation -> JSON value -> Eiffel value jrep := "3.1415926535897931" - create parser.make_parser (jrep) - if attached {JSON_NUMBER} parser.parse as l_jn then + create parser.make_with_string (jrep) + if attached {JSON_NUMBER} parser.next_parsed_json_value as l_jn then if attached {REAL_64} json.object (jn, Void) as l_r64 then assert ("l_r64 = 3.1415926535897931", l_r64 = 3.1415926535897931) else assert ("json.object (jn, Void) is a REAL_64", False) end else - assert ("parser.parse is a JSON_NUMBER", False) + assert ("parser.next_parsed_json_value is a JSON_NUMBER", False) end end @@ -434,7 +439,7 @@ feature -- Test do -- Eiffel value -> JSON value -> JSON representation b := True - create jb.make_boolean (b) + create jb.make (b) assert ("jb.representation.is_equal (%"true%")", jb.representation.is_equal ("true")) -- Eiffel value -> JSON value -> JSON representation with factory if attached {JSON_BOOLEAN} json.value (b) as l_jb then @@ -444,20 +449,20 @@ feature -- Test end -- JSON representation -> JSON value -> Eiffel value - create parser.make_parser ("true") - if attached {JSON_BOOLEAN} parser.parse as l_jb then + create parser.make_with_string ("true") + if attached {JSON_BOOLEAN} parser.next_parsed_json_value as l_jb then if attached {BOOLEAN} json.object (l_jb, Void) as l_b then assert ("l_b = True", l_b = True) else assert ("json.object (l_jb, Void) is BOOLEAN", False) end else - assert ("parser.parse is a JSON_BOOLEAN", False) + assert ("parser.next_parsed_json_value is a JSON_BOOLEAN", False) end -- Eiffel value -> JSON value -> JSON representation b := False - create jb.make_boolean (b) + create jb.make (b) assert ("jb.representation.same_string (%"false%")", jb.representation.same_string ("false")) -- Eiffel value -> JSON value -> JSON representation with factory if attached {JSON_BOOLEAN} json.value (b) as l_jb then @@ -467,15 +472,15 @@ feature -- Test end -- JSON representation -> JSON value -> Eiffel value - create parser.make_parser ("false") - if attached {JSON_BOOLEAN} parser.parse as l_jb then + create parser.make_with_string ("false") + if attached {JSON_BOOLEAN} parser.next_parsed_json_value as l_jb then if attached {BOOLEAN} json.object (l_jb, Void) as l_b then assert ("l_b = False", l_b = False) else assert ("json.object (l_jb, Void) is a BOOLEAN", False) end else - assert ("parser.parse is a JSON_BOOLEAN", False) + assert ("parser.next_parsed_json_value is a JSON_BOOLEAN", False) end end @@ -497,11 +502,11 @@ feature -- Test end -- JSON representation -> JSON value -> Eiffel value - create parser.make_parser (jrep) - if attached parser.parse as l_json_null then + create parser.make_with_string (jrep) + if attached parser.next_parsed_json_value as l_json_null then assert ("a = Void", json.object (l_json_null, Void) = Void) else - assert ("parser.parse /= Void", False) + assert ("parser.next_parsed_json_value /= Void", False) end end @@ -514,7 +519,7 @@ feature -- Test do c := 'a' -- Eiffel value -> JSON value -> JSON representation - create js.make_json (c.out) + create js.make_from_string (c.out) assert ("js.representation.is_equal (%"%"a%"%")", js.representation.is_equal ("%"a%"")) -- Eiffel value -> JSON value -> JSON representation with factory if attached {JSON_STRING} json.value (c) as l_json_str then @@ -525,13 +530,13 @@ feature -- Test -- JSON representation -> JSON value -> Eiffel value jrep := "%"a%"" - create parser.make_parser (jrep) - if attached {JSON_STRING} parser.parse as l_json_str then + create parser.make_with_string (jrep) + if attached {JSON_STRING} parser.next_parsed_json_value as l_json_str then if attached {STRING_32} json.object (l_json_str, Void) as ucs then assert ("ucs.string.is_equal (%"a%")", ucs.string.is_equal ("a")) end else - assert ("parser.parse /= Void", False) + assert ("parser.next_parsed_json_value /= Void", False) end end @@ -546,7 +551,7 @@ feature -- Test jrep := "%"foobar%"" -- Eiffel value -> JSON value -> JSON representation - create js.make_json (s) + create js.make_from_string (s) assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal (jrep)) -- Eiffel value -> JSON value -> JSON representation with factory if attached {JSON_STRING} json.value (s) as l_js then @@ -556,13 +561,13 @@ feature -- Test end -- JSON representation -> JSON value -> Eiffel value - create parser.make_parser (jrep) - if attached {JSON_STRING} parser.parse as l_js then + create parser.make_with_string (jrep) + if attached {JSON_STRING} parser.next_parsed_json_value as l_js then if attached {STRING_32} json.object (l_js, Void) as l_ucs then assert ("ucs.string.is_equal (%"foobar%")", l_ucs.string.is_equal (s)) end else - assert ("parser.parse /= Void", False) + assert ("parser.next_parsed_json_value /= Void", False) end end @@ -578,7 +583,7 @@ feature -- Test create ucs.make_from_string (s) -- Eiffel value -> JSON value -> JSON representation - create js.make_json (ucs) + create js.make_from_string (ucs) assert ("js.representation.is_equal (%"%"foobar%"%")", js.representation.is_equal (jrep)) -- Eiffel value -> JSON value -> JSON representation with factory @@ -589,15 +594,15 @@ feature -- Test end -- JSON representation -> JSON value -> Eiffel value - create parser.make_parser (jrep) - if attached {JSON_STRING} parser.parse as l_js then + create parser.make_with_string (jrep) + if attached {JSON_STRING} parser.next_parsed_json_value as l_js then if attached {STRING_32} json.object (l_js, Void) as l_ucs then assert ("ucs.string.is_equal (%"foobar%")", l_ucs.string.is_equal (s)) else assert ("json.object (js, Void) /= Void", False) end else - assert ("parser.parse /= Void", False) + assert ("parser.next_parsed_json_value /= Void", False) end end @@ -610,7 +615,7 @@ feature -- Test do jrep := "%"foo\\bar%"" create s.make_from_string ("foo\bar") - create js.make_json (s) + create js.make_from_string (s) assert ("js.representation.same_string (%"%"foo\\bar%"%")", js.representation.same_string (jrep)) -- Eiffel value -> JSON value -> JSON representation with factory @@ -621,32 +626,84 @@ feature -- Test end -- JSON representation -> JSON value -> Eiffel value - create parser.make_parser (jrep) - if attached {JSON_STRING} parser.parse as l_js then + create parser.make_with_string (jrep) + if attached {JSON_STRING} parser.next_parsed_json_value as l_js then if attached {STRING_32} json.object (l_js, Void) as l_ucs then assert ("ucs.same_string (%"foo\bar%")", l_ucs.same_string ("foo\bar")) end else - assert ("parser.parse /= Void", False) + assert ("parser.next_parsed_json_value /= Void", False) end jrep := "%"foo\\bar%"" - create parser.make_parser (jrep) - if attached {JSON_STRING} parser.parse as jstring then + create parser.make_with_string (jrep) + if attached {JSON_STRING} parser.next_parsed_json_value as jstring then assert ("unescaped string %"foo\\bar%" to %"foo\bar%"", jstring.unescaped_string_8.same_string ("foo\bar")) else - assert ("parser.parse /= Void", False) + assert ("parser.next_parsed_json_value /= Void", False) end - create js.make_json_from_string_32 ({STRING_32} "你好") + create js.make_from_string_32 ({STRING_32} "你好") assert ("escaping unicode string32 %"%%/20320/%%/22909/%" %"\u4F60\u597D%"", js.item.same_string ("\u4F60\u597D")) jrep := "%"\u4F60\u597D%"" --| Ni hao - create parser.make_parser (jrep) - if attached {JSON_STRING} parser.parse as jstring then + create parser.make_with_string (jrep) + if attached {JSON_STRING} parser.next_parsed_json_value as jstring then assert ("same unicode string32 %"%%/20320/%%/22909/%"", jstring.unescaped_string_32.same_string ({STRING_32} "你好")) else - assert ("parser.parse /= Void", False) + assert ("parser.next_parsed_json_value /= Void", False) end end + test_json_string_and_special_characters_2 + local + js: detachable JSON_STRING + s,j: STRING + do + s := "foo%Tbar" + j := "foo\tbar" + create js.make_from_string (s) + assert ("string %"" + s + "%" to json %"" + j + "%"", js.item.same_string (j)) + create js.make_from_escaped_json_string (js.item) + assert ("json %"" + j + "%" to string %"" + s + "%"", js.unescaped_string_8.same_string (s)) + + s := "tab=%T cr=%R newline=%N backslash=%H slash=/ end" + j := "tab=\t cr=\r newline=\n backslash=\\ slash=/ end" + create js.make_from_string (s) + assert ("string %"" + s + "%" to json %"" + j + "%"", js.item.same_string (j)) + create js.make_from_escaped_json_string (js.item) + assert ("json %"" + j + "%" to string %"" + s + "%"", js.unescaped_string_8.same_string (s)) + + s := "" + j := "%")", js.unescaped_string_8.same_string ("")) + + create js.make_from_escaped_json_string (js.item) + assert ("js.item.same_string (%"%")", js.unescaped_string_8.same_string ("")) + + -- + create js.make_from_escaped_json_string ("") + assert ("js.item.same_string (%"%")", js.item.same_string ("")) + assert ("js.unescaped_string_8.same_string (%"%")", js.unescaped_string_8.same_string ("")) + + create js.make_from_escaped_json_string (js.item) + assert ("js.item.same_string (%"")) + assert ("js.unescaped_string_8.same_string (%"%")", js.unescaped_string_8.same_string ("")) + + end + test_json_array local ll: LINKED_LIST [INTEGER_8] @@ -665,7 +722,7 @@ feature -- Test ll.extend (5) -- Note: Currently there is no simple way of creating a JSON_ARRAY -- from an LINKED_LIST. - create ja.make_array + create ja.make (ll.count) from ll.start until @@ -690,15 +747,15 @@ feature -- Test -- it means we will get an LINKED_LIST [ANY] containing the INTEGER_8 -- values 0, 1, 1, 2, 3, 5 jrep := "[0,1,1,2,3,5]" - create parser.make_parser (jrep) - if attached {JSON_ARRAY} parser.parse as l_ja then + create parser.make_with_string (jrep) + if attached {JSON_ARRAY} parser.next_parsed_json_value as l_ja then if attached {LINKED_LIST [detachable ANY]} json.object (ja, Void) as l_ll2 then assert ("ll2.is_equal (ll)", l_ll2.is_equal (ll)) else assert ("json.object (ja, Void) /= Void", False) end else - assert ("parser.parse /= Void", False) + assert ("parser.next_parsed_json_value /= Void", False) end end @@ -720,14 +777,14 @@ feature -- Test -- a HASH_TABLE, so we do it manually. -- t = {"name": "foobar", "size": 42, "contents", [0, 1, 1, 2, 3, 5]} create jo.make - create js_key.make_json ("name") - create js.make_json ("foobar") + create js_key.make_from_string ("name") + create js.make_from_string ("foobar") jo.put (js, js_key) - create js_key.make_json ("size") + create js_key.make_from_string ("size") create jn.make_integer (42) jo.put (jn, js_key) - create js_key.make_json ("contents") - create ja.make_array + create js_key.make_from_string ("contents") + create ja.make (6) create jn.make_integer (0) ja.add (jn) create jn.make_integer (1) @@ -763,8 +820,8 @@ feature -- Test -- JSON representation -> JSON value -> Eiffel value -> JSON value -> JSON representation jrep := "{%"name%":%"foobar%",%"size%":42,%"contents%":[0,1,1,2,3,5]}" - create parser.make_parser (jrep) - if attached {JSON_OBJECT} parser.parse as l_jo then + create parser.make_with_string (jrep) + if attached {JSON_OBJECT} parser.next_parsed_json_value as l_jo then if attached {HASH_TABLE [detachable ANY, STRING_GENERAL]} json.object (l_jo, Void) as l_t2 then if attached json.value (l_t2) as l_jo_2 then assert ("jrep.is_equal (jo.representation)", jrep.is_equal (l_jo_2.representation)) @@ -775,7 +832,7 @@ feature -- Test assert ("json.object (jo, Void) /= Void", False) end else - assert ("parser.parse /= Void", jo /= Void) + assert ("parser.next_parsed_json_value /= Void", jo /= Void) end end diff --git a/test/autotest/test_suite/test_json_suite.e b/test/autotest/test_suite/test_json_suite.e index 096a8db2..649366d1 100644 --- a/test/autotest/test_suite/test_json_suite.e +++ b/test/autotest/test_suite/test_json_suite.e @@ -1,4 +1,4 @@ -note +note description: "[ Eiffel tests that can be executed by testing tool. ]" @@ -11,7 +11,6 @@ class TEST_JSON_SUITE inherit - EQA_TEST_SET redefine on_prepare @@ -28,38 +27,38 @@ feature {NONE} -- Events feature -- Tests Pass test_json_pass1 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("pass1.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("pass1.json", parse_json.is_parsed = True) + parse_json.parse_content + assert ("pass1.json", parse_json.is_valid) end end test_json_pass2 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("pass2.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("pass2.json", parse_json.is_parsed = True) + parse_json.parse_content + assert ("pass2.json",parse_json.is_valid) end end - test_json_pass3 - -- + test_json_pass3 + -- local parse_json: like new_json_parser do if attached json_file_from ("pass3.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("pass3.json", parse_json.is_parsed = True) + parse_json.parse_content + assert ("pass3.json",parse_json.is_valid) end end @@ -69,412 +68,420 @@ feature -- Tests Pass utf: UTF_CONVERTER s: READABLE_STRING_32 do - s := {STRING_32} "{ %"nihaoma%": %"你好吗\t?%" }" + s := {STRING_32} "{ %"nihaoma%": %"你好吗\t?%" }" parse_json := new_json_parser (utf.string_32_to_utf_8_string_8 (s)) - json_value := parse_json.parse_json - assert ("utf8.pass1.json", parse_json.is_parsed = True) - if attached {JSON_OBJECT} json_value as jo and then attached {JSON_STRING} jo.item ("nihaoma") as js then - assert ("utf8.nihaoma", js.unescaped_string_32.same_string ({STRING_32} "你好吗%T?")) + parse_json.parse_content + assert ("utf8.pass1.json", parse_json.is_valid) + if attached {JSON_OBJECT} parse_json.parsed_json_value as jo and then attached {JSON_STRING} jo.item ("nihaoma") as js then + assert ("utf8.nihaoma", js.unescaped_string_32.same_string ({STRING_32} "你好吗%T?")) else assert ("utf8.nihaoma", False) - end - end + end + end feature -- Tests Failures - - test_json_fail1 - -- + test_json_fail1 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail1.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail1.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail1.json", parse_json.is_valid = False) end end - test_json_fail2 - -- + test_json_fail2 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail2.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail2.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail2.json",parse_json.is_valid = False) end end test_json_fail3 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail3.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail3.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail3.json",parse_json.is_valid = False) end end test_json_fail4 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail4.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail4.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail4.json",parse_json.is_valid = False) end end - test_json_fail5 - -- + test_json_fail5 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail5.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail5.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail5.json",parse_json.is_valid = False) end end + test_json_fail6 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail6.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail6.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail6.json",parse_json.is_valid = False ) end end - test_json_fail7 - -- + test_json_fail7 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail7.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail7.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail7.json",parse_json.is_valid = False) end end - test_json_fail8 - -- + test_json_fail8 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail8.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail8.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail8.json",parse_json.is_valid = False ) end end + test_json_fail9 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail9.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail9.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail9.json",parse_json.is_valid = False) end end + test_json_fail10 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail10.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail10.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail10.json",parse_json.is_valid = False) end end - test_json_fail11 - -- + test_json_fail11 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail11.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail11.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail11.json",parse_json.is_valid = False) end end test_json_fail12 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail12.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail12.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail12.json",parse_json.is_valid = False) end end - test_json_fail13 - -- + test_json_fail13 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail13.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail13.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail13.json",parse_json.is_valid = False) end end - test_json_fail14 - -- + test_json_fail14 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail14.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail14.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail14.json",parse_json.is_valid = False) end end test_json_fail15 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail15.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail15.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail15.json",parse_json.is_valid = False) end end test_json_fail16 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail16.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail16.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail16.json",parse_json.is_valid = False) end end test_json_fail17 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail17.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail17.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail17.json",parse_json.is_valid = False) end end test_json_fail18 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail18.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail18.json", parse_json.is_parsed = True) + parse_json.parse_content + assert ("fail18.json",parse_json.is_valid = True) end end test_json_fail19 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail19.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail19.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail19.json",parse_json.is_valid = False) end end test_json_fail20 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail20.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail20.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail20.json",parse_json.is_valid = False) end end - test_json_fail21 - -- + test_json_fail21 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail21.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail21.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail21.json",parse_json.is_valid = False) end end - test_json_fail22 - -- + + test_json_fail22 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail22.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail22.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail22.json",parse_json.is_valid = False) end end - test_json_fail23 - -- + test_json_fail23 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail23.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail23.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail23.json",parse_json.is_valid = False) end end - test_json_fail24 - -- + test_json_fail24 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail24.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail24.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail24.json",parse_json.is_valid = False) end end test_json_fail25 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail25.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail25.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail25.json",parse_json.is_valid = False) end end - test_json_fail26 - -- + + test_json_fail26 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail26.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail26.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail26.json",parse_json.is_valid = False) end end - test_json_fail27 - -- + + test_json_fail27 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail27.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail27.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail27.json",parse_json.is_valid = False) end end - test_json_fail28 - -- + + test_json_fail28 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail28.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail28.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail28.json",parse_json.is_valid = False) end end - test_json_fail29 - -- + + test_json_fail29 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail29.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail29.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail29.json",parse_json.is_valid = False ) end end - test_json_fail30 - -- + + test_json_fail30 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail30.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail30.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail30.json",parse_json.is_valid = False) end end test_json_fail31 - -- + -- local parse_json: like new_json_parser do if attached json_file_from ("fail31.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail31.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail31.json",parse_json.is_valid = False) end end - test_json_fail32 - -- + test_json_fail32 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail32.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail32.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail32.json",parse_json.is_valid = False) end end - test_json_fail33 - -- + test_json_fail33 + -- local parse_json: like new_json_parser do if attached json_file_from ("fail33.json") as json_file then parse_json := new_json_parser (json_file) - json_value := parse_json.parse_json - assert ("fail33.json", parse_json.is_parsed = False) + parse_json.parse_content + assert ("fail33.json",parse_json.is_valid = False) end end @@ -482,19 +489,16 @@ feature -- JSON_FROM_FILE file_reader: JSON_FILE_READER - json_value: detachable JSON_VALUE - - json_file_from (fn: STRING): detachable STRING + json_file_from (fn: READABLE_STRING_GENERAL): detachable STRING local f: RAW_FILE - l_path: STRING - test_dir: STRING + l_path: PATH + test_dir: PATH i: INTEGER do - test_dir := (create {EXECUTION_ENVIRONMENT}).current_working_directory - test_dir.append_character ((create {OPERATING_ENVIRONMENT}).directory_separator) - l_path := test_dir + fn - create f.make_with_name (l_path) + test_dir := (create {EXECUTION_ENVIRONMENT}).current_working_path + l_path := test_dir.extended (fn) + create f.make_with_path (l_path) if f.exists then -- Found json file else @@ -505,26 +509,27 @@ feature -- JSON_FROM_FILE until i = 0 loop - test_dir.append_character ('.') - test_dir.append_character ('.') - test_dir.append_character ((create {OPERATING_ENVIRONMENT}).directory_separator) + test_dir := test_dir.extended ("..") i := i - 1 end - l_path := test_dir + fn + l_path := test_dir.extended (fn) end - create f.make_with_name (l_path) + create f.make_with_path (l_path) if f.exists then - Result := file_reader.read_json_from (l_path) + Result := file_reader.read_json_from (l_path.name) end - assert ("File contains json data", Result /= Void) - end + assert ("File contains json data", Result /= Void) + end + new_json_parser (a_string: STRING): JSON_PARSER do - create Result.make_parser (a_string) + create Result.make_with_string (a_string) end invariant file_reader /= Void end + + diff --git a/test/autotest/test_suite/test_suite-safe.ecf b/test/autotest/test_suite/test_suite-safe.ecf index 541c8d9e..0b10a63e 100644 --- a/test/autotest/test_suite/test_suite-safe.ecf +++ b/test/autotest/test_suite/test_suite-safe.ecf @@ -1,5 +1,5 @@ - + @@ -7,11 +7,11 @@ /CVS$ /.svn$ - - + From 82f832a556ba8c113df35e838260f39f5f0b8ad5 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 30 Sep 2014 10:46:12 +0200 Subject: [PATCH 06/11] Updated license and copyright. Updated classes with bottom indexing notes related to copyright and license. --- License.txt | 3 ++- library/json-safe.ecf | 15 ++++++++------- library/kernel/json_array.e | 3 +++ library/kernel/json_boolean.e | 3 +++ library/kernel/json_null.e | 3 +++ library/kernel/json_number.e | 3 +++ library/kernel/json_object.e | 3 +++ library/kernel/json_string.e | 3 +++ library/kernel/json_value.e | 3 +++ library/license.lic | 4 ++++ library/parser/json_parser.e | 9 ++++++--- library/parser/json_parser_access.e | 3 +++ library/parser/json_reader.e | 3 +++ library/parser/json_tokens.e | 3 +++ library/utility/file/json_file_reader.e | 3 +++ library/utility/visitor/json_iterator.e | 3 +++ .../utility/visitor/json_pretty_string_visitor.e | 3 +++ library/utility/visitor/json_visitor.e | 3 +++ library/utility/visitor/print_json_visitor.e | 3 +++ 19 files changed, 65 insertions(+), 11 deletions(-) create mode 100644 library/license.lic diff --git a/License.txt b/License.txt index 8bf6765c..56c30878 100644 --- a/License.txt +++ b/License.txt @@ -1,4 +1,5 @@ -Copyright (c) 2010 Javier Velilla and others, http://ejson.origo.ethz.ch +Copyright (c) 2010-2014 Javier Velilla and others, +https://github.com/eiffelhub/json . Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/library/json-safe.ecf b/library/json-safe.ecf index f3a3bb52..8025f959 100644 --- a/library/json-safe.ecf +++ b/library/json-safe.ecf @@ -1,5 +1,6 @@ - + + JSON parser @@ -7,15 +8,15 @@ /CVS$ /.svn$ - - - - - + + + + - + diff --git a/library/kernel/json_array.e b/library/kernel/json_array.e index 2006c1e1..6b30b8fd 100644 --- a/library/kernel/json_array.e +++ b/library/kernel/json_array.e @@ -186,4 +186,7 @@ feature {NONE} -- Implementation invariant items_not_void: items /= Void +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/kernel/json_boolean.e b/library/kernel/json_boolean.e index e642ed48..47b49979 100644 --- a/library/kernel/json_boolean.e +++ b/library/kernel/json_boolean.e @@ -81,4 +81,7 @@ feature -- Status report Result := item.out end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/kernel/json_null.e b/library/kernel/json_null.e index 04130ce5..ad0a85fe 100644 --- a/library/kernel/json_null.e +++ b/library/kernel/json_null.e @@ -45,4 +45,7 @@ feature {NONE} -- Implementation null_value: STRING = "null" +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/kernel/json_number.e b/library/kernel/json_number.e index ea72cf4c..84ccbf8f 100644 --- a/library/kernel/json_number.e +++ b/library/kernel/json_number.e @@ -143,4 +143,7 @@ feature -- Implementation invariant item_not_void: item /= Void +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/kernel/json_object.e b/library/kernel/json_object.e index b5a0d44b..7b37ea1e 100644 --- a/library/kernel/json_object.e +++ b/library/kernel/json_object.e @@ -325,4 +325,7 @@ feature {NONE} -- Implementation invariant items_not_void: items /= Void +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/kernel/json_string.e b/library/kernel/json_string.e index 1359c4bb..bf246f6a 100644 --- a/library/kernel/json_string.e +++ b/library/kernel/json_string.e @@ -500,4 +500,7 @@ feature {NONE} -- Implementation invariant item_not_void: item /= Void +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/kernel/json_value.e b/library/kernel/json_value.e index f5a5fccf..a7fb0f43 100644 --- a/library/kernel/json_value.e +++ b/library/kernel/json_value.e @@ -40,4 +40,7 @@ feature -- Visitor pattern deferred end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/license.lic b/library/license.lic new file mode 100644 index 00000000..4d58ac79 --- /dev/null +++ b/library/license.lic @@ -0,0 +1,4 @@ +${NOTE_KEYWORD} + copyright: "2010-${YEAR}, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" + diff --git a/library/parser/json_parser.e b/library/parser/json_parser.e index d607ddce..b513de80 100644 --- a/library/parser/json_parser.e +++ b/library/parser/json_parser.e @@ -1,8 +1,8 @@ note description: "Parse serialized JSON data" - author: "jvelilla" - date: "2008/08/24" - revision: "Revision 0.1" + author: "$Author$" + date: "$Date$" + revision: "$Revision$" class JSON_PARSER @@ -637,4 +637,7 @@ feature {NONE} -- Constants null_id: STRING = "null" +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/parser/json_parser_access.e b/library/parser/json_parser_access.e index 19b8e815..ffc32d6e 100644 --- a/library/parser/json_parser_access.e +++ b/library/parser/json_parser_access.e @@ -6,4 +6,7 @@ note deferred class JSON_PARSER_ACCESS +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/parser/json_reader.e b/library/parser/json_reader.e index 9cd3c2b0..3869ee9f 100644 --- a/library/parser/json_reader.e +++ b/library/parser/json_reader.e @@ -121,4 +121,7 @@ feature {NONE} -- Implementation invariant representation_not_void: representation /= Void +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/parser/json_tokens.e b/library/parser/json_tokens.e index 7286f2b3..0374330f 100644 --- a/library/parser/json_tokens.e +++ b/library/parser/json_tokens.e @@ -84,4 +84,7 @@ feature -- Status report Result := c = token_exp or else c.as_lower = token_exp end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/utility/file/json_file_reader.e b/library/utility/file/json_file_reader.e index cd3f4de3..53085adc 100644 --- a/library/utility/file/json_file_reader.e +++ b/library/utility/file/json_file_reader.e @@ -43,4 +43,7 @@ feature -- Access end end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/utility/visitor/json_iterator.e b/library/utility/visitor/json_iterator.e index 3489ce85..9f09ee92 100644 --- a/library/utility/visitor/json_iterator.e +++ b/library/utility/visitor/json_iterator.e @@ -55,4 +55,7 @@ feature -- Visitor Pattern do end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/utility/visitor/json_pretty_string_visitor.e b/library/utility/visitor/json_pretty_string_visitor.e index 3ac76617..65e69551 100644 --- a/library/utility/visitor/json_pretty_string_visitor.e +++ b/library/utility/visitor/json_pretty_string_visitor.e @@ -160,4 +160,7 @@ feature -- Visitor Pattern output.append ("%"") end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/utility/visitor/json_visitor.e b/library/utility/visitor/json_visitor.e index a4fc6d3f..c1ae4031 100644 --- a/library/utility/visitor/json_visitor.e +++ b/library/utility/visitor/json_visitor.e @@ -53,4 +53,7 @@ feature -- Visitor Pattern deferred end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/utility/visitor/print_json_visitor.e b/library/utility/visitor/print_json_visitor.e index 4dcd08a3..4265413e 100644 --- a/library/utility/visitor/print_json_visitor.e +++ b/library/utility/visitor/print_json_visitor.e @@ -101,4 +101,7 @@ feature -- Visitor Pattern to_json.append ("%"") end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end From ae9f67391c81ab312f3ed1e4af5b2ce7caa6c811 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 30 Sep 2014 10:46:28 +0200 Subject: [PATCH 07/11] Marked converters classes as obsolete. --- library/converter/json_arrayed_list_converter.e | 6 ++++++ library/converter/json_converter.e | 6 ++++++ library/converter/json_hash_table_converter.e | 6 ++++++ library/converter/json_linked_list_converter.e | 6 ++++++ library/converter/json_list_converter.e | 6 ++++++ library/converter/support/ejson.e | 6 ++++++ library/converter/support/shared_ejson.e | 7 +++++++ 7 files changed, 43 insertions(+) diff --git a/library/converter/json_arrayed_list_converter.e b/library/converter/json_arrayed_list_converter.e index 21bcd4d4..154c1717 100644 --- a/library/converter/json_arrayed_list_converter.e +++ b/library/converter/json_arrayed_list_converter.e @@ -8,6 +8,9 @@ note class JSON_ARRAYED_LIST_CONVERTER +obsolete + "This JSON converter design has issues [Sept/2014]." + inherit JSON_LIST_CONVERTER @@ -29,4 +32,7 @@ feature {NONE} -- Factory create Result.make (nb) end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end -- class JSON_ARRAYED_LIST_CONVERTER diff --git a/library/converter/json_converter.e b/library/converter/json_converter.e index b4d78a66..987c116a 100644 --- a/library/converter/json_converter.e +++ b/library/converter/json_converter.e @@ -8,6 +8,9 @@ note deferred class JSON_CONVERTER +obsolete + "This JSON converter design has issues [Sept/2014]." + inherit SHARED_EJSON @@ -35,4 +38,7 @@ feature -- Conversion invariant has_eiffel_object: object /= Void -- An empty object must be created at creation time! +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/converter/json_hash_table_converter.e b/library/converter/json_hash_table_converter.e index c3b2c724..5787246b 100644 --- a/library/converter/json_hash_table_converter.e +++ b/library/converter/json_hash_table_converter.e @@ -8,6 +8,9 @@ note class JSON_HASH_TABLE_CONVERTER +obsolete + "This JSON converter design has issues [Sept/2014]." + inherit JSON_CONVERTER @@ -79,4 +82,7 @@ feature -- Conversion end end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end -- class JSON_HASH_TABLE_CONVERTER diff --git a/library/converter/json_linked_list_converter.e b/library/converter/json_linked_list_converter.e index 1edb6bf8..82fc5041 100644 --- a/library/converter/json_linked_list_converter.e +++ b/library/converter/json_linked_list_converter.e @@ -8,6 +8,9 @@ note class JSON_LINKED_LIST_CONVERTER +obsolete + "This JSON converter design has issues [Sept/2014]." + inherit JSON_LIST_CONVERTER @@ -29,4 +32,7 @@ feature {NONE} -- Factory create Result.make end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end -- class JSON_LINKED_LIST_CONVERTER diff --git a/library/converter/json_list_converter.e b/library/converter/json_list_converter.e index 343851c9..aa3f596b 100644 --- a/library/converter/json_list_converter.e +++ b/library/converter/json_list_converter.e @@ -8,6 +8,9 @@ note deferred class JSON_LIST_CONVERTER +obsolete + "This JSON converter design has issues [Sept/2014]." + inherit JSON_CONVERTER @@ -71,4 +74,7 @@ feature -- Conversion end end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end -- class JSON_ARRAYED_LIST_CONVERTER diff --git a/library/converter/support/ejson.e b/library/converter/support/ejson.e index 1ea6c8c1..1d15a28d 100644 --- a/library/converter/support/ejson.e +++ b/library/converter/support/ejson.e @@ -8,6 +8,9 @@ note class EJSON +obsolete + "This JSON converter design has issues [Sept/2014]." + inherit EXCEPTIONS @@ -265,4 +268,7 @@ feature {NONE} -- Implementation (JSON parser) create Result.make_with_string ("{}") end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" end -- class EJSON diff --git a/library/converter/support/shared_ejson.e b/library/converter/support/shared_ejson.e index 066bad88..4d0b5a50 100644 --- a/library/converter/support/shared_ejson.e +++ b/library/converter/support/shared_ejson.e @@ -14,6 +14,9 @@ note class SHARED_EJSON +obsolete + "This JSON converter design has issues [Sept/2014]." + feature -- Access json: EJSON @@ -33,4 +36,8 @@ feature -- Access Result.add_converter (jhtc) end +note + copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" + end -- class SHARED_EJSON From 0647a74875fbcf08b89e9943700ab728961aadcd Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Fri, 3 Oct 2014 18:44:09 +0200 Subject: [PATCH 08/11] Ensure backward compatibility for `parse' / `is_parsed'. --- library/parser/json_parser.e | 1 + 1 file changed, 1 insertion(+) diff --git a/library/parser/json_parser.e b/library/parser/json_parser.e index b513de80..b2c3a468 100644 --- a/library/parser/json_parser.e +++ b/library/parser/json_parser.e @@ -172,6 +172,7 @@ feature -- Obsolete commands "Use restricted `next_parsed_json_value' [sept/2014]." do Result := next_parsed_json_value + is_parsed := is_valid end feature {JSON_PARSER_ACCESS} -- Obsolete commands: restricted area From 641e114fedbca5652e22013af6309652b1de0614 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 17 Nov 2014 11:22:33 +0100 Subject: [PATCH 09/11] Converted ecf file to complete void-safe. Improved JSON_PRETTY_STRING_VISITOR to support STRING_8 or STRING_32 output. Added examples. Added doc in the folder "doc". Updated Readme and other files. Added package.iron file. --- History.txt | 2 + License.txt | 2 +- Readme.txt | 47 ++- doc/user_guide.mediawiki | 295 ++++++++++++++++++ examples/basic/basic.e | 83 +++++ examples/basic/basic.ecf | 10 + library/json-safe.ecf | 2 +- library/json.rc | 1 - .../visitor/json_pretty_string_visitor.e | 84 +++-- package.iron | 16 + 10 files changed, 503 insertions(+), 39 deletions(-) create mode 100644 doc/user_guide.mediawiki create mode 100644 examples/basic/basic.e create mode 100644 examples/basic/basic.ecf delete mode 100644 library/json.rc create mode 100644 package.iron diff --git a/History.txt b/History.txt index 02fd7cb6..96ec4ab0 100644 --- a/History.txt +++ b/History.txt @@ -5,6 +5,8 @@ team: "" date: "2011-07-06" revision: "0.3.0" +WARNING: THIS FILE IS NOT UP TO DATE + +++++++++++++++++++++Important Changes since 0.2.0 version++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/License.txt b/License.txt index 56c30878..36d303a0 100644 --- a/License.txt +++ b/License.txt @@ -1,4 +1,4 @@ -Copyright (c) 2010-2014 Javier Velilla and others, +Copyright (c) 2010-2014 Javier Velilla, Jocelyn Fiat and others, https://github.com/eiffelhub/json . diff --git a/Readme.txt b/Readme.txt index c0085d5d..44f30cb7 100644 --- a/Readme.txt +++ b/Readme.txt @@ -1,21 +1,26 @@ Readme file for eJSON ===================== -team: "Javier Velilla,Jocelyn Fiat, Paul Cohen" -date: "$Date$" -revision: "$Revision$" +team: "Javier Velilla, Jocelyn Fiat" +previous contributors: "Paul Cohen" +date: "2014-nov-17" 1. Introduction --------------- eJSON stands for Eiffel JSON library and is a small Eiffel library for dealing -with the JSON format. The objective of the library is to provide two basic -features Eiffel2JSON and JSON2Eiffel. +with the JSON format. This library provides a JSON parser and visitors, +including a pretty printer. + +The converters part is now obsolete and not recommended (remember: the +objective of converters were to provide two basic features Eiffel2JSON and +JSON2Eiffel). There will be a new design for converters as a standalone +library on top of Current json library. 2. Legal stuff -------------- -eJSON is copyrighted by the author Javier Velilla and others. It is licensed +eJSON is copyrighted by the author Javier Velilla, Jocelyn Fiat and others. It is licensed under the MIT License. See the file license.txt in the same directory as this readme file. @@ -46,18 +51,18 @@ Currently the only documentation on eJSON is available at: EJSON requires that you have: -1. Gobo 3.9 installed or later -2. One of the following compiler combinations installed: - * ISE Eiffel 6.5 or later. +1. One of the following compiler combinations installed: + * ISE Eiffel 13.11 or later. * gec [try to test] - * tecomp [try to test] eJSON probably works fine with other versions of the above compilers. There are no known platform dependencies (Windows, Linux). To install eJSON simply extract the ejson-X.Y.Z.zip file to some appropriate place on your hard disk. There are no requirements on environment variables or -registry variables. +registry variables. +Note eJSON is also delivered within EiffelStudio release, under +$ISE_LIBRARY/contrib/library/text/parser/json To verify that everything works you should compile the example programs and/or the test program. @@ -70,18 +75,18 @@ installation. Directory Description --------- ----------- -doc Contains the eJSON.pdf documentation file. -examples Contains the two example programs. -ejson Contains the actual eJSON library classes. -test Contains a test program for eJSON. +doc Contains documentation file. +examples Contains example codes. +library Contains the actual eJSON library classes. +test Contains test suite for eJSON. 7. Contacting the Team ---------------------- Contact the team: + https://github.com/eiffelhub/json/issues Javier Velilla «javier.hector@gmail.com» - Paul Cohen «paco@seibostudios.se» Jocelyn Fiat «jfiat@eiffel.com» 8. Releases @@ -92,8 +97,16 @@ history.txt. Version Date Description ------- ---- ----------- +0.6.0 2014-11-17 Fixed various issue with parsing string (such as \t and related), + Implemented escaping of slash '/' only in case of ' + Many feature renaming to match Eiffel style and naming convention, + kept previous feature as obsolete. + Restructured the library to make easy extraction of "converter" + classes if needed in the future. + Marked converters classes as obsolete. 0.5.0 2013-11-dd Added JSON_ITERATOR, simplified JSON_OBJECT 0.4.0 2012-12-12 Updated documentation URI 0.3.0 2011-07-06 JSON Factory Converters 0.2.0 2010-02-07 Adapted to EiffelStudio 6.4 or later, supports void-safety -0.1.0 2010-02-07 First release, Adapted to SmartEiffel 1.2r7 and EiffelStudio 6.2 or previous \ No newline at end of file +0.1.0 2010-02-07 First release, Adapted to SmartEiffel 1.2r7 and EiffelStudio 6.2 or previous diff --git a/doc/user_guide.mediawiki b/doc/user_guide.mediawiki new file mode 100644 index 00000000..c4ab9b3e --- /dev/null +++ b/doc/user_guide.mediawiki @@ -0,0 +1,295 @@ +== Preface == + +This document is a living document! As always read and try out the code to understand what's really going on. + +=== About the project === + +The eJSON project was started by Javier Velilla in 2008. The aim was simply to +provide JSON support to Eiffel programmers. A couple of other people have been +involved to various extent since the start; Berend de Boer, Jocelyn Fiat and +Manu Stapf. In 2009 Paul Cohen joined the project as an active developer and +later Jocelyn Fiat. + +The current active maintainers: +- Javier Velilla +- Jocelyn Fiat + +The formal name of the project is “eJSON”. + +For questions regarding eJSON please contact +- +- +- or directly on [https://github.com/eiffelhub/json/issues] + +=== Current version and status === + +The latest release is 0.6.0. eJSON has been improved and cleaned. +The converters are not obsolete. + + +== Introduction == + +=== What is JSON? === + +JSON (JavaScript Object Notation) is a lightweight computer data interchange format. It is a text-based, human-readable format for representing simple data structures and associative arrays (called objects). See the [http://en.wikipedia.org/wiki/JSON Wikipedia article on JSON], [http://www.json.org www.json.org] and [http://www.json.com www.json.com] for more information. + +The JSON format is specified in [http://www.ietf.org/rfc/rfc4627.txt IETF RFC 4627] by Douglas Crockford. The official [http://www.iana.org/assignments/media-types Internet MIME media type] for JSON is "application/json". The recommended file name extension for JSON files is ".json". + +=== Advantages === + +1. Lightweight data-interchange format. +2. Easy for humans to read and write. +3. Enables easy integration with AJAX/JavaScript web applications. See the article [http://www.developer.com/lang/jscript/article.php/3596836 Speeding Up AJAX with JSON] for a good short discussion on this subject. +4. JSON data structures translate with ease into the native data structures universal to almost all programming languages used today. + +=== Use in Eiffel applications === + +JSON can be used as a general serialization format for Eiffel objects. As such it could be used as a: + +* Data representation format in REST-based web service applications written in Eiffel. +* Serialization format for Eiffel objects in persistence solutions. +* File format for configuration files in Eiffel systems. + +=== Prerequisites === + +eJSON works today with EiffelStudio 13.11 +There is an optional extension that requires the latest snapshot of the Gobo Eiffel libraries (a working snapshot is distributed with EiffelStudio). The depencencies on Gobo are on Gobo's unicode +and regex libraries and for some of the extra features in eJSON, on Gobos structure classes DS_HASH_TABLE and DS_LINKED_LIST. + +eJSON is intended to work with all ECMA compliant Eiffel compilers. + +=== Installation === + +You can either download a given release and install on your machine or you can get the latest snapshot of the code. +To download go to the [http://ejson.origo.ethz.ch/download download page]. +To get the latest snapshot of the code do: + +: $ git clone https://github.com/eiffelhub/json.git json + +*[https://github.com/eiffelhub/json/releases download page] +*[https://github.com/eiffelhub/json github project] + +Note that the latest json release is also delivered with EiffelStudio installation under $ISE_LIBRARY/contrib/library/text/parser/json. + + +=== Cluster and directory layout === + + json/ + library/ (Root directory for eJSON library classes) + kernel/ (All classes in this cluster should eventually only depend on ECMA Eiffel and FreeELKS). + json_array.e + json_boolean.e + json_null.e + json_number.e + json_object.e + json_string.e + json_value.e + parser/ + json_parser.e + json_parser_access.e + json_reader.e + json_tokens.e + utility/ + file/ + json_file_reader.e + visitor/ + json_visitor.e + json_iterator.e + json_pretty_string_visitor.e + print_json_visitor.e + converters/ (JSON core converter classes !OBSOLETE!) + json_converter.e + json_hash_table_converter.e + json_list_converter.e + json_linked_list_converter.e + json_arrayed_list_converter.e + support/ + ejson.e + shared_ejson.e + gobo_converters/ (JSON core converter classes support for GOBO !OBSOLETE!) + converters/ + json_ds_hash_table_converter.e + json_ds_linked_list_converter.e + shared_gobo_ejson.e + test/ (Contains autotest suite) + autotest/ (AutoTest based unit test). + examples/ (Example code) + +=== Future development === + +Here is a list of suggestions for future development of eJSON. +* Ongoing: Provide a JSON_FACTORY class for easy conversion between arbitrary JSON and Eiffel values. +* Ongoing: Provide a mechanism for users to add custom converters between JSON values and user space Eiffel classes. +* Ongoing: Implement a full test framework for eJSON. +* Suggestion: Investigate performance and improve it if neccessary. +* Suggestion: Support JSON references. See [http://www.json.com/2007/10/19/json-referencing-proposal-and-library JSON Referencing Proposal and Library] and [http://www.sitepen.com/blog/2008/06/17/json-referencing-in-dojo JSON referencing in Dojo] for more information. +* Suggestion: Support JSON path. See [http://goessner.net/articles/JsonPath JSONPath - XPath for JSON] for more information. +* Suggestion: Support JSON schema validation. See [http://json-schema.org JSON Schema Proposal] for more information. +* Suggestion: Support RDF JSON serialization. See [http://n2.talis.com/wiki/RDF_JSON_Specification RDF JSON Specification] for more information. +* Suggestion: Add support to JSON classes for conversion from Eiffel manifest values. So one can write things like: + +== A simple example == + +There are two basic approaches to using eJSON; either you use the basic JSON_VALUE classes, converting to and from JSON values to corresponding Eiffel instances or you use the high level eJSON interface class SHARED_EJSON. Of course you can use a mix of both approaches if you find it appropriate! + +Here is an example of how to create a JSON number value from an INTEGER and then obtain the JSON representation for that value. + + simple_example is + local + i: INTEGER + jn: JSON_NUMBER + s: STRING + do + i := 42 + create jn.make_integer (i) + s := jn.representation -- s.is_equal ("42") + end + +== Mapping of JSON values to Eiffel values == + +=== JSON number === + +JSON numbers are represented by the class JSON_NUMBER. JSON number values can be converted to/from NATURAL_*, INTEGER_* and REAL_64 values. For floating point values REAL_* is used. The complete mapping is as follows: + +JSON number -> Eiffel: +* -128 <= n <= +127 -> INTEGER_8 +* n can't be represented by INTEGER_8 and -32768 <= n <= +32767 -> INTEGER_16 +* n can't be represented by INTEGER_16 and -2147483648 <= n <= +2147483647 -> INTEGER_32 +* n can't be represented by INTEGER_32 and -9223372036854775808 <= n <= +9223372036854775807 -> INTEGER_64 +* n can't be represented by INTEGER_64 and 9223372036854775808 <= n <= 18446744073709551615 -> NATURAL_64 +* n has fractional dot '.' -> REAL_64. +* n -> eJSON exception if number can't be represented by a INTEGER_64, NATURAL_64 or REAL_64. + +Eiffel -> JSON number: +* NATURAL_8, NATURAL_16, NATURAL_32, NATURAL_64, NATURAL -> JSON number +* INTEGER_8, INTEGER_16, INTEGER_32, INTEGER_64, INTEGER -> JSON number +* REAL_32, REAL_64, REAL -> JSON number + +You can use the following creation routines to create JSON_NUMBER instances: + +* JSON_NUMBER.make_integer +* JSON_NUMBER.make_real +* JSON_NUMBER.make_natural + + eiffel_to_json_number_representation is + local + i: INTEGER + r: REAL + jn: JSON_NUMBER + do + print ("JSON representation of Eiffel INTEGER: '") + i := 123 + create jn.make_integer (i) + print (jn.representation) + print ("'%N") + print ("JSON representation of Eiffel REAL: '") + r := 12.3 + create jn.make_real (r) + print (jn.representation) + print ("'%N") + end + +The output of the above code will be: + + JSON representation of Eiffel INTEGER: '123' + JSON representation of Eiffel REAL: '12.300000190734863' + +=== JSON boolean === + +JSON boolean values are represented by the class JSON_BOOLEAN. The JSON boolean value "true" is converted to/from the BOOLEAN value "True" and the JSON boolean value "false is converted to/from the BOOLEAN value "False". + + eiffel_to_json_boolean_representation is + local + b: BOOLEAN + jb: JSON_BOOLEAN + do + print ("JSON representation of Eiffel BOOLEAN: '") + b := True + create jb.make (b) + print (jb.representation) + print ("'%N") + print("JSON representation of Eiffel BOOLEAN: '") + b := False + create jb.make (b) + print (jb.representation) + print ("'%N") + end + +The output of the above code will be: + + JSON representation of Eiffel BOOLEAN: 'true' + JSON representation of Eiffel BOOLEAN: 'false' + +=== JSON string === + +JSON strings are represented by the class JSON_STRING. JSON string values can be converted to/from STRING_32, STRING and CHARACTER values. The complete mapping is as follows: + +JSON string -> Eiffel: +* All JSON strings -> STRING or STRING_32 + +Eiffel -> JSON string: +* STRING_32 -> JSON string +* STRING -> JSON string +* CHARACTER -> JSON string + + eiffel_to_json_string_representation is + local + s: STRING + js: JSON_STRING + do + print ("JSON representation of Eiffel STRING: '") + s := "JSON rocks!" + create js.make_from_string (s) + print (js.representation) + print ("'%N") + end + +The output of the above code will be: + + JSON representation of Eiffel STRING: '"JSON rocks!"' + +Note: JSON escape unicode characters, as well a other specific characters, to get the unescaped string value, use either 'unescaped_string_8' or 'unescaped_string_32'. + +=== JSON null === + +The JSON null value is represented by the class JSON_NULL. The JSON null value can be converted to/from Void. + + eiffel_to_json_null_representation is + local + a: ANY + jn: JSON_NULL + do + create jn + print ("JSON representation for JSON null value: '") + print (jn.representation) + print ("'%N") + a := Void + if attached {JSON_NULL} json.value (a) as l_jn then -- json from SHARED_EJSON! + print ("JSON representation of Eiffel Void reference: '") + print (l_jn.representation) + print ("'%N") + end + end + +The output of the above code will be: + + JSON representation for JSON null value: 'null' + JSON representation of Eiffel Void reference: 'null' + +=== JSON array === + +JSON array is represented by the class JSON_ARRAY. + +=== JSON object === + +JSON object is represented by the class JSON_OBJECT. + + +== The eJSON visitor pattern == + +TBD. See examples. + +== The eJSON file reader class == + +TBD. + diff --git a/examples/basic/basic.e b/examples/basic/basic.e new file mode 100644 index 00000000..52520394 --- /dev/null +++ b/examples/basic/basic.e @@ -0,0 +1,83 @@ +class + BASIC + +create + make + +feature {NONE} -- Initialization + + make + -- Initialize `Current'. + local + parser: JSON_PARSER + printer: JSON_PRETTY_STRING_VISITOR + s: STRING_32 + do + -- Create parser for content `json_content' + create parser.make_with_string (json_content) + -- Parse the content + parser.parse_content + if + parser.is_valid and then + attached parser.parsed_json_value as jv + then + -- Json content is valid, and well parser. + -- and the parsed json value is `jv' + + -- Let's access the glossary/title value + if + attached {JSON_OBJECT} jv as j_object and then + attached {JSON_OBJECT} j_object.item ("glossary") as j_glossary and then + attached {JSON_STRING} j_glossary.item ("title") as j_title + then + print ("The glossary title is %"" + j_title.unescaped_string_8 + "%".%N") + else + print ("The glossary title was not found!%N") + end + + -- Pretty print the parsed JSON + create s.make_empty + create printer.make (s) + jv.accept (printer) + print ("The JSON formatted using a pretty printer:%N") + print (s) + end + end + +feature -- Status + +feature -- Access + + json_content: STRING = "[ +{ + "glossary": { + "title": "example glossary", + "GlossDiv": { + "title": "S", + "GlossList": { + "GlossEntry": { + "ID": "SGML", + "SortAs": "SGML", + "GlossTerm": "Standard Generalized Markup Language", + "Acronym": "SGML", + "Abbrev": "ISO 8879:1986", + "GlossDef": { + "para": "A meta-markup language, used to create markup languages such as DocBook.", + "GlossSeeAlso": ["GML", "XML"] + }, + "GlossSee": "markup" + } + } + } + } +} + ]" + +feature -- Change + +feature {NONE} -- Implementation + +invariant +-- invariant_clause: True + +end diff --git a/examples/basic/basic.ecf b/examples/basic/basic.ecf new file mode 100644 index 00000000..17ceee6f --- /dev/null +++ b/examples/basic/basic.ecf @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/library/json-safe.ecf b/library/json-safe.ecf index 8025f959..0a4e9d75 100644 --- a/library/json-safe.ecf +++ b/library/json-safe.ecf @@ -8,7 +8,7 @@ /CVS$ /.svn$ - diff --git a/library/json.rc b/library/json.rc deleted file mode 100644 index 8b137891..00000000 --- a/library/json.rc +++ /dev/null @@ -1 +0,0 @@ - diff --git a/library/utility/visitor/json_pretty_string_visitor.e b/library/utility/visitor/json_pretty_string_visitor.e index 65e69551..e89c215c 100644 --- a/library/utility/visitor/json_pretty_string_visitor.e +++ b/library/utility/visitor/json_pretty_string_visitor.e @@ -10,7 +10,8 @@ inherit JSON_VISITOR create - make, make_custom + make, + make_custom feature -- Initialization @@ -32,14 +33,52 @@ feature -- Initialization feature -- Access - output: STRING_32 + output: STRING_GENERAL -- JSON representation - indentation: like output +feature -- Settings - indentation_step: like indentation + indentation_step: STRING + -- Text used for indentation. + --| by default a tabulation "%T" - line_number: INTEGER + object_count_inlining: INTEGER + -- Inline where object item count is under `object_count_inlining'. + --| ex 3: + --| { "a", "b", "c" } + --| ex 2: + --| { + --| "a", + --| "b", + --| "c" + --| } + + array_count_inlining: INTEGER + -- Inline where array item count is under `object_count_inlining'. + +feature -- Element change + + set_indentation_step (a_step: STRING) + -- Set `indentation_step' to `a_step'. + do + indentation_step := a_step + end + + set_object_count_inlining (a_nb: INTEGER) + -- Set `object_count_inlining' to `a_nb'. + do + object_count_inlining := a_nb + end + + set_array_count_inlining (a_nb: INTEGER) + -- Set `array_count_inlining' to `a_nb'. + do + array_count_inlining := a_nb + end + +feature {NONE} -- Implementation + + indentation: STRING indent do @@ -58,9 +97,7 @@ feature -- Access line_number := line_number + 1 end - object_count_inlining: INTEGER - - array_count_inlining: INTEGER + line_number: INTEGER feature -- Visitor Pattern @@ -71,10 +108,14 @@ feature -- Visitor Pattern l_json_array: ARRAYED_LIST [JSON_VALUE] l_line: like line_number l_multiple_lines: BOOLEAN + l_output: like output do + l_output := output l_json_array := a_json_array.array_representation - l_multiple_lines := l_json_array.count >= array_count_inlining or across l_json_array as p some attached {JSON_OBJECT} p.item or attached {JSON_ARRAY} p.item end - output.append ("[") + l_multiple_lines := l_json_array.count >= array_count_inlining + or across l_json_array as p some attached {JSON_OBJECT} p.item or attached {JSON_ARRAY} p.item end + l_output.append_code (91) -- '[' : 91 + l_line := line_number indent from @@ -89,14 +130,14 @@ feature -- Visitor Pattern value.accept (Current) l_json_array.forth if not l_json_array.after then - output.append (", ") + l_output.append (", ") end end exdent if line_number > l_line or l_json_array.count >= array_count_inlining then new_line end - output.append ("]") + l_output.append_code (93) -- ']' : 93 end visit_json_boolean (a_json_boolean: JSON_BOOLEAN) @@ -123,10 +164,12 @@ feature -- Visitor Pattern l_pairs: HASH_TABLE [JSON_VALUE, JSON_STRING] l_line: like line_number l_multiple_lines: BOOLEAN + l_output: like output do + l_output := output l_pairs := a_json_object.map_representation l_multiple_lines := l_pairs.count >= object_count_inlining or across l_pairs as p some attached {JSON_OBJECT} p.item or attached {JSON_ARRAY} p.item end - output.append ("{") + l_output.append_code (123) -- '{' : 123 l_line := line_number indent from @@ -138,26 +181,29 @@ feature -- Visitor Pattern new_line end l_pairs.key_for_iteration.accept (Current) - output.append (": ") + l_output.append (": ") l_pairs.item_for_iteration.accept (Current) l_pairs.forth if not l_pairs.after then - output.append (", ") + l_output.append (", ") end end exdent if line_number > l_line or l_pairs.count >= object_count_inlining then new_line end - output.append ("}") + l_output.append_code (125) -- '}' : 125 end visit_json_string (a_json_string: JSON_STRING) -- Visit `a_json_string'. + local + l_output: like output do - output.append ("%"") - output.append (a_json_string.item) - output.append ("%"") + l_output := output + l_output.append_code (34) -- '%"' : 34 + l_output.append (a_json_string.item) + l_output.append_code (34) -- '%"' : 34 end note diff --git a/package.iron b/package.iron new file mode 100644 index 00000000..90cfb9c9 --- /dev/null +++ b/package.iron @@ -0,0 +1,16 @@ +package json + +project + json_safe = "library/json-safe.ecf" + json = "library/json.ecf" + json_gobo_extension = "library/json_gobo_extension.ecf" + +note + title: Eiffel JSON + description: Eiffel JSON parser and visitors + tags: json,parser,text + license: MIT + copyright: Copyright (c) 2010-2014 Javier Velilla, Jocelyn Fiat and others, + link[github]: "project" https://github.com/eiffelhub/json + +end From 0cc0ba047fe42eb1d9b7dc4821aec9171ed731bd Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 17 Nov 2014 16:04:37 +0100 Subject: [PATCH 10/11] Reintroduced parse_object as obsolete, to avoid breaking existing code. --- library/parser/json_parser.e | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/library/parser/json_parser.e b/library/parser/json_parser.e index b2c3a468..32c3ffbc 100644 --- a/library/parser/json_parser.e +++ b/library/parser/json_parser.e @@ -1,8 +1,8 @@ note description: "Parse serialized JSON data" - author: "$Author$" - date: "$Date$" - revision: "$Revision$" + author: "$Author: jfiat $" + date: "$Date: 2014-11-17 11:54:05 +0100 (lun., 17 nov. 2014) $" + revision: "$Revision: 96099 $" class JSON_PARSER @@ -166,6 +166,18 @@ feature -- Obsolete commands end end + parse_object: detachable JSON_OBJECT + -- Parse JSON data `representation' + -- start ::= object | array + obsolete + "Use `parse_content' and `parsed_json_value' [nov/2014]." + do + parse_content + if is_parsed and then attached {JSON_OBJECT} parsed_json_value as jo then + Result := jo + end + end + parse: detachable JSON_VALUE -- Next JSON value from current position on `representation'. obsolete @@ -197,7 +209,7 @@ feature {NONE} -- Implementation: parsing c := actual inspect c when token_object_open then - Result := parse_object + Result := next_json_object when token_double_quote then Result := parse_string when token_array_open then @@ -231,7 +243,7 @@ feature {NONE} -- Implementation: parsing is_parsed_implies_result_not_void: not has_error implies Result /= Void end - parse_object: JSON_OBJECT + next_json_object: JSON_OBJECT -- object -- {} -- {"key" : "value" [,]} From 33b555ff279875068eaf574117ce2445caf0cb00 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 8 Jan 2015 18:57:31 +0100 Subject: [PATCH 11/11] Fixed implementation of JSON_PARSER.is_valid_number (STRING): BOOLEAN --- library/parser/json_parser.e | 145 ++++++++++++++++++++--------------- 1 file changed, 84 insertions(+), 61 deletions(-) diff --git a/library/parser/json_parser.e b/library/parser/json_parser.e index 32c3ffbc..c016da22 100644 --- a/library/parser/json_parser.e +++ b/library/parser/json_parser.e @@ -1,8 +1,8 @@ note description: "Parse serialized JSON data" - author: "$Author: jfiat $" - date: "$Date: 2014-11-17 11:54:05 +0100 (lun., 17 nov. 2014) $" - revision: "$Revision: 96099 $" + author: "$Author$" + date: "$Date$" + revision: "$Revision$" class JSON_PARSER @@ -509,88 +509,111 @@ feature {NONE} -- Implementation if c = token_minus then s.extend (c) i := i + 1 - c := a_number [i] + if i > n then + Result := False + else + c := a_number [i] + end end --| "0|[1-9]\d* - if c.is_digit then + if Result and c.is_digit then if c = '0' then --| "0" s.extend (c) i := i + 1 - c := a_number [i] + if i <= n then + c := a_number [i] + end else --| "[1-9]" s.extend (c) - i := i + 1 - c := a_number [i] + --| "\d*" - from - until - i > n or not c.is_digit - loop - s.extend (c) - i := i + 1 + i := i + 1 + if i <= n then c := a_number [i] + from + until + i > n or not c.is_digit + loop + s.extend (c) + i := i + 1 + if i <= n then + c := a_number [i] + end + end end end end end - if Result then - --| "(\.\d+)?" - if c = token_dot then - --| "\.\d+" = "\.\d\d*" - s.extend (c) - i := i + 1 - c := a_number [i] - if c.is_digit then - from - until - i > n or not c.is_digit - loop - s.extend (c) - i := i + 1 - c := a_number [i] - end - else - Result := False --| expecting digit - end - end - end - if Result then --| "(?:[eE][+-]?\d+)?\b" - if is_exp_token (c) then - --| "[eE][+-]?\d+" - s.extend (c) - i := i + 1 - c := a_number [i] - if c = token_plus or c = token_minus then + if i > n then + -- Exit + else + if Result then + --| "(\.\d+)?" + if c = token_dot then + --| "\.\d+" = "\.\d\d*" s.extend (c) i := i + 1 c := a_number [i] + if c.is_digit then + from + until + i > n or not c.is_digit + loop + s.extend (c) + i := i + 1 + if i <= n then + c := a_number [i] + end + end + else + Result := False --| expecting digit + end end - if c.is_digit then - from - until - i > n or not c.is_digit - loop + end + if Result then --| "(?:[eE][+-]?\d+)?\b" + if is_exp_token (c) then + --| "[eE][+-]?\d+" + s.extend (c) + i := i + 1 + c := a_number [i] + if c = token_plus or c = token_minus then s.extend (c) i := i + 1 - c := a_number [i] + if i <= n then + c := a_number [i] + end + end + if c.is_digit then + from + until + i > n or not c.is_digit + loop + s.extend (c) + i := i + 1 + if i <= n then + c := a_number [i] + end + end + else + Result := False --| expecting digit end - else - Result := False --| expecting digit end end - end - if Result then --| "\b" - from - until - i > n or not c.is_space - loop - s.extend (c) - i := i + 1 - c := a_number [i] + if Result then --| "\b" + from + until + i > n or not c.is_space + loop + s.extend (c) + i := i + 1 + if i <= n then + c := a_number [i] + end + end + Result := i > n and then s.same_string (a_number) end - Result := i > n and then s.same_string (a_number) end end @@ -651,6 +674,6 @@ feature {NONE} -- Constants null_id: STRING = "null" note - copyright: "2010-2014, Javier Velilla and others https://github.com/eiffelhub/json." + copyright: "2010-2015, Javier Velilla and others https://github.com/eiffelhub/json." license: "https://github.com/eiffelhub/json/blob/master/License.txt" end