Property definitions

libevent $ Connection :: defaultinit
# Spawned to manage a specific connection
class Connection
	super Writer

	# Closing this connection has been requested, but may not yet be `closed`
	var close_requested = false

	# This connection is closed
	var closed = false

	# The native libevent linked to `self`
	var native_buffer_event: NativeBufferEvent

	# Close this connection if possible, otherwise mark it to be closed later
	redef fun close
	do
		if closed then return

		var i = native_buffer_event.input_buffer
		var o = native_buffer_event.output_buffer
		if i.length > 0 or o.length > 0 then
			close_requested = true
		else
			force_close
		end
	end

	# Force closing this connection and freeing `native_buffer_event`
	fun force_close
	do
		if closed then return

		native_buffer_event.free
		closed = true
	end

	# Callback method on a write event
	fun write_callback
	do
		if close_requested then close
	end

	private fun read_callback_native(bev: NativeBufferEvent)
	do
		var evbuffer = bev.input_buffer
		var len = evbuffer.length
		var buf = new CString(len)
		evbuffer.remove(buf, len)
		var str = buf.to_s_with_length(len)
		read_callback str
	end

	# Callback method when data is available to read
	fun read_callback(content: String)
	do
		if close_requested then close
	end

	# Callback method on events: EOF, user-defined timeout and unrecoverable errors
	#
	# Returns `true` if the native handles to `self` can be released.
	fun event_callback(events: Int): Bool
	do
		if events & bev_event_error != 0 or events & bev_event_eof != 0 then
			if events & bev_event_error != 0 then
				var sock_err = evutil_socket_error
				# Ignore some normal errors and print the others for debugging
				if sock_err == 110 then
					# Connection timed out (ETIMEDOUT)
				else if sock_err == 104 then
					# Connection reset by peer (ECONNRESET)
				else
					print_error "libevent error event: {evutil_socket_error_to_string(sock_err)} ({sock_err})"
				end
			end
			force_close
			return true
		end

		return false
	end

	# Write a string to the connection
	redef fun write(str)
	do
		if close_requested then return
		native_buffer_event.write(str.to_cstring, str.byte_length)
	end

	redef fun write_byte(byte)
	do
		if close_requested then return
		native_buffer_event.write_byte(byte)
	end

	redef fun write_bytes_from_cstring(ns, len)
	do
		if close_requested then return
		native_buffer_event.write(ns, len)
	end

	# Write a file to the connection
	#
	# If `not path.file_exists`, the method returns.
	fun write_file(path: String)
	do
		if close_requested then return

		var file = new FileReader.open(path)
		if file.last_error != null then
			var error = new IOError("Failed to open file at '{path}'")
			error.cause = file.last_error
			self.last_error = error
			file.close
			return
		end

		var stat = file.file_stat
		if stat == null then
			last_error = new IOError("Failed to stat file at '{path}'")
			file.close
			return
		end

		var err = native_buffer_event.output_buffer.add_file(file.fd, 0, stat.size)
		if err then
			last_error = new IOError("Failed to add file at '{path}'")
			file.close
		end
	end
end
lib/libevent/libevent.nit:150,1--280,3