using System;
using System.Collections.Specialized;
using System.Threading;
namespace I2P.SAM.Client
{
///
/// Optional base class providing basic SAM event handling and helper
/// methods.
///
public class SamBaseEventHandler
{
private object _helloLock = new Object();
private string _helloOk;
private NameValueCollection _namingReplies = new NameValueCollection();
private object _namingReplyLock = new Object();
private SamReader _samReader;
private object _sessionCreateLock = new Object();
private string _sessionCreateOk;
///
/// Creates a new SamBaseEventHandler instance and registers
/// overridable handler methods for all events generated by the given
/// SamReader.
///
public SamBaseEventHandler(SamReader samReader) {
_samReader = samReader;
_samReader.DestReplyReceived += new DestReplyReceivedHandler(OnDestReplyReceived);
_samReader.HelloReplyReceived += new HelloReplyReceivedHandler(OnHelloReplyReceived);
_samReader.NamingReplyReceived += new NamingReplyReceivedHandler(OnNamingReplyReceived);
_samReader.SessionStatusReceived += new SessionStatusReceivedHandler(OnSessionStatusReceived);
_samReader.StreamClosedReceived += new StreamClosedReceivedHandler(OnStreamClosedReceived);
_samReader.StreamConnectedReceived += new StreamConnectedReceivedHandler(OnStreamConnectedReceived);
_samReader.StreamDataReceived += new StreamDataReceivedHandler(OnStreamDataReceived);
_samReader.StreamStatusReceived += new StreamStatusReceivedHandler(OnStreamStatusReceived);
_samReader.UnknownMessageReceived += new UnknownMessageReceivedHandler(OnUnknownMessageReceived);
}
public virtual void OnDestReplyReceived(string publicKey, string privateKey) {
}
public virtual void OnHelloReplyReceived(bool ok) {
lock (_helloLock) {
if (ok)
_helloOk = Boolean.TrueString;
else
_helloOk = Boolean.FalseString;
Monitor.PulseAll(_helloLock);
}
}
public virtual void OnNamingReplyReceived(string name, string result, string valueString, string message) {
lock (_namingReplyLock) {
if (result.Equals(SamBridgeMessages.NAMING_REPLY_OK))
_namingReplies.Add(name, valueString);
else
_namingReplies.Add(name, result);
Monitor.PulseAll(_namingReplyLock);
}
}
public virtual void OnSessionStatusReceived(string result, string destination, string message) {
lock (_sessionCreateLock) {
if (result.Equals(SamBridgeMessages.SESSION_STATUS_OK))
_sessionCreateOk = Boolean.TrueString;
else
_sessionCreateOk = Boolean.FalseString;
Monitor.PulseAll(_sessionCreateLock);
}
}
public virtual void OnStreamClosedReceived(string result, int id, string message) {
}
public virtual void OnStreamConnectedReceived(string remoteDestination, int id) {
}
public virtual void OnStreamDataReceived(int id, byte[] data, int offset, int length) {
}
public virtual void OnStreamStatusReceived(string result, int id, string message) {
}
public virtual void OnUnknownMessageReceived(string major, string minor, NameValueCollection parameters) {
Console.WriteLine("wrt, [" + major + "] [" + minor + "] [" + parameters + "]");
}
// Helper methods below.
///
/// Waits for a SAM connection to be established.
///
///
/// This method blocks until the connection is established.
///
/// true if the handshake was successful.
public virtual bool WaitForHelloReply() {
while (true) {
lock (_helloLock) {
if (_helloOk == null)
Monitor.Wait(_helloLock);
else
return Boolean.Parse(_helloOk);
}
}
}
///
/// Waits for a SAM naming reply message.
///
///
/// This method blocks until all naming replies are received.
///
/// The name to be looked for, or ME.
/// The matching destination for name, or null if
/// the key was not able to be retrieved.
public virtual string WaitForNamingReply(string name) {
while (true) {
lock (_namingReplyLock) {
try {
string valueString = _namingReplies[name];
_namingReplies.Remove(name);
if (valueString.Equals(SamBridgeMessages.NAMING_REPLY_INVALID_KEY))
return null;
else if (valueString.Equals(SamBridgeMessages.NAMING_REPLY_KEY_NOT_FOUND))
return null;
else
return valueString;
} catch (ArgumentNullException ane) {
Monitor.Wait(_namingReplyLock);
}
}
}
}
///
/// Waits for a SAM session to be created.
///
///
/// This method blocks until a SAM session is created.
///
/// true if the SAM session was created successfully.
//
public virtual bool WaitForSessionCreateReply() {
while (true) {
lock (_sessionCreateLock) {
if (_sessionCreateOk == null)
Monitor.Wait(_sessionCreateLock);
else
return Boolean.Parse(_sessionCreateOk);
}
}
}
}
}