eJson initial import

This commit is contained in:
jvelilla
2008-05-24 14:23:27 +00:00
commit 308fa7f2e7
13 changed files with 854 additions and 0 deletions

23
json/json.ecf Normal file
View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-3-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-3-0 http://www.eiffel.com/developers/xml/configuration-1-3-0.xsd" name="json" uuid="4E21C3BD-7951-4C6E-A673-431E762D7414" library_target="json">
<target name="json">
<root all_classes="true"/>
<option namespace="EJSON.Library">
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<cluster name="json" location=".\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
</file_rule>
<file_rule>
<exclude>^/scanner$</exclude>
</file_rule>
<cluster name="scanner" location=".\scanner\"/>
</cluster>
</target>
<target name="json_dotnet" extends="json">
<setting name="msil_generation" value="true"/>
</target>
</system>

1
json/json.rc Normal file
View File

@@ -0,0 +1 @@

87
json/json_array.e Normal file
View File

@@ -0,0 +1,87 @@
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: "$Date$"
revision: "$Revision$"
class
JSON_ARRAY
inherit
JSON_VALUE
create
make_array
feature -- Initialization
make_array is
--
do
create values.make (10)
end
feature -- Access
feature -- Change Element
add(value:JSON_VALUE) is
require
not_null:value /= void
local
l_json_value:JSON_VALUE
do
values.extend(value)
ensure
has_new_value:old values.count + 1 = values.count
end
to_json:STRING is
--Printable json representation
-- [] or [elements]
local
value:JSON_VALUE
do
create Result.make_empty
Result.append("[")
from
values.start
until
values.off
loop
value:=values.item
Result.append(value.to_json)
values.forth
if not values.after then
Result.append(",")
end
end
Result.append("]")
end
hash_code:INTEGER is
--
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 {NONE} --Implementation
values:ARRAYED_LIST[JSON_VALUE]
end

39
json/json_boolean.e Normal file
View File

@@ -0,0 +1,39 @@
indexing
description: "JSON Truth values"
author: "Javier Velilla"
date: "$Date$"
revision: "$Revision$"
class
JSON_BOOLEAN
inherit
JSON_VALUE
create
make_boolean
feature -- Initialization
make_boolean(a_value:BOOLEAN) is
--
do
value:=a_value
end
feature -- Access
to_json:STRING is
--
do
Result:=value.out
end
hash_code:INTEGER is
--
do
Result:=value.hash_code
end
value:BOOLEAN
end

35
json/json_file_reader.e Normal file
View File

@@ -0,0 +1,35 @@
indexing
description: "Objects that ..."
author: ""
date: "$Date$"
revision: "$Revision$"
class
JSON_FILE_READER
feature -- Access
read_json_from(a_path:STRING):STRING is
local
l_file: PLAIN_TEXT_FILE
template_content:STRING
do
create l_file.make (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)
template_content.append (l_file.last_string.twin)
Result := template_content
l_file.close
end
end
end
end

27
json/json_null.e Normal file
View File

@@ -0,0 +1,27 @@
indexing
description: "JSON Null Values"
author: "Javier Velilla"
date: "$Date$"
revision: "$Revision$"
class
JSON_NULL
inherit
JSON_VALUE
feature --Access
to_json:STRING is
--
do
Result:=null_value
end
hash_code:INTEGER is
--
do
Result:= null_value.hash_code
end
feature -- Implementation
null_value:STRING is "null"
end

59
json/json_number.e Normal file
View File

@@ -0,0 +1,59 @@
indexing
description: "JSON Numbers, octal and hexadecimal formats are not used."
author: "Javier Velilla"
date: "$Date$"
revision: "$Revision$"
license:"MIT (see http://www.opensource.org/licenses/mit-license.php)"
class
JSON_NUMBER
inherit
JSON_VALUE
rename is_equal as is_equal_json_value
end
create
make_integer,
make_real
feature -- initialization
make_integer(argument:INTEGER) is
do
value:= argument.out
internal_hash_code:=argument.hash_code
numeric_type:="INTEGER"
end
make_real(argument:REAL) is
do
value:= argument.out
internal_hash_code:=argument.hash_code
numeric_type:="REAL"
end
feature -- Access
to_json:STRING is
--
do
Result:=value
end
hash_code:INTEGER is
--
do
Result:=internal_hash_code
end
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:=value.is_equal(other.to_json)
end
feature -- Implementation
value:STRING
internal_hash_code:INTEGER
numeric_type:STRING -- REAL or INTEGER
end

