diff --git a/library/kernel/json_array.e b/library/kernel/json_array.e index 39c148c..505bb65 100644 --- a/library/kernel/json_array.e +++ b/library/kernel/json_array.e @@ -23,12 +23,20 @@ inherit ITERABLE [JSON_VALUE] + JSON_COLLECTION + redefine + items + end + DEBUG_OUTPUT create - make, make_empty, + make, + make_empty, + make_from_separate, make_array + feature {NONE} -- Initialization make (nb: INTEGER) @@ -51,6 +59,16 @@ feature {NONE} -- Initialization make (10) end + make_from_separate (other: separate like Current) + -- + do + create items.make (other.capacity) + append_from_separate (other) + ensure then + capacity = other.capacity + count = other.count + end + feature -- Status report is_array: BOOLEAN = True @@ -58,7 +76,21 @@ feature -- Status report feature -- Access - i_th alias "[]" (i: INTEGER): JSON_VALUE + first: like items.item + require + not_empty: not is_empty + do + Result := items.i_th (1) + end + + last: like items.item + require + not_empty: not is_empty + do + Result := items.i_th (count) + end + + i_th alias "[]" (i: INTEGER): like items.item -- Item at `i'-th position require is_valid_index: valid_index (i) @@ -66,7 +98,7 @@ feature -- Access Result := items.i_th (i) end - chained_item alias "@" (a_key: JSON_STRING): JSON_VALUE + chained_item alias "@" (a_key: JSON_STRING): like items.item -- . do if a_key.item.is_integer then @@ -88,6 +120,9 @@ feature -- Access Result.append (ic.item.representation) end Result.append_character (']') + ensure then + Result.starts_with ("[") + Result.ends_with ("]") end feature -- Visitor pattern @@ -101,7 +136,7 @@ feature -- Visitor pattern feature -- Access - new_cursor: ITERATION_CURSOR [JSON_VALUE] + new_cursor: like items.new_cursor -- Fresh cursor associated with current structure do Result := items.new_cursor @@ -109,12 +144,18 @@ feature -- Access feature -- Mesurement - count: INTEGER + count: like items.count -- Number of items. do Result := items.count end + capacity: like items.capacity + -- Number of items that may be stored. + do + Result := items.capacity + end + feature -- Status report is_empty: BOOLEAN @@ -131,7 +172,7 @@ feature -- Status report feature -- Change Element - put_front (v: JSON_VALUE) + put_front (v: like items.item) require v_not_void: v /= Void do @@ -140,7 +181,7 @@ feature -- Change Element has_new_value: old items.count + 1 = items.count and items.first = v end - add, extend (v: JSON_VALUE) + add, extend (v: like items.item) require v_not_void: v /= Void do @@ -149,7 +190,7 @@ feature -- Change Element has_new_value: old items.count + 1 = items.count and items.has (v) end - prune_all (v: JSON_VALUE) + prune_all (v: like items.item) -- Remove all occurrences of `v'. require v_not_void: v /= Void @@ -159,10 +200,25 @@ feature -- Change Element not_has_new_value: not items.has (v) end + append_from_separate (other: separate like Current) + -- Appends Current with content of other `other' + local + l_item_non_sep: JSON_VALUE + do + across + other as l_item + loop + l_item_non_sep := non_sep_json_value (l_item.item) + extend (l_item_non_sep) + end + end + wipe_out -- Remove all items. do items.wipe_out + ensure + is_empty end feature -- Report @@ -187,13 +243,87 @@ feature -- Report feature -- Conversion - array_representation: ARRAYED_LIST [JSON_VALUE] + array_representation: like items -- Representation as a sequences of values. -- be careful, modifying the return object may have impact on the original JSON_ARRAY object. do Result := items end + non_sep_json_value (a_json_v: separate JSON_VALUE): JSON_VALUE + -- dirty but don't see any other option, see https://github.com/eiffelhub/json/issues/19#issuecomment-592171283 issue for details + local + l_json_s: JSON_STRING + l_s: STRING + do +-- - JSON_ARRAY: no assertion +-- - JSON_BOOLEAN: no assertion +-- - JSON_NULL: no assertion +-- - JSON_NUMBER: no assertion +-- - JSON_OBJECT: no assertion +-- - JSON_STRING: no assertion + if attached {separate JSON_ARRAY} a_json_v as l_json then + create {JSON_ARRAY} Result.make (l_json.count) + check + attached {JSON_ARRAY} Result as l_res + then + across + l_json as l_item + loop + check + attached {JSON_VALUE} non_sep_json_value (l_item.item) as l_non_sep_json_value + then + l_res.extend (l_non_sep_json_value) + end + end + end + elseif attached {separate JSON_BOOLEAN} a_json_v as l_json then + create {JSON_BOOLEAN} Result.make (l_json.item) + elseif attached {separate JSON_STRING} a_json_v as l_json then + create l_s.make_from_separate (l_json.item) + create {JSON_STRING} Result.make_from_string (l_s) + elseif attached {separate JSON_NULL} a_json_v as l_json then + create {JSON_NULL} Result + elseif attached {separate JSON_NUMBER} a_json_v as l_json then + if l_json.is_integer then + create {JSON_NUMBER} Result.make_integer (l_json.integer_64_item) + elseif l_json.is_real then + create {JSON_NUMBER} Result.make_real (l_json.real_64_item) + elseif l_json.is_natural then + create {JSON_NUMBER} Result.make_natural (l_json.natural_64_item) + else + create {JSON_NUMBER} Result.make_natural (0) + check + invalid_json_number: False + end + end + elseif attached {separate JSON_OBJECT} a_json_v as l_json then + create {JSON_OBJECT} Result.make_with_capacity (l_json.count) + check + attached {JSON_OBJECT} Result as l_res + then + across + l_json as l_item + loop + check + attached {JSON_VALUE} non_sep_json_value (l_item.item) as l_non_sep_json_value + then + create l_s.make_from_separate (l_item.key.item) + create l_json_s.make_from_string (l_s) + l_res.put (l_non_sep_json_value, l_json_s) + end + end + end + else + create {JSON_ARRAY} Result.make_empty + check + not_implemented: False + end + end + ensure + instance_free: Class + end + feature -- Status report debug_output: STRING @@ -211,6 +341,6 @@ invariant items_not_void: items /= Void note - copyright: "2010-2018, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." + copyright: "2010-2020, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/kernel/json_boolean.e b/library/kernel/json_boolean.e index 8a50c0e..c724238 100644 --- a/library/kernel/json_boolean.e +++ b/library/kernel/json_boolean.e @@ -13,7 +13,9 @@ inherit create make, - make_true, make_false, + make_true, + make_false, + make_from_separate, make_boolean feature {NONE} -- Initialization @@ -44,6 +46,12 @@ feature {NONE} -- Initialization make (a_item) end + make_from_separate (other: separate like Current) + -- + do + make (other.item) + end + feature -- Access item: BOOLEAN @@ -82,6 +90,6 @@ feature -- Status report end note - copyright: "2010-2017, Javier Velilla and others https://github.com/eiffelhub/json." + copyright: "2010-2020, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/kernel/json_collection.e b/library/kernel/json_collection.e new file mode 100644 index 0000000..1a6aefc --- /dev/null +++ b/library/kernel/json_collection.e @@ -0,0 +1,19 @@ +note + description: "JSON Collection of items" + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + JSON_COLLECTION + + +feature {NONE} -- Implementation + + items: READABLE_INDEXABLE [JSON_VALUE] + -- Value container + +;note + copyright: "2010-2020, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." + license: "https://github.com/eiffelhub/json/blob/master/License.txt" +end diff --git a/library/kernel/json_null.e b/library/kernel/json_null.e index 26451bb..ae4985d 100644 --- a/library/kernel/json_null.e +++ b/library/kernel/json_null.e @@ -13,6 +13,17 @@ inherit is_null end +create + default_create, + make_from_separate + +feature {NONE} -- Initialization + + make_from_separate (other: separate like Current) + -- + do + end + feature -- Status report is_null: BOOLEAN = True @@ -57,6 +68,6 @@ feature {NONE} -- Implementation null_value: STRING = "null" note - copyright: "2010-2019, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." + copyright: "2010-2020, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/kernel/json_number.e b/library/kernel/json_number.e index 7ab0c9c..1b61c96 100644 --- a/library/kernel/json_number.e +++ b/library/kernel/json_number.e @@ -16,7 +16,10 @@ inherit end create - make_integer, make_natural, make_real + make_integer, + make_natural, + make_from_separate, + make_real feature {NONE} -- initialization @@ -49,6 +52,15 @@ feature {NONE} -- initialization numeric_type := double_type end + make_from_separate (other: separate like Current) + -- + do + item := create {STRING}.make_from_separate (other.item.out) -- Not quite sure of that + numeric_type := other.numeric_type + ensure then + numeric_type = other.numeric_type + end + feature -- Status report is_number: BOOLEAN = True @@ -199,6 +211,6 @@ invariant inf_only_for_real: inv_item.is_case_insensitive_equal_general (positive_infinity_real_value) implies is_real note - copyright: "2010-2019, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." + copyright: "2010-2020, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/kernel/json_object.e b/library/kernel/json_object.e index 0c405f9..ab62b83 100644 --- a/library/kernel/json_object.e +++ b/library/kernel/json_object.e @@ -27,10 +27,18 @@ inherit TABLE_ITERABLE [JSON_VALUE, JSON_STRING] + JSON_COLLECTION + redefine + items + end + DEBUG_OUTPUT create - make_empty, make_with_capacity, make + make_empty, + make_with_capacity, + make_from_separate, + make feature {NONE} -- Initialization @@ -52,6 +60,16 @@ feature {NONE} -- Initialization make_with_capacity (10) end + make_from_separate (other: separate like Current) + -- + do + make_with_capacity (other.count) + append_from_separate (other) + ensure then + capacity = other.capacity + count = other.count + end + feature -- Status report is_object: BOOLEAN = True @@ -59,7 +77,7 @@ feature -- Status report feature -- Change Element - put (a_value: detachable JSON_VALUE; a_key: JSON_STRING) + put (a_value: detachable like items.item; a_key: like items.key_for_iteration) -- Assuming there is no item of key `a_key', -- insert `a_value' with `a_key'. require @@ -72,7 +90,7 @@ feature -- Change Element end end - put_string (a_value: READABLE_STRING_GENERAL; a_key: JSON_STRING) + put_string (a_value: READABLE_STRING_GENERAL; a_key: like items.key_for_iteration) -- Assuming there is no item of key `a_key', -- insert `a_value' with `a_key'. require @@ -90,7 +108,7 @@ feature -- Change Element put (l_value, a_key) end - put_integer (a_value: INTEGER_64; a_key: JSON_STRING) + put_integer (a_value: INTEGER_64; a_key: like items.key_for_iteration) -- Assuming there is no item of key `a_key', -- insert `a_value' with `a_key'. require @@ -102,7 +120,7 @@ feature -- Change Element put (l_value, a_key) end - put_natural (a_value: NATURAL_64; a_key: JSON_STRING) + put_natural (a_value: NATURAL_64; a_key: like items.key_for_iteration) -- Assuming there is no item of key `a_key', -- insert `a_value' with `a_key'. require @@ -114,7 +132,7 @@ feature -- Change Element put (l_value, a_key) end - put_real (a_value: DOUBLE; a_key: JSON_STRING) + put_real (a_value: DOUBLE; a_key: like items.key_for_iteration) -- Assuming there is no item of key `a_key', -- insert `a_value' with `a_key'. require @@ -126,7 +144,7 @@ feature -- Change Element put (l_value, a_key) end - put_boolean (a_value: BOOLEAN; a_key: JSON_STRING) + put_boolean (a_value: BOOLEAN; a_key: like items.key_for_iteration) -- Assuming there is no item of key `a_key', -- insert `a_value' with `a_key'. require @@ -138,7 +156,7 @@ feature -- Change Element put (l_value, a_key) end - replace (a_value: detachable JSON_VALUE; a_key: JSON_STRING) + replace (a_value: like items.item; a_key: like items.key_for_iteration) -- Assuming there is no item of key `a_key', -- insert `a_value' with `a_key'. do @@ -149,7 +167,7 @@ feature -- Change Element end end - replace_with_string (a_value: READABLE_STRING_GENERAL; a_key: JSON_STRING) + replace_with_string (a_value: READABLE_STRING_GENERAL; a_key: like items.key_for_iteration) -- Assuming there is no item of key `a_key', -- insert `a_value' with `a_key'. local @@ -163,7 +181,7 @@ feature -- Change Element replace (l_value, a_key) end - replace_with_integer (a_value: INTEGER_64; a_key: JSON_STRING) + replace_with_integer (a_value: INTEGER_64; a_key: like items.key_for_iteration) -- Assuming there is no item of key `a_key', -- insert `a_value' with `a_key'. local @@ -173,7 +191,7 @@ feature -- Change Element replace (l_value, a_key) end - replace_with_with_natural (a_value: NATURAL_64; a_key: JSON_STRING) + replace_with_with_natural (a_value: NATURAL_64; a_key: like items.key_for_iteration) -- Assuming there is no item of key `a_key', -- insert `a_value' with `a_key'. local @@ -183,7 +201,7 @@ feature -- Change Element replace (l_value, a_key) end - replace_with_real (a_value: DOUBLE; a_key: JSON_STRING) + replace_with_real (a_value: DOUBLE; a_key: like items.key_for_iteration) -- Assuming there is no item of key `a_key', -- insert `a_value' with `a_key'. local @@ -193,7 +211,7 @@ feature -- Change Element replace (l_value, a_key) end - replace_with_boolean (a_value: BOOLEAN; a_key: JSON_STRING) + replace_with_boolean (a_value: BOOLEAN; a_key: like items.key_for_iteration) -- Assuming there is no item of key `a_key', -- insert `a_value' with `a_key'. local @@ -203,7 +221,20 @@ feature -- Change Element replace (l_value, a_key) end - remove (a_key: JSON_STRING) + append_from_separate (other: separate like Current) + -- Appends Current with content of other `other' + local + l_item_non_sep: JSON_VALUE + do + across + other as l_item + loop + l_item_non_sep := {JSON_ARRAY}.non_sep_json_value (l_item.item) + put (l_item_non_sep, create {JSON_STRING}.make_from_separate (l_item.key)) + end + end + + remove (a_key: like items.key_for_iteration) -- Remove item indexed by `a_key' if any. do items.remove (a_key) @@ -217,62 +248,84 @@ feature -- Change Element feature -- Status report - has_key (a_key: JSON_STRING): BOOLEAN + has_key (a_key: like items.key_for_iteration): 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_item (a_value: like items.item_for_iteration): BOOLEAN -- has the JSON_OBJECT contain a specfic item `a_value' do Result := items.has_item (a_value) end +feature -- Measurement + + capacity: like items.capacity + -- Number of items that may be stored. + do + Result := items.capacity + end + + count: like items.count + do + Result := items.count + end + feature -- Access - item alias "[]" (a_key: JSON_STRING): detachable JSON_VALUE + item alias "[]" (a_key: like items.key_for_iteration): like items.item -- the json_value associated with a key `a_key'. do Result := items.item (a_key) end - string_item (a_key: JSON_STRING): detachable JSON_STRING + item_separate (a_key: separate like items.key_for_iteration): like items.item + -- the json_value associated with a key `a_key'. + local + l_s: like items.key_for_iteration + do + create l_s.make_from_string_separate (a_key.item) + Result := items.item (l_s) + end + + string_item (a_key: like items.key_for_iteration): detachable JSON_STRING do if attached {JSON_STRING} item (a_key) as js then Result := js end end - number_item (a_key: JSON_STRING): detachable JSON_NUMBER + number_item (a_key: like items.key_for_iteration): detachable JSON_NUMBER do if attached {JSON_NUMBER} item (a_key) as jn then Result := jn end end - boolean_item (a_key: JSON_STRING): detachable JSON_BOOLEAN + boolean_item (a_key: like items.key_for_iteration): detachable JSON_BOOLEAN do if attached {JSON_BOOLEAN} item (a_key) as jb then Result := jb end end - object_item (a_key: JSON_STRING): detachable JSON_OBJECT + object_item (a_key: like items.key_for_iteration): detachable JSON_OBJECT do if attached {JSON_OBJECT} item (a_key) as jo then Result := jo end end - array_item (a_key: JSON_STRING): detachable JSON_ARRAY + array_item (a_key: like items.key_for_iteration): detachable JSON_ARRAY do if attached {JSON_ARRAY} item (a_key) as ja then Result := ja end end - chained_item alias "@" (a_key: JSON_STRING): JSON_VALUE + chained_item alias "@" (a_key: like items.key_for_iteration): like items.item_for_iteration -- . do if attached item (a_key) as v then @@ -306,17 +359,9 @@ feature -- Access Result.append_character ('}') end -feature -- Mesurement - - count: INTEGER - -- Number of field. - do - Result := items.count - end - feature -- Access - new_cursor: TABLE_ITERATION_CURSOR [JSON_VALUE, JSON_STRING] + new_cursor: like items.new_cursor -- Fresh cursor associated with current structure do Result := items.new_cursor @@ -341,7 +386,7 @@ feature -- Visitor pattern feature -- Conversion - map_representation: HASH_TABLE [JSON_VALUE, JSON_STRING] + map_representation: HASH_TABLE [like items.item_for_iteration, like items.key_for_iteration] -- A representation that maps keys to values do Result := items @@ -382,6 +427,6 @@ invariant items_not_void: items /= Void note - copyright: "2010-2018, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." + copyright: "2010-2020, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/kernel/json_string.e b/library/kernel/json_string.e index cec7bc8..408b55c 100644 --- a/library/kernel/json_string.e +++ b/library/kernel/json_string.e @@ -24,6 +24,7 @@ inherit create make_from_string, make_from_string_32, make_from_string_general, make_from_escaped_json_string, + make_from_separate, make_from_string_separate, make_with_escaped_json, make_json, make_json_from_string_32 convert @@ -107,6 +108,23 @@ feature {NONE} -- Initialization make_with_escaped_json (escaped_json_string (s)) end + make_from_separate (other: separate like Current) + -- + local + l_s: like escaped_json_string + do + create l_s.make_from_separate (other.item) + make_from_string (l_s) + end + + make_from_string_separate (s: separate READABLE_STRING_8) + local + l_s: STRING + do + create l_s.make_from_separate (s) + make_from_string (l_s) + end + feature -- Access item: STRING @@ -117,6 +135,11 @@ feature -- Status report is_string: BOOLEAN = True -- + is_empty: BOOLEAN + do + Result := item.is_empty + end + same_string (a_string: READABLE_STRING_GENERAL): BOOLEAN -- Current value is a string value, and same content as `a_string`? do @@ -561,6 +584,6 @@ invariant item_not_void: item /= Void note - copyright: "2010-2019, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." + copyright: "2010-2020, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." license: "https://github.com/eiffelhub/json/blob/master/License.txt" end diff --git a/library/kernel/json_value.e b/library/kernel/json_value.e index 53e6c78..addd244 100644 --- a/library/kernel/json_value.e +++ b/library/kernel/json_value.e @@ -22,6 +22,13 @@ inherit DEBUG_OUTPUT +feature {NONE} -- Initialization + + make_from_separate (other: separate like Current) + -- Initialize current from `other'. + deferred + end + feature -- Status report is_string: BOOLEAN @@ -96,6 +103,6 @@ feature -- Visitor pattern end note - copyright: "2010-2018, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." + copyright: "2010-2020, Javier Velilla, Jocelyn Fiat, Eiffel Software and others https://github.com/eiffelhub/json." license: "https://github.com/eiffelhub/json/blob/master/License.txt" end