Skip to content

Instantly share code, notes, and snippets.

@MikuAuahDark
Last active November 5, 2021 06:48
Show Gist options
  • Save MikuAuahDark/e6428ac49248dd436f67c6c64fcec604 to your computer and use it in GitHub Desktop.
Save MikuAuahDark/e6428ac49248dd436f67c6c64fcec604 to your computer and use it in GitHub Desktop.
Lua 5.1 stringstream (pure)
local stringstream = {}
stringstream.__index = stringstream
function stringstream.create(str)
local out = setmetatable({}, stringstream)
out.buffer = str or ""
out.pos = 0
out.__index = stringstream
return out
end
function stringstream.read(ss, num)
if num == "*a" then
if ss.pos == #ss.buffer then
return nil
end
local out = ss.buffer:sub(ss.pos + 1)
ss.pos = #ss.buffer
return out
elseif num <= 0 then
return ""
end
local out = ss.buffer:sub(ss.pos + 1, ss.pos + num)
if #out == 0 then return nil end
ss.pos = math.min(ss.pos + num, #ss.buffer)
return out
end
-- FIXME: Should overwrite string instead
function stringstream.write(ss, ...)
local gap1 = ss.buffer:sub(1, ss.pos)
local gap2 = ss.buffer:sub(ss.pos + 1)
local con = {}
for i, v in ipairs({...}) do
con[i] = tostring(v)
end
con = table.concat(con)
ss.pos = ss.pos + #con
ss.buffer = gap1..con..gap2
return true
end
function stringstream.seek(ss, whence, offset)
whence = whence or "cur"
if whence == "set" then
ss.pos = offset or 0
elseif whence == "cur" then
ss.pos = ss.pos + (offset or 0)
elseif whence == "end" then
ss.pos = #ss.buffer + (offset or 0)
else
error("bad argument #1 to 'seek' (invalid option '"..tostring(whence).."')", 2)
end
ss.pos = math.min(math.max(ss.pos, 0), #ss.buffer)
return ss.pos
end
setmetatable(stringstream, {
__call = function(_, str)
return stringstream.create(str)
end
})
return stringstream
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment