local strsub = string.sub
local t_insert = table.insert
local t_concat = table.concat

local function get_from_string ( s , i )
	i = i or 1
	return function ( n )
		if not n then -- Rest of string
			n = #s - i + 1
		end
		i = i + n
		assert ( i-1 <= #s , "Unable to read enough characters" )
		return strsub ( s , i-n , i-1 )
	end , function ( new_i )
		if new_i then i = new_i end
		return i
	end
end

local function string_to_array_of_chars ( s )
	local t = { }
	for i = 1 , #s do
		t [ i ] = strsub ( s , i , i )
	end
	return t
end

local function read_terminated_string ( get , terminators )
	local terminators = string_to_array_of_chars ( terminators or "\0" )
	local str = { }
	local found = 0
	while found < #terminators do
		local c = get ( 1 )
		if c == terminators [ found + 1 ] then
			found = found + 1
		else
			found = 0
		end
		t_insert ( str , c )
	end
	return t_concat ( str , "" , 1 , #str - #terminators )
end

return {
	get_from_string = get_from_string ;
	read_terminated_string = read_terminated_string ;
}
