indexing description: "Base class for origo messages." author: "Patrick Ruckstuhl " date: "$Date$" revision: "$Revision$" deferred class O_MESSAGE inherit O_CONSTANTS redefine out end feature {NONE} -- Initialization make is -- Create. do id := uuid_generator.generate_uuid end make_from_generic (a_msg: O_GENERIC_MESSAGE) is -- Create from a generic message. require a_msge_not_void: a_msg /= Void do id := a_msg.id reply_id := a_msg.reply_id peer := a_msg.peer peer_name := a_msg.peer_name reply_handler := a_msg.reply_handler end feature -- Access namespace: STRING is -- Namespace of the message type. deferred ensure Result_ok: Result /= Void and then not Result.is_empty end type: STRING is -- Type of the message. deferred ensure Result_ok: Result /= Void and then not Result.is_empty end arguments: HASH_TABLE [STRING, STRING] is -- Table with named arguments. deferred ensure Result_not_void: Result /= Void end peer_name: STRING -- Name of the peer that sent the message. feature -- Update -- Set reply handler. set_reply_handler (a_handler: like reply_handler) is -- Call a_handler if a reply to this message is received. require a_handler_not_void: a_handler /= Void do reply_handler := a_handler ensure reply_handler_set: reply_handler = a_handler end feature {O_P2P_MODULE, O_MESSAGE} -- P2P access id: UUID -- A unique identifier for the message. reply_id: UUID -- Id this message is a reply to. peer: P2P_PEER_ID assign set_peer -- Message sender p2p_message: P2P_MESSAGE is -- P2P_MESSAGE for Current. require peer_set: peer /= Void peer_name_set: peer_name /= Void local l_args: like arguments do create Result.make -- create elements Result.extend (create {P2P_MESSAGE_ELEMENT}.make_string (message_namespace, namespace_element, Void, namespace)) Result.extend (create {P2P_MESSAGE_ELEMENT}.make_string (message_namespace, type_element, Void, type)) Result.extend (create {P2P_MESSAGE_ELEMENT}.make_string (message_namespace, id_element, Void, id.out)) Result.extend (create {P2P_MESSAGE_ELEMENT}.make_string (message_namespace, peer_element, Void, peer.out)) Result.extend (create {P2P_MESSAGE_ELEMENT}.make_string (message_namespace, peer_name_element, Void, peer_name)) if reply_id /= Void then Result.extend (create {P2P_MESSAGE_ELEMENT}.make_string (message_namespace, reply_id_element, Void, reply_id.out)) end from l_args := arguments l_args.start until l_args.after loop Result.extend (create {P2P_MESSAGE_ELEMENT}.make_string (message_argument_namespace, l_args.key_for_iteration, Void, l_args.item_for_iteration)) l_args.forth end end reply_handler: PROCEDURE [ANY, TUPLE [O_MESSAGE]] -- Handler to call if we receive a reply to this message. feature {O_P2P_MODULE} -- P2P update set_peer (a_peer: like peer) is -- Set peer to a_peer. require a_peer_not_void: a_peer /= Void -- peer_not_set: peer = Void do peer := a_peer ensure peer_set: peer = a_peer end set_peer_name (a_name: like peer_name) is -- Set peer_name to a_name. require a_name_ok: a_name /= Void and then not a_name.is_empty do peer_name := a_name ensure peer_name_set: peer_name = a_name end set_reply_id (a_id: like reply_id) is -- Set reply_id to a_id. require a_id_not_void: a_id /= Void do reply_id := a_id ensure reply_id_set: reply_id = a_id end feature -- Display out: STRING is -- Display. local l_args: like arguments do create Result.make (100) Result.append (namespace + "::" + type + "%N") Result.append ("ID: " + id.out + "%N") if reply_id /= Void then Result.append ("Reply ID: "+ reply_id.out + "%N") end if peer /= Void then Result.append ("Peer ID: "+ peer.out_short + "%N") end if peer_name /= Void then Result.append ("Peer Name: "+ peer_name + "%N") end from l_args := arguments l_args.start until l_args.after loop Result.append (l_args.key_for_iteration + " = " + l_args.item_for_iteration + "%N") l_args.forth end end feature -- Serialization serialize (a_object: ANY): STRING is -- Serialize `a_object'. require a_object_not_void: a_object /= Void local l_sed_rw: SED_MEMORY_READER_WRITER l_sed_ser: SED_INDEPENDENT_SERIALIZER l_cstring: C_STRING l_cnt: INTEGER do create l_sed_rw.make l_sed_rw.set_for_writing create l_sed_ser.make (l_sed_rw) l_sed_ser.set_root_object (a_object) l_sed_ser.encode -- the `count' gives us the number of bytes -- we have to read and put into the string. l_cnt := l_sed_rw.count create l_cstring.make_by_pointer_and_count (l_sed_rw.buffer.item, l_cnt) Result := l_cstring.substring (1, l_cnt) ensure serialize_not_void: Result /= Void end deserialize (a_string: STRING): ANY is -- Deserialize `a_string'. require a_string_not_void: a_string /= Void local l_sed_rw: SED_MEMORY_READER_WRITER l_sed_ser: SED_INDEPENDENT_DESERIALIZER l_cstring: C_STRING do create l_cstring.make (a_string) create l_sed_rw.make_with_buffer (l_cstring.managed_data) l_sed_rw.set_for_reading create l_sed_ser.make (l_sed_rw) l_sed_ser.decode (True) Result := l_sed_ser.last_decoded_object end feature {NONE} -- Implementation uuid_generator: UUID_GENERATOR is -- UUID generator. once create Result end invariant id_set: id /= Void end