New directory layout created

This commit is contained in:
paul.cohen
2010-03-08 15:28:47 +00:00
parent 6bef8ec387
commit 8cd53b87eb
19 changed files with 0 additions and 0 deletions

122
library/kernel/json_array.e Normal file
View File

@@ -0,0 +1,122 @@
indexing
description: "[
JSON_ARRAY represent an array in JSON.
An array in JSON is an ordered set of names.
Examples
array
[]
[elements]
]"
author: "Javier Velilla"
date: "2008/08/24"
revision: "Revision 0.1"
class
JSON_ARRAY
inherit
JSON_VALUE
DEBUG_OUTPUT
create
make_array
feature {NONE} -- Initialization
make_array is
-- Initialize JSON Array
do
create values.make (10)
end
feature -- Access
i_th alias "[]" (i: INTEGER): JSON_VALUE is
-- Item at `i'-th position
require
is_valid_index: valid_index (i)
do
Result := values.i_th (i)
end
feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR) is
-- Accept `a_visitor'.
-- (Call `visit_json_array' procedure on `a_visitor'.)
do
a_visitor.visit_json_array (Current)
end
feature -- Mesurement
count: INTEGER is
-- Number of items.
do
Result := values.count
end
feature -- Status report
valid_index (i: INTEGER): BOOLEAN is
-- Is `i' a valid index?
do
Result := (1 <= i) and (i <= count)
end
feature -- Change Element
add (value: JSON_VALUE) is
require
value_not_null: value /= void
do
values.extend(value)
ensure
has_new_value: old values.count + 1 = values.count and
values.has (value)
end
feature -- Report
hash_code: INTEGER is
-- Hash code value
do
from
values.start
Result := values.item.hash_code
until
values.off
loop
Result:= ((Result \\ 8388593) |<< 8) + values.item.hash_code
values.forth
end
Result := Result \\ values.count
end
feature -- Conversion
array_representation: ARRAYED_LIST [JSON_VALUE] is
-- Representation as a sequences of values
do
Result := values
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
values: ARRAYED_LIST [JSON_VALUE]
-- Value container
invariant
value_not_void: values /= Void
end

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,130 @@
indexing
description: "[
An JSON_OBJECT represent an object in JSON.
An object is an unordered set of name/value pairs
Examples:
object
{}
{"key","value"}
]"
author: "Javier Velilla"
date: "2008/08/24"
revision: "Revision 0.1"
license:"MIT (see http://www.opensource.org/licenses/mit-license.php)"
class
JSON_OBJECT
inherit
JSON_VALUE
create
make
feature {NONE} -- Initialization
make is
-- Initialize
do
create object.make (10)
end
feature -- Change Element
put (value: ?JSON_VALUE; key: JSON_STRING) is
-- Assuming there is no item of key `key',
-- insert `value' with `key'.
require
key_not_present: not has_key (key)
local
l_value: ?JSON_VALUE
do
l_value := value
if l_value = Void then
create {JSON_NULL} l_value
end
object.extend (l_value, key)
end
feature -- Access
has_key (key: JSON_STRING): BOOLEAN is
-- has the JSON_OBJECT contains a specific key 'key'.
do
Result := object.has (key)
end
has_item (value: JSON_VALUE): BOOLEAN is
-- has the JSON_OBJECT contain a specfic item 'value'
do
Result := object.has_item (value)
end
item (key: JSON_STRING): ?JSON_VALUE is
-- the json_value associated with a key.
do
Result := object.item (key)
end
current_keys: ARRAY [JSON_STRING] is
-- array containing actually used keys
do
Result := object.current_keys
end
feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR) is
-- Accept `a_visitor'.
-- (Call `visit_json_object' procedure on `a_visitor'.)
do
a_visitor.visit_json_object (Current)
end
feature -- Conversion
map_representation: HASH_TABLE [JSON_VALUE, JSON_STRING] is
--A representation that maps keys to values
do
Result := object
end
feature -- Report
hash_code: INTEGER is
-- Hash code value
do
from
object.start
Result := object.item_for_iteration.hash_code
until
object.off
loop
Result := ((Result \\ 8388593) |<< 8) + object.item_for_iteration.hash_code
object.forth
end
-- Ensure it is a positive value.
Result := Result.hash_code
end
feature -- Status report
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
Result := object.count.out
end
feature {NONE} -- Implementation
object: HASH_TABLE [JSON_VALUE, JSON_STRING]
-- Value container
invariant
object_not_null: object /= Void
end

View File

