Subversion Repositories general

Compare Revisions

Ignore whitespace Rev 1094 → Rev 1095

/TCPproxy/trunk/src/Network.cs
28,7 → 28,7
Connecting,
Connected,
ShutdownSend,
ShutdownReceive,
ShutdownReceived,
Closed
}
 
152,10 → 152,10
socket.BeginAccept(new AsyncCallback(OnClientConnect), null);
SendLog(null, LogLevel.Important, "Listen on " + socket.LocalEndPoint);
}
 
public void StopListening()
{
try
try
{
if(socket != null)
{
164,10 → 164,10
}
}
catch(ObjectDisposedException) // socket is already closed
{
}
catch(Exception ex)
{
}
catch(Exception ex)
{
Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
}
}
189,7 → 189,7
 
protected virtual void OnClientConnect(IAsyncResult asyn)
{
try
try
{
Socket worker = socket.EndAccept(asyn);
socket.BeginAccept(new AsyncCallback(OnClientConnect), null); // wait for next client
198,7 → 198,7
tcp.Close += new TcpEventHandler(TcpConnectionClosed);
OnNewTcp(new TcpConnectionEventArgs(tcp));
 
lock(tcpConnections)
lock(tcpConnections)
{
tcpConnections.Add(tcp);
}
206,7 → 206,7
tcp.Continue(resendHost, resendPort, worker);
}
catch(ObjectDisposedException) {} // socket is closed
catch(Exception ex)
catch(Exception ex)
{
Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
}
224,9 → 224,9
 
protected virtual void OnNewTcp(TcpConnectionEventArgs e)
{
if(NewTcp != null)
if(NewTcp != null)
{
NewTcp(this, e);
NewTcp(this, e);
}
}
 
234,9 → 234,9
 
protected virtual void OnLog(TcpLogEventArgs e)
{
if(Log != null)
if(Log != null)
{
Log(this, e);
Log(this, e);
}
}
 
364,7 → 364,7
 
TcpMessage message;
 
lock(this)
lock(this)
{
message = new TcpMessage();
message.Direction = direction;
397,71 → 397,71
 
protected void SetLocalPoint(IPEndPoint localPoint)
{
this.localPoint = localPoint;
this.localPoint = localPoint;
OnUpdate(new TcpEventArgs());
}
 
protected void SetRemotePoint(IPEndPoint remotePoint)
{
this.remotePoint = remotePoint;
this.remotePoint = remotePoint;
OnUpdate(new TcpEventArgs());
}
 
protected void SetLocalState(SocketState localState)
{
if(this.localState == SocketState.None && localState == SocketState.Connecting)
if(this.localState == SocketState.None && localState == SocketState.Connecting)
{
startTimestamp = DateTime.Now;
}
else if(this.localState == SocketState.None && localState == SocketState.Connected)
else if(this.localState == SocketState.None && localState == SocketState.Connected)
{
startTimestamp = DateTime.Now;
}
else if(this.localState == SocketState.None && localState == SocketState.Closed)
else if(this.localState == SocketState.None && localState == SocketState.Closed)
{
}
else if(this.localState == SocketState.Connecting && localState == SocketState.Connected)
else if(this.localState == SocketState.Connecting && localState == SocketState.Connected)
{
}
else if(this.localState == SocketState.Connecting && localState == SocketState.Closed)
else if(this.localState == SocketState.Connecting && localState == SocketState.Closed)
{
if(localEndTimestamp == DateTime.MinValue) localEndTimestamp = DateTime.Now;
}
else if(this.localState == SocketState.Connected && localState == SocketState.ShutdownSend)
else if(this.localState == SocketState.Connected && localState == SocketState.ShutdownSend)
{
}
else if(this.localState == SocketState.Connected && localState == SocketState.ShutdownReceive)
else if(this.localState == SocketState.Connected && localState == SocketState.ShutdownReceived)
{
if(localEndTimestamp == DateTime.MinValue) localEndTimestamp = DateTime.Now;
}
else if(this.localState == SocketState.Connected && localState == SocketState.Closed)
else if(this.localState == SocketState.Connected && localState == SocketState.Closed)
{
if(localEndTimestamp == DateTime.MinValue) localEndTimestamp = DateTime.Now;
}
else if(this.localState == SocketState.ShutdownSend && localState == SocketState.Closed)
else if(this.localState == SocketState.ShutdownSend && localState == SocketState.Closed)
{
if(localEndTimestamp == DateTime.MinValue) localEndTimestamp = DateTime.Now;
}
else if(this.localState == SocketState.ShutdownSend && localState == SocketState.ShutdownReceive)
else if(this.localState == SocketState.ShutdownSend && localState == SocketState.ShutdownReceived)
{
if(localEndTimestamp == DateTime.MinValue) localEndTimestamp = DateTime.Now;
}
else if(this.localState == SocketState.ShutdownReceive && localState == SocketState.ShutdownSend)
else if(this.localState == SocketState.ShutdownReceived && localState == SocketState.ShutdownSend)
{
}
else if(this.localState == SocketState.ShutdownReceive && localState == SocketState.Closed)
else if(this.localState == SocketState.ShutdownReceived && localState == SocketState.Closed)
{
if(localEndTimestamp == DateTime.MinValue) localEndTimestamp = DateTime.Now;
}
else if(this.localState == SocketState.Closed && localState == SocketState.Closed)
else if(this.localState == SocketState.Closed && localState == SocketState.Closed)
{
if(localEndTimestamp == DateTime.MinValue) localEndTimestamp = DateTime.Now;
}
else
else
{
throw new Exception("Wrong local socket state change: from " + this.localState + " to " + localState);
}
this.localState = localState;
this.localState = localState;
if(this.localState == SocketState.Closed) httpParser.NewMessageArived();
OnUpdate(new TcpEventArgs());
}
468,57 → 468,57
 
protected void SetRemoteState(SocketState remoteState)
{
if(this.remoteState == SocketState.None && remoteState == SocketState.Connecting)
if(this.remoteState == SocketState.None && remoteState == SocketState.Connecting)
{
}
else if(this.remoteState == SocketState.None && remoteState == SocketState.Connected)
else if(this.remoteState == SocketState.None && remoteState == SocketState.Connected)
{
}
else if(this.remoteState == SocketState.None && remoteState == SocketState.Closed)
else if(this.remoteState == SocketState.None && remoteState == SocketState.Closed)
{
}
else if(this.remoteState == SocketState.Connecting && remoteState == SocketState.Connected)
else if(this.remoteState == SocketState.Connecting && remoteState == SocketState.Connected)
{
}
else if(this.remoteState == SocketState.Connecting && remoteState == SocketState.Closed)
else if(this.remoteState == SocketState.Connecting && remoteState == SocketState.Closed)
{
if(remoteEndTimestamp == DateTime.MinValue) remoteEndTimestamp = DateTime.Now;
}
else if(this.remoteState == SocketState.Connected && remoteState == SocketState.ShutdownSend)
else if(this.remoteState == SocketState.Connected && remoteState == SocketState.ShutdownSend)
{
}
else if(this.remoteState == SocketState.Connected && remoteState == SocketState.ShutdownReceive)
else if(this.remoteState == SocketState.Connected && remoteState == SocketState.ShutdownReceived)
{
if(remoteEndTimestamp == DateTime.MinValue) remoteEndTimestamp = DateTime.Now;
}
else if(this.remoteState == SocketState.Connected && remoteState == SocketState.Closed)
else if(this.remoteState == SocketState.Connected && remoteState == SocketState.Closed)
{
if(remoteEndTimestamp == DateTime.MinValue) remoteEndTimestamp = DateTime.Now;
}
else if(this.remoteState == SocketState.ShutdownSend && remoteState == SocketState.Closed)
else if(this.remoteState == SocketState.ShutdownSend && remoteState == SocketState.Closed)
{
if(remoteEndTimestamp == DateTime.MinValue) remoteEndTimestamp = DateTime.Now;
}
else if(this.remoteState == SocketState.ShutdownSend && remoteState == SocketState.ShutdownReceive)
else if(this.remoteState == SocketState.ShutdownSend && remoteState == SocketState.ShutdownReceived)
{
if(remoteEndTimestamp == DateTime.MinValue) remoteEndTimestamp = DateTime.Now;
}
else if(this.remoteState == SocketState.ShutdownReceive && remoteState == SocketState.ShutdownSend)
else if(this.remoteState == SocketState.ShutdownReceived && remoteState == SocketState.ShutdownSend)
{
}
else if(this.remoteState == SocketState.ShutdownReceive && remoteState == SocketState.Closed)
else if(this.remoteState == SocketState.ShutdownReceived && remoteState == SocketState.Closed)
{
if(remoteEndTimestamp == DateTime.MinValue) remoteEndTimestamp = DateTime.Now;
}
else if(this.remoteState == SocketState.Closed && remoteState == SocketState.Closed)
else if(this.remoteState == SocketState.Closed && remoteState == SocketState.Closed)
{
if(remoteEndTimestamp == DateTime.MinValue) remoteEndTimestamp = DateTime.Now;
}
else
else
{
throw new Exception("Wrong remote socket state change: from " + this.remoteState + " to " + remoteState);
}
this.remoteState = remoteState;
this.remoteState = remoteState;
if(this.remoteState == SocketState.Closed) httpParser.NewMessageArived();
OnUpdate(new TcpEventArgs());
}
527,9 → 527,9
 
protected virtual void OnUpdate(TcpEventArgs e)
{
if(Update != null)
if(Update != null)
{
Update(this, e);
Update(this, e);
}
}
 
537,9 → 537,9
 
protected virtual void OnNewHttp(TcpHttpEventArgs e)
{
if(NewHttp != null)
if(NewHttp != null)
{
NewHttp(this, e);
NewHttp(this, e);
}
}
 
547,9 → 547,9
 
protected virtual void OnClose(TcpEventArgs e)
{
if(Close != null)
if(Close != null)
{
Close(this, e);
Close(this, e);
}
}
 
557,9 → 557,9
 
protected virtual void OnLog(TcpLogEventArgs e)
{
if(Log != null)
if(Log != null)
{
Log(this, e);
Log(this, e);
}
}
 
588,7 → 588,7
{
public byte[] buffer = null;
public int length = 0;
public SendCommandType cmdType = SendCommandType.Send;
public SendCommandType cmdType = SendCommandType.Send;
}
 
private static int BUF_SIZE = 2048;
614,12 → 614,12
 
public SocketWorker(IPAddress resendHost, int resendPort, Socket localSocket, TcpConnection tcp)
{
try
try
{
tcp.SendLog(LogLevel.Debug, string.Format("Local socket: {0}:{1} <-> {2}:{3}",
((IPEndPoint)localSocket.LocalEndPoint).Address,
tcp.SendLog(LogLevel.Debug, string.Format("Local socket: {0}:{1} <-> {2}:{3}",
((IPEndPoint)localSocket.LocalEndPoint).Address,
((IPEndPoint)localSocket.LocalEndPoint).Port,
((IPEndPoint)localSocket.RemoteEndPoint).Address,
((IPEndPoint)localSocket.RemoteEndPoint).Address,
((IPEndPoint)localSocket.RemoteEndPoint).Port));
 
this.localSocket = localSocket;
629,13 → 629,13
 
tcp.SetLocalPoint((IPEndPoint)localSocket.RemoteEndPoint);
this.localSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1);
 
localSendThread = new Thread(new ThreadStart(LocalSendProc));
localSendThread.Name = "SocketWorker.LocalSendProc";
localSendThread.Start();
 
ContinueLocalReceive();
 
if(resendHost == null)
{
remoteSocket = null;
659,10 → 659,10
remoteSocketEvent.Set(); // remote socket ready to send data
tcp.SendLog(LogLevel.Info, "Connected to server " + tcp.RemotePoint.ToString());
 
tcp.SendLog(LogLevel.Debug, string.Format("Remote socket: {0}:{1} <-> {2}:{3}",
((IPEndPoint)remoteSocket.LocalEndPoint).Address,
tcp.SendLog(LogLevel.Debug, string.Format("Remote socket: {0}:{1} <-> {2}:{3}",
((IPEndPoint)remoteSocket.LocalEndPoint).Address,
((IPEndPoint)remoteSocket.LocalEndPoint).Port,
((IPEndPoint)remoteSocket.RemoteEndPoint).Address,
((IPEndPoint)remoteSocket.RemoteEndPoint).Address,
((IPEndPoint)remoteSocket.RemoteEndPoint).Port));
}
}
675,7 → 675,7
 
private void ContinueLocalReceive()
{
try
try
{
localDataBuffer = new byte[BUF_SIZE];
localSocket.BeginReceive(localDataBuffer, 0, BUF_SIZE, SocketFlags.None, receiveLocalMethod, this);
694,7 → 694,7
 
private void ContinueRemoteReceive()
{
try
try
{
remoteDataBuffer = new byte[BUF_SIZE];
remoteSocket.BeginReceive(remoteDataBuffer, 0, BUF_SIZE, SocketFlags.None, receiveRemoteMethod, this);
713,9 → 713,9
 
private void CheckLocalSocket()
{
lock(localSocket)
lock(localSocket)
{
try
try
{
if(localSocketReceiveShutdown && localSocketSendShutdown)
{
732,11 → 732,11
 
private void CheckRemoteSocket()
{
lock(remoteSocket)
lock(remoteSocket)
{
try
try
{
if(remoteSocketReceiveShutdown && remoteSocketSendShutdown)
if(remoteSocketReceiveShutdown && remoteSocketSendShutdown)
{
if(remoteSocket.Connected) remoteSocket.Close();
tcp.SetRemoteState(SocketState.Closed);
751,7 → 751,7
 
private void OnLocalReceived(IAsyncResult asyn)
{
try
try
{
int bytesReceived = 0;
bool reset = false;
766,9 → 766,9
}
catch(SocketException ex)
{
if(ex.ErrorCode == 10054)
if(ex.ErrorCode == 10054)
reset = true;
else
else
throw ex;
}
 
795,7 → 795,7
tcp.SendLog(LogLevel.Info, "Got showdown from local end");
 
localSocket.Shutdown(SocketShutdown.Receive);
tcp.SetLocalState(SocketState.ShutdownReceive);
tcp.SetLocalState(SocketState.ShutdownReceived);
localSocketReceiveShutdown = true;
CheckLocalSocket();
 
833,16 → 833,16
{
try
{
while(true)
while(true)
{
SendCommand cmd;
 
if(localSendQueue.Count == 0)
if(localSendQueue.Count == 0)
{
localSendEvent.WaitOne();
}
 
lock(localSendQueue)
lock(localSendQueue)
{
localSendEvent.Reset();
cmd = (SendCommand)localSendQueue.Dequeue();
895,7 → 895,7
 
private void OnRemoteReceived(IAsyncResult asyn)
{
try
try
{
int bytesReceived = 0;
bool reset = false;
910,9 → 910,9
}
catch(SocketException ex)
{
if(ex.ErrorCode == 10054)
if(ex.ErrorCode == 10054)
reset = true;
else
else
throw ex;
}
 
939,7 → 939,7
tcp.SendLog(LogLevel.Info, "Got showdown from remote end");
 
remoteSocket.Shutdown(SocketShutdown.Receive);
tcp.SetRemoteState(SocketState.ShutdownReceive);
tcp.SetRemoteState(SocketState.ShutdownReceived);
remoteSocketReceiveShutdown = true;
CheckRemoteSocket();
 
975,18 → 975,18
 
private void RemoteSendProc()
{
try
try
{
while(true)
while(true)
{
SendCommand cmd;
 
if(remoteSendQueue.Count == 0)
if(remoteSendQueue.Count == 0)
{
remoteSendEvent.WaitOne();
}
 
lock(remoteSendQueue)
lock(remoteSendQueue)
{
remoteSendEvent.Reset();
cmd = (SendCommand)remoteSendQueue.Dequeue();
1038,15 → 1038,15
{
tcp.SendLog(LogLevel.Important, "Connection canceled");
 
try
try
{
if(localSendThread != null && localSendThread.IsAlive) localSendThread.Abort();
if(remoteSendThread != null && remoteSendThread.IsAlive) remoteSendThread.Abort();
 
// close sockets
try
try
{
if(localSocket != null)
if(localSocket != null)
{
lock(localSocket)
{
1060,7 → 1060,7
}
tcp.SetLocalState(SocketState.Closed);
 
try
try
{
if(remoteSocket != null)
{
1103,14 → 1103,14
 
private static HttpCharType[] charTypes = null;
private static bool[] tokenChars = null;
private static char[] charValues = {
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
private static char[] charValues = {
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\0'
};
 
1158,9 → 1158,9
 
// token table
tokenChars = new bool[256];
for(int i = 0; i < tokenChars.Length; i++)
for(int i = 0; i < tokenChars.Length; i++)
{
tokenChars[i] = !(charTypes[i] == HttpCharType.NonChar
tokenChars[i] = !(charTypes[i] == HttpCharType.NonChar
|| charTypes[i] == HttpCharType.Control || charTypes[i] == HttpCharType.Separator
|| charTypes[i] == HttpCharType.CrLf);
}
1202,7 → 1202,7
 
private bool MoveNext()
{
for(bool moved = false; !moved; )
for(bool moved = false; !moved; )
{
lock(messages)
{
1212,7 → 1212,7
 
if(moved) break;
 
if(!newMessageEvent.WaitOne())
if(!newMessageEvent.WaitOne())
throw new Exception("Cannot get next TCP message");
 
lock(messages)
1233,7 → 1233,7
 
TcpMessage newTcp = null;
 
do
do
{
if(!MoveNext())
{
1273,7 → 1273,7
 
public void SetDirection(TcpMessageDirection direction)
{
do
do
{
if(!MoveNext())
{
1336,7 → 1336,7
{
Thread responseThread = null;
 
try
try
{
requestPos = new ParsePosition(messages, nextMessageEvent);
responsePos = new ParsePosition(messages, null);
1346,10 → 1346,10
responseThread.Start();
 
// find requests
while(!requestPos.IsEnd)
while(!requestPos.IsEnd)
{
HttpMessage http = new HttpMessage();
lock(https)
lock(https)
{
https.Add(http);
requestEvent.Set(); // new request available
1364,7 → 1364,7
ParseHeaders(requestPos, http, true);
SetRequestProperties(http);
http.UpdateHttpMessage();
 
bool fullLength = ParseBody(requestPos, http, true);
if("text" == http.RequestContentType && "xml" == http.RequestContentSubtype)
{
1381,7 → 1381,7
 
responseThread.Join();
}
catch(Exception ex)
catch(Exception ex)
{
Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
if(responseThread != null) responseThread.Abort();
1390,16 → 1390,16
 
private void MatchResponses()
{
try
try
{
IEnumerator httpEnum = https.GetEnumerator();
 
if(!nextMessageEvent.WaitOne()) throw new Exception("Cannot get first message of request");
 
responsePos.SetDirection(requestPos.CurrentMessage.Direction == TcpMessageDirection.Local
responsePos.SetDirection(requestPos.CurrentMessage.Direction == TcpMessageDirection.Local
? TcpMessageDirection.Remote : TcpMessageDirection.Local);
while(!responsePos.IsEnd)
 
while(!responsePos.IsEnd)
{
bool moved;
 
1409,14 → 1409,14
moved = httpEnum.MoveNext();
}
 
if(!moved)
if(!moved)
{
if(!requestEvent.WaitOne())
if(!requestEvent.WaitOne())
throw new Exception("Cannot get next request");
 
lock(https)
{
if(!httpEnum.MoveNext())
if(!httpEnum.MoveNext())
throw new Exception("Tried to find response by no HTTP message available");
}
}
1442,7 → 1442,7
http.UpdateHttpMessage();
}
}
catch(Exception ex)
catch(Exception ex)
{
Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
}
1473,7 → 1473,7
if(limit > 0 && limit < ++len) return null; // length limit
}
 
return res.ToString();
return res.ToString();
}
 
private string GetUntilEoL(ParsePosition pos, int limit)
1487,7 → 1487,7
if(limit > 0 && limit < ++len) return null; // length limit
}
 
return res.ToString();
return res.ToString();
}
 
private void ExpectSpace(ParsePosition pos)
1510,7 → 1510,7
 
private void SkipEmptyLines(ParsePosition pos)
{
while(pos.CurrentOctet() == 13)
while(pos.CurrentOctet() == 13)
ExpectCRLF(pos);
}
 
1532,13 → 1532,13
 
// EoL or version
byte b = pos.CurrentOctet();
if(b == 13)
if(b == 13)
{
if(pos.IsEnd || pos.NextOctet() != 10)
if(pos.IsEnd || pos.NextOctet() != 10)
{
throw new HttpParseException("Linefeed expected");
}
else
else
{
if(!pos.IsEnd) ExpectCRLF(pos);
http.RequestVersion = HttpVersion.V0_9;
1545,7 → 1545,7
return;
}
}
else if(b != 32)
else if(b != 32)
{
throw new HttpParseException("HTTP version expected");
}
1556,15 → 1556,15
if(pos.IsEnd || versionStr == null || versionStr.Length == 0)
throw new HttpParseException("HTTP version expected");
 
if(versionStr == "HTTP/1.0")
if(versionStr == "HTTP/1.0")
{
http.RequestVersion = HttpVersion.V1_0;
}
else if(versionStr == "HTTP/1.1")
else if(versionStr == "HTTP/1.1")
{
http.RequestVersion = HttpVersion.V1_1;
}
else
else
{
throw new HttpParseException("Unknown HTTP version: " + versionStr);
}
1576,18 → 1576,18
{
if(pos.IsEnd) return; // end of TCP messages
 
while(true)
while(true)
{
if(pos.IsEnd)
throw new HttpParseException("Unexpected end of message");
 
if(pos.CurrentOctet() == 13)
if(pos.CurrentOctet() == 13)
{
if(pos.IsEnd || pos.NextOctet() != 10)
if(pos.IsEnd || pos.NextOctet() != 10)
{
throw new HttpParseException("Linefeed expected");
}
else
else
{
pos.NextOctet(); // end of header, move to body
return;
1628,21 → 1628,21
HeaderValueState state = HeaderValueState.Space;
StringBuilder buf = new StringBuilder();
 
for(int i = 0, l = s.Length; i < l; i++)
for(int i = 0, l = s.Length; i < l; i++)
{
char c = s[i];
switch(state)
switch(state)
{
case HeaderValueState.Space:
if(c != ' ' && c != '\t')
{
if(c == '"')
if(c == '"')
{
if(buf.Length > 0) buf.Append(' ');
buf.Append(c);
state = HeaderValueState.Quoted;
}
else
else
{
if(buf.Length > 0) buf.Append(' ');
buf.Append(c);
1652,16 → 1652,16
break;
 
case HeaderValueState.Token:
if(c == ' ' || c == '\t')
if(c == ' ' || c == '\t')
{
state = HeaderValueState.Space;
}
else if(c == '"')
else if(c == '"')
{
buf.Append(c);
state = HeaderValueState.Quoted;
}
else
else
{
buf.Append(c);
}
1668,18 → 1668,18
break;
 
case HeaderValueState.Quoted:
if(c == '"')
if(c == '"')
{
buf.Append(c);
i++;
if(i < l)
{
{
c = s[i];
if(c == ' ' || c == '\t')
if(c == ' ' || c == '\t')
{
state = HeaderValueState.Space;
}
else if(c == '"')
else if(c == '"')
{
buf.Append(c);
state = HeaderValueState.Quoted;
1691,7 → 1691,7
}
}
}
else
else
{
buf.Append(c);
}
1704,15 → 1704,15
 
private HttpEncoding ParseEncoding(string encoding)
{
if(encoding == null || encoding == "identity")
if(encoding == null || encoding == "identity")
return HttpEncoding.Identify;
else if(encoding == "gzip")
else if(encoding == "gzip")
return HttpEncoding.Gzip;
else if(encoding == "compress")
else if(encoding == "compress")
return HttpEncoding.Compress;
else if(encoding == "deflate")
else if(encoding == "deflate")
return HttpEncoding.Deflate;
else
else
return HttpEncoding.Unknown;
}
 
1720,7 → 1720,7
{
// length
string contentLength = (string)http.RequestHeadersHash["Content-Length"];
if(contentLength != null)
if(contentLength != null)
{
http.RequestLength = int.Parse(contentLength);
}
1730,10 → 1730,10
 
// type & charset
string contentType = (string)http.RequestHeadersHash["Content-Type"];
if(contentType != null)
if(contentType != null)
{
Match match = Regex.Match(contentType, @"^\s*(\S+)/(\S+)\s*($|;\s*(charset=""?(\S+)""?)?)");
if(match.Success)
if(match.Success)
{
http.RequestContentType = match.Groups[1].Captures[0].Value;
http.RequestContentSubtype = match.Groups[2].Captures[0].Value;
1743,7 → 1743,7
 
// soap action
string soapAction = (string)http.RequestHeadersHash["soapaction"];
if(soapAction != null)
if(soapAction != null)
{
http.SoapAction = soapAction.Trim('"');
}
1765,7 → 1765,7
 
for(byte b = pos.CurrentOctet(); !pos.IsEnd; b = pos.NextOctet())
{
if(len >= bin.Length)
if(len >= bin.Length)
{
byte[] newBin = new byte[bin.Length*2];
Array.Copy(bin, newBin, len);
1780,26 → 1780,26
}
 
string text = null;
if(encoding == HttpEncoding.Identify && contentType == "text")
if(encoding == HttpEncoding.Identify && contentType == "text")
{
try
try
{
Encoding enc = Encoding.GetEncoding(charset == null ? (contentSubtype == "xml" ? "UTF-8" : "ASCII") : charset);
text = enc.GetString(bin, 0, len);
}
catch(NotSupportedException)
catch(NotSupportedException)
{
Console.WriteLine("Unsupported encoding: " + charset);
}
}
 
if(request)
if(request)
{
http.RequestLength = len;
http.RequestBody = bin;
http.RequestText = text;
}
else
else
{
http.ResponseLength = len;
http.ResponseBody = bin;
1816,15 → 1816,15
if(pos.IsEnd || versionStr == null || versionStr.Length == 0)
throw new HttpParseException("HTTP version expected");
 
if(versionStr == "HTTP/1.0")
if(versionStr == "HTTP/1.0")
{
http.ResponseVersion = HttpVersion.V1_0;
}
else if(versionStr == "HTTP/1.1")
else if(versionStr == "HTTP/1.1")
{
http.ResponseVersion = HttpVersion.V1_1;
}
else
else
{
throw new HttpParseException("Unknown HTTP version: " + versionStr);
}
1835,13 → 1835,13
if(code == null || code.Length != 3)
throw new HttpParseException("Status code expected");
 
try
try
{
int c = int.Parse(code);
if(c < 100 || c >= 1000) throw new HttpParseException("Status code expected");
http.ResponseStatusCode = c;
}
catch(FormatException)
catch(FormatException)
{
throw new HttpParseException("Status code expected");
}
1849,7 → 1849,7
 
// status message
http.ResponseStatusMessage = GetUntilEoL(pos, 0);
 
if(pos.IsEnd)
throw new HttpParseException("Unexpected end of message");
 
1860,7 → 1860,7
{
// length
HttpHeader contentLength = (HttpHeader)http.ResponseHeadersHash["Content-Length"];
if(contentLength != null)
if(contentLength != null)
{
http.ResponseLength = int.Parse(contentLength.Values[0]);
}
1871,14 → 1871,14
 
// type & charset
HttpHeader contentType = (HttpHeader)http.ResponseHeadersHash["Content-Type"];
if(contentType != null)
if(contentType != null)
{
Match match = Regex.Match(contentType.Values[0], @"^\s*(\S+)/(\S+)\s*($|;\s*(charset=""?(\S+)""?)?)");
if(match.Success)
if(match.Success)
{
http.ResponseContentType = match.Groups[1].Captures[0].Value;
http.ResponseContentSubtype = match.Groups[2].Captures[0].Value;
if(match.Groups.Count >= 6 && match.Groups[5].Captures.Count > 0)
if(match.Groups.Count >= 6 && match.Groups[5].Captures.Count > 0)
http.ResponseCharset = match.Groups[5].Captures[0].Value.Trim('"');
}
}
1916,7 → 1916,7
{
headerValues = new string[1];
}
else
else
{
string[] newValues = new string[headerValues.Length + 1];
Array.Copy(headerValues, 0, newValues, 0, headerValues.Length);
2153,7 → 2153,7
 
public override string ToString() // FIXME delete the method
{
return (soapAction != null ? soapAction
return (soapAction != null ? soapAction
: (requestMethod == null ? "" : requestMethod) + " " + (requestUri == null ? "" : requestUri));
}
 
2161,9 → 2161,9
 
protected virtual void OnUpdate(TcpEventArgs e)
{
if(Update != null)
if(Update != null)
{
Update(this, e);
Update(this, e);
}
}
 
2210,7 → 2210,7
 
internal XmlMessage(string text)
{
try
try
{
this.xml = new XmlDocument();
this.xml.LoadXml(text);
2242,7 → 2242,7
 
public byte[] Bytes
{
get
get
{
return bytes;
}
2283,10 → 2283,10
{
if(newBytes == null) return this;
 
lock(this)
lock(this)
{
// grow array
if(this.length + length > bytes.Length)
if(this.length + length > bytes.Length)
{
int newLength = bytes.Length;
while(this.length + length > newLength) newLength *= 2;
/TCPproxy/trunk/src/ViewControl.cs
97,7 → 97,7
| ControlStyles.ResizeRedraw, true);
 
fontMeasureFormat.LineAlignment = StringAlignment.Near;
fontMeasureFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.FitBlackBox
fontMeasureFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.FitBlackBox
| StringFormatFlags.NoWrap | StringFormatFlags.NoClip;
 
vScrollBar = new ScrollBarsControl(this, true);
122,7 → 122,7
get
{
CreateParams cp = base.CreateParams;
if(!base.DesignMode)
if(!base.DesignMode)
{
cp.Style = cp.Style | WS_HSCROLL | WS_VSCROLL;
cp.ExStyle = cp.ExStyle | WS_EX_CLIENTEDGE;
134,9 → 134,9
public bool WordWrap
{
get { return wordWrap; }
set
{
wordWrap = value;
set
{
wordWrap = value;
RecalcParams();
Invalidate();
// FIXME recalc number of lines for the vertical scroll bar
164,7 → 164,7
selEndLineOrig = -1;
selEndPosOrig = -1;
 
if(!updateBlocked)
if(!updateBlocked)
{
vScrollBar.Update(curLine, 0, linesCount, 1, 1);
UpdateHScrollBar();
207,7 → 207,7
 
public void RestoreState(object state, bool restorePosition)
{
if(!(state is ViewControlState))
if(!(state is ViewControlState))
throw new ArgumentException("Can restore only from object returned by SaveState()");
 
ViewControlState s = (ViewControlState)state;
230,7 → 230,7
foreach(LineFragment[] line in lineFragments)
{
int lineLength = 0;
foreach(LineFragment frag in line)
foreach(LineFragment frag in line)
{
lineLength += frag.indent + (frag.text == null ? 0 : frag.text.Length);
}
246,7 → 246,7
selEndLineOrig = s.selEndLineOrig;
selEndPosOrig = s.selEndPosOrig;
}
else
else
{
curLine = 0;
curCol = 0;
323,7 → 323,7
if(lineLen > 0) break;
}
 
if(line == null || lineLen == 0)
if(line == null || lineLen == 0)
{
fragment = new LineFragment();
fragment.color = this.ForeColor;
333,7 → 333,7
fragment.indent = 0;
fragment.wrapIndent = 0;
}
else
else
{
fragment = line[lineLen-1];
fragment.indent = 0;
367,7 → 367,7
{
LineFragment[] lastLine = (linesCount > 0) ? (LineFragment[])lineFragments[linesCount-1] : null;
 
if(lastLine == null)
if(lastLine == null)
{
lastLine = AddEmptyLine(Color.Transparent);
}
386,13 → 386,13
{
lineLength += lastLine[i].indent + (lastLine[i].text == null ? 0 : lastLine[i].text.Length);
}
if(lineLength > maxLineLength)
if(lineLength > maxLineLength)
{
maxLineLength = lineLength;
if(!updateBlocked && !wordWrap) hScrollBar.Maximum = maxLineLength + 2;
}
 
if(!updateBlocked)
if(!updateBlocked)
{
if(curLine + linesVisible + 1 >= lastLineLen) Invalidate();
}
414,7 → 414,7
 
private TextMarker GetTextMarker(object marker)
{
if(!(marker is TextMarker))
if(!(marker is TextMarker))
throw new ArgumentException("Can mark only with object returned by BeginMark()");
 
TextMarker m = (TextMarker)marker;
429,9 → 429,9
{
validMarkers.RemoveAt(i);
}
else
else
{
if(refer.Target == m)
if(refer.Target == m)
{
isValid = true;
}
474,7 → 474,7
DeleteLinePart(m.endLine - lineDeleted, 0, m.endPos);
 
// update screen
if(!updateBlocked)
if(!updateBlocked)
{
Invalidate();
}
503,7 → 503,7
lineBackColors.RemoveAt(lineNum);
linesCount--;
}
else
else
{
// delete part of line
LineFragment[] newLine = new LineFragment[(lineNum == linesCount - 1) ? line.Length : lineLen - end + begin];
516,7 → 516,7
return deleted;
}
 
public void ChangeText(object marker, string text, Color color, Color backColor,
public void ChangeText(object marker, string text, Color color, Color backColor,
bool italic, bool bold, int indent, int wrapIndent)
{
lock(this)
528,8 → 528,8
LineFragment[] line = (LineFragment[])lineFragments[m.beginLine];
LineFragment fragment = line[m.beginPos];
 
if(fragment.text == text && fragment.color == color && fragment.backColor == backColor
&& fragment.italic == italic && fragment.bold == bold && fragment.indent == indent
if(fragment.text == text && fragment.color == color && fragment.backColor == backColor
&& fragment.italic == italic && fragment.bold == bold && fragment.indent == indent
&& fragment.wrapIndent == wrapIndent)
{
return; // the fragment is not changed
545,7 → 545,7
 
line[m.beginPos] = fragment;
 
if(!updateBlocked)
if(!updateBlocked)
{
if(m.beginLine >= curLine && m.beginLine <= curLine + linesVisible + 1) Invalidate();
}
553,7 → 553,7
}
 
// side effect - the given marker is moved to position after the inserted text
public void InsertText(object marker, string text, Color color, Color backColor,
public void InsertText(object marker, string text, Color color, Color backColor,
bool italic, bool bold, int indent, int wrapIndent)
{
lock(this)
571,7 → 571,7
fragment.indent = indent;
fragment.wrapIndent = wrapIndent;
 
if(line == null)
if(line == null)
{
line = AddEmptyLine(Color.Transparent);
lastLineLen++;
580,16 → 580,17
{
if(line.Length <= lastLineLen || m.endPos < lastLineLen)
{
LineFragment[] newLine = new LineFragment[lastLineLen * (line.Length == lastLineLen ? 2 : 1)];
LineFragment[] newLine = new LineFragment[lastLineLen * (line.Length + 1 >= lastLineLen ? 2 : 1)];
 
if(m.endPos > 0) Array.Copy(line, 0, newLine, 0, m.endPos);
if(lastLineLen > m.endPos) Array.Copy(line, m.endPos, newLine, m.endPos+1, lastLineLen - m.endPos);
 
line = newLine;
lineFragments[m.endLine] = line;
}
lastLineLen++;
}
else
else
{
LineFragment[] newLine = new LineFragment[line.Length + 1];
if(m.endPos > 0) Array.Copy(line, 0, newLine, 0, m.endPos);
607,7 → 608,7
{
lineLength += line[i].indent + (line[i].text == null ? 0 : line[i].text.Length);
}
if(lineLength > maxLineLength)
if(lineLength > maxLineLength)
{
maxLineLength = lineLength;
if(!updateBlocked && !wordWrap) hScrollBar.Maximum = maxLineLength + 2;
614,7 → 615,7
}
 
// update screen
if(!updateBlocked)
if(!updateBlocked)
{
if(m.endLine >= curLine && m.endLine <= curLine + linesVisible + 1) Invalidate();
}
640,13 → 641,14
SaveLastLine();
AddEmptyLine(backColor);
}
else
else
{
LineFragment[] oldLine = (LineFragment[])lineFragments[m.endLine];
int oldLineLen = (m.endLine == linesCount - 1) ? lastLineLen : oldLine.Length;
LineFragment[] line1 = new LineFragment[m.endPos];
LineFragment[] line2 = new LineFragment[
(m.endLine == linesCount - 1) ? NEW_LINE_LENGTH : oldLine.Length - m.endPos];
LineFragment[] line2 = new LineFragment[(m.endLine == linesCount - 1)
? (int)Math.Ceiling((double)(oldLineLen - m.endPos) / NEW_LINE_LENGTH) * NEW_LINE_LENGTH
: oldLineLen - m.endPos];
 
if(m.endPos > 0) Array.Copy(oldLine, 0, line1, 0, m.endPos);
if(oldLineLen - m.endPos > 0) Array.Copy(oldLine, m.endPos, line2, 0, oldLineLen - m.endPos);
654,13 → 656,13
lineFragments[m.endLine] = line1;
lineFragments.Insert(m.endLine + 1, line2);
lineBackColors.Insert(m.endLine + 1, backColor);
linesCount++;
 
if(m.endLine == linesCount - 1) lastLineLen = oldLineLen - m.endPos;
linesCount++;
}
 
// update screen
if(!updateBlocked)
if(!updateBlocked)
{
if(m.endLine >= curLine && m.endLine <= curLine + linesVisible + 1) Invalidate();
vScrollBar.Maximum = linesCount;
681,7 → 683,7
{
validMarkers.RemoveAt(i);
}
else
else
{
TextMarker m = (TextMarker)refer.Target;
 
691,7 → 693,7
}
}
 
private void ShiftTextMarkerBorder(ref int borderLine, ref int borderPos,
private void ShiftTextMarkerBorder(ref int borderLine, ref int borderPos,
int line, int pos, int lineDelta, int posDelta)
{
if(borderLine > line)
812,7 → 814,7
{
lock(this)
{
try
try
{
Graphics g = e.Graphics;
SolidBrush brush = new SolidBrush(Color.Black);
850,7 → 852,7
int textLen = (text == null) ? 0 : text.Length;
 
// calc shift using curCol
if(shift > 0)
if(shift > 0)
{
if(shift < fragment.indent)
{
857,9 → 859,9
curIndent -= shift;
shift = 0;
}
else if(shift < textLen + fragment.indent)
else if(shift < textLen + fragment.indent)
{
if(text != null)
if(text != null)
{
text = text.Substring(shift - fragment.indent);
textLen = text.Length;
867,7 → 869,7
shift = 0;
curIndent = 0;
}
else
else
{
curIndent = 0;
shift -= textLen + fragment.indent;
877,7 → 879,7
}
 
// draw the line, m.b. split it to several display lines
while(true)
while(true)
{
string drawText = text;
int drawLen = textLen;
890,7 → 892,7
{
int visibleLen = colsVisible - 2;
int availableLen = visibleLen - indent - curIndent;
if(textLen > availableLen)
if(textLen > availableLen)
{
if(textLen == 0 || availableLen < 0)
{
919,7 → 921,7
if(fragment.backColor != Color.Transparent && (indent >= 0) && (drawLen + curIndent > 0))
{
brush.Color = fragment.backColor;
g.FillRectangle(brush, indent * fontWidth, drawLine * fontHeight,
g.FillRectangle(brush, indent * fontWidth, drawLine * fontHeight,
(float)Math.Ceiling((drawLen + curIndent) * fontWidth), fontHeight);
}
 
932,13 → 934,13
selEnd = (lineNumber == selEndLine) ? selEndPos - curCol : colsVisible;
 
int selBeginBack = Math.Max(indent, selBegin);
int selLen = (j == lineLen-1) ? (selEnd - selBeginBack)
int selLen = (j == lineLen-1) ? (selEnd - selBeginBack)
: Math.Min(drawLen + curIndent, selEnd - selBeginBack);
 
if(selLen > 0)
{
brush.Color = SystemColors.Highlight;
g.FillRectangle(brush, selBeginBack * fontWidth, drawLine * fontHeight,
g.FillRectangle(brush, selBeginBack * fontWidth, drawLine * fontHeight,
(float)Math.Ceiling(selLen* fontWidth), fontHeight);
}
}
969,7 → 971,7
}
}
 
if(s1 != null)
if(s1 != null)
{
brush.Color = fragment.color;
g.DrawString(s1, font, brush, indent * fontWidth, drawLine * fontHeight, fontMeasureFormat);
976,7 → 978,7
p2 = s1.Length;
}
 
if(s2 != null)
if(s2 != null)
{
brush.Color = SystemColors.HighlightText;
g.DrawString(s2, font, brush, (indent + p2) * fontWidth, drawLine * fontHeight, fontMeasureFormat);
983,7 → 985,7
p3 = p2 + s2.Length;
}
 
if(s3 != null)
if(s3 != null)
{
brush.Color = fragment.color;
g.DrawString(s3, font, brush, (indent + p3) * fontWidth, drawLine * fontHeight, fontMeasureFormat);
1049,7 → 1051,7
 
public string SelectedText
{
get
get
{
lock(this)
{
1075,7 → 1077,7
}
else
{
for(int j = fragment.indent - 1; j >= 0; j--)
for(int j = fragment.indent - 1; j >= 0; j--)
{
if(cur >= begin && cur < end) b.Append(' ');
cur++;
1082,7 → 1084,7
}
}
 
if(fragment.text != null)
if(fragment.text != null)
{
int curEnd = cur + fragment.text.Length;
if(begin <= cur && curEnd <= end)
1136,7 → 1138,7
{
curCol = 0;
}
else
else
{
curCol = pos;
if(curCol < 0) curCol = 0;
1163,7 → 1165,7
case Keys.Home:
case Keys.End:
return true;
 
default:
return base.IsInputKey(keyData);
}
1186,7 → 1188,7
MoveByVertical(-linesVisible, true);
}
break;
 
case Keys.Down:
lock(this)
{
1193,7 → 1195,7
MoveByVertical(1, true);
}
break;
 
case Keys.Up:
lock(this)
{
1200,7 → 1202,7
MoveByVertical(-1, true);
}
break;
 
case Keys.Right:
lock(this)
{
1207,7 → 1209,7
MoveByHorizontal(1, true);
}
break;
 
case Keys.Left:
lock(this)
{
1214,7 → 1216,7
MoveByHorizontal(-1, true);
}
break;
 
case Keys.Home:
lock(this)
{
1222,7 → 1224,7
MoveToVertical(0, true);
}
break;
 
case Keys.End:
lock(this)
{
1230,7 → 1232,7
MoveToVertical(linesCount - linesVisible + 1, true);
}
break;
 
default:
base.OnKeyDown(e);
break;
1276,13 → 1278,13
 
protected override void OnMouseMove(MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
if(e.Button == MouseButtons.Left)
{
lock(this)
{
UpdateSelectionEnd(e.X, e.Y);
// FIXME scroll if selection is dragged outside of the control, use timer to scroll
if(e.Y > this.ClientSize.Height && fontWidth > 0)
if(e.Y > this.ClientSize.Height && fontWidth > 0)
{
MoveToVertical(selEndLine - linesVisible + 1, true);
}
1339,7 → 1341,7
{
case WM_VSCROLL:
vScrollBar.HandleWindowMessage(ref m);
break;
break;
 
case WM_HSCROLL:
hScrollBar.HandleWindowMessage(ref m);
1389,7 → 1391,7
case WM_VSCROLL:
if(!vertical)
throw new ArgumentException("I'm horizontal scroll bar, can not handle vertical scroll");
break;
break;
 
case WM_HSCROLL:
if(vertical)
1406,7 → 1408,7
 
switch(cmd)
{
case SB_LINEDOWN:
case SB_LINEDOWN:
type = ScrollEventType.SmallIncrement;
currentValue += smallChange;
update = true;
1413,7 → 1415,7
break;
 
case SB_LINEUP:
type = ScrollEventType.SmallDecrement;
type = ScrollEventType.SmallDecrement;
currentValue -= smallChange;
update = true;
break;
1430,28 → 1432,28
update = true;
break;
 
case SB_TOP:
case SB_TOP:
type = ScrollEventType.First;
currentValue = minimum;
update = true;
break;
 
case SB_BOTTOM:
case SB_BOTTOM:
type = ScrollEventType.Last;
currentValue = maximum;
update = true;
break;
 
case SB_ENDSCROLL:
type = ScrollEventType.EndScroll;
case SB_ENDSCROLL:
type = ScrollEventType.EndScroll;
break;
 
case SB_THUMBTRACK:
case SB_THUMBTRACK:
type = ScrollEventType.ThumbTrack;
currentValue = GetTrackPos();
break;
 
case SB_THUMBPOSITION:
case SB_THUMBPOSITION:
type = ScrollEventType.ThumbPosition;
currentValue = GetTrackPos();
update = true;
1468,7 → 1470,7
 
private int GetTrackPos()
{
lock(this)
lock(this)
{
scrollInfo.fMask = SIF_TRACKPOS;
GetScrollInfo(owner.Handle, vertical ? SB_VERT : SB_HORZ, ref scrollInfo);
1478,7 → 1480,7
 
public int Value
{
get
get
{
return currentValue;
}
1493,8 → 1495,8
public bool ShowAlways
{
get { return showAlways; }
set
{
set
{
showAlways = value;
SetRange(false);
}
1502,7 → 1504,7
 
public int Minimum
{
get
get
{
return minimum;
}
1516,7 → 1518,7
 
public int Maximum
{
get
get
{
return maximum;
}
1541,7 → 1543,7
 
private void SetRange(bool setPos)
{
lock(this)
lock(this)
{
scrollInfo.fMask = SIF_RANGE | SIF_PAGE;
if(showAlways) scrollInfo.fMask |= SIF_DISABLENOSCROLL;
1549,7 → 1551,7
scrollInfo.nMax = maximum;
scrollInfo.nPage = (uint)largeChange;
 
if(setPos || currentValue < minimum || currentValue > maximum)
if(setPos || currentValue < minimum || currentValue > maximum)
{
if(currentValue < minimum) currentValue = minimum;
if(currentValue > maximum) currentValue = maximum;
1566,10 → 1568,10
SetScrollInfo(owner.Handle, vertical ? SB_VERT : SB_HORZ, ref scrollInfo, true);
}
}
 
public int SmallChange
{
get
get
{
return smallChange;
}
1583,7 → 1585,7
 
public int LargeChange
{
get
get
{
return largeChange;
}
1593,7 → 1595,7
if(value < 0) throw new ArgumentException("LargeChange must be non-negative");
largeChange = value;
 
lock(this)
lock(this)
{
scrollInfo.fMask = SIF_PAGE;
if(showAlways) scrollInfo.fMask |= SIF_DISABLENOSCROLL;
1610,7 → 1612,7
if(currentValue < minimum) currentValue = minimum;
if(currentValue > maximum) currentValue = maximum;
 
lock(this)
lock(this)
{
scrollInfo.fMask = SIF_POS;
if(showAlways) scrollInfo.fMask |= SIF_DISABLENOSCROLL;
1621,9 → 1623,9
 
protected virtual void OnScroll(ScrollEventArgs e)
{
if(Scroll != null)
if(Scroll != null)
{
Scroll(this, e);
Scroll(this, e);
}
}
 
1656,15 → 1658,15
private const uint SIF_ALL = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS);
 
/*
typedef struct tagSCROLLINFO {
UINT cbSize;
UINT fMask;
int nMin;
int nMax;
UINT nPage;
int nPos;
int nTrackPos;
} SCROLLINFO, *LPSCROLLINFO;
typedef struct tagSCROLLINFO {
UINT cbSize;
UINT fMask;
int nMin;
int nMax;
UINT nPage;
int nPos;
int nTrackPos;
} SCROLLINFO, *LPSCROLLINFO;
typedef SCROLLINFO CONST *LPCSCROLLINFO;
*/
 
1671,17 → 1673,17
[StructLayout(LayoutKind.Sequential, Pack=4, CharSet=CharSet.Auto)]
private struct SCROLLINFO
{
public uint cbSize;
public uint fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos;
public uint cbSize;
public uint fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos;
}
 
/*
BOOL GetScrollInfo(
BOOL GetScrollInfo(
HWND hwnd,
int fnBar,
LPSCROLLINFO lpsi