indexing
	description: "Data resources"
	status: "See note at end of class"
	date: "$Date$"
	revision: "$Revision$"

deferred class interface
	DATA_RESOURCE

feature -- Access

	address: URL
			-- Associated address

	hash_code: INTEGER
			-- Hash function
		ensure -- from HASHABLE
			good_hash_value: Result >= 0

	last_packet: STRING
			-- Last packet read

	location: STRING
			-- Location of resource
		require
			address_exists: address /= void

	mode: INTEGER
			-- Current mode

	port: INTEGER
			-- Port used by service

	service: STRING
			-- Name of service
	
feature -- Measurement

	bytes_transferred: INTEGER
			-- Number of transferred bytes

	count: INTEGER
			-- Size of data resource

	last_packet_size: INTEGER
			-- Size of last packet

	read_buffer_size: INTEGER
			-- Size of read buffer
	
feature -- Comparison

	is_equal (other: like Current): BOOLEAN
			-- Is resource equal to other?
		require -- from ANY
			other_not_void: other /= void
		ensure -- from ANY
			symmetric: Result implies other.is_equal (Current)
			consistent: standard_is_equal (other) implies Result
	
feature -- Status report

	address_exists: BOOLEAN
			-- Does address exists?

	error: BOOLEAN
			-- Has an error occurred?

	error_code: INTEGER
			-- Code of error

	error_text (code: INTEGER): STRING
			-- Textual description of error
			-- (from DATA_RESOURCE_ERROR_CONSTANTS)
		require -- from DATA_RESOURCE_ERROR_CONSTANTS
			positive_code: code > 0

	has_packet: BOOLEAN
			-- Is there a packet available in last_packet?

	is_count_valid: BOOLEAN
			-- Is value in count valid?

	is_hashable: BOOLEAN
			-- Are objects of current type hashable?
		ensure -- from HASHABLE
			ok_if_not_default: Result implies (Current /= default)

	is_mode_set: BOOLEAN
			-- Has resource mode been set?

	is_open: BOOLEAN
			-- Is resource open?

	is_packet_pending: BOOLEAN
			-- Can another packet currently be read out?

	is_proxy_supported: BOOLEAN
			-- Is proxy supported by resource?

	is_readable: BOOLEAN
			-- Is it possible to open in read mode currently?
		ensure
			mode_unchanged: mode = old mode

	is_writable: BOOLEAN
			-- Is it possible to open in write mode currently?
		ensure
			mode_unchanged: mode = old mode

	read_mode: BOOLEAN
			-- Is read mode set?

	supports_multiple_transactions: BOOLEAN
			-- Does resource support multiple tranactions per connection?

	timeout: INTEGER
			-- Connection timeout

	transfer_initiated: BOOLEAN
			-- Has transfer being initiated.

	valid_mode (n: INTEGER): BOOLEAN
			-- Is mode n valid?

	write_mode: BOOLEAN
			-- Is write mode set?
	
feature -- Status setting

	close
			-- Close.
		require
			open: is_open
		ensure
			closed: not is_open
			mode_unchanged: mode = old mode
			no_packet_available: not (has_packet and is_packet_pending)

	initiate_transfer
			-- Initiate transfer.
		require
			no_error_occurred: not error
			mode_set: is_mode_set
			open: is_open
			not_initiated: not transfer_initiated
		ensure
			failure_means_error: not transfer_initiated implies error

	open
			-- Open resource.
		require
			no_error_occurred: not error
			mode_set: is_mode_set
		ensure
			no_packet_available: not (has_packet and is_packet_pending)
			initiated_flag_reset: not transfer_initiated
			failure_means_error: not is_open implies error

	reset_error
			-- Reset error.
		ensure
			error_reset: not error

	reset_proxy
			-- Reset proxy information.
		ensure
			proxy_reset: not address.is_proxy_used

	reuse_connection (other: DATA_RESOURCE)
			-- Reuse connection of other.
		require
			other_exists: other /= void
			same_type: same_type (other)
			supports_multiple_transactions: supports_multiple_transactions and other.supports_multiple_transactions
			other_opened: other.is_open

	set_password (pw: STRING)
			-- Set password to pw.
		require
			password_accepted: address.is_password_accepted
			non_empty_password: pw /= void and then not pw.is_empty

	set_port (port_no: INTEGER)
			-- Set port number to port_no.
		require
			closed: not is_open
			non_negative_port_number: port_no >= 0
		ensure
			port_set: port = port_no

	set_proxy (host: STRING; port_no: INTEGER)
			-- Set proxy host to host and port to port_no.
		require
			proxy_supported: is_proxy_supported
			closed: not is_open
			non_empty_host: host /= void and then not host.is_empty
			host_ok: address.proxy_host_ok (host)
			non_negative_port: port_no >= 0
		ensure
			proxy_set: address.is_proxy_used

	set_proxy_information (pi: PROXY_INFORMATION)
			-- Set proxy information to pi.
		require
			proxy_supported: is_proxy_supported
		ensure
			proxy_set: address.is_proxy_used

	set_read_buffer_size (n: INTEGER)
			-- Set size of read buffer.
		require
			size_positive: n > 0
		ensure
			buffer_size_set: read_buffer_size = n

	set_read_mode
			-- Set read mode.
		ensure
			read_mode_set: read_mode

	set_timeout (n: INTEGER)
			-- Set connection timeout to n.
		require
			non_negative: n >= 0
		ensure
			timeout_set: timeout = n

	set_username (un: STRING)
			-- Set username to un.
		require
			username_accepted: address.has_username
			non_empty_username: un /= void and then not un.is_empty

	set_write_mode
			-- Set write mode.
		ensure
			write_mode_set: write_mode
	
feature -- Removal

	dispose
			-- Clean up resource.
	
feature -- Input

	read
			-- Read packet.
		require
			no_error_occurred: not error
			open: is_open
			transfer_initated: transfer_initiated
			readable: is_readable
			positive_read_buffer_size: read_buffer_size > 0
			packet_pending: is_packet_pending
		ensure
			packet_received: is_packet_pending implies last_packet_size > 0
			counter_correct: not error implies bytes_transferred = old bytes_transferred + last_packet_size
	
feature -- Output

	put (other: DATA_RESOURCE)
			-- Write out resource other.
		require
			no_error_occurred: not (error and other.error)
			other_resource_exists: other /= void
			resources_open: is_open and other.is_open
			writable: is_writable
			transfer_initated: transfer_initiated
	
invariant

	address_assigned: address /= void
	timeout_non_negative: timeout >= 0
	packet_constraint: not (has_packet xor last_packet /= void)
	pending_constraint: is_packet_pending implies (is_open and is_readable and transfer_initiated)
	error_definition: error = (error_code /= 0)
	valid_count_constraint: count > 0 implies is_count_valid
	mode_constraint: is_mode_set = read_mode xor write_mode
		-- from ANY
	reflexive_equality: standard_is_equal (Current)
	reflexive_conformance: conforms_to (Current)

end -- class DATA_RESOURCE