diff --git a/spec/std/io/io_spec.cr b/spec/std/io/io_spec.cr index ac51d4bddaea..e2c065ecebf0 100644 --- a/spec/std/io/io_spec.cr +++ b/spec/std/io/io_spec.cr @@ -183,6 +183,40 @@ describe IO do io.gets(chomp: false).should be_nil end + it "does gets with empty string (no peek)" do + io = SimpleIOMemory.new("") + io.gets(chomp: true).should be_nil + end + + it "does gets with empty string (with peek)" do + io = IO::Memory.new("") + io.gets(chomp: true).should be_nil + end + + it "does gets with \\n (no peek)" do + io = SimpleIOMemory.new("\n") + io.gets(chomp: true).should eq("") + io.gets(chomp: true).should be_nil + end + + it "does gets with \\n (with peek)" do + io = IO::Memory.new("\n") + io.gets(chomp: true).should eq("") + io.gets(chomp: true).should be_nil + end + + it "does gets with \\r\\n (no peek)" do + io = SimpleIOMemory.new("\r\n") + io.gets(chomp: true).should eq("") + io.gets(chomp: true).should be_nil + end + + it "does gets with \\r\\n (with peek)" do + io = IO::Memory.new("\r\n") + io.gets(chomp: true).should eq("") + io.gets(chomp: true).should be_nil + end + it "does gets with big line" do big_line = "a" * 20_000 io = SimpleIOMemory.new("#{big_line}\nworld\n") diff --git a/src/io.cr b/src/io.cr index 0294ec0272b7..28a3652c9e4c 100644 --- a/src/io.cr +++ b/src/io.cr @@ -752,11 +752,12 @@ abstract class IO private def gets_slow(delimiter : Char, limit, chomp) buffer = String::Builder.new - gets_slow(delimiter, limit, chomp, buffer) - buffer.empty? ? nil : buffer.to_s + bytes_read = gets_slow(delimiter, limit, chomp, buffer) + buffer.to_s if bytes_read end - private def gets_slow(delimiter : Char, limit, chomp, buffer : String::Builder) : Nil + private def gets_slow(delimiter : Char, limit, chomp, buffer : String::Builder) : Bool + bytes_read = false chomp_rn = delimiter == '\n' && chomp while true @@ -766,6 +767,7 @@ abstract class IO end char, char_bytesize = info + bytes_read = true # Consider the case of \r\n when the delimiter is \n and chomp = true if chomp_rn && char == '\r' @@ -801,6 +803,8 @@ abstract class IO break if char_bytesize >= limit limit -= char_bytesize end + + bytes_read end # Reads until *delimiter* is found or the end of the `IO` is reached.