Cosmetic + Optimization + Assertion + Void-safety

(no significant interface changes)
This commit is contained in:
jfiat
2009-03-18 15:29:41 +00:00
parent 1359a1ceae
commit 548a320448
13 changed files with 1367 additions and 1273 deletions

View File

@@ -14,20 +14,25 @@ indexing
class class
JSON_ARRAY JSON_ARRAY
inherit inherit
JSON_VALUE JSON_VALUE
DEBUG_OUTPUT
create create
make_array make_array
feature -- Initialization feature {NONE} -- Initialization
make_array is make_array is
-- -- Initialize JSON Array
do do
create values.make (10) create values.make (10)
end end
feature -- Access feature -- Access
i_th alias "[]" (i: INTEGER): JSON_VALUE is i_th alias "[]" (i: INTEGER): JSON_VALUE is
-- Item at `i'-th position -- Item at `i'-th position
require require
@@ -46,6 +51,7 @@ feature -- Visitor pattern
end end
feature -- Mesurement feature -- Mesurement
count: INTEGER is count: INTEGER is
-- Number of items. -- Number of items.
do do
@@ -53,6 +59,7 @@ feature -- Mesurement
end end
feature -- Status report feature -- Status report
valid_index (i: INTEGER): BOOLEAN is valid_index (i: INTEGER): BOOLEAN is
-- Is `i' a valid index? -- Is `i' a valid index?
do do
@@ -60,9 +67,10 @@ feature -- Status report
end end
feature -- Change Element feature -- Change Element
add (value: JSON_VALUE) is add (value: JSON_VALUE) is
require require
not_null:value /= void value_not_null: value /= void
do do
values.extend(value) values.extend(value)
ensure ensure
@@ -73,7 +81,7 @@ feature -- Change Element
feature -- Report feature -- Report
hash_code: INTEGER is hash_code: INTEGER is
-- -- Hash code value
do do
from from
values.start values.start
@@ -85,8 +93,8 @@ feature -- Report
values.forth values.forth
end end
Result := Result \\ values.count Result := Result \\ values.count
end end
feature -- Conversion feature -- Conversion
array_representation: ARRAYED_LIST [JSON_VALUE] is array_representation: ARRAYED_LIST [JSON_VALUE] is
@@ -95,8 +103,18 @@ feature -- Conversion
Result := values Result := values
end end
feature -- Status report
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
Result := count.out
end
feature {NONE} -- Implementation feature {NONE} -- Implementation
values: ARRAYED_LIST [JSON_VALUE] values: ARRAYED_LIST [JSON_VALUE]
-- Value container
invariant invariant
value_not_void: values /= Void value_not_void: values /= Void

View File

@@ -5,17 +5,15 @@ indexing
revision: "Revision 0.1" revision: "Revision 0.1"
class class
JSON_BOOLEAN JSON_BOOLEAN
inherit inherit
JSON_VALUE JSON_VALUE
create create
make_boolean make_boolean
feature -- Initialization feature {NONE} -- Initialization
make_boolean (an_item: BOOLEAN) is make_boolean (an_item: BOOLEAN) is
--Initialize. --Initialize.
@@ -28,7 +26,6 @@ feature -- Access
item: BOOLEAN item: BOOLEAN
-- Content -- Content
hash_code: INTEGER is hash_code: INTEGER is
-- Hash code value -- Hash code value
do do
@@ -44,6 +41,12 @@ feature -- Visitor pattern
a_visitor.visit_json_boolean (Current) a_visitor.visit_json_boolean (Current)
end end
feature -- Status report
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
Result := item.out
end
end end

View File

