Skip to content

Commit

Permalink
Try make IOPayload#to_io smart
Browse files Browse the repository at this point in the history
  • Loading branch information
spuun committed Oct 23, 2024
1 parent 6fe6a74 commit 123aab2
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
25 changes: 25 additions & 0 deletions spec/payload_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,29 @@ describe MQTT::Protocol::Payload do
(one == two).should be_false
end
end

describe "IOPayload" do
it "#to_slice should peek if possible" do
io = IO::Memory.new("foo".to_slice)
io.rewind

obj = MQTT::Protocol::IOPayload.new(io, 3)
data = obj.to_slice

Check warning on line 84 in spec/payload_spec.cr

View workflow job for this annotation

GitHub Actions / Ameba

Lint/UselessAssign

Useless assignment to variable `data`
Raw output
> data = obj.to_slice
  ^

obj.@data.should be_nil
end

it "#to_io should not affect position" do
io = IO::Memory.new("foo".to_slice)
io.rewind

obj = MQTT::Protocol::IOPayload.new(io, 3)

dst = IO::Memory.new
obj.to_io(dst)

obj.@data.should be_nil
obj.@io.pos.should eq(0)
end
end
end
17 changes: 14 additions & 3 deletions src/mqtt/protocol/payload.cr
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ module MQTT
end

struct IOPayload < Payload
alias IOWithPosition = ::IO::Memory | ::IO::FileDescriptor

getter bytesize : Int32

@data : Bytes? = nil
Expand All @@ -62,19 +64,28 @@ module MQTT
if peeked = @io.peek.try &.[0, bytesize]?
return peeked
end
return @data || begin
@data ||= begin
data = Bytes.new(bytesize)
@io.read(data)
data
end
end

def to_io(io, format : ::IO::ByteFormat = ::IO::ByteFormat::SystemEndian)
# Use data that has already been copied to memory
if data = @data
io.write data
else
copied = ::IO.copy(@io, io, bytesize)
raise "Failed to copy payload" if copied != bytesize
# else try to copy
if @io.io.is_a?(IOWithPosition)
pos = @io.pos
copied = ::IO.copy(@io, io, bytesize)
raise "Failed to copy payload" if copied != bytesize
@io.pos = pos
else
# copy to memory and write
io.write to_slice
end
end
end
end
Expand Down

0 comments on commit 123aab2

Please sign in to comment.