util.dbuffer: Add read_until() method

This commit is contained in:
Matthew Wild 2021-06-29 13:48:14 +01:00
parent 08253e2671
commit 4e56658eb3
2 changed files with 58 additions and 0 deletions

View file

@ -36,6 +36,50 @@ describe("util.dbuffer", function ()
end);
end);
describe(":read_until", function ()
it("works", function ()
local b = dbuffer.new();
b:write("hello\n");
b:write("world");
b:write("\n");
b:write("\n\n");
b:write("stuff");
b:write("more\nand more");
assert.equal(nil, b:read_until("."));
assert.equal(nil, b:read_until("%"));
assert.equal("hello\n", b:read_until("\n"));
assert.equal("world\n", b:read_until("\n"));
assert.equal("\n", b:read_until("\n"));
assert.equal("\n", b:read_until("\n"));
assert.equal("stu", b:read(3));
assert.equal("ffmore\n", b:read_until("\n"));
assert.equal(nil, b:read_until("\n"));
assert.equal("and more", b:read_chunk());
end);
it("works with multi-character sequences", function ()
local b = dbuffer.new();
b:write("hello\r\n");
b:write("world");
b:write("\r\n");
b:write("\r\n\r\n");
b:write("stuff");
b:write("more\r\nand more");
assert.equal(nil, b:read_until("."));
assert.equal(nil, b:read_until("%"));
assert.equal("hello\r\n", b:read_until("\r\n"));
assert.equal("world\r\n", b:read_until("\r\n"));
assert.equal("\r\n", b:read_until("\r\n"));
assert.equal("\r\n", b:read_until("\r\n"));
assert.equal("stu", b:read(3));
assert.equal("ffmore\r\n", b:read_until("\r\n"));
assert.equal(nil, b:read_until("\r\n"));
assert.equal("and more", b:read_chunk());
end);
end);
describe(":discard", function ()
local b = dbuffer.new();
it("works", function ()

View file

@ -76,6 +76,20 @@ function dbuffer_methods:read(requested_bytes)
return table.concat(chunks);
end
-- Read to, and including, the specified character sequence (return nil if not found)
function dbuffer_methods:read_until(char)
local buffer_pos = 0;
for i, chunk in self.items:items() do
local start = 1 + self.front_consumed;
local char_pos = chunk:find(char, start, true);
if char_pos then
return self:read(buffer_pos + (char_pos - start) + #char);
end
buffer_pos = buffer_pos + #chunk;
end
return nil;
end
function dbuffer_methods:discard(requested_bytes)
if requested_bytes > self._length then
return nil;