@@ -8,12 +8,13 @@ class
JSON_FILE_READER JSON_FILE_READER
feature -- Access feature -- Access
read_json_from(a_path:STRING):STRING is
read_json_from (a_path: STRING): ?STRING is
local local
l_file: PLAIN_TEXT_FILE l_file: PLAIN_TEXT_FILE
template_content: STRING template_content: STRING
l_last_string: ?STRING
do do
create l_file.make (a_path) create l_file.make (a_path)
-- We perform several checks until we make a real attempt to open the file. -- We perform several checks until we make a real attempt to open the file.
if not l_file.exists then if not l_file.exists then
@@ -25,7 +26,9 @@ read_json_from(a_path:STRING):STRING is
l_file.open_read l_file.open_read
create template_content.make_empty create template_content.make_empty
l_file.read_stream (l_file.count) l_file.read_stream (l_file.count)
template_content.append (l_file.last_string.twin) 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 Result := template_content
l_file.close l_file.close
end end

View File

@@ -6,6 +6,7 @@ indexing
class class
JSON_NULL JSON_NULL
inherit inherit
JSON_VALUE JSON_VALUE
@@ -16,6 +17,7 @@ feature --Access
do do
Result := null_value.hash_code Result := null_value.hash_code
end end
feature -- Visitor pattern feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR) is accept (a_visitor: JSON_VISITOR) is
@@ -25,6 +27,16 @@ feature -- Visitor pattern
a_visitor.visit_json_null (Current) a_visitor.visit_json_null (Current)
end end
feature {NONE}-- Implementation feature -- Status report
null_value:STRING is "null"
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
Result := null_value
end
feature {NONE}-- Implementation
null_value: STRING is "null"
end end

View File

@@ -10,19 +10,16 @@ class
JSON_NUMBER JSON_NUMBER
inherit inherit
JSON_VALUE JSON_VALUE
redefine redefine
is_equal is_equal
end end
create create
make_integer, make_integer,
make_real make_real
feature -- initialization feature {NONE} -- initialization
make_integer (an_argument: INTEGER) is make_integer (an_argument: INTEGER) is
-- Initialize an instance of JSON_NUMBER as INTEGER -- Initialize an instance of JSON_NUMBER as INTEGER
@@ -38,7 +35,6 @@ feature -- initialization
numeric_type := DOUBLE_TYPE numeric_type := DOUBLE_TYPE
end end
feature -- Access feature -- Access
item: STRING item: STRING
@@ -68,7 +64,13 @@ feature -- Status
Result := item.is_equal (other.item) Result := item.is_equal (other.item)
end end
feature -- Status report
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
Result := item
end
feature -- Implementation feature -- Implementation
@@ -77,9 +79,7 @@ feature -- Implementation
numeric_type: INTEGER numeric_type: INTEGER
invariant invariant
item_not_void: item /= Void item_not_void: item /= Void
end end

View File

