-- vim: ft=terra
-- TODO: add support for windows IO calls
local handle_type = int
local posix = terralib.includec 'fcntl.h'
local unistd = terralib.includec 'unistd.h'
struct file {
handle: handle_type
read: bool
write: bool
}
file.mode = { read = 0, write = 1, rw = 2 }
file.seek = { abs = 0, ofs = 1, eof = 2 }
file.methods = {
open = terra(path: rawstring, mode: uint8)
var f: file
var flag: int
if mode == [file.mode.rw] then
flag = posix.O_RDWR
f.read = true f.write = true
elseif mode == [file.mode.read] then
flag = posix.O_RDONLY
f.read = true f.write = false
elseif mode == [file.mode.read] then
flag = posix.O_WRONLY
f.read = false f.write = true
else lib.bail('invalid file mode') end
lib.dbg('opening file ', path)
f.handle = posix.open(path, flag)
var r: lib.stat(file)
if f.handle == -1 then
r.ok = false
r.error = 1 -- TODO get errno somehow?
else
r.ok = true
r.val = f
end
return r
end;
close = terra(self: &file)
unistd.close(self.handle)
self.handle = -1
self.read = false
self.write = false
end;
read = terra(self: &file, dest: rawstring, sz: intptr): ptrdiff
return unistd.read(self.handle,dest,sz)
end;
write = terra(self: &file, data: &opaque, sz: intptr): ptrdiff
return unistd.write(self.handle,data,sz)
end;
seek = terra(self: &file, ofs: ptrdiff, wh: int)
var whence: int
if wh == [file.seek.abs] then
whence = unistd.SEEK_SET
elseif wh == [file.seek.ofs] then
whence = unistd.SEEK_CUR
elseif wh == [file.seek.eof] then
whence = unistd.SEEK_END
else lib.bail('invalid seek mode') end
return unistd.lseek(self.handle, ofs, whence)
end;
}
return file