Skip to content

Commit 9e33894

Browse files
authored
Support output buffer in read_partial/readpartial. (#61)
1 parent a472da1 commit 9e33894

File tree

2 files changed

+56
-5
lines changed

2 files changed

+56
-5
lines changed

lib/protocol/http/body/stream.rb

+18-5
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,25 @@ def read(length = nil, buffer = nil)
8989
# Will avoid reading from the underlying stream if there is buffered data available.
9090
#
9191
# @parameter length [Integer] The maximum number of bytes to read.
92-
def read_partial(length = nil)
92+
def read_partial(length = nil, buffer = nil)
9393
if @buffer
94-
buffer = @buffer
94+
if buffer
95+
buffer.replace(@buffer)
96+
else
97+
buffer = @buffer
98+
end
9599
@buffer = nil
96100
else
97-
buffer = read_next
101+
if chunk = read_next
102+
if buffer
103+
buffer.replace(chunk)
104+
else
105+
buffer = chunk
106+
end
107+
else
108+
buffer&.clear
109+
buffer = nil
110+
end
98111
end
99112

100113
if buffer and length
@@ -111,8 +124,8 @@ def read_partial(length = nil)
111124
end
112125

113126
# Similar to {read_partial} but raises an `EOFError` if the stream is at EOF.
114-
def readpartial(length)
115-
read_partial(length) or raise EOFError, "End of file reached!"
127+
def readpartial(length, buffer = nil)
128+
read_partial(length, buffer) or raise EOFError, "End of file reached!"
116129
end
117130

118131
# Read data from the stream without blocking if possible.

test/protocol/http/body/stream.rb

+38
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,24 @@
121121
expect(stream.read_partial(2)).to be == "d"
122122
expect(stream.read_partial(2)).to be == nil
123123
end
124+
125+
it "can read partial input with buffer" do
126+
buffer = String.new
127+
expect(stream.read_partial(2, buffer)).to be == "He"
128+
expect(buffer).to be == "He"
129+
expect(stream.read_partial(2, buffer)).to be == "ll"
130+
expect(buffer).to be == "ll"
131+
expect(stream.read_partial(2, buffer)).to be == "o"
132+
expect(buffer).to be == "o"
133+
expect(stream.read_partial(2, buffer)).to be == "Wo"
134+
expect(buffer).to be == "Wo"
135+
expect(stream.read_partial(2, buffer)).to be == "rl"
136+
expect(buffer).to be == "rl"
137+
expect(stream.read_partial(2, buffer)).to be == "d"
138+
expect(buffer).to be == "d"
139+
expect(stream.read_partial(2, buffer)).to be == nil
140+
expect(buffer).to be == ""
141+
end
124142
end
125143

126144
with '#readpartial' do
@@ -129,6 +147,16 @@
129147
expect(stream.readpartial(20)).to be == "World"
130148
expect{stream.readpartial(20)}.to raise_exception(EOFError)
131149
end
150+
151+
it "can read partial input with buffer" do
152+
buffer = String.new
153+
expect(stream.readpartial(20, buffer)).to be == "Hello"
154+
expect(buffer).to be == "Hello"
155+
expect(stream.readpartial(20, buffer)).to be == "World"
156+
expect(buffer).to be == "World"
157+
expect{stream.readpartial(20, buffer)}.to raise_exception(EOFError)
158+
expect(buffer).to be == ""
159+
end
132160
end
133161

134162
with '#read_until' do
@@ -224,4 +252,14 @@
224252
expect(stream).to be(:closed?)
225253
end
226254
end
255+
256+
with 'IO.copy_stream' do
257+
let(:output) {StringIO.new}
258+
259+
it "can copy input to output" do
260+
::IO.copy_stream(stream, output)
261+
262+
expect(output.string).to be == "HelloWorld"
263+
end
264+
end
227265
end

0 commit comments

Comments
 (0)