test isEOF, File:read should return FileData

This commit is contained in:
Grump
2020-05-07 18:49:55 +02:00
parent 71b82b2989
commit ba9eb1e935
2 changed files with 36 additions and 38 deletions

View File

@@ -1,5 +1,5 @@
local ffi, bit = require('ffi'), require('bit') local ffi, bit = require('ffi'), require('bit')
local C = ffi.C local nativefs = {}
ffi.cdef([[ ffi.cdef([[
typedef struct FILE FILE; typedef struct FILE FILE;
@@ -15,15 +15,15 @@ ffi.cdef([[
int feof(FILE* stream); int feof(FILE* stream);
]]) ]])
local fopen, fclose, ftell, fseek, fflush, feof = C.fopen, C.fclose, C.ftell, C.fseek, C.fflush local C = ffi.C
local fread, fwrite, feof = C.fread, C.fwrite, C.feof local fclose, ftell, fseek, fflush, feof = C.fclose, C.ftell, C.fseek, C.fflush
local setvbuf = C.setvbuf local fread, fwrite, feof, setvbuf = C.fread, C.fwrite, C.feof, C.setvbuf
local getcwd, chdir, unlink local fopen, getcwd, chdir, unlink -- system specific
local BUFFERMODE = { local BUFFERMODE = {
full = ffi.os == 'Windows' and 0 or 0, full = 0,
line = ffi.os == 'Windows' and 64 or 1, line = 1,
none = ffi.os == 'Windows' and 4 or 2, none = 2,
} }
if ffi.os == 'Windows' then if ffi.os == 'Windows' then
@@ -57,10 +57,12 @@ if ffi.os == 'Windows' then
int _wunlink(const wchar_t* name); int _wunlink(const wchar_t* name);
]]) ]])
BUFFERMODE.line, BUFFERMODE.none = 64, 4
local function towidestring(str) local function towidestring(str)
local size = C.MultiByteToWideChar(65001, 0, str, #str, nil, 0) local size = C.MultiByteToWideChar(65001, 0, str, #str, nil, 0)
local buf = ffi.new("wchar_t[?]", size + 1) local buf = ffi.new("wchar_t[?]", size + 1)
C.MultiByteToWideChar(65001, 0, str, #str, buf, size + 1) C.MultiByteToWideChar(65001, 0, str, #str, buf, size)
return buf return buf
end end
@@ -88,13 +90,10 @@ else
local MAX_PATH = 4096 local MAX_PATH = 4096
local nameBuffer = ffi.new("char[?]", MAX_PATH) local nameBuffer = ffi.new("char[?]", MAX_PATH)
unlink, chdir = C.unlink, C.chdir fopen, unlink, chdir = C.fopen, C.unlink, C.chdir
getcwd = function() getcwd = function()
local cwd = C.getcwd(nameBuffer, MAX_PATH) local cwd = C.getcwd(nameBuffer, MAX_PATH)
if cwd == nil then return cwd and ffi.string(cwd) or nil
return nil
end
return ffi.string(cwd)
end end
end end
@@ -106,14 +105,14 @@ local File = {}
File.__index = File File.__index = File
function File:open(mode) function File:open(mode)
if self._mode ~= 'c' then if self._mode ~= 'c' then return false, "File is already open" end
return false, "File is already open"
if mode ~= 'r' and mode ~= 'w' and mode ~= 'a' then
return false, "Invalid file open mode: " .. mode
end end
mode = mode or 'r'
local handle = fopen(self._name, mode .. 'b') local handle = fopen(self._name, mode .. 'b')
if handle == nil then if handle == nil then
-- TODO: get error message
return false, "Could not open " .. self._name .. " in mode " .. mode return false, "Could not open " .. self._name .. " in mode " .. mode
end end
@@ -146,12 +145,7 @@ function File:setBuffer(mode, size)
self._bufferMode, self._bufferSize = mode, size self._bufferMode, self._bufferSize = mode, size
if self._mode == 'c' then return true end if self._mode == 'c' then return true end
if C.setvbuf(self._handle, nil, bufferMode, size) ~= 0 then return C.setvbuf(self._handle, nil, bufferMode, size) == 0
-- TODO: get error message
return false
end
return true
end end
function File:getBuffer() function File:getBuffer()
@@ -187,7 +181,7 @@ function File:getSize()
end end
function File:isEOF() function File:isEOF()
return self:isOpen() and feof(self._handle) or false return not self:isOpen() or feof(self._handle) ~= 0
end end
function File:isOpen() function File:isOpen()
@@ -200,15 +194,11 @@ function File:read(containerOrBytes, bytes)
end end
local container = bytes ~= nil and containerOrBytes or 'string' local container = bytes ~= nil and containerOrBytes or 'string'
bytes = bytes == nil and containerOrBytes or 'all' bytes = not bytes and containerOrBytes or 'all'
if bytes == 'all' then bytes = bytes == 'all' and self:getSize() - self:tell() or math.min(self:getSize() - self:tell(), bytes)
bytes = self:getSize() - self:tell()
else
bytes = math.min(self:getSize() - self:tell(), bytes)
end
if bytes <= 0 then if bytes <= 0 then
local data = container == 'string' and '' or love.data.newByteData(0) local data = container == 'string' and '' or love.data.newFileData('', self._name)
return data, 0 return data, 0
end end
@@ -219,6 +209,10 @@ function File:read(containerOrBytes, bytes)
local str = data:getString() local str = data:getString()
data:release() data:release()
data = str data = str
else
local fd = love.filesystem.newFileData(data:getString(), self._name)
data:release()
data = fd
end end
return data, r return data, r
end end
@@ -270,8 +264,6 @@ end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local nativefs = {}
function nativefs.newFile(name) function nativefs.newFile(name)
return setmetatable({ return setmetatable({
_name = name, _name = name,

View File

@@ -58,6 +58,8 @@ function test_fs_read()
local data, size = fs.read('data', 'data/ümläüt.txt', 'all') local data, size = fs.read('data', 'data/ümläüt.txt', 'all')
equals(size, textSize) equals(size, textSize)
equals(data:type(), 'FileData')
equals(data:getSize(), size)
equals(data:getString(), text) equals(data:getString(), text)
local foo, bar = fs.read('does_not_exist') local foo, bar = fs.read('does_not_exist')
@@ -141,16 +143,13 @@ end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function test_File()
end
function test_File_open() function test_File_open()
local f = fs.newFile('data/ümläüt.txt') local f = fs.newFile('data/ümläüt.txt')
notEquals(f, nil) notEquals(f, nil)
equals(f:isOpen(), false) equals(f:isOpen(), false)
equals(f:getMode(), 'c') equals(f:getMode(), 'c')
notFailed(f:open()) notFailed(f:open('r'))
equals(f:isOpen(), true) equals(f:isOpen(), true)
equals(f:getMode(), 'r') equals(f:getMode(), 'r')
@@ -171,6 +170,13 @@ function test_File_setBuffer()
end end
function test_File_isEOF() function test_File_isEOF()
local f = love.filesystem.newFile('data/ümläüt.txt')
f:open('r')
f:read(f:getSize() - 1)
equals(f:isEOF(), false)
f:read(1)
equals(f:isEOF(), true)
end end
function test_File_read() function test_File_read()