Fixed various issue with parsing string (such as \t and related),
Implemented escaping of slash '/' only in case of '</' to avoid potential issue with javascript and </script> Many feature renaming to match Eiffel style and naming convention, kept previous feature as obsolete. Restructured the library to make easy extraction of "converter" classes if needed in the future. Updated part of the code to use new feature names.
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -7,3 +7,4 @@
|
||||
*.ecf text
|
||||
*.bat text
|
||||
*.json text
|
||||
*.txt text
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +1,2 @@
|
||||
*.swp
|
||||
EIFGENs
|
||||
EIFGENs/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
History file for EJSON
|
||||
History file for EJSON
|
||||
======================
|
||||
|
||||
team: ""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -14,7 +14,7 @@ note
|
||||
class
|
||||
SHARED_EJSON
|
||||
|
||||
feature
|
||||
feature -- Access
|
||||
|
||||
json: EJSON
|
||||
-- A shared EJSON instance with default converters for
|
||||
@@ -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
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="json" uuid="4E21C3BD-7951-4C6E-A673-431E762D7414" library_target="json">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="json" uuid="4E21C3BD-7951-4C6E-A673-431E762D7414" library_target="json">
|
||||
<target name="json">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
@@ -9,20 +9,13 @@
|
||||
</file_rule>
|
||||
<option trace="false" profile="false" debug="false" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard" namespace="EJSON.Library">
|
||||
<assertions/>
|
||||
<warning name="export_class_missing" enabled="false"/>
|
||||
<warning name="old_verbatim_strings" enabled="false"/>
|
||||
<warning name="syntax" enabled="false"/>
|
||||
<warning name="vjrv" enabled="false"/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf" readonly="true"/>
|
||||
<cluster name="json" location=".\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>^/gobo$</exclude>
|
||||
<exclude>^/kernel$</exclude>
|
||||
<exclude>^/extras$</exclude>
|
||||
</file_rule>
|
||||
<cluster name="kernel" location=".\kernel\" recursive="true"/>
|
||||
<cluster name="extras" location=".\extras\" recursive="true"/>
|
||||
<cluster name="json" location=".\" >
|
||||
<cluster name="json_kernel" location=".\kernel" recursive="true"/>
|
||||
<cluster name="json_parser" location=".\parser" recursive="true"/>
|
||||
<cluster name="json_utility" location=".\utility" recursive="true"/>
|
||||
</cluster>
|
||||
<cluster name="json_converter" location=".\converter" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -9,20 +9,13 @@
|
||||
</file_rule>
|
||||
<option trace="false" profile="false" debug="false" warning="true" full_class_checking="true" void_safety="none" syntax="standard" namespace="EJSON.Library">
|
||||
<assertions/>
|
||||
<warning name="export_class_missing" enabled="false"/>
|
||||
<warning name="old_verbatim_strings" enabled="false"/>
|
||||
<warning name="syntax" enabled="false"/>
|
||||
<warning name="vjrv" enabled="false"/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf" readonly="true"/>
|
||||
<cluster name="json" location=".\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>^/gobo$</exclude>
|
||||
<exclude>^/kernel$</exclude>
|
||||
<exclude>^/extras$</exclude>
|
||||
</file_rule>
|
||||
<cluster name="kernel" location=".\kernel\" recursive="true"/>
|
||||
<cluster name="extras" location=".\extras\" recursive="true"/>
|
||||
<cluster name="json" location=".\" >
|
||||
<cluster name="json_kernel" location=".\kernel" recursive="true"/>
|
||||
<cluster name="json_parser" location=".\parser" recursive="true"/>
|
||||
<cluster name="json_utility" location=".\utility" recursive="true"/>
|
||||
</cluster>
|
||||
<cluster name="json_converter" location=".\converter" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf" readonly="true"/>
|
||||
<library name="json" location="json.ecf" readonly="true"/>
|
||||
<library name="gobo_structure" location="$ISE_LIBRARY\library\gobo\gobo_structure.ecf"/>
|
||||
<cluster name="json_gobo" location=".\gobo" recursive="true" />
|
||||
<cluster name="json_gobo_converter" location=".\gobo_converter" recursive="true" />
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -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
|
||||
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
|
||||
Result := Result \\ values.count
|
||||
end
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,14 +4,14 @@ note
|
||||
An object is an unordered set of name/value pairs
|
||||
|
||||
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]
|
||||
-- <Precursor>
|
||||
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
|
||||
@@ -275,7 +288,7 @@ feature -- Conversion
|
||||
map_representation: HASH_TABLE [JSON_VALUE, JSON_STRING]
|
||||
-- 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
|
||||
@@ -306,10 +319,10 @@ feature -- Status report
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
@@ -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')
|
||||
@@ -200,11 +257,11 @@ feature -- Conversion
|
||||
end
|
||||
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
|
||||
@@ -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 </script> ...
|
||||
-- escape only </ to <\/
|
||||
if s.valid_index (i - 1) and then s.item (i - 1) = '<' then
|
||||
Result.append_string ("\/")
|
||||
else
|
||||
Result.append_string ("/")
|
||||
end
|
||||
when '%B' then
|
||||
Result.append_string ("\b")
|
||||
when '%F' then
|
||||
@@ -426,7 +489,7 @@ feature {NONE} -- Implementation
|
||||
h.prepend_integer (0)
|
||||
end
|
||||
check
|
||||
h.count = 4
|
||||
hexastring_has_4_chars: h.count = 4
|
||||
end
|
||||
Result.append (h)
|
||||
end
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
note
|
||||
description: ""
|
||||
author: "jvelilla"
|
||||
date: "2008/08/24"
|
||||
revision: "0.1"
|
||||
|
||||
class
|
||||
JSON_TOKENS
|
||||
|
||||
feature -- Access
|
||||
|
||||
j_OBJECT_OPEN: CHARACTER = '{'
|
||||
|
||||
j_ARRAY_OPEN: CHARACTER = '['
|
||||
|
||||
j_OBJECT_CLOSE: CHARACTER = '}'
|
||||
|
||||
j_ARRAY_CLOSE: CHARACTER = ']'
|
||||
|
||||
j_STRING: CHARACTER = '"'
|
||||
|
||||
j_PLUS: CHARACTER = '+'
|
||||
|
||||
j_MINUS: CHARACTER = '-'
|
||||
|
||||
j_DOT: CHARACTER = '.'
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_open_token (c: CHARACTER): BOOLEAN
|
||||
-- Characters which open a type
|
||||
do
|
||||
inspect c
|
||||
when j_OBJECT_OPEN, j_ARRAY_OPEN, j_STRING, j_PLUS, j_MINUS, j_DOT then
|
||||
Result := True
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
is_close_token (c: CHARACTER): BOOLEAN
|
||||
-- Characters which close a type
|
||||
do
|
||||
inspect c
|
||||
when j_OBJECT_CLOSE, j_ARRAY_CLOSE, j_STRING then
|
||||
Result := True
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
is_special_character (c: CHARACTER): BOOLEAN
|
||||
-- Control Characters
|
||||
-- %F Form feed
|
||||
-- %H backslasH
|
||||
-- %N Newline
|
||||
-- %R carriage Return
|
||||
-- %T horizontal Tab
|
||||
-- %B Backspace
|
||||
-- / Solidus
|
||||
-- " Quotation
|
||||
do
|
||||
inspect c
|
||||
when '%F', '%H', '%N', '%R', '%T', '%B', '/', '"' then
|
||||
Result := True
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
is_special_control (c: CHARACTER): BOOLEAN
|
||||
--Control Characters
|
||||
-- \b\f\n\r\t
|
||||
do
|
||||
inspect c
|
||||
when 'b', 'f', 'n', 'r', 't' then
|
||||
Result := True
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -8,24 +8,36 @@ class
|
||||
JSON_PARSER
|
||||
|
||||
inherit
|
||||
|
||||
JSON_READER
|
||||
rename
|
||||
make as make_reader,
|
||||
reset as reset_reader
|
||||
end
|
||||
|
||||
JSON_TOKENS
|
||||
|
||||
create
|
||||
make_with_string,
|
||||
make_parser
|
||||
|
||||
feature {NONE} -- Initialize
|
||||
|
||||
make_with_string (a_content: STRING)
|
||||
-- Initialize parser with JSON content `a_content'.
|
||||
require
|
||||
a_content_not_empty: a_content /= Void and then not a_content.is_empty
|
||||
do
|
||||
create errors.make
|
||||
make_reader (a_content)
|
||||
reset
|
||||
end
|
||||
|
||||
make_parser (a_json: STRING)
|
||||
-- Initialize.
|
||||
require
|
||||
json_not_empty: a_json /= Void and then not a_json.is_empty
|
||||
obsolete
|
||||
"Use `make_with_string' [sept/2014]."
|
||||
do
|
||||
make (a_json)
|
||||
is_parsed := True
|
||||
create errors.make
|
||||
make_with_string (a_json)
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
@@ -33,23 +45,99 @@ feature -- Status report
|
||||
is_parsed: BOOLEAN
|
||||
-- Is parsed ?
|
||||
|
||||
is_valid: BOOLEAN
|
||||
-- Is valid?
|
||||
do
|
||||
Result := not has_error
|
||||
end
|
||||
|
||||
has_error: BOOLEAN
|
||||
-- Has error?
|
||||
|
||||
errors: LINKED_LIST [STRING]
|
||||
-- Current errors
|
||||
|
||||
current_errors: STRING
|
||||
-- Current errors as string
|
||||
errors_as_string: STRING
|
||||
-- String representation of `errors'.
|
||||
do
|
||||
create Result.make_empty
|
||||
from
|
||||
errors.start
|
||||
until
|
||||
errors.after
|
||||
across
|
||||
errors as ic
|
||||
loop
|
||||
Result.append_string (errors.item + "%N")
|
||||
errors.forth
|
||||
Result.append_string (ic.item)
|
||||
Result.append_character ('%N')
|
||||
end
|
||||
end
|
||||
|
||||
current_errors: STRING
|
||||
-- Current errors as string
|
||||
obsolete
|
||||
"USe errors_as_string [sept/2014]"
|
||||
do
|
||||
Result := errors_as_string
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
parsed_json_value: detachable JSON_VALUE
|
||||
-- Parsed json value if any.
|
||||
require
|
||||
is_parsed: is_parsed
|
||||
attribute
|
||||
ensure
|
||||
attached_result_if_valid: is_valid implies Result /= Void
|
||||
end
|
||||
|
||||
parsed_json_object: detachable JSON_OBJECT
|
||||
-- parsed json value as a JSON_OBJECT if it is an object.
|
||||
require
|
||||
is_parsed: is_parsed
|
||||
do
|
||||
if attached {JSON_OBJECT} parsed_json_value as j_object then
|
||||
Result := j_object
|
||||
end
|
||||
end
|
||||
|
||||
parsed_json_array: detachable JSON_ARRAY
|
||||
-- parsed json value as a JSON_OBJECT if it is an array.
|
||||
require
|
||||
is_parsed: is_parsed
|
||||
do
|
||||
if attached {JSON_ARRAY} parsed_json_value as j_array then
|
||||
Result := j_array
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Commands
|
||||
|
||||
reset
|
||||
-- Reset parsing values.
|
||||
do
|
||||
parsed_json_value := Void
|
||||
errors.wipe_out
|
||||
has_error := False
|
||||
is_parsed := False
|
||||
end
|
||||
|
||||
parse_content
|
||||
-- Parse JSON content `representation'.
|
||||
-- start ::= object | array
|
||||
do
|
||||
reset
|
||||
reset_reader
|
||||
|
||||
if is_valid_start_symbol then
|
||||
parsed_json_value := next_json_value
|
||||
if extra_elements then
|
||||
report_error ("Remaining element outside the main json value!")
|
||||
end
|
||||
else
|
||||
report_error ("Syntax error unexpected token, expecting `{' or `['")
|
||||
end
|
||||
is_parsed := is_valid
|
||||
end
|
||||
|
||||
|
||||
feature -- Element change
|
||||
|
||||
report_error (e: STRING)
|
||||
@@ -57,43 +145,64 @@ feature -- Element change
|
||||
require
|
||||
e_not_void: e /= Void
|
||||
do
|
||||
has_error := True
|
||||
errors.force (e)
|
||||
ensure
|
||||
has_error: has_error
|
||||
is_not_valid: not is_valid
|
||||
end
|
||||
|
||||
feature -- Commands
|
||||
feature -- Obsolete commands
|
||||
|
||||
parse_json: detachable JSON_VALUE
|
||||
-- Parse JSON data `representation'
|
||||
-- start ::= object | array
|
||||
obsolete
|
||||
"Use `parse_content' and `parsed_json_value' [sept/2014]."
|
||||
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 `['")
|
||||
parse_content
|
||||
if is_parsed then
|
||||
Result := parsed_json_value
|
||||
end
|
||||
end
|
||||
|
||||
parse: detachable JSON_VALUE
|
||||
-- Parse JSON data `representation'
|
||||
-- Next JSON value from current position on `representation'.
|
||||
obsolete
|
||||
"Use restricted `next_parsed_json_value' [sept/2014]."
|
||||
do
|
||||
Result := next_parsed_json_value
|
||||
end
|
||||
|
||||
feature {JSON_PARSER_ACCESS} -- Obsolete commands: restricted area
|
||||
|
||||
next_parsed_json_value: detachable JSON_VALUE
|
||||
-- Return next json value from current position.
|
||||
--| this does not call `reset_reader'.
|
||||
do
|
||||
reset
|
||||
Result := next_json_value
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: parsing
|
||||
|
||||
next_json_value: detachable JSON_VALUE
|
||||
-- Next JSON value from current position on `representation'.
|
||||
local
|
||||
c: CHARACTER
|
||||
do
|
||||
if is_parsed then
|
||||
if not has_error then
|
||||
skip_white_spaces
|
||||
c := actual
|
||||
inspect c
|
||||
when j_OBJECT_OPEN then
|
||||
when token_object_open then
|
||||
Result := parse_object
|
||||
when j_STRING then
|
||||
when token_double_quote then
|
||||
Result := parse_string
|
||||
when j_ARRAY_OPEN then
|
||||
when token_array_open then
|
||||
Result := parse_array
|
||||
else
|
||||
if c.is_digit or c = j_MINUS then
|
||||
if c.is_digit or c = token_minus then
|
||||
Result := parse_number
|
||||
elseif is_null then
|
||||
Result := create {JSON_NULL}
|
||||
@@ -101,25 +210,24 @@ feature -- Commands
|
||||
next
|
||||
next
|
||||
elseif is_true then
|
||||
Result := create {JSON_BOOLEAN}.make_boolean (True)
|
||||
Result := create {JSON_BOOLEAN}.make_true
|
||||
next
|
||||
next
|
||||
next
|
||||
elseif is_false then
|
||||
Result := create {JSON_BOOLEAN}.make_boolean (False)
|
||||
Result := create {JSON_BOOLEAN}.make_false
|
||||
next
|
||||
next
|
||||
next
|
||||
next
|
||||
else
|
||||
is_parsed := False
|
||||
report_error ("JSON is not well formed in parse")
|
||||
Result := Void
|
||||
end
|
||||
end
|
||||
end
|
||||
ensure
|
||||
is_parsed_implies_result_not_void: is_parsed implies Result /= Void
|
||||
is_parsed_implies_result_not_void: not has_error implies Result /= Void
|
||||
end
|
||||
|
||||
parse_object: JSON_OBJECT
|
||||
@@ -132,13 +240,13 @@ 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
|
||||
if actual = token_object_close then
|
||||
--| is an empty object
|
||||
else
|
||||
-- a complex object {"key" : "value"}
|
||||
--| a complex object {"key" : "value"}
|
||||
previous
|
||||
from
|
||||
has_more := True
|
||||
@@ -150,24 +258,22 @@ feature -- Commands
|
||||
l_json_string := parse_string
|
||||
next
|
||||
skip_white_spaces
|
||||
if actual = ':' then
|
||||
if actual = token_colon then --| token_colon = ':'
|
||||
next
|
||||
skip_white_spaces
|
||||
else
|
||||
is_parsed := False
|
||||
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
|
||||
l_value := next_json_value
|
||||
if not has_error and then (l_value /= Void and l_json_string /= Void) then
|
||||
Result.put (l_value, l_json_string)
|
||||
next
|
||||
skip_white_spaces
|
||||
if actual = j_OBJECT_CLOSE then
|
||||
if actual = token_object_close then
|
||||
has_more := False
|
||||
elseif actual /= ',' then
|
||||
elseif actual /= token_comma then
|
||||
has_more := False
|
||||
is_parsed := False
|
||||
report_error ("JSON Object syntactically malformed expected , found: [" + actual.out + "]")
|
||||
end
|
||||
else
|
||||
@@ -187,7 +293,7 @@ feature -- Commands
|
||||
c: like actual
|
||||
do
|
||||
create l_json_string.make_empty
|
||||
if actual = j_STRING then
|
||||
if actual = token_double_quote then
|
||||
from
|
||||
has_more := True
|
||||
until
|
||||
@@ -195,9 +301,9 @@ feature -- Commands
|
||||
loop
|
||||
next
|
||||
c := actual
|
||||
if c = j_STRING then
|
||||
if c = token_double_quote then
|
||||
has_more := False
|
||||
elseif c = '%H' then
|
||||
elseif c = '%H' then -- '%H' = '\' = reverse solidus
|
||||
next
|
||||
c := actual
|
||||
if c = 'u' then
|
||||
@@ -208,12 +314,10 @@ feature -- Commands
|
||||
l_json_string.append (l_unicode)
|
||||
else
|
||||
has_more := False
|
||||
is_parsed := False
|
||||
report_error ("Input String is not well formed JSON, expected a Unicode value, found [" + c.out + " ]")
|
||||
end
|
||||
elseif (not is_special_character (c) and not is_special_control (c)) or c = '%N' then
|
||||
has_more := False
|
||||
is_parsed := False
|
||||
report_error ("Input String is not well formed JSON, found [" + c.out + " ]")
|
||||
else
|
||||
l_json_string.append_character ('\')
|
||||
@@ -222,14 +326,13 @@ feature -- Commands
|
||||
else
|
||||
if is_special_character (c) and c /= '/' then
|
||||
has_more := False
|
||||
is_parsed := False
|
||||
report_error ("Input String is not well formed JSON, found [" + c.out + " ]")
|
||||
else
|
||||
l_json_string.append_character (c)
|
||||
end
|
||||
end
|
||||
end
|
||||
create Result.make_with_escaped_json (l_json_string)
|
||||
create Result.make_from_escaped_json_string (l_json_string)
|
||||
else
|
||||
Result := Void
|
||||
end
|
||||
@@ -244,11 +347,11 @@ feature -- Commands
|
||||
l_value: detachable JSON_VALUE
|
||||
c: like actual
|
||||
do
|
||||
create Result.make_array
|
||||
create Result.make_empty
|
||||
-- check if is an empty array []
|
||||
next
|
||||
skip_white_spaces
|
||||
if actual = j_array_close then
|
||||
if actual = token_array_close then
|
||||
-- is an empty array
|
||||
else
|
||||
previous
|
||||
@@ -259,17 +362,16 @@ feature -- Commands
|
||||
loop
|
||||
next
|
||||
skip_white_spaces
|
||||
l_value := parse
|
||||
if is_parsed and then l_value /= Void then
|
||||
l_value := next_json_value
|
||||
if not has_error and then l_value /= Void then
|
||||
Result.add (l_value)
|
||||
next
|
||||
skip_white_spaces
|
||||
c := actual
|
||||
if c = j_ARRAY_CLOSE then
|
||||
if c = token_array_close then
|
||||
flag := False
|
||||
elseif c /= ',' then
|
||||
elseif c /= token_comma then
|
||||
flag := False
|
||||
is_parsed := False
|
||||
report_error ("Array is not well formed JSON, found [" + c.out + " ]")
|
||||
end
|
||||
else
|
||||
@@ -297,7 +399,7 @@ 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 = token_comma or c = '%N' or c = '%R' then
|
||||
flag := False
|
||||
previous
|
||||
else
|
||||
@@ -312,7 +414,6 @@ feature -- Commands
|
||||
create Result.make_real (sb.to_double)
|
||||
end
|
||||
else
|
||||
is_parsed := False
|
||||
report_error ("Expected a number, found: [ " + sb + " ]")
|
||||
end
|
||||
end
|
||||
@@ -357,7 +458,7 @@ feature -- Commands
|
||||
end
|
||||
|
||||
read_unicode: STRING
|
||||
-- Read Unicode and return value
|
||||
-- Read unicode and return value.
|
||||
local
|
||||
i: INTEGER
|
||||
do
|
||||
@@ -392,30 +493,30 @@ feature {NONE} -- Implementation
|
||||
i := 1
|
||||
--| "-?"
|
||||
c := a_number [i]
|
||||
if c = '-' then
|
||||
s.extend (c);
|
||||
i := i + 1;
|
||||
if c = token_minus then
|
||||
s.extend (c)
|
||||
i := i + 1
|
||||
c := a_number [i]
|
||||
end
|
||||
--| "0|[1-9]\d*
|
||||
if c.is_digit then
|
||||
if c = '0' then
|
||||
--| "0"
|
||||
s.extend (c);
|
||||
i := i + 1;
|
||||
s.extend (c)
|
||||
i := i + 1
|
||||
c := a_number [i]
|
||||
else
|
||||
--| "[1-9]"
|
||||
s.extend (c);
|
||||
i := i + 1;
|
||||
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;
|
||||
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
|
||||
|
||||
9
library/parser/json_parser_access.e
Normal file
9
library/parser/json_parser_access.e
Normal file
@@ -0,0 +1,9 @@
|
||||
note
|
||||
description: "Inherit to access restricted feature from {JSON_PARSER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
JSON_PARSER_ACCESS
|
||||
|
||||
end
|
||||
@@ -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
|
||||
87
library/parser/json_tokens.e
Normal file
87
library/parser/json_tokens.e
Normal file
@@ -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
|
||||
46
library/utility/file/json_file_reader.e
Normal file
46
library/utility/file/json_file_reader.e
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 := "<script>tab=%T cr=%R newline=%N backslash=%H slash=/ end</script>"
|
||||
j := "<script>tab=\t cr=\r newline=\n backslash=\\ slash=/ end<\/script>"
|
||||
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))
|
||||
|
||||
create js.make_from_escaped_json_string ("tab=\t")
|
||||
assert ("js.item.same_string (%"tab=\t%")", js.item.same_string ("tab=\t"))
|
||||
create js.make_from_escaped_json_string (js.item)
|
||||
assert ("js.item.same_string (%"tab=\t%")", js.item.same_string ("tab=\t"))
|
||||
|
||||
|
||||
-- <\/script>
|
||||
create js.make_from_escaped_json_string ("<script>tab=\t<\/script>")
|
||||
assert ("js.item.same_string (%"<script>tab=\t<\/script>%")", js.item.same_string ("<script>tab=\t<\/script>"))
|
||||
assert ("js.unescaped_string_8.same_string (%"<script>tab=%%T</script>%")", js.unescaped_string_8.same_string ("<script>tab=%T</script>"))
|
||||
|
||||
create js.make_from_escaped_json_string (js.item)
|
||||
assert ("js.item.same_string (%"<script>tab=\t<\/script>%")", js.item.same_string ("<script>tab=\t<\/script>"))
|
||||
assert ("js.unescaped_string_8.same_string (%"<script>tab=%%T</script>%")", js.unescaped_string_8.same_string ("<script>tab=%T</script>"))
|
||||
|
||||
-- </script>
|
||||
create js.make_from_escaped_json_string ("<script>tab=\t</script>")
|
||||
assert ("js.item.same_string (%"<script>tab=\t</script>%")", js.item.same_string ("<script>tab=\t</script>"))
|
||||
assert ("js.unescaped_string_8.same_string (%"<script>tab=%%T</script>%")", js.unescaped_string_8.same_string ("<script>tab=%T</script>"))
|
||||
|
||||
create js.make_from_escaped_json_string (js.item)
|
||||
assert ("js.item.same_string (%"<script>tab=\t<\/script>%")", js.item.same_string ("<script>tab=\t</script>"))
|
||||
assert ("js.unescaped_string_8.same_string (%"<script>tab=%%T</script>%")", js.unescaped_string_8.same_string ("<script>tab=%T</script>"))
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -34,8 +33,8 @@ feature -- Tests Pass
|
||||
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
|
||||
|
||||
@@ -46,8 +45,8 @@ feature -- Tests Pass
|
||||
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
|
||||
|
||||
@@ -58,8 +57,8 @@ feature -- Tests Pass
|
||||
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,19 +68,18 @@ 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
|
||||
|
||||
feature -- Tests Failures
|
||||
|
||||
test_json_fail1
|
||||
--
|
||||
local
|
||||
@@ -89,8 +87,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -101,8 +99,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -113,8 +111,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -125,8 +123,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -137,11 +135,12 @@ feature -- Tests Failures
|
||||
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
|
||||
@@ -149,8 +148,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -161,8 +160,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -173,11 +172,12 @@ feature -- Tests Failures
|
||||
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
|
||||
@@ -185,11 +185,12 @@ feature -- Tests Failures
|
||||
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
|
||||
@@ -197,8 +198,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -209,8 +210,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -221,8 +222,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -233,8 +234,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -245,8 +246,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -257,8 +258,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -269,8 +270,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -281,8 +282,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -293,8 +294,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -305,8 +306,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -317,8 +318,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -329,11 +330,12 @@ feature -- Tests Failures
|
||||
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
|
||||
--
|
||||
local
|
||||
@@ -341,8 +343,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -353,8 +355,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -365,8 +367,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -377,11 +379,12 @@ feature -- Tests Failures
|
||||
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
|
||||
--
|
||||
local
|
||||
@@ -389,11 +392,12 @@ feature -- Tests Failures
|
||||
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
|
||||
--
|
||||
local
|
||||
@@ -401,11 +405,12 @@ feature -- Tests Failures
|
||||
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
|
||||
--
|
||||
local
|
||||
@@ -413,11 +418,12 @@ feature -- Tests Failures
|
||||
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
|
||||
--
|
||||
local
|
||||
@@ -425,11 +431,12 @@ feature -- Tests Failures
|
||||
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
|
||||
--
|
||||
local
|
||||
@@ -437,8 +444,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -449,8 +456,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -461,8 +468,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
@@ -473,8 +480,8 @@ feature -- Tests Failures
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="test_suite" uuid="EA141B17-6A21-4781-8B5F-E9939BAE968A">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="test_suite" uuid="EA141B17-6A21-4781-8B5F-E9939BAE968A">
|
||||
<target name="test_suite">
|
||||
<root cluster="test_suite" class="APPLICATION" feature="make"/>
|
||||
<file_rule>
|
||||
@@ -7,11 +7,11 @@
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="standard">
|
||||
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="transitional" syntax="standard">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="json" location="..\..\..\library\json-safe.ecf"/>
|
||||
<library name="json" location="..\..\..\library\json-safe.ecf" readonly="false"/>
|
||||
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
|
||||
<cluster name="test_suite" location=".\" recursive="true"/>
|
||||
</target>
|
||||
|
||||
Reference in New Issue
Block a user