~rootmos/lua-hack

2d372dd6acd022f063bb691ac50b07b7d91c3a48 — Gustav Behm 1 year, 9 months ago 5738bb3
Add a bytes iterator for strings and files
2 files changed, 105 insertions(+), 0 deletions(-)

M char.lua
A char.test.lua
M char.lua => char.lua +38 -0
@@ 22,5 22,43 @@ M.is_lower = mk(function(b) return 97 <= b and b <= 122 end)
M.is_letter = mk(function(b) return (65 <= b and b <= 90) or (97 <= b and b <= 122) end)
M.is_digit = mk(function(b) return 48 <= b and b <= 57 end)
M.is_alphanum = mk(function(b) return (48 <= b and b <= 57) or (65 <= b and b <= 90) or (97 <= b and b <= 122) end)
M.is_whitespace = mk(function(b) return b == 32 or b == 9 end)

local function snext(s, i)
    i = i + 1
    local c = s:byte(i)
    if c == nil then
        return nil
    else
        return i, c
    end
end

local function fnext(st, o)
    o = o + 1
    if st.i >= #st.buf then
        st.buf = st.file:read(st.bufsize)
        st.i = 0
        if st.buf == nil then
            return nil
        end
    end
    st.i = st.i + 1
    return o, st.buf:byte(st.i)
end

function M.stream(x, bufsize)
    if type(x) == "string" then
        return snext, x, 0
    else
        return fnext, {buf={}, file=x, i=0, bufsize=bufsize or 4096}, 0
    end
end

function M.bytes(s)
    local t = {}
    s:gsub(".", function(c) table.insert(t, c:byte()) end)
    return t
end

return M

A char.test.lua => char.test.lua +67 -0
@@ 0,0 1,67 @@
local lu = require("luaunit")
local C = require("char")
local F = require("fresh")

function test_bytes()
	lu.assertEquals(C.bytes(""), {})
	lu.assertEquals(C.bytes("foo"), {102, 111, 111})
end

function collect(...)
	local t = {}
	for _, x in ... do
		table.insert(t, x)
	end
	return t
end

function test_stream_string_empty()
	lu.assertEquals(collect(C.stream("")), {})
end

function test_stream_string_foo()
	lu.assertEquals(collect(C.stream("foo")), C.bytes("foo"))
end

function test_stream_fresh_string()
    local bs = F.bytestring()
	lu.assertEquals(collect(C.stream(bs)), C.bytes(bs))
end

function test_stream_file_empty()
    local f = io.tmpfile()
	lu.assertEquals(collect(C.stream(f)), {})
    f:close()
end

function test_stream_file_foo()
    local f = io.tmpfile()
    f:write("foo")
    f:flush()
    f:seek("set")
	lu.assertEquals(collect(C.stream(f)), C.bytes("foo"))
    f:close()
end

function test_stream_fresh_file()
    local bs = F.bytestring()
    local f = io.tmpfile()
    f:write(bs)
    f:flush()
    f:seek("set")
	lu.assertEquals(collect(C.stream(f)), C.bytes(bs))
    f:close()
end

function test_stream_fresh_file_with_bufsize()
    local bs = F.bytestring()
    local f = io.tmpfile()
    f:write(bs)
    f:flush()
    f:seek("set")
    local bufsize = math.random(#bs)
	lu.assertEquals(collect(C.stream(f, bufsize)), C.bytes(bs))
    f:close()
end

os.exit(lu.LuaUnit.run())