Skip to content

Commit

Permalink
Handle the case of a delimiter starting right after a delimiter look-…
Browse files Browse the repository at this point in the history
…like
  • Loading branch information
Ary Borenszweig committed Jul 23, 2023
1 parent e00ab0b commit 193515d
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
15 changes: 15 additions & 0 deletions spec/std/io/delimited_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,21 @@ describe "IO::Delimited" do
io.gets_to_end.should eq("")
end

it "handles the case of peek matching first byte, not having enough room, but rest not immediately matching (with a potential match afterwards)" do
# not a delimiter, but the second 'f' will actually match the delimiter
# ---
io = MemoryIOWithFixedPeek.new("abcdeffghijk")
# -------
# peek
io.peek_size = 7
delimited = IO::Delimited.new(io, read_delimiter: "fgh")

delimited.peek.should eq("abcde".to_slice)
delimited.gets_to_end.should eq("abcdef")
delimited.gets_to_end.should eq("")
io.gets_to_end.should eq("ijk")
end

it "handles the case of peek matching first byte, not having enough room, but later matching" do
# delimiter
# ---
Expand Down
11 changes: 6 additions & 5 deletions src/io/delimited.cr
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,12 @@ class IO::Delimited < IO
# doesn't match the read delimiter's portion, we can move on
rest = peek[index..]
unless rest == @read_delimiter[0, rest.size]
# If not, we can read from the peek buffer for now
slice.copy_from(peek)
@io.skip(peek.size)
slice += peek.size
return peek.size
# We can read up to past that byte for now
safe_to_read = peek[0, index + 1]
slice.copy_from(safe_to_read)
@io.skip(safe_to_read.size)
slice += safe_to_read.size
return safe_to_read.size
end

# Copy up to index into slice
Expand Down

0 comments on commit 193515d

Please sign in to comment.