///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System.Collections;
using System.Windows.Forms;
namespace JetBrains.Omea.Net
{
public delegate void AsciiProtocolUnitDelegate( AsciiProtocolUnit unit );
public abstract class AsciiProtocolUnit
{
public event AsciiProtocolUnitDelegate Finished;
protected internal abstract void Start( AsciiTcpConnection connection );
protected static void StartUnit( AsciiProtocolUnit unit, AsciiTcpConnection connection )
{
unit.Start( connection );
}
protected virtual void FireFinished()
{
if( Finished != null )
{
try
{
Finished( this );
}
finally
{
Finished = null;
}
}
}
protected internal static void FireFinished( AsciiProtocolUnit unit )
{
unit.FireFinished();
}
}
///
/// Connects to server
///
public class AsciiConnectUnit: AsciiProtocolUnit
{
protected internal override void Start( AsciiTcpConnection connection )
{
_connection = connection;
connection.AfterConnect += new MethodInvoker( connection_AfterConnect );
connection.ResolveFailed += new MethodInvoker( FireFinished );
connection.ConnectFailed += new MethodInvoker( FireFinished );
connection.Connect();
}
public bool Connected
{
get { return _connected; }
}
protected override void FireFinished()
{
_connection.AfterConnect -= new MethodInvoker( connection_AfterConnect );
_connection.ResolveFailed -= new MethodInvoker( FireFinished );
_connection.ConnectFailed -= new MethodInvoker( FireFinished );
base.FireFinished();
}
private void connection_AfterConnect()
{
_connected = true;
FireFinished();
}
private bool _connected;
private AsciiTcpConnection _connection;
}
///
/// Connects to server and receives its prompt
///
public class AsciiConnectAndGetServerPromptUnit: AsciiProtocolUnit
{
protected internal override void Start( AsciiTcpConnection connection )
{
_connection = connection;
AsciiConnectUnit connectUnit = new AsciiConnectUnit();
connectUnit.Finished += new AsciiProtocolUnitDelegate( connectUnit_Finished );
StartUnit( connectUnit, connection );
}
public bool Connected
{
get { return _connected; }
}
///
/// returns null on error, otherwise the first line of server response after connect
///
public string ServerPrompt
{
get { return _serverPrompt; }
}
protected override void FireFinished()
{
if( _connected )
{
_connection.AfterReceive -= new MethodInvoker( FireFinished );
_connection.LineReceived -= new LineDelegate( _connection_LineReceived );
_connection.OperationFailed -= new MethodInvoker( FireFinished );
}
base.FireFinished();
}
private void connectUnit_Finished( AsciiProtocolUnit unit )
{
AsciiConnectUnit connectUnit = (AsciiConnectUnit) unit;
if( !( _connected = connectUnit.Connected ) )
{
FireFinished();
}
else
{
_connection.AfterReceive += new MethodInvoker( FireFinished );
_connection.LineReceived += new LineDelegate( _connection_LineReceived );
_connection.OperationFailed += new MethodInvoker( FireFinished );
_connection.SkipReceivedStream();
_connection.Receive();
}
}
private void _connection_LineReceived( string line )
{
if( _serverPrompt == null )
{
_serverPrompt = line;
}
}
private bool _connected;
private string _serverPrompt;
private AsciiTcpConnection _connection;
}
///
/// Send a line to server
///
public class AsciiSendLineUnit: AsciiProtocolUnit
{
public AsciiSendLineUnit( string line )
{
_line = line;
}
protected internal override void Start( AsciiTcpConnection connection )
{
_connection = connection;
connection.AfterSend += new MethodInvoker( connection_AfterSend );
connection.OperationFailed += new MethodInvoker( FireFinished );
connection.SendLine( _line );
}
public bool LineSent
{
get { return _lineSent; }
}
protected override void FireFinished()
{
_connection.AfterSend -= new MethodInvoker( connection_AfterSend );
_connection.OperationFailed -= new MethodInvoker( FireFinished );
base.FireFinished();
}
private void connection_AfterSend()
{
_lineSent = true;
FireFinished();
}
private string _line;
private bool _lineSent;
private AsciiTcpConnection _connection;
}
///
/// Sends line to server, gets line as response
///
public class AsciiSendLineGetLineUnit: AsciiProtocolUnit
{
public AsciiSendLineGetLineUnit( string line )
{
_line = line;
}
///
/// Was line successfully sent?
///
public bool LineSent
{
get { return _lineSent; }
}
///
/// returns null on error, otherwise response as line
///
public string ResponseLine
{
get { return _responseLine; }
}
protected internal override void Start( AsciiTcpConnection connection )
{
_connection = connection;
AsciiSendLineUnit sendUnit = new AsciiSendLineUnit( _line );
sendUnit.Finished += new AsciiProtocolUnitDelegate( sendUnit_Finished );
StartUnit( sendUnit, connection );
}
protected override void FireFinished()
{
if( _lineSent )
{
_connection.AfterReceive -= new MethodInvoker( FireFinished );
_connection.LineReceived -= new LineDelegate( _connection_LineReceived );
_connection.OperationFailed -= new MethodInvoker( FireFinished );
}
base.FireFinished();
}
private void sendUnit_Finished( AsciiProtocolUnit unit )
{
AsciiSendLineUnit sendUnit = (AsciiSendLineUnit) unit;
if( !( _lineSent = sendUnit.LineSent ) )
{
FireFinished();
}
else
{
_connection.AfterReceive += new MethodInvoker( FireFinished );
_connection.LineReceived += new LineDelegate( _connection_LineReceived );
_connection.OperationFailed += new MethodInvoker( FireFinished );
_connection.SkipReceivedStream();
_connection.Receive();
}
}
private void _connection_LineReceived( string line )
{
if( _responseLine == null )
{
_responseLine = line;
}
}
private string _line;
private bool _lineSent;
private string _responseLine;
private AsciiTcpConnection _connection;
}
///
/// Sends line to server, gets response as line array
/// if a response line starts with terminator then unit is finished
///
public class AsciiSendLineGetLineArrayUnit: AsciiProtocolUnit
{
public AsciiSendLineGetLineArrayUnit( string line, string terminator )
{
_line = line;
_terminator = terminator;
}
///
/// Was line successfully sent?
///
public bool LineSent
{
get { return _lineSent; }
}
///
/// returns null on error, otherwise array of response lines
///
public string[] ResponseLines
{
get { return ( _responseLines == null ) ? null : (string[]) _responseLines.ToArray( typeof( string ) ); }
}
protected internal override void Start( AsciiTcpConnection connection )
{
_connection = connection;
AsciiSendLineUnit sendUnit = new AsciiSendLineUnit( _line );
sendUnit.Finished += new AsciiProtocolUnitDelegate( sendUnit_Finished );
StartUnit( sendUnit, connection );
}
protected override void FireFinished()
{
if( _lineSent )
{
_connection.AfterReceive -= new MethodInvoker( _connection_AfterReceive );
_connection.LineReceived -= new LineDelegate( _connection_LineReceived );
_connection.OperationFailed -= new MethodInvoker( FireFinished );
}
base.FireFinished();
}
private void sendUnit_Finished( AsciiProtocolUnit unit )
{
AsciiSendLineUnit sendUnit = (AsciiSendLineUnit) unit;
if( !( _lineSent = sendUnit.LineSent ) )
{
FireFinished();
}
else
{
_connection.AfterReceive += new MethodInvoker( _connection_AfterReceive );
_connection.LineReceived += new LineDelegate( _connection_LineReceived );
_connection.OperationFailed += new MethodInvoker( FireFinished );
_connection.SkipReceivedStream();
_connection.Receive();
}
}
private void _connection_AfterReceive()
{
_connection.Receive();
}
private void _connection_LineReceived( string line )
{
if( _responseLines == null )
{
_responseLines = new ArrayList();
}
if( line.StartsWith( _terminator ) )
{
FireFinished();
}
else
{
_responseLines.Add( line );
}
}
private string _line;
private string _terminator;
private bool _lineSent;
private ArrayList _responseLines;
private AsciiTcpConnection _connection;
}
///
/// Sends line to server, invokes method for each line of response
/// if a response line starts with terminator then unit is finished
///
public class AsciiSendLineAndApplyMethodUnit: AsciiProtocolUnit
{
public AsciiSendLineAndApplyMethodUnit( string line, string terminator, LineDelegate method )
{
_line = line;
_terminator = terminator;
_method = method;
}
///
/// Was line successfully sent?
///
public bool LineSent
{
get { return _lineSent; }
}
protected internal override void Start( AsciiTcpConnection connection )
{
_connection = connection;
AsciiSendLineUnit sendUnit = new AsciiSendLineUnit( _line );
sendUnit.Finished += new AsciiProtocolUnitDelegate( sendUnit_Finished );
StartUnit( sendUnit, connection );
}
protected override void FireFinished()
{
if( _lineSent )
{
_connection.AfterReceive -= new MethodInvoker( _connection_AfterReceive );
_connection.LineReceived -= new LineDelegate( _connection_LineReceived );
_connection.OperationFailed -= new MethodInvoker( FireFinished );
}
base.FireFinished();
}
private void sendUnit_Finished( AsciiProtocolUnit unit )
{
AsciiSendLineUnit sendUnit = (AsciiSendLineUnit) unit;
if( !( _lineSent = sendUnit.LineSent ) )
{
FireFinished();
}
else
{
_connection.AfterReceive += new MethodInvoker( _connection_AfterReceive );
_connection.LineReceived += new LineDelegate( _connection_LineReceived );
_connection.OperationFailed += new MethodInvoker( FireFinished );
_connection.SkipReceivedStream();
_connection.Receive();
}
}
private void _connection_AfterReceive()
{
_connection.Receive();
}
private void _connection_LineReceived( string line )
{
if( line.StartsWith( _terminator ) )
{
FireFinished();
}
else
{
_method( line );
}
}
private string _line;
private string _terminator;
private LineDelegate _method;
private bool _lineSent;
private AsciiTcpConnection _connection;
}
}