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:
@@ -3,15 +3,15 @@ note
|
||||
An JSON_OBJECT represent an object in JSON.
|
||||
An object is an unordered set of name/value pairs
|
||||
|
||||
Examples:
|
||||
|
||||
object
|
||||
{}
|
||||
{"key": "value"}
|
||||
Examples:
|
||||
object
|
||||
{}
|
||||
{"key": value}
|
||||
{"key": "value"}
|
||||
]"
|
||||
author: "Javier Velilla"
|
||||
date: "2008/08/24"
|
||||
revision: "Revision 0.1"
|
||||
author: "$Author$"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
license: "MIT (see http://www.opensource.org/licenses/mit-license.php)"
|
||||
|
||||
class
|
||||
@@ -26,213 +26,226 @@ inherit
|
||||
DEBUG_OUTPUT
|
||||
|
||||
create
|
||||
make
|
||||
make_empty, make_with_capacity, make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Initialize
|
||||
make_with_capacity (nb: INTEGER)
|
||||
-- Initialize with a capacity of `nb' items.
|
||||
do
|
||||
create object.make (10)
|
||||
create items.make (nb)
|
||||
end
|
||||
|
||||
make_empty
|
||||
-- Initialize as empty object.
|
||||
do
|
||||
make_with_capacity (0)
|
||||
end
|
||||
|
||||
make
|
||||
-- Initialize with default capacity.
|
||||
do
|
||||
make_with_capacity (3)
|
||||
end
|
||||
|
||||
feature -- Change Element
|
||||
|
||||
put (value: detachable JSON_VALUE; key: JSON_STRING)
|
||||
-- Assuming there is no item of key `key',
|
||||
-- insert `value' with `key'.
|
||||
put (a_value: detachable JSON_VALUE; a_key: JSON_STRING)
|
||||
-- Assuming there is no item of key `a_key',
|
||||
-- insert `a_value' with `a_key'.
|
||||
require
|
||||
key_not_present: not has_key (key)
|
||||
local
|
||||
l_value: like value
|
||||
a_key_not_present: not has_key (a_key)
|
||||
do
|
||||
l_value := value
|
||||
if l_value = Void then
|
||||
create {JSON_NULL} l_value
|
||||
if a_value = Void then
|
||||
items.extend (create {JSON_NULL}, a_key)
|
||||
else
|
||||
items.extend (a_value, a_key)
|
||||
end
|
||||
object.extend (l_value, key)
|
||||
end
|
||||
|
||||
put_string (value: READABLE_STRING_GENERAL; key: JSON_STRING)
|
||||
-- Assuming there is no item of key `key',
|
||||
-- insert `value' with `key'.
|
||||
put_string (a_value: READABLE_STRING_GENERAL; a_key: JSON_STRING)
|
||||
-- Assuming there is no item of key `a_key',
|
||||
-- insert `a_value' with `a_key'.
|
||||
require
|
||||
key_not_present: not has_key (key)
|
||||
key_not_present: not has_key (a_key)
|
||||
local
|
||||
l_value: JSON_STRING
|
||||
do
|
||||
create l_value.make_json_from_string_32 (value.as_string_32)
|
||||
put (l_value, key)
|
||||
if attached {READABLE_STRING_8} a_value as s then
|
||||
create l_value.make_from_string (s)
|
||||
else
|
||||
create l_value.make_from_string_32 (a_value.as_string_32)
|
||||
end
|
||||
put (l_value, a_key)
|
||||
end
|
||||
|
||||
put_integer (value: INTEGER_64; key: JSON_STRING)
|
||||
-- Assuming there is no item of key `key',
|
||||
-- insert `value' with `key'.
|
||||
put_integer (a_value: INTEGER_64; a_key: JSON_STRING)
|
||||
-- Assuming there is no item of key `a_key',
|
||||
-- insert `a_value' with `a_key'.
|
||||
require
|
||||
key_not_present: not has_key (key)
|
||||
key_not_present: not has_key (a_key)
|
||||
local
|
||||
l_value: JSON_NUMBER
|
||||
do
|
||||
create l_value.make_integer (value)
|
||||
put (l_value, key)
|
||||
create l_value.make_integer (a_value)
|
||||
put (l_value, a_key)
|
||||
end
|
||||
|
||||
put_natural (value: NATURAL_64; key: JSON_STRING)
|
||||
-- Assuming there is no item of key `key',
|
||||
-- insert `value' with `key'.
|
||||
put_natural (a_value: NATURAL_64; a_key: JSON_STRING)
|
||||
-- Assuming there is no item of key `a_key',
|
||||
-- insert `a_value' with `a_key'.
|
||||
require
|
||||
key_not_present: not has_key (key)
|
||||
key_not_present: not has_key (a_key)
|
||||
local
|
||||
l_value: JSON_NUMBER
|
||||
do
|
||||
create l_value.make_natural (value)
|
||||
put (l_value, key)
|
||||
create l_value.make_natural (a_value)
|
||||
put (l_value, a_key)
|
||||
end
|
||||
|
||||
put_real (value: DOUBLE; key: JSON_STRING)
|
||||
-- Assuming there is no item of key `key',
|
||||
-- insert `value' with `key'.
|
||||
put_real (a_value: DOUBLE; a_key: JSON_STRING)
|
||||
-- Assuming there is no item of key `a_key',
|
||||
-- insert `a_value' with `a_key'.
|
||||
require
|
||||
key_not_present: not has_key (key)
|
||||
key_not_present: not has_key (a_key)
|
||||
local
|
||||
l_value: JSON_NUMBER
|
||||
do
|
||||
create l_value.make_real (value)
|
||||
put (l_value, key)
|
||||
create l_value.make_real (a_value)
|
||||
put (l_value, a_key)
|
||||
end
|
||||
|
||||
put_boolean (value: BOOLEAN; key: JSON_STRING)
|
||||
-- Assuming there is no item of key `key',
|
||||
-- insert `value' with `key'.
|
||||
put_boolean (a_value: BOOLEAN; a_key: JSON_STRING)
|
||||
-- Assuming there is no item of key `a_key',
|
||||
-- insert `a_value' with `a_key'.
|
||||
require
|
||||
key_not_present: not has_key (key)
|
||||
key_not_present: not has_key (a_key)
|
||||
local
|
||||
l_value: JSON_BOOLEAN
|
||||
do
|
||||
create l_value.make_boolean (value)
|
||||
put (l_value, key)
|
||||
create l_value.make (a_value)
|
||||
put (l_value, a_key)
|
||||
end
|
||||
|
||||
replace (value: detachable JSON_VALUE; key: JSON_STRING)
|
||||
-- Assuming there is no item of key `key',
|
||||
-- insert `value' with `key'.
|
||||
local
|
||||
l_value: like value
|
||||
replace (a_value: detachable JSON_VALUE; a_key: JSON_STRING)
|
||||
-- Assuming there is no item of key `a_key',
|
||||
-- insert `a_value' with `a_key'.
|
||||
do
|
||||
l_value := value
|
||||
if l_value = Void then
|
||||
create {JSON_NULL} l_value
|
||||
if a_value = Void then
|
||||
items.force (create {JSON_NULL}, a_key)
|
||||
else
|
||||
items.force (a_value, a_key)
|
||||
end
|
||||
object.force (l_value, key)
|
||||
end
|
||||
|
||||
replace_with_string (value: READABLE_STRING_GENERAL; key: JSON_STRING)
|
||||
-- Assuming there is no item of key `key',
|
||||
-- insert `value' with `key'.
|
||||
replace_with_string (a_value: READABLE_STRING_GENERAL; a_key: JSON_STRING)
|
||||
-- Assuming there is no item of key `a_key',
|
||||
-- insert `a_value' with `a_key'.
|
||||
local
|
||||
l_value: JSON_STRING
|
||||
do
|
||||
create l_value.make_json_from_string_32 (value.as_string_32)
|
||||
replace (l_value, key)
|
||||
if attached {READABLE_STRING_8} a_value as s then
|
||||
create l_value.make_from_string (s)
|
||||
else
|
||||
create l_value.make_from_string_32 (a_value.as_string_32)
|
||||
end
|
||||
replace (l_value, a_key)
|
||||
end
|
||||
|
||||
replace_with_integer (value: INTEGER_64; key: JSON_STRING)
|
||||
-- Assuming there is no item of key `key',
|
||||
-- insert `value' with `key'.
|
||||
replace_with_integer (a_value: INTEGER_64; a_key: JSON_STRING)
|
||||
-- Assuming there is no item of key `a_key',
|
||||
-- insert `a_value' with `a_key'.
|
||||
local
|
||||
l_value: JSON_NUMBER
|
||||
do
|
||||
create l_value.make_integer (value)
|
||||
replace (l_value, key)
|
||||
create l_value.make_integer (a_value)
|
||||
replace (l_value, a_key)
|
||||
end
|
||||
|
||||
replace_with_with_natural (value: NATURAL_64; key: JSON_STRING)
|
||||
-- Assuming there is no item of key `key',
|
||||
-- insert `value' with `key'.
|
||||
replace_with_with_natural (a_value: NATURAL_64; a_key: JSON_STRING)
|
||||
-- Assuming there is no item of key `a_key',
|
||||
-- insert `a_value' with `a_key'.
|
||||
local
|
||||
l_value: JSON_NUMBER
|
||||
do
|
||||
create l_value.make_natural (value)
|
||||
replace (l_value, key)
|
||||
create l_value.make_natural (a_value)
|
||||
replace (l_value, a_key)
|
||||
end
|
||||
|
||||
replace_with_real (value: DOUBLE; key: JSON_STRING)
|
||||
-- Assuming there is no item of key `key',
|
||||
-- insert `value' with `key'.
|
||||
replace_with_real (a_value: DOUBLE; a_key: JSON_STRING)
|
||||
-- Assuming there is no item of key `a_key',
|
||||
-- insert `a_value' with `a_key'.
|
||||
local
|
||||
l_value: JSON_NUMBER
|
||||
do
|
||||
create l_value.make_real (value)
|
||||
replace (l_value, key)
|
||||
create l_value.make_real (a_value)
|
||||
replace (l_value, a_key)
|
||||
end
|
||||
|
||||
replace_with_boolean (value: BOOLEAN; key: JSON_STRING)
|
||||
-- Assuming there is no item of key `key',
|
||||
-- insert `value' with `key'.
|
||||
replace_with_boolean (a_value: BOOLEAN; a_key: JSON_STRING)
|
||||
-- Assuming there is no item of key `a_key',
|
||||
-- insert `a_value' with `a_key'.
|
||||
local
|
||||
l_value: JSON_BOOLEAN
|
||||
do
|
||||
create l_value.make_boolean (value)
|
||||
replace (l_value, key)
|
||||
create l_value.make (a_value)
|
||||
replace (l_value, a_key)
|
||||
end
|
||||
|
||||
remove (key: JSON_STRING)
|
||||
-- Remove item indexed by `key' if any.
|
||||
remove (a_key: JSON_STRING)
|
||||
-- Remove item indexed by `a_key' if any.
|
||||
do
|
||||
object.remove (key)
|
||||
items.remove (a_key)
|
||||
end
|
||||
|
||||
wipe_out
|
||||
-- Reset all items to default values; reset status.
|
||||
do
|
||||
object.wipe_out
|
||||
items.wipe_out
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
has_key (a_key: JSON_STRING): BOOLEAN
|
||||
-- has the JSON_OBJECT contains a specific key `a_key'.
|
||||
do
|
||||
Result := items.has (a_key)
|
||||
end
|
||||
|
||||
has_item (a_value: JSON_VALUE): BOOLEAN
|
||||
-- has the JSON_OBJECT contain a specfic item `a_value'
|
||||
do
|
||||
Result := items.has_item (a_value)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
has_key (key: JSON_STRING): BOOLEAN
|
||||
-- has the JSON_OBJECT contains a specific key 'key'.
|
||||
item (a_key: JSON_STRING): detachable JSON_VALUE
|
||||
-- the json_value associated with a key `a_key'.
|
||||
do
|
||||
Result := object.has (key)
|
||||
end
|
||||
|
||||
has_item (value: JSON_VALUE): BOOLEAN
|
||||
-- has the JSON_OBJECT contain a specfic item 'value'
|
||||
do
|
||||
Result := object.has_item (value)
|
||||
end
|
||||
|
||||
item (key: JSON_STRING): detachable JSON_VALUE
|
||||
-- the json_value associated with a key.
|
||||
do
|
||||
Result := object.item (key)
|
||||
Result := items.item (a_key)
|
||||
end
|
||||
|
||||
current_keys: ARRAY [JSON_STRING]
|
||||
-- array containing actually used keys
|
||||
-- Array containing actually used keys.
|
||||
do
|
||||
Result := object.current_keys
|
||||
Result := items.current_keys
|
||||
end
|
||||
|
||||
representation: STRING
|
||||
local
|
||||
t: HASH_TABLE [JSON_VALUE, JSON_STRING]
|
||||
-- <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
|
||||
@@ -273,9 +286,9 @@ feature -- Visitor pattern
|
||||
feature -- Conversion
|
||||
|
||||
map_representation: HASH_TABLE [JSON_VALUE, JSON_STRING]
|
||||
--A representation that maps keys to values
|
||||
-- A representation that maps keys to values
|
||||
do
|
||||
Result := object
|
||||
Result := items
|
||||
end
|
||||
|
||||
feature -- Report
|
||||
@@ -284,13 +297,13 @@ feature -- Report
|
||||
-- Hash code value
|
||||
do
|
||||
from
|
||||
object.start
|
||||
Result := object.out.hash_code
|
||||
items.start
|
||||
Result := items.out.hash_code
|
||||
until
|
||||
object.off
|
||||
items.off
|
||||
loop
|
||||
Result := ((Result \\ 8388593) |<< 8) + object.item_for_iteration.hash_code
|
||||
object.forth
|
||||
Result := ((Result \\ 8388593) |<< 8) + items.item_for_iteration.hash_code
|
||||
items.forth
|
||||
end
|
||||
-- Ensure it is a positive value.
|
||||
Result := Result.hash_code
|
||||
@@ -301,15 +314,15 @@ feature -- Status report
|
||||
debug_output: STRING
|
||||
-- String that should be displayed in debugger to represent `Current'.
|
||||
do
|
||||
Result := count.out + " item(s)"
|
||||
Result := count.out + "item(s)"
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
object: HASH_TABLE [JSON_VALUE, JSON_STRING]
|
||||
items: HASH_TABLE [JSON_VALUE, JSON_STRING]
|
||||
-- Value container
|
||||
|
||||
invariant
|
||||
object_not_void: object /= Void
|
||||
items_not_void: items /= Void
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user