indexing description: "[ Represents Internet IPv4 addresses. ]" date: "$Date$" revision: "$Revision$" class EM_INET_ADDRESS inherit ANY EM_SHARED_SUBSYSTEMS export {NONE} all {ANY} Network_subsystem end EM_SHARED_ERROR_HANDLER export {NONE} all end EM_NETWORK_HELPER_FUNCTIONS export {NONE} all end EM_NETWORK_CONSTANTS export {NONE} all end KL_IMPORTED_STRING_ROUTINES export {NONE} all end SDL_NET_FUNCTIONS_EXTERNAL export {NONE} all end NET2_FUNCTIONS_EXTERNAL export {NONE} all end create make_local, make_by_hostname, make_by_ip, make_by_ip_string feature {NONE} -- Initialization make_local is -- Creates a new IPv4 address for all network interfaces. require networking_enabled: network_subsystem.is_enabled do create resolve_finished_event create ip_address_struct.make_new_unshared ip_address_struct.set_host (convert_to_big_endian_32 (0)) hostname := "localhost" ensure hostname_set: hostname.is_equal ("localhost") resolve_finished_event_created: resolve_finished_event /= Void end make_by_hostname (a_host: STRING) is -- Create an unresolved IPv4 address by `a_host' -- `a_host' can be a full qualified hostname or an IPv4 address -- in textual representation (x.x.x.x). require networking_enabled: network_subsystem.is_enabled host_not_void: a_host /= Void host_not_empty: not a_host.is_empty do create resolve_finished_event create ip_address_struct.make_new_unshared ip_address_struct.set_host (convert_to_big_endian_32 (In_addr_unresolved)) hostname := a_host ensure hostname_set: hostname = a_host resolve_finished_event_created: resolve_finished_event /= Void end make_by_ip (an_ip: INTEGER) is -- Creates a new IPv4 address from `an_ip'. -- Use `reverse_resolve' to get the corresponding hostname. require networking_enabled: network_subsystem.is_enabled do create resolve_finished_event create ip_address_struct.make_new_unshared ip_address_struct.set_host (convert_to_big_endian_32 (an_ip)) create hostname.make_empty ensure ip_address_set: host_ip = an_ip hostname_not_void: hostname /= Void resolve_finished_event_created: resolve_finished_event /= Void end make_by_ip_string (an_ip_string: STRING) is -- Creates a new IPv4 address from `an_ip_string' -- Use `reverse_resolve' to get the corresponding hostname. require an_ip_string_not_void: an_ip_string /= Void is_valid_ip_string: is_valid_ip_string (an_ip_string) do create resolve_finished_event create ip_address_struct.make_new_unshared ip_address_struct.set_host (convert_to_big_endian_32 (convert_ip_string_to_ip (an_ip_string))) create hostname.make_empty ensure hostname_not_void: hostname /= Void resolve_finished_event_created: resolve_finished_event /= Void end feature -- Access hostname: STRING -- Hostname host_ip: INTEGER is -- Host IPv4 do Result := convert_from_big_endian_32 (ip_address_struct.host) end feature -- Status is_resolved: BOOLEAN is -- Is host_ip resolved? -- Is host_ip ready for usage? do Result := host_ip /= In_addr_unresolved end is_reverse_resolved: BOOLEAN is -- Is hostname reverse resolved? -- Ist hostname ready for usage? do Result := not hostname.is_empty end feature -- Status setting resolve_blocking is -- Resolve `host_ip' from `hostname'. -- This feature is blocking. require not_is_resolved: not is_resolved is_reverse_resolved: is_reverse_resolved local c_string: EWG_ZERO_TERMINATED_STRING do create c_string.make_unshared_from_string (hostname) if sdlnet_resolve_host_external (ip_address_struct.item, c_string.item, convert_from_big_endian_16 (ip_address_struct.port)) /= 0 then ip_address_struct.set_host (In_Addr_Any) end end resolve_non_blocking is -- Resolve `host_ip' from `hostname'. -- This feature is non-blocking. -- Subscribe to the `resolve_finished_event' and use `is_resolved' which indicates success or failure. require not_is_resolved: not is_resolved is_reverse_resolved: is_reverse_resolved local c_string: EWG_ZERO_TERMINATED_STRING a_transaction_id: INTEGER do create c_string.make_unshared_from_string (hostname) -- Setup resolve transaction a_transaction_id := Network_subsystem.sockets.next_transaction_id Network_subsystem.sockets.add_transaction (a_transaction_id, Current) net2_resolve_host_threaded_external (ip_address_struct.item, c_string.item, convert_from_big_endian_16 (ip_address_struct.port), a_transaction_id) end reverse_resolve_blocking is -- Reverse resolve `hostname' from `host_ip' -- This feature is blocking. require not_is_reverse_resolved: not is_reverse_resolved is_resolved: is_resolved local pointer: POINTER c_string: EWG_ZERO_TERMINATED_STRING do pointer := sdlnet_resolve_ip_external (ip_address_struct.item) if pointer /= default_pointer then create c_string.make_shared (pointer) hostname := c_string.string else hostname := "" end end feature -- Conversion host_ip_as_string: STRING is -- Host IP in textual representation (xy.xy.xy.xy) do create Result.make_empty Result.append (host_ip.bit_shift_right (24).bit_and (255).out + ".") Result.append (host_ip.bit_shift_right (16).bit_and (255).out + ".") Result.append (host_ip.bit_shift_right (8).bit_and (255).out + ".") Result.append (host_ip.bit_and (255).out) end to_hex_string: STRING is -- To IP in hexadecimal representation do Result := host_ip.to_hex_string end feature -- Events resolve_finished_event: EM_EVENT_CHANNEL[TUPLE[]] feature {EM_SOCKETS, EM_SOCKET, EM_UDP_PACKET} -- Implementation ip_address_struct: IPADDRESS_STRUCT -- IP Address Struct invariant hostname_set: hostname /= Void end