note description: "[ Encoding of arbitrary objects graphs within a session of a same program. Some routines are explicitely frozen, not because we do not want them to be redefined but if they are frozen, it saves us having to look at all possible descendants whenever we do a change. ]" legal: "See notice at end of class." status: "See notice at end of class." date: "$Date: 2017-03-28 12:36:24 +0000 (Tue, 28 Mar 2017) $" revision: "$Revision: 100064 $" class SED_SESSION_SERIALIZER create make feature {NONE} -- Initialization default_create -- Process instances of classes with no creation clause. -- (Default: do nothing.) -- (from ANY) do end make (a_serializer: SED_READER_WRITER) -- Initialize current instance require a_serializer_not_void: a_serializer /= Void a_serializer_ready: a_serializer.is_ready_for_writing do create reflector create reflected_object.make (reflector) create object_indexes.make (1) traversable := Breadth_first_traversable serializer := a_serializer set_version ({SED_VERSIONS}.version_7_3) ensure serializer_set: serializer = a_serializer end feature -- Access generating_type: TYPE [detachable SED_SESSION_SERIALIZER] -- Type of current object -- (type of which it is a direct instance) -- (from ANY) external "built_in" ensure -- from ANY generating_type_not_void: Result /= Void end generator: STRING_8 -- Name of current object's generating class -- (base class of the type of which it is a direct instance) -- (from ANY) external "built_in" ensure -- from ANY generator_not_void: Result /= Void generator_not_empty: not Result.is_empty end root_object: detachable ANY -- Root object of object graph do Result := traversable.root_object end serializer: SED_READER_WRITER -- Serializer used to encode data feature -- Comparison frozen deep_equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void -- or attached to isomorphic object structures? -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.is_deep_equal (b) end ensure -- from ANY instance_free: class shallow_implies_deep: standard_equal (a, b) implies Result both_or_none_void: (a = Void) implies (Result = (b = Void)) same_type: (Result and (a /= Void)) implies (b /= Void and then a.same_type (b)) symmetric: Result implies deep_equal (b, a) end frozen equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void or attached -- to objects considered equal? -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.is_equal (b) end ensure -- from ANY instance_free: class definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.is_equal (b)) end frozen is_deep_equal alias "≡≡≡" (other: SED_SESSION_SERIALIZER): BOOLEAN -- Are Current and other attached to isomorphic object structures? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY shallow_implies_deep: standard_is_equal (other) implies Result same_type: Result implies same_type (other) symmetric: Result implies other.is_deep_equal (Current) end is_equal (other: SED_SESSION_SERIALIZER): BOOLEAN -- Is other attached to an object considered -- equal to current object? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY symmetric: Result implies other ~ Current consistent: standard_is_equal (other) implies Result end frozen standard_equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void or attached to -- field-by-field identical objects of the same type? -- Always uses default object comparison criterion. -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.standard_is_equal (b) end ensure -- from ANY instance_free: class definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.standard_is_equal (b)) end frozen standard_is_equal alias "≜" (other: SED_SESSION_SERIALIZER): BOOLEAN -- Is other attached to an object of the same type -- as current object, and field-by-field identical to it? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY same_type: Result implies same_type (other) symmetric: Result implies other.standard_is_equal (Current) end feature -- Status report conforms_to (other: ANY): BOOLEAN -- Does type of current object conform to type -- of other (as per Eiffel: The Language, chapter 13)? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" end is_root_object_set: BOOLEAN -- Is root object of object graph set? is_traversing_mode_set: BOOLEAN -- Is traversing mode set? do Result := traversable /= Void end same_type (other: ANY): BOOLEAN -- Is type of current object identical to type of other? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY definition: Result = (conforms_to (other) and other.conforms_to (Current)) end feature {NONE} -- Status report has_reference_with_copy_semantics: BOOLEAN -- Does serialized data have some reference with copy semantics? -- If none, we optimize the serialization of references by not emitting -- a boolean switch each time we refer to an object. is_store_settings_enabled: BOOLEAN -- Are settings stored? -- By default not for SED_INDEPENDENT_SERIALIZER. do Result := True end feature -- Element change set_breadth_first_traversing_mode -- Change graph traversing to breadth first. do traversable := Breadth_first_traversable ensure traversing_mode_set: is_traversing_mode_set breadth_first_mode: attached {OBJECT_GRAPH_BREADTH_FIRST_TRAVERSABLE} traversable end set_depth_first_traversing_mode -- Change graph traversing to depth first. do traversable := Depth_first_traversable ensure traversing_mode_set: is_traversing_mode_set depth_first_mode: attached {OBJECT_GRAPH_DEPTH_FIRST_TRAVERSABLE} traversable end set_root_object (an_object: like root_object) -- Make 'an_object' the root_object. require an_object_not_void: an_object /= Void traversing_mode_set: is_traversing_mode_set do traversable.set_root_object (an_object) is_root_object_set := True ensure root_object_set: root_object = an_object and is_root_object_set root_object_identity: root_object = traversable.root_object end set_serializer (a_serializer: like serializer) -- Set serializer with a_serializer. require a_serializer_not_void: a_serializer /= Void a_serializer_ready: a_serializer.is_ready_for_writing do serializer := a_serializer ensure serializer_set: serializer = a_serializer end feature -- Duplication frozen clone (other: detachable ANY): like other obsolete "Use `twin' instead. [2017-05-31]" -- Void if other is void; otherwise new object -- equal to other -- -- For non-void other, clone calls copy; -- to change copying/cloning semantics, redefine copy. -- (from ANY) do if other /= Void then Result := other.twin end ensure -- from ANY instance_free: class equal: Result ~ other end copy (other: SED_SESSION_SERIALIZER) -- Update current object using fields of object attached -- to other, so as to yield equal objects. -- (from ANY) require -- from ANY other_not_void: other /= Void type_identity: same_type (other) external "built_in" ensure -- from ANY is_equal: Current ~ other end frozen deep_clone (other: detachable ANY): like other obsolete "Use `deep_twin' instead. [2017-05-31]" -- Void if other is void: otherwise, new object structure -- recursively duplicated from the one attached to other -- (from ANY) do if other /= Void then Result := other.deep_twin end ensure -- from ANY instance_free: class deep_equal: deep_equal (other, Result) end frozen deep_copy (other: SED_SESSION_SERIALIZER) -- Effect equivalent to that of: -- copy (other . deep_twin) -- (from ANY) require -- from ANY other_not_void: other /= Void do copy (other.deep_twin) ensure -- from ANY deep_equal: deep_equal (Current, other) end frozen deep_twin: SED_SESSION_SERIALIZER -- New object structure recursively duplicated from Current. -- (from ANY) external "built_in" ensure -- from ANY deep_twin_not_void: Result /= Void deep_equal: deep_equal (Current, Result) end frozen standard_clone (other: detachable ANY): like other obsolete "Use `standard_twin' instead. [2017-05-31]" -- Void if other is void; otherwise new object -- field-by-field identical to other. -- Always uses default copying semantics. -- (from ANY) do if other /= Void then Result := other.standard_twin end ensure -- from ANY instance_free: class equal: standard_equal (Result, other) end frozen standard_copy (other: SED_SESSION_SERIALIZER) -- Copy every field of other onto corresponding field -- of current object. -- (from ANY) require -- from ANY other_not_void: other /= Void type_identity: same_type (other) external "built_in" ensure -- from ANY is_standard_equal: standard_is_equal (other) end frozen standard_twin: SED_SESSION_SERIALIZER -- New object field-by-field identical to other. -- Always uses default copying semantics. -- (from ANY) external "built_in" ensure -- from ANY standard_twin_not_void: Result /= Void equal: standard_equal (Result, Current) end frozen twin: SED_SESSION_SERIALIZER -- New object equal to Current -- twin calls copy; to change copying/twinning semantics, redefine copy. -- (from ANY) external "built_in" ensure -- from ANY twin_not_void: Result /= Void is_equal: Result ~ Current end feature -- Basic operations frozen as_attached: attached SED_SESSION_SERIALIZER obsolete "Remove calls to this feature. [2017-05-31]" -- Attached version of Current. -- (Can be used during transitional period to convert -- non-void-safe classes to void-safe ones.) -- (from ANY) do Result := Current end frozen default: detachable SED_SESSION_SERIALIZER -- Default value of object's type -- (from ANY) do end frozen default_pointer: POINTER -- Default value of type POINTER -- (Avoid the need to write p.default for -- some p of type POINTER.) -- (from ANY) do ensure -- from ANY instance_free: class end default_rescue -- Process exception for routines with no Rescue clause. -- (Default: do nothing.) -- (from ANY) do end frozen do_nothing -- Execute a null action. -- (from ANY) do ensure -- from ANY instance_free: class end frozen encode -- Encode object graph starting with the root object. require traversing_mode_set: is_traversing_mode_set root_object_set: is_root_object_set local l_mem: detachable MEMORY l_is_collecting: BOOLEAN l_list_count: NATURAL_32 do if not {PLATFORM}.is_dotnet then create l_mem l_is_collecting := l_mem.collecting; l_mem.collection_off end; traversable.set_is_skip_transient (True); traversable.set_is_skip_copy_semantics_reference (True); traversable.traverse if attached traversable.visited_objects as l_list and then attached traversable.visited_types as l_type_table then has_reference_with_copy_semantics := traversable.has_reference_with_copy_semantics l_list_count := l_list.count.to_natural_32 if l_list.count > object_indexes.capacity then create object_indexes.make (l_list_count) end; serializer.write_compressed_natural_32 (l_list_count) write_header (l_list, l_type_table) encode_objects (l_list) end; traversable.wipe_out; object_indexes.wipe_out if l_mem /= Void and then l_is_collecting then l_mem.collection_on end end feature {NONE} -- Implementation abstract_type (a_type_id: INTEGER_32): INTEGER_32 -- Abstract type of a_type_id. -- (from SED_UTILITIES) require -- from SED_UTILITIES a_type_id_non_negative: a_type_id >= 0 local l_spec_mapping: like Special_type_mapping do l_spec_mapping := Special_type_mapping; l_spec_mapping.search (a_type_id) if l_spec_mapping.found then Result := l_spec_mapping.found_item else Result := {REFLECTOR_CONSTANTS}.reference_type end end frozen encode_normal_object (a_reflected_object: REFLECTED_OBJECT) -- Encode normal object a_reflected_object. local i, nb: INTEGER_32 l_ser: like serializer l_exp: REFLECTED_COPY_SEMANTICS_OBJECT do from l_ser := serializer i := 1 nb := a_reflected_object.field_count + 1 until i = nb loop if not a_reflected_object.is_field_transient (i) then inspect a_reflected_object.field_type (i) when {REFLECTOR_CONSTANTS}.boolean_type then l_ser.write_boolean (a_reflected_object.boolean_field (i)) when {REFLECTOR_CONSTANTS}.character_8_type then l_ser.write_character_8 (a_reflected_object.character_8_field (i)) when {REFLECTOR_CONSTANTS}.character_32_type then l_ser.write_character_32 (a_reflected_object.character_32_field (i)) when {REFLECTOR_CONSTANTS}.natural_8_type then l_ser.write_natural_8 (a_reflected_object.natural_8_field (i)) when {REFLECTOR_CONSTANTS}.natural_16_type then l_ser.write_natural_16 (a_reflected_object.natural_16_field (i)) when {REFLECTOR_CONSTANTS}.natural_32_type then l_ser.write_natural_32 (a_reflected_object.natural_32_field (i)) when {REFLECTOR_CONSTANTS}.natural_64_type then l_ser.write_natural_64 (a_reflected_object.natural_64_field (i)) when {REFLECTOR_CONSTANTS}.integer_8_type then l_ser.write_integer_8 (a_reflected_object.integer_8_field (i)) when {REFLECTOR_CONSTANTS}.integer_16_type then l_ser.write_integer_16 (a_reflected_object.integer_16_field (i)) when {REFLECTOR_CONSTANTS}.integer_32_type then l_ser.write_integer_32 (a_reflected_object.integer_32_field (i)) when {REFLECTOR_CONSTANTS}.integer_64_type then l_ser.write_integer_64 (a_reflected_object.integer_64_field (i)) when {REFLECTOR_CONSTANTS}.real_32_type then l_ser.write_real_32 (a_reflected_object.real_32_field (i)) when {REFLECTOR_CONSTANTS}.real_64_type then l_ser.write_real_64 (a_reflected_object.real_64_field (i)) when {REFLECTOR_CONSTANTS}.pointer_type then l_ser.write_pointer (a_reflected_object.pointer_field (i)) when {REFLECTOR_CONSTANTS}.reference_type then if has_reference_with_copy_semantics then if a_reflected_object.is_copy_semantics_field (i) then l_ser.write_boolean (True) l_exp := a_reflected_object.copy_semantics_field (i); l_ser.write_compressed_integer_32 (l_exp.dynamic_type) encode_normal_object (l_exp) else l_ser.write_boolean (False) encode_reference (a_reflected_object.reference_field (i)) end else encode_reference (a_reflected_object.reference_field (i)) end when {REFLECTOR_CONSTANTS}.expanded_type then l_ser.write_compressed_integer_32 (a_reflected_object.dynamic_type) encode_normal_object (a_reflected_object.expanded_field (i)) else check False end end end i := i + 1 end end frozen encode_objects (a_list: ARRAYED_LIST [separate ANY]) -- Encode all objects referenced in a_list. require a_list_not_void: a_list /= Void a_list_not_empty: not a_list.is_empty local l_reflected_object: like reflected_object l_ser: like serializer l_object_indexes: like object_indexes l_obj: separate ANY i, nb: INTEGER_32 l_area: SPECIAL [separate ANY] l_obj_index: NATURAL_32 do l_reflected_object := reflected_object l_ser := serializer l_object_indexes := object_indexes from l_area := a_list.area i := 0 nb := a_list.count until i = nb loop l_obj := l_area.item (i); l_reflected_object.set_object (l_obj) i := i + 1 l_obj_index := l_object_indexes.index (l_obj); l_ser.write_compressed_natural_32 (l_obj_index) check l_obj_index = i.as_natural_32 end if l_reflected_object.is_special then encode_special (l_obj, abstract_type (l_reflected_object.generic_dynamic_type (1))) elseif l_reflected_object.is_tuple then if attached {TUPLE} l_obj as l_tuple then encode_tuple_object (l_tuple) else check l_tuple_attached: False end end else encode_normal_object (l_reflected_object) end end end frozen encode_reference (an_object: detachable separate ANY) -- Encode reference to an_object. do if an_object /= Void then serializer.write_compressed_natural_32 (object_indexes.index (an_object)) else serializer.write_compressed_natural_32 (0) end end frozen encode_special (an_object: separate ANY; a_item_type: INTEGER_32) -- Encode an object which is a special object. require an_object_not_void: an_object /= Void an_object_is_special: attached {separate SPECIAL [detachable ANY]} an_object a_item_type_non_negative: a_item_type >= 0 do inspect a_item_type when {REFLECTOR_CONSTANTS}.boolean_type then if attached {SPECIAL [BOOLEAN]} an_object as l_spec_boolean then encode_special_boolean (l_spec_boolean) else check l_spec_boolean_not_void: False end end when {REFLECTOR_CONSTANTS}.character_8_type then if attached {SPECIAL [CHARACTER_8]} an_object as l_spec_character_8 then encode_special_character_8 (l_spec_character_8) else check l_spec_character_8_not_void: False end end when {REFLECTOR_CONSTANTS}.character_32_type, {REFLECTOR_CONSTANTS}.natural_32_type then if attached {SPECIAL [CHARACTER_32]} an_object as l_spec_character_32 then encode_special_character_32 (l_spec_character_32) elseif attached {SPECIAL [NATURAL_32]} an_object as l_spec_natural_32 then encode_special_natural_32 (l_spec_natural_32) else check l_spec_natural_32_not_void: False end end when {REFLECTOR_CONSTANTS}.natural_8_type then if attached {SPECIAL [NATURAL_8]} an_object as l_spec_natural_8 then encode_special_natural_8 (l_spec_natural_8) else check l_spec_natural_8_not_void: False end end when {REFLECTOR_CONSTANTS}.natural_16_type then if attached {SPECIAL [NATURAL_16]} an_object as l_spec_natural_16 then encode_special_natural_16 (l_spec_natural_16) else check l_spec_natural_16_not_void: False end end when {REFLECTOR_CONSTANTS}.natural_64_type then if attached {SPECIAL [NATURAL_64]} an_object as l_spec_natural_64 then encode_special_natural_64 (l_spec_natural_64) else check l_spec_natural_64_not_void: False end end when {REFLECTOR_CONSTANTS}.integer_8_type then if attached {SPECIAL [INTEGER_8]} an_object as l_spec_integer_8 then encode_special_integer_8 (l_spec_integer_8) else check l_spec_integer_8_not_void: False end end when {REFLECTOR_CONSTANTS}.integer_16_type then if attached {SPECIAL [INTEGER_16]} an_object as l_spec_integer_16 then encode_special_integer_16 (l_spec_integer_16) else check l_spec_integer_16_not_void: False end end when {REFLECTOR_CONSTANTS}.integer_32_type then if attached {SPECIAL [INTEGER_32]} an_object as l_spec_integer_32 then encode_special_integer_32 (l_spec_integer_32) else check l_spec_integer_32_not_void: False end end when {REFLECTOR_CONSTANTS}.integer_64_type then if attached {SPECIAL [INTEGER_64]} an_object as l_spec_integer_64 then encode_special_integer_64 (l_spec_integer_64) else check l_spec_integer_64_not_void: False end end when {REFLECTOR_CONSTANTS}.real_32_type then if attached {SPECIAL [REAL_32]} an_object as l_spec_real_32 then encode_special_real_32 (l_spec_real_32) else check l_spec_real_32_not_void: False end end when {REFLECTOR_CONSTANTS}.real_64_type then if attached {SPECIAL [REAL_64]} an_object as l_spec_real_64 then encode_special_real_64 (l_spec_real_64) else check l_spec_real_64_not_void: False end end when {REFLECTOR_CONSTANTS}.pointer_type then if attached {SPECIAL [POINTER]} an_object as l_spec_pointer then encode_special_pointer (l_spec_pointer) else check l_spec_pointer_not_void: False end end else check a_item_type_valid: a_item_type = {REFLECTOR_CONSTANTS}.reference_type end if attached {SPECIAL [detachable ANY]} an_object as l_spec_any then encode_special_reference (l_spec_any) else check l_spec_any_not_void: False end end end end frozen encode_special_boolean (a_spec: SPECIAL [BOOLEAN]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_boolean (a_spec.item (i)) i := i + 1 end end frozen encode_special_character_32 (a_spec: SPECIAL [CHARACTER_32]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_character_32 (a_spec.item (i)) i := i + 1 end end frozen encode_special_character_8 (a_spec: SPECIAL [CHARACTER_8]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_character_8 (a_spec.item (i)) i := i + 1 end end frozen encode_special_integer_16 (a_spec: SPECIAL [INTEGER_16]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_integer_16 (a_spec.item (i)) i := i + 1 end end frozen encode_special_integer_32 (a_spec: SPECIAL [INTEGER_32]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_integer_32 (a_spec.item (i)) i := i + 1 end end frozen encode_special_integer_64 (a_spec: SPECIAL [INTEGER_64]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_integer_64 (a_spec.item (i)) i := i + 1 end end frozen encode_special_integer_8 (a_spec: SPECIAL [INTEGER_8]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_integer_8 (a_spec.item (i)) i := i + 1 end end frozen encode_special_natural_16 (a_spec: SPECIAL [NATURAL_16]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_natural_16 (a_spec.item (i)) i := i + 1 end end frozen encode_special_natural_32 (a_spec: SPECIAL [NATURAL_32]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_natural_32 (a_spec.item (i)) i := i + 1 end end frozen encode_special_natural_64 (a_spec: SPECIAL [NATURAL_64]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_natural_64 (a_spec.item (i)) i := i + 1 end end frozen encode_special_natural_8 (a_spec: SPECIAL [NATURAL_8]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_natural_8 (a_spec.item (i)) i := i + 1 end end frozen encode_special_pointer (a_spec: SPECIAL [POINTER]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_pointer (a_spec.item (i)) i := i + 1 end end frozen encode_special_real_32 (a_spec: SPECIAL [REAL_32]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_real_32 (a_spec.item (i)) i := i + 1 end end frozen encode_special_real_64 (a_spec: SPECIAL [REAL_64]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_ser: like serializer do from nb := a_spec.count l_ser := serializer; l_ser.write_compressed_integer_32 (nb) until i = nb loop l_ser.write_real_64 (a_spec.item (i)) i := i + 1 end end frozen encode_special_reference (a_spec: SPECIAL [detachable ANY]) -- Encode a_spec. require a_spec_not_void: a_spec /= Void local i, nb: INTEGER_32 l_reflected_object: like reflected_object l_exp: REFLECTED_COPY_SEMANTICS_OBJECT l_ser: like serializer l_has_copy_semantics: BOOLEAN do l_ser := serializer nb := a_spec.count; l_ser.write_compressed_integer_32 (nb) if version >= {SED_VERSIONS}.version_7_3 then from l_reflected_object := reflected_object; l_reflected_object.set_object (a_spec) until i = nb loop if l_reflected_object.is_special_copy_semantics_item (i) then l_has_copy_semantics := True i := nb - 1 end i := i + 1 end; l_ser.write_boolean (l_has_copy_semantics) if l_has_copy_semantics then from i := 0 until i = nb loop if l_reflected_object.is_special_copy_semantics_item (i) then l_ser.write_boolean (True) l_exp := l_reflected_object.special_copy_semantics_item (i); l_ser.write_compressed_integer_32 (l_exp.dynamic_type) encode_normal_object (l_exp) else l_ser.write_boolean (False) encode_reference (a_spec.item (i)) end i := i + 1 end end end if not l_has_copy_semantics then from i := 0 until i = nb loop encode_reference (a_spec.item (i)) i := i + 1 end end end frozen encode_tuple_object (a_tuple: TUPLE) -- Encode a TUPLE object. require a_tuple_not_void: a_tuple /= Void local i, nb: INTEGER_32 l_code: NATURAL_8 l_ser: like serializer do from l_ser := serializer i := 1 nb := a_tuple.count + 1 until i = nb loop l_code := a_tuple.item_code (i); l_ser.write_natural_8 (l_code) inspect l_code when {TUPLE}.boolean_code then l_ser.write_boolean (a_tuple.boolean_item (i)) when {TUPLE}.character_8_code then l_ser.write_character_8 (a_tuple.character_8_item (i)) when {TUPLE}.character_32_code then l_ser.write_character_32 (a_tuple.character_32_item (i)) when {TUPLE}.natural_8_code then l_ser.write_natural_8 (a_tuple.natural_8_item (i)) when {TUPLE}.natural_16_code then l_ser.write_natural_16 (a_tuple.natural_16_item (i)) when {TUPLE}.natural_32_code then l_ser.write_natural_32 (a_tuple.natural_32_item (i)) when {TUPLE}.natural_64_code then l_ser.write_natural_64 (a_tuple.natural_64_item (i)) when {TUPLE}.integer_8_code then l_ser.write_integer_8 (a_tuple.integer_8_item (i)) when {TUPLE}.integer_16_code then l_ser.write_integer_16 (a_tuple.integer_16_item (i)) when {TUPLE}.integer_32_code then l_ser.write_integer_32 (a_tuple.integer_32_item (i)) when {TUPLE}.integer_64_code then l_ser.write_integer_64 (a_tuple.integer_64_item (i)) when {TUPLE}.real_32_code then l_ser.write_real_32 (a_tuple.real_32_item (i)) when {TUPLE}.real_64_code then l_ser.write_real_64 (a_tuple.real_64_item (i)) when {TUPLE}.pointer_code then l_ser.write_pointer (a_tuple.pointer_item (i)) when {TUPLE}.reference_code then encode_reference (a_tuple.reference_item (i)) else check False end end i := i + 1 end end Is_special_flag: NATURAL_8 = 1 -- (from SED_UTILITIES) Is_tuple_flag: NATURAL_8 = 2 -- Various flags for storing objects -- (from SED_UTILITIES) Is_void_safe: BOOLEAN -- Is current system compiled in void-safe mode? -- (from SED_UTILITIES) once Result := {SPECIAL [ANY]} /= {SPECIAL [detachable ANY]} end Special_type_mapping: HASH_TABLE [INTEGER_32, INTEGER_32] -- Mapping betwwen dynamic type of SPECIAL instances -- to abstract element types. -- (from SED_UTILITIES) once create Result.make (10); Result.put ({REFLECTOR_CONSTANTS}.boolean_type, ({BOOLEAN}).type_id); Result.put ({REFLECTOR_CONSTANTS}.character_8_type, ({CHARACTER_8}).type_id); Result.put ({REFLECTOR_CONSTANTS}.character_32_type, ({CHARACTER_32}).type_id); Result.put ({REFLECTOR_CONSTANTS}.natural_8_type, ({NATURAL_8}).type_id); Result.put ({REFLECTOR_CONSTANTS}.natural_16_type, ({NATURAL_16}).type_id); Result.put ({REFLECTOR_CONSTANTS}.natural_32_type, ({NATURAL_32}).type_id); Result.put ({REFLECTOR_CONSTANTS}.natural_64_type, ({NATURAL_64}).type_id); Result.put ({REFLECTOR_CONSTANTS}.integer_8_type, ({INTEGER_8}).type_id); Result.put ({REFLECTOR_CONSTANTS}.integer_16_type, ({INTEGER_16}).type_id); Result.put ({REFLECTOR_CONSTANTS}.integer_32_type, ({INTEGER_32}).type_id); Result.put ({REFLECTOR_CONSTANTS}.integer_64_type, ({INTEGER_64}).type_id); Result.put ({REFLECTOR_CONSTANTS}.real_32_type, ({REAL_32}).type_id); Result.put ({REFLECTOR_CONSTANTS}.real_64_type, ({REAL_64}).type_id); Result.put ({REFLECTOR_CONSTANTS}.pointer_type, ({POINTER}).type_id) ensure -- from SED_UTILITIES special_type_mapping_not_void: Result /= Void end write_header (a_list: ARRAYED_LIST [separate ANY]; a_type_table: HASH_TABLE [INTEGER_32, INTEGER_32]) -- Operation performed before encoding_objects. require a_list_not_void: a_list /= Void a_list_not_empty: not a_list.is_empty do write_settings write_object_table (a_list) end frozen write_object_table (a_list: ARRAYED_LIST [separate ANY]) -- Write mapping between object's reference ID in a_list with -- all the necessary information necessary to recreate it at a -- later time. require a_list_not_void: a_list /= Void a_list_not_empty: not a_list.is_empty local l_reflected_object: like reflected_object l_ser: like serializer l_object_indexes: like object_indexes i, nb: INTEGER_32 l_obj: separate ANY l_area: SPECIAL [separate ANY] do l_ser := serializer; l_ser.write_boolean (True) l_reflected_object := reflected_object l_object_indexes := object_indexes from l_area := a_list.area i := 0 nb := a_list.count until i = nb loop l_obj := l_area.item (i); l_reflected_object.set_object (l_obj) i := i + 1; l_ser.write_compressed_natural_32 (l_reflected_object.dynamic_type.to_natural_32); l_ser.write_compressed_natural_32 (l_object_indexes.index (l_obj)) if l_reflected_object.is_special then l_ser.write_natural_8 (Is_special_flag); l_ser.write_compressed_integer_32 (abstract_type (l_reflected_object.generic_dynamic_type (1))) if attached {ABSTRACT_SPECIAL} l_obj as l_abstract_spec then l_ser.write_compressed_integer_32 (l_abstract_spec.capacity) else check l_abstract_spec_attached: False end end elseif l_reflected_object.is_tuple then l_ser.write_natural_8 (Is_tuple_flag) else l_ser.write_natural_8 (0) end end end frozen write_settings do if is_store_settings_enabled then serializer.write_compressed_natural_32 (version); serializer.write_boolean (has_reference_with_copy_semantics) end end feature {NONE} -- Implementation: Access Breadth_first_traversable: OBJECT_GRAPH_BREADTH_FIRST_TRAVERSABLE -- Return an instance of OBJECT_GRAPH_BREADTH_FIRST_TRAVERSABLE. once Result := create {OBJECT_GRAPH_BREADTH_FIRST_TRAVERSABLE} end Depth_first_traversable: OBJECT_GRAPH_DEPTH_FIRST_TRAVERSABLE -- Return an instance of OBJECT_GRAPH_DEPTH_FIRST_TRAVERSABLE. once Result := create {OBJECT_GRAPH_DEPTH_FIRST_TRAVERSABLE} end object_indexes: SED_OBJECTS_TABLE -- Mapping between object and their associated index. reflected_object: REFLECTED_REFERENCE_OBJECT -- Facility to inspect object. reflector: REFLECTOR -- Facilities to inspect. traversable: OBJECT_GRAPH_TRAVERSABLE -- Object used for traversing object graph version: NATURAL_32 -- Internal version of the format (See SED_VERSIONS for possible values). feature {NONE} -- Implementation: Setting set_version (v: like version) -- Set version with v. do version := v end feature -- Output Io: STD_FILES -- Handle to standard file setup -- (from ANY) once create Result; Result.set_output_default ensure -- from ANY instance_free: class io_not_void: Result /= Void end out: STRING_8 -- New string containing terse printable representation -- of current object -- (from ANY) do Result := tagged_out ensure -- from ANY out_not_void: Result /= Void end print (o: detachable ANY) -- Write terse external representation of o -- on standard output. -- (from ANY) local s: READABLE_STRING_8 do if attached o then s := o.out if attached {READABLE_STRING_32} s as s32 then Io.put_string_32 (s32) elseif attached {READABLE_STRING_8} s as s8 then Io.put_string (s8) else Io.put_string_32 (s.as_string_32) end end ensure -- from ANY instance_free: class end frozen tagged_out: STRING_8 -- New string containing terse printable representation -- of current object -- (from ANY) external "built_in" ensure -- from ANY tagged_out_not_void: Result /= Void end feature -- Platform Operating_environment: OPERATING_ENVIRONMENT -- Objects available from the operating system -- (from ANY) once create Result ensure -- from ANY instance_free: class operating_environment_not_void: Result /= Void end feature {NONE} -- Retrieval frozen internal_correct_mismatch -- Called from runtime to perform a proper dynamic dispatch on correct_mismatch -- from MISMATCH_CORRECTOR. -- (from ANY) local l_msg: STRING_32 l_exc: EXCEPTIONS do if attached {MISMATCH_CORRECTOR} Current as l_corrector then l_corrector.correct_mismatch else create l_msg.make_from_string ("Mismatch: ".as_string_32) create l_exc; l_msg.append (generating_type.name_32); l_exc.raise_retrieval_exception (l_msg) end end invariant reflector_not_void: reflector /= Void reflected_object_not_void: reflected_object /= Void traversable_not_void: traversable /= Void serializer_not_void: serializer /= Void object_indexes_not_void: object_indexes /= Void -- from ANY reflexive_equality: standard_is_equal (Current) reflexive_conformance: conforms_to (Current) note library: "EiffelBase: Library of reusable components for Eiffel." copyright: "Copyright (c) 1984-2017, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end -- class SED_SESSION_SERIALIZER
Generated by ISE EiffelStudio