Protocol::HTTPSourceProtocolHTTPBodyRewindable

class Rewindable

A body which buffers all it's contents as it is read.

As the body is buffered in memory, you may want to ensure your server has sufficient (virtual) memory available to buffer the entire body.

Definitions

def self.wrap(message)

Wrap the given message body in a rewindable body, if it is not already rewindable.

Signature

parameter message Request | Response

the message to wrap.

Implementation

def self.wrap(message)
	if body = message.body
		if body.rewindable?
			body
		else
			message.body = self.new(body)
		end
	end
end

def initialize(body)

Initialize the body with the given body.

Signature

parameter body Readable

the body to wrap.

Implementation

def initialize(body)
	super(body)
	
	@chunks = []
	@index = 0
end

def empty?

Signature

returns Boolean

Whether the body is empty.

Implementation

def empty?
	(@index >= @chunks.size) && super
end

def ready?

Signature

returns Boolean

Whether the body is ready to be read.

Implementation

def ready?
	(@index < @chunks.size) || super
end

def buffered

A rewindable body wraps some other body. Convert it to a buffered body. The buffered body will share the same chunks as the rewindable body.

Signature

returns Buffered

the buffered body.

Implementation

def buffered
	Buffered.new(@chunks)
end

def read

Read the next available chunk. This may return a buffered chunk if the stream has been rewound, or a chunk from the underlying stream, if available.

Signature

returns String | Nil

The chunk of data, or nil if the stream has finished.

Implementation

def read
	if @index < @chunks.size
		chunk = @chunks[@index]
		@index += 1
	else
		if chunk = super
			@chunks << -chunk
			@index += 1
		end
	end
	
	# We dup them on the way out, so that if someone modifies the string, it won't modify the rewindability.
	return chunk
end

def rewind

Rewind the stream to the beginning.

Implementation

def rewind
	@index = 0
end

def rewindable?

Signature

returns Boolean

Whether the stream is rewindable, which it is.

Implementation

def rewindable?
	true
end

def inspect

Inspect the rewindable body.

Signature

returns String

a string representation of the body.

Implementation

def inspect
	"\#<#{self.class} #{@index}/#{@chunks.size} chunks read>"
end