@@ -0,0 +1,89 @@
indexing
description:"[
A JSON_STRING represent a string in JSON.
A string is a collection of zero or more Unicodes characters, wrapped in double
quotes, using blackslash espaces.
]"
author: "Javier Velilla"
date: "2008/08/24"
revision: "Revision 0.1"
license:"MIT (see http://www.opensource.org/licenses/mit-license.php)"
class
JSON_STRING
inherit
JSON_VALUE
redefine
is_equal
end
create
make_json
feature {NONE} -- Initialization
make_json (an_item: STRING) is
-- Initialize.
require
item_not_void: an_item /= Void
do
item := an_item
end
feature -- Access
item: STRING
-- Contents
feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR) is
-- Accept `a_visitor'.
-- (Call `visit_json_string' procedure on `a_visitor'.)
do
a_visitor.visit_json_string (Current)
end
feature -- Comparison
is_equal (other: like Current): BOOLEAN is
-- Is JSON_STRING made of same character sequence as `other'
-- (possibly with a different capacity)?
do
Result := item.is_equal (other.item)
end
feature -- Change Element
append (a_string: STRING)is
-- Add an_item
require
a_string_not_void: a_string /= Void
do
item.append_string (a_string)
end
feature -- Status report
hash_code: INTEGER is
-- Hash code value
do
Result := item.hash_code
end
feature -- Status report
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
Result := item
end
invariant
value_not_void: item /= Void
end

View File

@@ -0,0 +1,36 @@
indexing
description:"[
JSON_VALUE represent a value in JSON.
A value can be
* a string in double quotes
* a number
* boolean value(true, false )
* null
* an object
* an array
]"
author: "Javier Velilla"
date: "2008/05/19"
revision: "Revision 0.1"
license:"MIT (see http://www.opensource.org/licenses/mit-license.php)"
deferred class
JSON_VALUE
inherit
HASHABLE
DEBUG_OUTPUT
feature -- Visitor pattern
accept (a_visitor: JSON_VISITOR) is
-- Accept `a_visitor'.
-- (Call `visit_*' procedure on `a_visitor'.)
require
a_visitor_not_void: a_visitor /= Void
deferred
end
end

View File

@@ -0,0 +1,446 @@
indexing
description: "Parse serialized JSON data"
author: "jvelilla"
date: "2008/08/24"
revision: "Revision 0.1"
class
JSON_PARSER
inherit
JSON_READER
JSON_TOKENS
create
make_parser
feature {NONE} -- Initialize
make_parser (a_json: STRING) is
-- Initialize.
require
json_not_empty: a_json /= Void and then not a_json.is_empty
do
make (a_json)
is_parsed := True
create errors.make
end
feature -- Status report
is_parsed: BOOLEAN
-- Is parsed?
errors: LINKED_LIST [STRING]
-- Current errors
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
parse_json: ?JSON_VALUE is
-- Parse JSON data `representation'
-- start ::= object | array
do
if is_valid_start_symbol then
Result := parse
if extra_elements then
is_parsed := False
end
else
is_parsed := False
report_error ("Syntax error unexpected token, expecting `{' or `['")
end
end
parse: ?JSON_VALUE is
-- Parse JSON data `representation'
local
c: CHARACTER
do
if is_parsed then
skip_white_spaces
c := actual
inspect c
when j_OBJECT_OPEN then
Result := parse_object
when j_STRING then
Result := parse_string
when j_ARRAY_OPEN then
Result := parse_array
else
if c.is_digit or c = j_MINUS then
Result := parse_number
elseif is_null then
Result := create {JSON_NULL}
next
next
next
elseif is_true then
Result := create {JSON_BOOLEAN}.make_boolean (True)
next
next
next
elseif is_false then
Result := create {JSON_BOOLEAN}.make_boolean (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
end
parse_object: JSON_OBJECT is
-- object
-- {}
-- {"key" : "value" [,]}
local
has_more: BOOLEAN
l_json_string: ?JSON_STRING
l_value: ?JSON_VALUE
do
create Result.make
-- check if is an empty object {}
next
skip_white_spaces
if actual = j_OBJECT_CLOSE then
--is an empty object
else
-- a complex object {"key" : "value"}
previous
from has_more := True until not has_more loop
next
skip_white_spaces
l_json_string := parse_string
next
skip_white_spaces
if actual = ':' then
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
Result.put (l_value, l_json_string)
next
skip_white_spaces
if actual = j_OBJECT_CLOSE then
has_more := False
elseif actual /= ',' then
has_more := False
is_parsed := False
report_error ("JSON Object syntactically malformed expected , found: [" + actual.out + "]")
end
else
has_more := False
-- explain the error
end
end
end
end
parse_string: ?JSON_STRING is
-- Parsed string
local
has_more: BOOLEAN
l_json_string: STRING
l_unicode: STRING
c: like actual
do
create l_json_string.make_empty
if actual = j_STRING then
from
has_more := True
until
not has_more
loop
next
c := actual
if c = j_STRING then
has_more := False
elseif c = '%H' then
next
c := actual
if c = 'u' then
create l_unicode.make_from_string ("\u")
l_unicode.append (read_unicode)
c := actual
if is_a_valid_unicode (l_unicode) then
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 ("\")
l_json_string.append (c.out)
end
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_json (l_json_string)
else
Result := Void
end
end
parse_array: JSON_ARRAY is
-- array
-- []
-- [elements [,]]
local
flag: BOOLEAN
l_value: ?JSON_VALUE
c: like actual
do
create Result.make_array
--check if is an empty array []
next
skip_white_spaces
if actual = j_array_close then
--is an empty array
else
previous
from
flag := True
until
not flag
loop
next
skip_white_spaces
l_value := parse
if is_parsed and then l_value /= Void then
Result.add (l_value)
next
skip_white_spaces
c := actual
if c = j_ARRAY_CLOSE then
flag := False
elseif c /= ',' then
flag := False
is_parsed := False
report_error ("Array is not well formed JSON, found [" + c.out + " ]")
end
else
flag := False
report_error ("Array is not well formed JSON, found [" + actual.out + " ]")
end
end
end
end
parse_number: ?JSON_NUMBER is
-- Parsed number
local
sb: STRING
flag: BOOLEAN
is_integer: BOOLEAN
c: like actual
do
create sb.make_empty
sb.append_character (actual)
from
flag := True
until
not flag
loop
next
c := actual
if not has_next or is_close_token (c)
or c = ',' or c = '%N' or c = '%R'
then
flag := False
previous
else
sb.append_character (c)
end
end
if is_a_valid_number (sb) then
if sb.is_integer then
create Result.make_integer (sb.to_integer)
is_integer := True
elseif sb.is_double and not is_integer then
create Result.make_real (sb.to_double)
end
else
is_parsed := False
report_error ("Expected a number, found: [ " + sb + " ]")
end
end
is_null: BOOLEAN is
-- Word at index represents null?
local
l_null: STRING
l_string: STRING
do
l_null := null_id
l_string := json_substring (index,index + l_null.count - 1)
if l_string.is_equal (l_null) then
Result := True
end
end
is_false: BOOLEAN is
-- Word at index represents false?
local
l_false: STRING
l_string: STRING
do
l_false := false_id
l_string := json_substring (index, index + l_false.count - 1)
if l_string.is_equal (l_false) then
Result := True
end
end
is_true: BOOLEAN is
-- Word at index represents true?
local
l_true: STRING
l_string: STRING
do
l_true := true_id
l_string := json_substring (index,index + l_true.count - 1)
if l_string.is_equal (l_true) then
Result := True
end
end
read_unicode: STRING is
-- Read unicode and return value
local
i: INTEGER
do
create Result.make_empty
from
i := 1
until
i > 4 or not has_next
loop
next
Result.append_character (actual)
i := i + 1
end
end
feature {NONE} -- Implementation
is_a_valid_number (a_number: STRING): BOOLEAN is
-- is 'a_number' a valid number based on this regular expression
-- "-?(?: 0|[1-9]\d+)(?: \.\d+)?(?: [eE][+-]?\d+)?\b"?
do
Result := a_number.is_real_sequence
end
is_a_valid_unicode (a_unicode: STRING): BOOLEAN is
-- is 'a_unicode' a valid unicode based on this regular expression
-- "\\u[0-9a-fA-F]{4}"
local
i: INTEGER
do
if
a_unicode.count = 6 and then
a_unicode.item (1) = '\' and then
a_unicode.item (2) = 'u'
then
from
Result := True
i := 3
until
i > 6
loop
inspect a_unicode.item (i)
when '0'..'9', 'a'..'f', 'A'..'F' then
else
Result := False
i := 6
end
i := i + 1
end
end
end
extra_elements: BOOLEAN is
-- has more elements?
local
c: like actual
do
if has_next then
next
end
from
c := actual
until
c /= ' ' or c /= '%R' or c /= '%U' or c /= '%T' or c /= '%N' or not has_next
loop
next
end
Result := has_next
end
is_valid_start_symbol : BOOLEAN
-- expecting `{' or `[' as start symbol
do
Result := representation.starts_with ("{") or representation.starts_with ("[")
end
feature {NONE} -- Constants
false_id: STRING is "false"
true_id: STRING is "true"
null_id: STRING is "null"
end

View File

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

View File

@@ -0,0 +1,77 @@
indexing
description: ""
author: "jvelilla"
date: "2008/08/24"
revision: "0.1"
class
JSON_TOKENS
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_PLUS: CHARACTER is '+'
j_MINUS: CHARACTER is '-'
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
is_close_token (c: CHARACTER): BOOLEAN is
-- 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 is
-- 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 is
--Control Characters
-- \b\f\n\r\t
do
inspect c
when 'b', 'f', 'n', 'r', 't' then
Result := True
else
end
end
end