Protocol::HTTPSourceProtocolHTTPBodyFile

class File

A body which reads from a file.

Definitions

BLOCK_SIZE = 64*1024

The default block size.

MODE = ::File::RDONLY | ::File::BINARY

The default mode for opening files.

def self.open(path, *arguments, **options)

Open a file at the given path.

Signature

parameter path String

the path to the file.

Implementation

def self.open(path, *arguments, **options)
	self.new(::File.open(path, MODE), *arguments, **options)
end

def initialize(file, range = nil, size: file.size, block_size: BLOCK_SIZE)

Initialize the file body with the given file.

Signature

parameter file ::File

the file to read from.

parameter range Range

the range of bytes to read from the file.

parameter size Integer

the size of the file, if known.

parameter block_size Integer

the block size to use when reading from the file.

Implementation

def initialize(file, range = nil, size: file.size, block_size: BLOCK_SIZE)
	@file = file
	@range = range
	
	@block_size = block_size
	
	if range
		@file.seek(range.min)
		@offset = range.min
		@length = @remaining = range.size
	else
		@file.seek(0)
		@offset = 0
		@length = @remaining = size
	end
end

def close(error = nil)

Close the file.

Signature

parameter error Exception | Nil

the error that caused the file to be closed.

Implementation

def close(error = nil)
	@file.close
	@remaining = 0
	
	super
end

attr :file

Signature

attribute ::File

file the file to read from.

attr :offset

Signature

attribute Integer

the offset to read from.

attr :length

Signature

attribute Integer

the number of bytes to read.

def empty?

Signature

returns Boolean

whether more data should be read.

Implementation

def empty?
	@remaining == 0
end

def ready?

Signature

returns Boolean

whether the body is ready to be read, always true for files.

Implementation

def ready?
	true
end

def buffered

Returns a copy of the body, by duplicating the file descriptor, including the same range if specified.

Signature

returns File

the duplicated body.

Implementation

def buffered
	self.class.new(@file.dup, @range, block_size: @block_size)
end

def rewind

Rewind the file to the beginning of the range.

Implementation

def rewind
	@file.seek(@offset)
	@remaining = @length
end

def rewindable?

Signature

returns Boolean

whether the body is rewindable, generally always true for seekable files.

Implementation

def rewindable?
	true
end

def read

Read the next chunk of data from the file.

Signature

returns String | Nil

the next chunk of data, or nil if the file is fully read.

Implementation

def read
	if @remaining > 0
		amount = [@remaining, @block_size].min
		
		if chunk = @file.read(amount)
			@remaining -= chunk.bytesize
			
			return chunk
		end
	end
end

def join

Read all the remaining data from the file and return it as a single string.

Signature

returns String

the remaining data.

Implementation

def join
	return "" if @remaining == 0
	
	buffer = @file.read(@remaining)
	
	@remaining = 0
	
	return buffer
end

def inspect

Inspect the file body.

Signature

returns String

a string representation of the file body.

Implementation

def inspect
	"\#<#{self.class} file=#{@file.inspect} offset=#{@offset} remaining=#{@remaining}>"
end