parsav  file.t at [25e05466d5]

File file.t artifact fc7770c3f7 part of check-in 25e05466d5


-- 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