using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tor.Helpers;
using System.ComponentModel;
namespace Tor.Events
{
///
/// A class containing the logic for processing a stream-status event.
///
[EventAssoc(Event.Streams)]
internal sealed class StreamDispatcher : Dispatcher
{
#region Tor.Events.Dispatcher
///
/// Dispatches the event, parsing the content of the line and raising the relevant event.
///
/// The line which was received from the control connection.
///
/// true if the event is parsed and dispatched successfully; otherwise, false.
///
public override bool Dispatch(string line)
{
int streamID;
int circuitID;
int port;
StreamStatus status;
Host target;
string[] parts = StringHelper.GetAll(line, ' ');
if (parts.Length < 4)
return false;
if ("Tor_internal".Equals(parts[3], StringComparison.CurrentCultureIgnoreCase))
return false;
if (!int.TryParse(parts[0], out streamID))
return false;
if (!int.TryParse(parts[2], out circuitID))
return false;
string[] targetParts = parts[3].Split(new[] { ':' }, 2);
if (targetParts.Length < 2)
return false;
if (!int.TryParse(targetParts[1], out port))
return false;
status = ReflectionHelper.GetEnumerator(attr => parts[1].Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase));
target = new Host(targetParts[0], port);
Stream stream = new Stream(Client, streamID, target);
stream.CircuitID = circuitID;
stream.Status = status;
for (int i = 4; i < parts.Length; i++)
{
string data = parts[i].Trim();
if (!data.Contains("="))
continue;
string[] values = data.Split(new[] { '=' }, 2);
if (values.Length < 2)
continue;
string name = values[0].Trim();
string value = values[1].Trim();
if ("REASON".Equals(name, StringComparison.CurrentCultureIgnoreCase))
{
stream.Reason = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase));
continue;
}
if ("PURPOSE".Equals(name, StringComparison.CurrentCultureIgnoreCase))
{
stream.Purpose = ReflectionHelper.GetEnumerator(attr => value.Equals(attr.Description, StringComparison.CurrentCultureIgnoreCase));
continue;
}
}
Events.OnStreamChanged(new StreamEventArgs(stream));
return true;
}
#endregion
}
}