@@ -10,27 +10,22 @@ An object is an unordered set of name/value pairs
{} {}
{"key","value"} {"key","value"}
]" ]"
author: "Javier Velilla" author: "Javier Velilla"
date: "2008/08/24" date: "2008/08/24"
revision: "Revision 0.1" revision: "Revision 0.1"
license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" license:"MIT (see http://www.opensource.org/licenses/mit-license.php)"
class class
JSON_OBJECT JSON_OBJECT
inherit inherit
JSON_VALUE JSON_VALUE
create create
make make
feature -- Initialization feature {NONE} -- Initialization
make is make is
-- Initialize -- Initialize
@@ -40,25 +35,21 @@ feature -- Initialization
feature -- Change Element feature -- Change Element
put (value: ?JSON_VALUE; key: JSON_STRING) is
put (value: JSON_VALUE ; key: JSON_STRING) is
-- Assuming there is no item of key `key', -- Assuming there is no item of key `key',
-- insert `value' with `key'. -- insert `value' with `key'.
require require
not_present: not has_key (key) key_not_present: not has_key (key)
local local
l_json_null: JSON_NULL l_value: ?JSON_VALUE
l_value: JSON_VALUE
do do
l_value := value l_value := value
if value = Void then if l_value = Void then
create l_json_null create {JSON_NULL} l_value
l_value:=l_json_null
end end
object.extend (l_value, key) object.extend (l_value, key)
end end
feature -- Access feature -- Access
has_key (key: JSON_STRING): BOOLEAN is has_key (key: JSON_STRING): BOOLEAN is
@@ -73,7 +64,7 @@ feature -- Access
Result := object.has_item (value) Result := object.has_item (value)
end end
item (key: JSON_STRING):JSON_VALUE is item (key: JSON_STRING): ?JSON_VALUE is
-- the json_value associated with a key. -- the json_value associated with a key.
do do
Result := object.item (key) Result := object.item (key)
@@ -94,8 +85,8 @@ feature -- Visitor pattern
a_visitor.visit_json_object (Current) a_visitor.visit_json_object (Current)
end end
feature -- Conversion feature -- Conversion
map_representation: HASH_TABLE [JSON_VALUE, JSON_STRING] is map_representation: HASH_TABLE [JSON_VALUE, JSON_STRING] is
--A representation that maps keys to values --A representation that maps keys to values
do do
@@ -106,7 +97,6 @@ feature -- Report
hash_code: INTEGER is hash_code: INTEGER is
-- Hash code value -- Hash code value
local
do do
from from
object.start object.start
@@ -121,10 +111,18 @@ feature -- Report
Result := Result.hash_code Result := Result.hash_code
end end
feature -- Status report
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
Result := object.count.out
end
feature {NONE} -- Implementation feature {NONE} -- Implementation
object: HASH_TABLE [JSON_VALUE, JSON_STRING] object: HASH_TABLE [JSON_VALUE, JSON_STRING]
-- Value container
invariant invariant
object_not_null: object /= Void object_not_null: object /= Void

View File

@@ -13,21 +13,18 @@ indexing
class class
JSON_STRING JSON_STRING
inherit inherit
JSON_VALUE JSON_VALUE
redefine redefine
is_equal is_equal
end end
create create
make_json make_json
feature -- Initialization feature {NONE} -- Initialization
make_json (an_item: STRING) is make_json (an_item: STRING) is
-- Initialize. -- Initialize.
@@ -37,7 +34,6 @@ feature -- Initialization
item := an_item item := an_item
end end
feature -- Access feature -- Access
item: STRING item: STRING
@@ -52,7 +48,6 @@ feature -- Visitor pattern
a_visitor.visit_json_string (Current) a_visitor.visit_json_string (Current)
end end
feature -- Comparison feature -- Comparison
is_equal (other: like Current): BOOLEAN is is_equal (other: like Current): BOOLEAN is
@@ -64,13 +59,14 @@ feature -- Comparison
feature -- Change Element feature -- Change Element
append (an_item: STRING)is append (a_string: STRING)is
-- Add an_item -- Add an_item
require
a_string_not_void: a_string /= Void
do do
item.append_string (an_item) item.append_string (a_string)
end end
feature -- Status report feature -- Status report
hash_code: INTEGER is hash_code: INTEGER is
@@ -79,8 +75,15 @@ feature -- Status report
Result := item.hash_code Result := item.hash_code
end end
invariant feature -- Status report
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
Result := item
end
invariant
value_not_void: item /= Void value_not_void: item /= Void
end end

View File

@@ -8,8 +8,6 @@ indexing
* null * null
* an object * an object
* an array * an array
]" ]"
author: "Javier Velilla" author: "Javier Velilla"
date: "2008/05/19" date: "2008/05/19"
@@ -21,9 +19,10 @@ deferred class
JSON_VALUE JSON_VALUE
inherit inherit
HASHABLE HASHABLE
DEBUG_OUTPUT
feature -- Visitor pattern feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR) is accept (a_visitor: JSON_VISITOR) is
@@ -33,4 +32,5 @@ feature -- Visitor pattern
a_visitor_not_void: a_visitor /= Void a_visitor_not_void: a_visitor /= Void
deferred deferred
end end
end end

View File

@@ -6,14 +6,13 @@ indexing
revision: "Revision 0.1" revision: "Revision 0.1"
class class
JSON_PARSER JSON_PARSER
inherit inherit
JSON_READER JSON_READER
JSON_TOKENS JSON_TOKENS
create create
make_parser make_parser
feature {NONE} -- Initialize feature {NONE} -- Initialize
@@ -25,170 +24,204 @@ feature {NONE} -- Initialize
do do
make (a_json) make (a_json)
is_parsed := True is_parsed := True
create current_errors.make_empty create errors.make
end end
feature -- Status report
feature -- Access
is_parsed: BOOLEAN is_parsed: BOOLEAN
-- Is parsed?
errors: LINKED_LIST [STRING]
-- Current errors
current_errors: STRING current_errors: STRING
-- Current errors as string
do
create Result.make_empty
from
errors.start
until
errors.after
loop
Result.append_string (errors.item + "%N")
errors.forth
end
end
feature -- Element change
report_error (e: STRING) is
-- Report error `e'
require
e_not_void: e /= Void
do
errors.force (e)
end
feature -- Commands feature -- Commands
parse_json: JSON_VALUE is parse_json: ?JSON_VALUE is
-- -- Parse JSON data `representation'
do do
Result := parse Result := parse
if extra_elements then if extra_elements then
is_parsed := false is_parsed := False
end end
end end
parse: JSON_VALUE is parse: ?JSON_VALUE is
-- -- Parse JSON data `representation'
local local
c: CHARACTER c: CHARACTER
do do
if is_parsed then if is_parsed then
skip_withe_spaces skip_white_spaces
c := actual c := actual
if c.is_equal (j_object_open) then inspect c
when j_OBJECT_OPEN then
Result := parse_object Result := parse_object
elseif c.is_equal (j_string) then when j_STRING then
Result := parse_string Result := parse_string
elseif c.is_equal (j_array_open) then when j_ARRAY_OPEN then
Result := parse_array Result := parse_array
elseif c.is_digit or c.is_equal (j_minus) then else
if c.is_digit or c = j_MINUS then
Result := parse_number Result := parse_number
elseif is_null then elseif is_null then
--
Result := create {JSON_NULL} Result := create {JSON_NULL}
next;next;next next
next
next
elseif is_true then elseif is_true then
Result := create {JSON_BOOLEAN}.make_boolean (true) Result := create {JSON_BOOLEAN}.make_boolean (True)
next;next;next next
next
next
elseif is_false then elseif is_false then
Result := create {JSON_BOOLEAN}.make_boolean (false) Result := create {JSON_BOOLEAN}.make_boolean (False)
next;next;next;next next
next
next
next
else else
is_parsed := false is_parsed := False
current_errors.append ("JSON is not well formed in parse") report_error ("JSON is not well formed in parse")
Result := void Result := Void
end end
end end
end end
ensure
is_parsed_implies_result_not_void: is_parsed implies Result /= Void
end
parse_object: JSON_OBJECT is parse_object: JSON_OBJECT is
-- object -- object
-- {} -- {}
-- {"key" : "value" [,]} -- {"key" : "value" [,]}
local local
has_more: BOOLEAN has_more: BOOLEAN
l_json_string: JSON_STRING l_json_string: ?JSON_STRING
l_value: JSON_VALUE l_value: ?JSON_VALUE
do do
create Result.make create Result.make
-- check if is an empty object {} -- check if is an empty object {}
next next
skip_withe_spaces skip_white_spaces
if actual.is_equal (j_object_close) then if actual = j_OBJECT_CLOSE then
--is an empty object --is an empty object
else else
-- a complex object {"key" : "value"} -- a complex object {"key" : "value"}
previous previous
from has_more := true until not has_more from has_more := True until not has_more loop
loop
next next
skip_withe_spaces skip_white_spaces
l_json_string := parse_string l_json_string := parse_string
next next
skip_withe_spaces skip_white_spaces
if actual.is_equal (':') then if actual = ':' then
next next
skip_withe_spaces skip_white_spaces
else else
is_parsed := false is_parsed := False
current_errors.append ("%N Input string is a not well formed JSON, expected: : found: " + actual.out +"%N") report_error ("%N Input string is a not well formed JSON, expected: : found: " + actual.out)
has_more := false has_more := False
end end
l_value := parse l_value := parse
if is_parsed then if is_parsed and then (l_value /= Void and l_json_string /= Void) then
Result.put (l_value, l_json_string) Result.put (l_value, l_json_string)
next next
skip_withe_spaces skip_white_spaces
if actual.is_equal (j_object_close) then if actual = j_OBJECT_CLOSE then
has_more := false has_more := False
elseif not actual.is_equal (',') then elseif actual /= ',' then
has_more := false has_more := False
is_parsed := false is_parsed := False
current_errors.append ("JSON Object sintactically malformed expected , found: [" + actual.out + "] %N") report_error ("JSON Object syntactically malformed expected , found: [" + actual.out + "]")
end end
else else
has_more := false has_more := False
-- explain the error -- explain the error
end end
end end
end end
end end
parse_string: JSON_STRING is parse_string: ?JSON_STRING is
-- -- Parsed string
local local
has_more: BOOLEAN has_more: BOOLEAN
l_json_string: STRING l_json_string: STRING
l_unicode: STRING l_unicode: STRING
c: like actual
do do
create l_json_string.make_empty create l_json_string.make_empty
if actual.is_equal (j_string) then if actual = j_STRING then
from from
has_more := true has_more := True
until not has_more until
not has_more
loop loop
next next
if actual.is_equal (j_string) then c := actual
has_more := false if c = j_STRING then
elseif actual.is_equal ('%H') then has_more := False
elseif c = '%H' then
next next
if actual.is_equal ('u') then c := actual
if c = 'u' then
create l_unicode.make_from_string ("\u") create l_unicode.make_from_string ("\u")
l_unicode.append (read_unicode) l_unicode.append (read_unicode)
c := actual
if is_a_valid_unicode (l_unicode) then if is_a_valid_unicode (l_unicode) then
l_json_string.append (l_unicode) l_json_string.append (l_unicode)
else else
has_more := false has_more := False
is_parsed := false is_parsed := False
current_errors.append ("Input String is not well formed JSON, expected a Unicode value, found [" + actual.out + " ] %N") report_error ("Input String is not well formed JSON, expected a Unicode value, found [" + c.out + " ]")
end end
elseif (not special_characters.has (actual) and not special_controls.has (actual)) or actual.is_equal ('%N') then elseif (not is_special_character (c) and not is_special_control (c)) or c = '%N' then
has_more := false has_more := False
is_parsed := false is_parsed := False
current_errors.append ("Input String is not well formed JSON, found [" + actual.out + " ] %N") report_error ("Input String is not well formed JSON, found [" + c.out + " ]")
else else
l_json_string.append ("\") l_json_string.append ("\")
l_json_string.append (actual.out) l_json_string.append (c.out)
end end
else else
if special_characters.has (actual) and not actual.is_equal ('/') then if is_special_character (c) and c /= '/' then
has_more := false has_more := False
is_parsed := false is_parsed := False
current_errors.append ("Input String is not well formed JSON, found [" + actual.out + " ] %N") report_error ("Input String is not well formed JSON, found [" + c.out + " ]")
else else
l_json_string.append (actual.out) l_json_string.append_character (c)
end end
end end
end end
create Result.make_json (l_json_string) create Result.make_json (l_json_string)
else else
Result := void Result := Void
end end
end end
@@ -198,137 +231,142 @@ feature -- Commands
-- [elements [,]] -- [elements [,]]
local local
flag: BOOLEAN flag: BOOLEAN
l_value: JSON_VALUE l_value: ?JSON_VALUE
c: like actual
do do
create Result.make_array create Result.make_array
--check if is an empty array [] --check if is an empty array []
next next
skip_withe_spaces skip_white_spaces
if actual.is_equal (j_array_close) then if actual = j_array_close then
--is an empty array --is an empty array
else else
previous previous
from from
flag := true flag := True
until until
not flag not flag
loop loop
next next
skip_withe_spaces skip_white_spaces
l_value := parse l_value := parse
if is_parsed then if is_parsed and then l_value /= Void then
Result.add (l_value) Result.add (l_value)
next next
skip_withe_spaces skip_white_spaces
if not actual.is_equal (j_array_close) and not actual.is_equal (',')then c := actual
flag := false if c = j_ARRAY_CLOSE then
is_parsed := false flag := False
current_errors.append ("Array is not well formed JSON, found [" + actual.out + " ] %N") elseif c /= ',' then
elseif actual.is_equal (j_array_close) then flag := False
flag := false is_parsed := False
report_error ("Array is not well formed JSON, found [" + c.out + " ]")
end end
else else
flag := false flag := False
current_errors.append ("Array is not well formed JSON, found [" + actual.out + " ] %N") report_error ("Array is not well formed JSON, found [" + actual.out + " ]")
end end
end end
end end
end end
parse_number: JSON_NUMBER is parse_number: ?JSON_NUMBER is
-- -- Parsed number
local local
sb: STRING sb: STRING
flag: BOOLEAN flag: BOOLEAN
is_integer: BOOLEAN is_integer: BOOLEAN
c: like actual
do do
create sb.make_empty create sb.make_empty
sb.append (actual.out) sb.append_character (actual)
from from
flag := true flag := True
until not flag until
not flag
loop loop
next next
if not has_next or close_tokens.has (actual) or actual.is_equal (',') c := actual
or actual.is_equal ('%N') or actual.is_equal ('%R') then if not has_next or is_close_token (c)
flag := false or c = ',' or c = '%N' or c = '%R'
then
flag := False
previous previous
else else
sb.append (actual.out) sb.append_character (c)
end end
end end
if is_a_valid_number (sb) then if is_a_valid_number (sb) then
if sb.is_integer then if sb.is_integer then
create Result.make_integer (sb.to_integer) create Result.make_integer (sb.to_integer)
is_integer := true is_integer := True
elseif sb.is_double and not is_integer then elseif sb.is_double and not is_integer then
create Result.make_real (sb.to_double) create Result.make_real (sb.to_double)
end end
else else
is_parsed := false is_parsed := False
current_errors.append ("Expected a number, found: [ " + sb + " ]") report_error ("Expected a number, found: [ " + sb + " ]")
end end
end end
is_null: BOOLEAN is is_null: BOOLEAN is
-- -- Word at index represents null?
local local
l_null: STRING l_null: STRING
l_string: STRING l_string: STRING
do do
l_null := "null" l_null := null_id
l_string := json_substring (index,index + l_null.count - 1) l_string := json_substring (index,index + l_null.count - 1)
if l_string.is_equal (l_null) then if l_string.is_equal (l_null) then
Result := true Result := True
end end
end end
is_false: BOOLEAN is is_false: BOOLEAN is
-- -- Word at index represents false?
local local
l_false: STRING l_false: STRING
l_string: STRING l_string: STRING
do do
l_false := "false" l_false := false_id
l_string := json_substring (index, index + l_false.count - 1) l_string := json_substring (index, index + l_false.count - 1)
if l_string.is_equal (l_false) then if l_string.is_equal (l_false) then
Result := true Result := True
end end
end end
is_true: BOOLEAN is is_true: BOOLEAN is
-- -- Word at index represents true?
local local
l_true: STRING l_true: STRING
l_string: STRING l_string: STRING
do do
l_true := "true" l_true := true_id
l_string := json_substring (index,index + l_true.count - 1) l_string := json_substring (index,index + l_true.count - 1)
if l_string.is_equal (l_true) then if l_string.is_equal (l_true) then
Result := true Result := True
end end
end end
read_unicode: STRING is read_unicode: STRING is
-- -- Read unicode and return value
local local
i: INTEGER i: INTEGER
do do
create Result.make_empty create Result.make_empty
from from
i := 1 i := 1
until i > 4 or not has_next until
i > 4 or not has_next
loop loop
next next
Result.append (actual.out) Result.append_character (actual)
i := i + 1 i := i + 1
end end
end end
feature {NONE} -- Implementation feature {NONE} -- Implementation
is_a_valid_number (a_number: STRING): BOOLEAN is is_a_valid_number (a_number: STRING): BOOLEAN is
@@ -348,9 +386,7 @@ feature {NONE} -- Implementation
number_regex := "-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?\b" number_regex := "-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?\b"
regexp.compile (number_regex) regexp.compile (number_regex)
if regexp.matches (a_number) then if regexp.matches (a_number) then
if a_number.is_equal (regexp.captured_substring (0)) then Result := a_number.is_equal (regexp.captured_substring (0))
Result := true
end
end end
end end
@@ -365,7 +401,7 @@ feature {NONE} -- Implementation
unicode_regex := "\\u[0-9a-fA-F]{4}" unicode_regex := "\\u[0-9a-fA-F]{4}"
regexp.compile (unicode_regex) regexp.compile (unicode_regex)
if regexp.matches (a_unicode) then if regexp.matches (a_unicode) then
Result := true Result := True
check check
is_valid: a_unicode.is_equal (regexp.captured_substring (0)) is_valid: a_unicode.is_equal (regexp.captured_substring (0))
end end
@@ -374,25 +410,29 @@ feature {NONE} -- Implementation
extra_elements: BOOLEAN is extra_elements: BOOLEAN is
-- has more elements? -- has more elements?
local
c: like actual
do do
if has_next then if has_next then
next next
end end
from from
c := actual
until until
not actual.is_equal (' ') or not actual.is_equal ('%R') or c /= ' ' or c /= '%R' or c /= '%U' or c /= '%T' or c /= '%N' or not has_next
not actual.is_equal ('%U') or not actual.is_equal ('%T')
or not actual.is_equal ('%N') or not has_next
loop loop
next next
end end
Result := has_next
if has_next then
Result := True
end end
end feature {NONE} -- Constants
false_id: STRING is "false"
true_id: STRING is "false"
null_id: STRING is "null"
end end

View File

@@ -1,56 +1,36 @@
indexing indexing
description: "Objects that ..." description: "Objects that ..."
author: "jvelilla" author: "jvelilla"
date: "2008/08/24" date: "2008/08/24"
revision: "0.1" revision: "0.1"
class class
JSON_READER JSON_READER
create create
make make
feature -- Initialization feature {NONE} -- Initialization
make (a_json: STRING) is make (a_json: STRING) is
-- -- Initialize Reader
do do
representation := a_json representation := a_json
index := 1 index := 1
end end
feature -- Commands feature -- Commands
read: CHARACTER is read: CHARACTER is
-- -- Read character
do do
if not representation.is_empty then if not representation.is_empty then
Result := representation.item (index) Result := representation.item (index)
end end
end end
has_next: BOOLEAN is
--
do
if index <= representation.count then
Result := True
end
end
has_previous: BOOLEAN is
--
do
if index >=1 then
Result := True
end
end
next is next is
-- -- Move to next index
require require
has_more_elements: has_next has_more_elements: has_next
do do
@@ -60,7 +40,7 @@ feature -- Commands
end end
previous is previous is
-- -- Move to previous index
require require
not_is_first: has_previous not_is_first: has_previous
do do
@@ -69,30 +49,46 @@ feature -- Commands
incremented: old index - 1 = index incremented: old index - 1 = index
end end
skip_white_spaces is
skip_withe_spaces is -- Remove white spaces
-- Remove withe spaces local
c: like actual
do do
from from
until (actual /= ' ' and actual /= '%N' and actual /= '%R') or not has_next c := actual
until
(c /= ' ' and c /= '%N' and c /= '%R') or not has_next
loop loop
next next
c := actual
end end
end end
json_substring (start_index, end_index: INTEGER_32): STRING is json_substring (start_index, end_index: INTEGER_32): STRING is
-- -- JSON representation between `start_index' and `end_index'
do do
Result := representation.substring (start_index, end_index) Result := representation.substring (start_index, end_index)
end end
feature -- Status report
has_next: BOOLEAN is
-- Has a next character?
do
Result := index <= representation.count
end
has_previous: BOOLEAN is
-- Has a previous character?
do
Result := index >= 1
end
feature -- Access feature -- Access
representation: STRING representation: STRING
-- Serialized representation of the original JSON string -- Serialized representation of the original JSON string
feature {NONE} -- Implementation feature {NONE} -- Implementation
actual: CHARACTER is actual: CHARACTER is
@@ -108,9 +104,7 @@ feature {NONE} -- Implementation
index: INTEGER index: INTEGER
-- Actual index -- Actual index
invariant invariant
representation_not_void: representation /= Void representation_not_void: representation /= Void
end end

View File

@@ -8,29 +8,42 @@ class
JSON_TOKENS JSON_TOKENS
feature -- Access feature -- Access
J_OBJECT_OPEN:CHARACTER is '{'
J_ARRAY_OPEN:CHARACTER is '['
J_OBJECT_CLOSE:CHARACTER is '}'
J_ARRAY_CLOSE:CHARACTER is ']'
J_STRING:CHARACTER is '"' j_OBJECT_OPEN: CHARACTER is '{'
J_PLUS:CHARACTER is '+' j_ARRAY_OPEN: CHARACTER is '['
J_MINUS:CHARACTER is '-' j_OBJECT_CLOSE: CHARACTER is '}'
J_DOT:CHARACTER is '.' j_ARRAY_CLOSE: CHARACTER is ']'
open_tokens:ARRAY[CHARACTER] is j_STRING: CHARACTER is '"'
-- Characters wich open a type j_PLUS: CHARACTER is '+'
once j_MINUS: CHARACTER is '-'
Result:=<<J_OBJECT_OPEN,J_ARRAY_OPEN,J_STRING,J_PLUS,J_MINUS,J_DOT>> j_DOT: CHARACTER is '.'
feature -- Status report
is_open_token (c: CHARACTER): BOOLEAN is
-- 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 end
close_tokens:ARRAY[CHARACTER] is is_close_token (c: CHARACTER): BOOLEAN is
-- Characters wich close a type -- Characters which close a type
once do
Result:=<<J_OBJECT_CLOSE,J_ARRAY_CLOSE,J_STRING >> inspect c
when j_OBJECT_CLOSE, j_ARRAY_CLOSE, j_STRING then
Result := True
else
end
end end
special_characters:ARRAY[CHARACTER] is is_special_character (c: CHARACTER): BOOLEAN is
-- Control Characters -- Control Characters
-- %F Form feed -- %F Form feed
-- %H backslasH -- %H backslasH
@@ -41,13 +54,24 @@ feature -- Access
-- / Solidus -- / Solidus
-- " Quotation -- " Quotation
do do
Result:=<<'%F','%H','%N','%R','%T','%B','/','"'>> inspect c
when '%F', '%H', '%N', '%R', '%T', '%B', '/', '"' then
Result := True
else
end
end end
special_controls:ARRAY[CHARACTER] is is_special_control (c: CHARACTER): BOOLEAN is
--Control Characters --Control Characters
-- \b\f\n\r\t -- \b\f\n\r\t
do do
Result:=<<'b','f','n','r','t'>> inspect c
when 'b', 'f', 'n', 'r', 't' then
Result := True
else
end end
end end
end

View File

@@ -35,7 +35,6 @@ feature -- Visitor Pattern
deferred deferred
end end
visit_json_number (a_json_number: JSON_NUMBER) is visit_json_number (a_json_number: JSON_NUMBER) is
-- Visit `a_json_number'. -- Visit `a_json_number'.
require require
@@ -57,5 +56,4 @@ feature -- Visitor Pattern
deferred deferred
end end
end end

View File

@@ -13,6 +13,7 @@ inherit
create make create make
feature -- Initialization feature -- Initialization
make is make is
-- Create a new instance -- Create a new instance
do do
@@ -23,6 +24,7 @@ feature -- Access
to_json: STRING to_json: STRING
-- JSON representation -- JSON representation
feature -- Visitor Pattern feature -- Visitor Pattern
visit_json_array (a_json_array: JSON_ARRAY) is visit_json_array (a_json_array: JSON_ARRAY) is
@@ -60,7 +62,6 @@ feature -- Visitor Pattern
to_json.append ("null") to_json.append ("null")
end end
visit_json_number (a_json_number: JSON_NUMBER) is visit_json_number (a_json_number: JSON_NUMBER) is
-- Visit `a_json_number'. -- Visit `a_json_number'.
do do