vio/vio.lua

1
local vio = {};
2
vio.__index = vio; 
3
	
4
function vio.open(string)
5
	return setmetatable({ pos = 1, data = string }, vio);
6
end
7
 
8
function vio:read(format, ...)
9
	if self.pos >= #self.data then return; end
10
	if format == "*a" then
11
		local oldpos = self.pos;
12
		self.pos = #self.data;
13
		return self.data:sub(oldpos, self.pos);
14
	elseif format == "*l" then
15
		local data;
16
		data, self.pos = self.data:match("([^\r\n]*)\r?\n?()", self.pos)
17
		return data;
18
	elseif format == "*n" then
19
		local data;
20
		data, self.pos = self.data:match("(%d+)()", self.pos)
21
		return tonumber(data);	
22
	elseif type(format) == "number" then
23
		local oldpos = self.pos;
24
		self.pos = self.pos + format;
25
		return self.data:sub(oldpos, self.pos-1);
26
	end
27
end
28
 
29
function vio:seek(whence, offset)
30
	if type(whence) == "number" then
31
		whence, offset = "cur", whence;
32
	end
33
	offset = offset or 0;
34
	
35
	if whence == "cur" then
36
		self.pos = self.pos + offset;
37
	elseif whence == "set" then
38
		self.pos = offset + 1;
39
	elseif whence == "end" then
40
		self.pos = #self.data - offset;
41
	end
42
	
43
	return self.pos;
44
end
45
 
46
local function _readline(f) return f:read("*l"); end
47
function vio:lines()
48
	return _readline, self;
49
end
50
 
51
function vio:write(...)
52
	for i=1,select('#', ...) do
53
		local dat = tostring(select(i, ...));
54
		self.data = self.data:sub(1, self.pos-1)..dat..self.data:sub(self.pos+#dat, -1);
55
	end
56
end
57
 
58
function vio:close()
59
	self.pos, self.data = nil, nil;
60
end