Skip to content

Commit 1d9bafc

Browse files
committed
add readbyterange
1 parent 25b3f63 commit 1d9bafc

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

lua/plenary/path2.lua

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,6 +1282,53 @@ function Path:tail(lines)
12821282
return (table.concat(data):gsub("[\r\n]$", ""))
12831283
end
12841284

1285+
---@param offset integer
1286+
---@param length integer
1287+
---@return string
1288+
function Path:readbyterange(offset, length)
1289+
vim.validate {
1290+
offset = { offset, "n" },
1291+
length = { length, "n" },
1292+
}
1293+
1294+
local stat = self:_get_readable_stat()
1295+
local fd, err = uv.fs_open(self:absolute(), "r", 438)
1296+
if fd == nil then
1297+
error(err)
1298+
end
1299+
1300+
if offset < 0 then
1301+
offset = stat.size + offset
1302+
-- Windows fails if offset is < 0 even though offset is defined as signed
1303+
-- http://docs.libuv.org/en/v1.x/fs.html#c.uv_fs_read
1304+
if offset < 0 then
1305+
offset = 0
1306+
end
1307+
end
1308+
1309+
local data = ""
1310+
local read_chunk
1311+
while #data < length do
1312+
-- local read_chunk = assert(uv.fs_read(fd, length - #data, offset))
1313+
read_chunk, err = uv.fs_read(fd, length - #data, offset)
1314+
if read_chunk == nil then
1315+
error(err)
1316+
end
1317+
if #read_chunk == 0 then
1318+
break
1319+
end
1320+
data = data .. read_chunk
1321+
offset = offset + #read_chunk
1322+
end
1323+
1324+
_, err = uv.fs_close(fd)
1325+
if err ~= nil then
1326+
error(err)
1327+
end
1328+
1329+
return data
1330+
end
1331+
12851332
--- write to file
12861333
---@param data string|string[] data to write
12871334
---@param flags uv.aliases.fs_access_flags|integer flag used to open file (eg. "w" or "a")

tests/plenary/path2_spec.lua

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,4 +1085,20 @@ SOFTWARE.]]
10851085
assert.are.same(expect, data, diff_str(expect, data))
10861086
end)
10871087
end)
1088+
1089+
describe("readbyterange", function()
1090+
it_cross_plat("should read bytes at given offset", function()
1091+
local p = Path:new "LICENSE"
1092+
local data = p:readbyterange(13, 10)
1093+
local should = "Copyright "
1094+
assert.are.same(should, data)
1095+
end)
1096+
1097+
it_cross_plat("supports negative offset", function()
1098+
local p = Path:new "LICENSE"
1099+
local data = p:readbyterange(-10, 10)
1100+
local should = "SOFTWARE.\n"
1101+
assert.are.same(should, data)
1102+
end)
1103+
end)
10881104
end)

0 commit comments

Comments
 (0)