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