private ListData ParseListData(Stream stream)
{
var listData = new ListData();
var redirects = new List<string>();
Regex regex = new Regex(@"^(e|r|n|i|u|sd|ad)\:(.+)$");
Match match = null;
string line = null, type = null, value = null;
int state = 0xA;
bool error = false;
var sr = new StreamReader(stream);
//simple state machine
while (!sr.EndOfStream)
{
line = sr.ReadLine();
match = regex.Match(line);
if (!match.Success)
continue; //client must ignore lines it does not understand
type = match.Groups[1].Value;
value = match.Groups[2].Value;
switch (type)
{
case "n"://n: xxxx delay in seconds before poling again
if (state != 0xA)
{
error = true;
break;
}
//delay gets ignored at the moment
state = 0xB;
break;
case "e":
if (state != 0xA)
{
error = true;
break;
}
//error gets ignored at the moment
break;
case "r":
if (state != 0xB)
{
error = true;
break;
}
//reset signal gets ignored at the moment
break;
case "i": //i:xxxx list name
//list name is ignored
state = 0xB;
break;
case "u": //u:xxxx redirect url
if (state != 0xB)
{
error = true;
break;
}
redirects.Add(value);
break;
case "sd": //sd:x-y,z
if (state != 0xB)
{
error = true;
break;
}
listData.BlacklistDelete = ParseIntervals(value.Split(':').LastOrDefault());
break;
case "ad": //ad:x-y,z
if (state != 0xB)
{
error = true;
break;
}
listData.WhitelistDelete = ParseIntervals(value.Split(':').LastOrDefault());
break;
}
if (error)
throw new Exception("Unable to parse data");
}
listData.Redirects = redirects;
return listData;
}