100
json/json_object.e Normal file
View File

@@ -0,0 +1,100 @@
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: "$Date$"
revision: "$Revision$"
license:"MIT (see http://www.opensource.org/licenses/mit-license.php)"
class
JSON_OBJECT
inherit
JSON_VALUE
create
make
feature -- Initialization
make is
--
do
create object.make (10)
end
feature -- Change Element
put(key:JSON_STRING; value:JSON_VALUE) is
--
local
l_json_null:JSON_NULL
l_value:JSON_VALUE
do
l_value:=value
if value = void then
create l_json_null
l_value:=l_json_null
end
object.extend(key, l_value)
end
feature -- Report
to_json:STRING is
-- Printable json representation
-- {} or {member}
-- see documentation
do
create Result.make_empty
Result.append ("{")
from
object.start
until
object.off
loop
Result.append (object.item_for_iteration.to_json)
Result.append (":")
Result.append (object.key_for_iteration.to_json)
object.forth
if not object.after then
Result.append (",")
end
end
Result.append ("}")
end
hash_code: INTEGER is
-- Hash code value
local
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 -- Implementation
object:HASH_TABLE[JSON_STRING,JSON_VALUE]
end

63
json/json_string.e Normal file
View File

@@ -0,0 +1,63 @@
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: "$Date$"
revision: "$Revision$"
license:"MIT (see http://www.opensource.org/licenses/mit-license.php)"
class
JSON_STRING
inherit
JSON_VALUE
rename
is_equal as is_equal_json
end
create
make_json
feature -- Initialization
make_json(value:STRING) is
--
do
create buffer.make(256)
buffer.append (value)
end
feature -- Access
feature -- Change Element
append(value:STRING)is
--
do
buffer.append (value)
end
feature -- Status report
to_json:STRING is
--
do
create Result.make_empty
Result.append ("%"")
Result.append (buffer)
Result.append ("%"")
end
hash_code:INTEGER is
--
do
Result:= buffer.hash_code + buffer.count
end
feature {NONE} -- Implementation
buffer:STRING
invariant
invariant_clause: True -- Your invariant here
end

32
json/json_value.e Normal file
View File

@@ -0,0 +1,32 @@
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
feature -- Access
to_json:STRING is
-- Generate the JSON String for this value object
-- return a correct JSON-STRING
deferred
end
end

258
json/scanner/json_parser.e Normal file
View File

@@ -0,0 +1,258 @@
indexing
description: "Objects that ..."
author: ""
date: "$Date$"
revision: "$Revision$"
class
JSON_PARSER
inherit
JSON_READER
JSON_TOKENS
create
make_parser
feature -- Access
make_parser(a_json:STRING) is
--
do
make(a_json)
end
parse:JSON_VALUE is
--
local
c:CHARACTER
do
skip_withe_spaces
c:=actual
if c.is_equal (j_object_open) then
Result:=parse_object
elseif c.is_equal (j_string) then
Result:=parse_string
elseif c.is_equal (j_array_open) then
Result:=parse_array
elseif c.is_digit or c.is_equal (j_minus) or
c.is_equal (j_plus) or c.is_equal (j_dot) 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
Result:=void
end
rescue
handle_syntax_exception
retry
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_withe_spaces
if actual.is_equal (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_withe_spaces
l_json_string:=parse_string
next
skip_withe_spaces
if actual.is_equal (':') then
next
skip_withe_spaces
else
excpetions.raise("%N Input string is a not well formed JSON, expected: %":%", found:" +actual.out +"%N")
has_more:=false
end
l_value:=parse
Result.put (l_json_string, l_value)
next
skip_withe_spaces
if actual.is_equal (j_object_close) then
has_more:=false
elseif not actual.is_equal (',') then
has_more:=false
excpetions.raise("JSON Object sintactically malformed expected :%"'%" ")
end
end
end
end
parse_string:JSON_STRING is
--
local
has_more:BOOLEAN
l_json_string:STRING
do
create l_json_string.make_empty
if actual.is_equal (j_string) then
from
has_more:=true
until not has_more
loop
next
if actual.is_equal (j_string) then
has_more:=false
elseif close_tokens.has (actual) then
has_more:=false
excpetions.raise("Input String is not well formed JSON, expected %"")
else
l_json_string.append (actual.out)
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
do
create Result.make_array
--check if is an empty array []
next
skip_withe_spaces
if actual.is_equal (j_array_close) then
--is an empty array
else
previous
from
flag:=true
until
not flag
loop
next
skip_withe_spaces
l_value := parse
Result.add (l_value)
next
skip_withe_spaces
if not actual.is_equal (j_array_close) and not actual.is_equal (',')then
flag:=false
excpetions.raise("%NInput string is not well formed JSON, expected: ',' or ']', and found: " +actual.out+"%N")
elseif actual.is_equal (j_array_close) then
flag:= false
end
end
end
end
parse_number:JSON_NUMBER is
--
local
sb:STRING
flag:BOOLEAN
do
create sb.make_empty
if not actual.is_equal (j_plus) then
sb.append (actual.out)
end
from
flag:=true
until not flag
loop
next
if not has_next or close_tokens.has (actual) or actual.is_equal (',')
or actual.is_equal ('%N') or actual.is_equal ('%R') then
flag:=false
previous
else
sb.append (actual.out)
end
end
if sb.is_double then
create Result.make_real (sb.to_double)
elseif sb.is_integer then
create Result.make_integer (sb.to_integer)
else
excpetions.raise ("Input string is an not well formed JSON")
-- print ("Input string is an not well formed JSON")
end
end
is_null:BOOLEAN is
--
local
l_null:STRING
l_string:STRING
do
l_null:="null"
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
--
local
l_false:STRING
l_string:STRING
do
l_false:="false"
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
--
local
l_true:STRING
l_string:STRING
do
l_true:="true"
l_string:=json_substring (index,index + l_true.count - 1)
if l_string.is_equal (l_true) then
Result := true
end
end
feature {NONE}
handle_syntax_exception is
--
do
next
end
excpetions:EXCEPTIONS once
create Result
end
end

View File

@@ -0,0 +1,97 @@
indexing
description: "Objects that ..."
author: ""
date: "$Date$"
revision: "$Revision$"
class
JSON_READER
create
make
feature -- Access
make(a_json:STRING) is
--
do
representation:=a_json
index:=1
end
read:CHARACTER is
--
do
if not representation.is_empty then
Result:= representation.item (index)
end
end
actual:CHARACTER is
--
do
Result:=representation.item (index)
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
--
require
has_more_elements: has_next
do
index:=index + 1
ensure
incremented: old index + 1 = index
end
previous is
--
require
not_is_first: has_previous
do
index:=index - 1
ensure
incremented: old index - 1 = index
end
skip_withe_spaces is
-- Remove withe spaces
do
from
until not actual.is_space and has_next
loop
next
end
end
json_substring (start_index, end_index: INTEGER_32):STRING is
--
do
Result:=representation.substring (start_index, end_index)
end
feature -- Implementation
representation:STRING
--linear representation of the original json string
index:INTEGER
--actual index
end

View File

@@ -0,0 +1,33 @@
indexing
description: "Objects that ..."
author: ""
date: "$Date$"
revision: "$Revision$"
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 '.'
open_tokens:ARRAY[CHARACTER] is
-- Characters wich open a type
once
Result:=<<J_OBJECT_OPEN,J_ARRAY_OPEN,J_STRING,J_PLUS,J_MINUS,J_DOT>>
end
close_tokens:ARRAY[CHARACTER] is
-- Characters wich close a type
once
Result:=<<J_OBJECT_CLOSE,J_ARRAY_CLOSE,J_STRING >>
end
end