This commit is contained in:
Grump
2020-06-18 13:01:39 +02:00
parent 30d36b97e1
commit 3d4a838105
2 changed files with 52 additions and 36 deletions

View File

@@ -11,7 +11,7 @@ local File = {
local fopen, getcwd, chdir, unlink, mkdir, rmdir
local BUFFERMODE, MODEMAP
local ByteArray = ffi.typeof('unsigned char[?]')
local function _ptr(p) return p ~= nil and p or nil end
local function _ptr(p) return p ~= nil and p or nil end -- NULL pointer to nil
function File:open(mode)
if self._mode ~= 'c' then return false, "File " .. self._name .. " is already open" end
@@ -20,11 +20,9 @@ function File:open(mode)
local handle = _ptr(fopen(self._name, MODEMAP[mode]))
if not handle then return false, "Could not open " .. self._name .. " in mode " .. mode end
if C.setvbuf(handle, nil, BUFFERMODE[self._bufferMode], self._bufferSize) ~= 0 then
self._bufferMode, self._bufferSize = 'none', 0
end
self._handle, self._mode = ffi.gc(handle, C.fclose), mode
self:setBuffer(self._bufferMode, self._bufferSize)
return true
end
@@ -48,12 +46,13 @@ function File:setBuffer(mode, size)
end
local success = self._mode == 'c' or C.setvbuf(self._handle, nil, bufferMode, size) == 0
if success then
self._bufferMode, self._bufferSize = mode, size
return true
if not success then
self._bufferMode, self._bufferSize = 'none', 0
return false, "Could not set buffer mode"
end
return false, "Could not set buffer mode"
self._bufferMode, self._bufferSize = mode, size
return true
end
function File:getSize()
@@ -311,28 +310,25 @@ function nativefs.remove(name)
return true
end
local function withTempMount(dir, fn)
local function withTempMount(dir, fn, ...)
local mountPoint = _ptr(loveC.PHYSFS_getMountPoint(dir))
if mountPoint then return fn(ffi.string(mountPoint)) end
if mountPoint then return fn(ffi.string(mountPoint), ...) end
if not nativefs.mount(dir, '__nativefs__temp__') then return false, "Could not mount " .. dir end
local a, b = fn('__nativefs__temp__')
local a, b = fn('__nativefs__temp__', ...)
nativefs.unmount(dir)
return a, b
end
function nativefs.getDirectoryItems(dir)
local result, err = withTempMount(dir, function(mount)
return love.filesystem.getDirectoryItems(mount)
end)
local result, err = withTempMount(dir, love.filesystem.getDirectoryItems)
return result or {}
end
function nativefs.getDirectoryItemsInfo(path, filtertype)
local result, err = withTempMount(path, function(mount)
local function getDirectoryItemsInfo(path, filtertype)
local items = {}
local files = love.filesystem.getDirectoryItems(mount)
local files = love.filesystem.getDirectoryItems(path)
for i = 1, #files do
local filepath = string.format('%s/%s', mount, files[i])
local filepath = string.format('%s/%s', path, files[i])
local info = love.filesystem.getInfo(filepath, filtertype)
if info then
info.name = files[i]
@@ -340,23 +336,29 @@ function nativefs.getDirectoryItemsInfo(path, filtertype)
end
end
return items
end)
end
function nativefs.getDirectoryItemsInfo(path, filtertype)
local result, err = withTempMount(path, getDirectoryItemsInfo, filtertype)
return result or {}
end
local function getInfo(path, file, filtertype)
local filepath = string.format('%s/%s', path, file)
return love.filesystem.getInfo(filepath, filtertype)
end
function nativefs.getInfo(path, filtertype)
local dir = path:match("(.*[\\/]).*$") or './'
local file = love.path.leaf(path)
local result, err = withTempMount(dir, function(mount)
local filepath = string.format('%s/%s', mount, file)
return love.filesystem.getInfo(filepath, filtertype)
end)
local result, err = withTempMount(dir, getInfo, file, filtertype)
return result or nil
end
-----------------------------------------------------------------------------
MODEMAP = { r = 'rb', w = 'wb', a = 'ab' }
local MAX_PATH = 4096
ffi.cdef([[
int PHYSFS_mount(const char* dir, const char* mountPoint, int appendToPath);
@@ -406,7 +408,6 @@ if ffi.os == 'Windows' then
return ffi.string(buf)
end
local MAX_PATH = 260
local nameBuffer = ffi.new('wchar_t[?]', MAX_PATH + 1)
fopen = function(path, mode) return C._wfopen(towidestring(path), towidestring(mode)) end
@@ -426,7 +427,6 @@ else
int rmdir(const char* path);
]])
local MAX_PATH = 4096
local nameBuffer = ByteArray(MAX_PATH)
fopen = C.fopen

View File

@@ -137,14 +137,24 @@ function test_fs_getDirectoryItems()
for i = 1, #items2 do
equals(map[items2[i]], map2[items2[i]])
equals(fs.getInfo('data/' .. items2[i]), love.filesystem.getInfo('data/' .. items2[i]))
end
equals(#fs.getDirectoryItems('does_not_exist'), 0)
end
function test_fs_getDirectoryItemsInfo()
local items, map = fs.getDirectoryItems('data'), {}
for i = 1, #items do map[items[i]] = true end
local files = fs.getDirectoryItems('data')
local items, map = {}, {}
for i = 1, #files do
local info = fs.getInfo('data/' .. files[i])
if info then
info.name = files[i]
table.insert(items, info)
end
end
for i = 1, #items do map[items[i].name] = true end
local itemsEx, mapEx = fs.getDirectoryItemsInfo('data'), {}
for i = 1, #itemsEx do mapEx[itemsEx[i].name] = itemsEx[i] end
@@ -203,6 +213,12 @@ function test_fs_getInfo()
equals(info.type, 'file')
equals(info.size, testSize1)
notEquals(info.modtime, nil)
local info = fs.getInfo(testFile2)
notEquals(info, nil)
equals(info.type, 'file')
equals(info.size, testSize2)
notEquals(info.modtime, nil)
end
function test_fs_createDirectory()