unimportant

This commit is contained in:
Cosmin Apreutesei
2018-09-24 18:53:31 +03:00
parent 8b09d96635
commit 985b0b2f5a
2 changed files with 168 additions and 76 deletions
+102 -76
View File
@@ -12,6 +12,8 @@ local bundle = {}
local dir = arg[0]:gsub('[/\\]?[^/\\]+$', '') or '' --remove file name
dir = dir == '' and '.' or dir
--reading embedded blobs
local function getsym(sym)
return ffi.C[sym]
end
@@ -19,7 +21,7 @@ local function blob_data(file)
local sym = BBIN_PREFIX..file:gsub('[\\%-/%.]', '_')
pcall(ffi.cdef, 'void '..sym..'()')
local ok, p = pcall(getsym, sym)
if not ok then return end
if not ok then return nil end
local p = ffi.cast('const uint32_t*', p)
return ffi.cast('void*', p+1), p[0]
end
@@ -34,23 +36,108 @@ local function mmap_blob(file)
return data and {data = data, size = size, close = function() end}
end
function bundle.canopen(file)
local f = io.open(file, 'r')
if f then
f:close()
return true
end
local function canopen_blob(file)
return blob_data(file) and true or false
end
local function fs_open_blob(file)
local fs = require'fs'
local buf, sz = blob_data(file)
if not buf then return nil end
return fs.open_buffer(buf, sz)
end
function bundle.open_dir_listing(dir, s)
local path = require'path'
local entries = s and assert(loadstring(s))()
local d = {}
local closed, name, ftype
local i = 1
function d:next()
if closed then
return nil
end
if not entries then
closed = true
return false, 'not_found'
end
name = entries[i]
if not name then
closed = true
return nil
end
i = i + 1
name, ftype = name:match'^(.-)([/]?)$'
if ftype == '/' then
ftype = 'dir'
else
ftype = 'file'
end
return name, d
end
function d:close() closed = true; return true; end
function d:closed() return closed end
function d:name() return name end
function d:dir() return dir end
function d:path() return path.combine(dir, name) end
function d:attr(attr)
if attr == 'type' then
return ftype
elseif not attr then
return {type = ftype}
else
return nil
end
end
function d:is(ftype1) return ftype == ftype1 end
return d.next, d
end
local function fs_dir_blob(dir)
local fs = require'fs'
return bundle.open_dir_listing(dir, load_blob(dir))
end
--reading the filesystem
local function load_file(file)
file = dir..'/'..file
local f = io.open(file, 'rb')
if f then
local s = f:read'*a'
f:close()
return s
end
if not f then return nil end
local s = f:read'*a'
f:close()
return s
end
local function mmap_file(file)
local s = load_file(file)
if not s then return end
--TODO: use fs.mmap() here
return {data = ffi.cast('const void*', s), size = #s,
close = function() local _ = s; end}
end
local function canopen_file(file)
local f = io.open(file, 'r')
if f then f:close() end
return f and true or false
end
function fs_open_file(file)
local fs = require'fs'
return (fs.open(file))
end
function fs_dir_file(dir)
local fs = require'fs'
if not fs.is(dir, 'dir') then return nil end
return fs.dir(dir)
end
--user API
function bundle.canopen(file)
return canopen_file(file) or canopen_blob(file)
end
function bundle.load(file)
@@ -58,76 +145,15 @@ function bundle.load(file)
end
function bundle.mmap(file)
local s = load_file(file)
if s then
--TODO: use fs.mmap() here
return {data = ffi.cast('const void*', s), size = #s,
close = function() local _ = s; end}
else
return mmap_blob(file)
end
return mmap_file(file) or mmap_blob(file)
end
function bundle.fs_open(file)
local fs = require'fs'
local buf, sz = blob_data(file)
if not buf then
return fs.open(file)
else
return fs.open_buffer(buf, sz)
end
return fs_open_file(file) or fs_open_blob(file)
end
function bundle.fs_dir(dir)
local fs = require'fs'
local path = require'path'
if fs.is(dir, 'dir') then
return fs.dir(dir)
else
local s = load_blob(dir)
local entries = s and assert(loadstring(s))()
local d = {}
local closed, name, ftype
local i = 1
function d:next()
if closed then
return nil
end
if not entries then
closed = true
return false, 'not_found'
end
name = entries[i]
if not name then
closed = true
return nil
end
i = i + 1
name, ftype = name:match'^(.-)([/]?)$'
if ftype == '/' then
ftype = 'dir'
else
ftype = 'file'
end
return name, d
end
function d:close() closed = true; return true; end
function d:closed() return closed end
function d:name() return name end
function d:dir() return dir end
function d:path() return path.combine(dir, name) end
function d:attr(attr)
if attr == 'type' then
return ftype
elseif not attr then
return {type = ftype}
else
return nil
end
end
function d:is(ftype1) return ftype == ftype1 end
return d.next, d
end
return fs_dir_file(dir) or fs_dir_blob(dir)
end
local ok, ver = pcall(require, 'bundle_appversion')
+66
View File
@@ -0,0 +1,66 @@
--fs.dir() and fs.open() interfaces over mmapped tar-like files.
--Written by Cosmin Apreutesei. Public Domain.
local ffi = require'ffi'
local fs = require'fs'
local bundle = require'bundle'
local rat = {}
function rat:build(dir, write)
--TODO:
end
function rat:build_tofile(dir, file)
local f, err, errcode = fs.open(file, 'w')
if not f then
return nil, err, errcode
end
local function write(buf, sz)
return f:write(buf, sz)
end
local ok, err, errcode = rat:build(write)
f:close()
return ok, err, errcode
end
local mountpoint = {}
function rat:mount(buf, sz)
local mountpoint = {
data = ffi.cast('char*', buf),
size = sz,
_buffer = buf, --anchor it
__index = mountpoint,
}
local self = setmetatable(mountpoint, mountpoint)
self:init()
return self
end
function mountpoint:find_entry(path)
--TODO:
local ftype, offset, size
return ftype, offset, size
end
function mountpoint:init()
--TODO:
end
function mountpoint:dir(dir)
local ftype, offset, size = self:find_entry(dir)
local entries
local s = ftype == 'dir' and ffi.string(self.data + offset, size)
return bundle.open_dir_listing(dir, s)
end
function mountpoint:open(path, mode)
local ftype, offset, size = self:find_entry(path)
if not ftype then return nil, 'not_found' end
if ftype ~= 'file' then return nil, 'access_denied' end
return fs.open_buffer(self.data + offset, size)
end
return rat