SuperSocket内置的命令行协议的解析

SuperSocket\SocketBase\Protocol\TerminatorReceiveFilter.cs

  /// <summary>
        /// Filters received data of the specific session into request info.
        /// </summary>
        /// <param name="readBuffer">The read buffer.</param>
        /// <param name="offset">The offset of the current received data in this read buffer.</param>
        /// <param name="length">The length of the current received data.</param>
        /// <param name="toBeCopied">if set to <c>true</c> [to be copied].</param>
        /// <param name="rest">The rest, the length of the data which hasn't been parsed.</param>
        /// <returns>return the parsed TRequestInfo</returns>
        public override TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest)
        {
            rest = 0;

            int prevMatched = m_SearchState.Matched;

            int result = readBuffer.SearchMark(offset, length, m_SearchState);

            if (result < 0)
            {
                if (m_OffsetDelta != m_ParsedLengthInBuffer)
                {
                    Buffer.BlockCopy(readBuffer, offset - m_ParsedLengthInBuffer, readBuffer, offset - m_OffsetDelta, m_ParsedLengthInBuffer + length);

                    m_ParsedLengthInBuffer += length;
                    m_OffsetDelta = m_ParsedLengthInBuffer;
                }
                else
                {
                    m_ParsedLengthInBuffer += length;

                    if (m_ParsedLengthInBuffer >= m_Session.Config.ReceiveBufferSize)
                    {
                        this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied);
                        m_ParsedLengthInBuffer = 0;
                        m_OffsetDelta = 0;

                        return NullRequestInfo;
                    }

                    m_OffsetDelta += length;
                }

                return NullRequestInfo;
            }

            var findLen = result - offset;
            var currentMatched = m_SearchState.Mark.Length - prevMatched;

            //The prev matched part is not belong to the current matched terminator mark
            if (prevMatched > 0 && findLen != 0)
            {
                //rest prevMatched to 0
                prevMatched = 0;
                currentMatched = m_SearchState.Mark.Length;
            }

            rest = length - findLen - currentMatched;

            TRequestInfo requestInfo;

            if (findLen > 0)
            {
                if(this.BufferSegments != null && this.BufferSegments.Count > 0)
                {
                    this.AddArraySegment(readBuffer, offset - m_ParsedLengthInBuffer, findLen + m_ParsedLengthInBuffer, toBeCopied);
                    requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count);
                }
                else
                {
                    requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, findLen + m_ParsedLengthInBuffer);
                }
            }
            else if (prevMatched > 0)
            {
                if (m_ParsedLengthInBuffer > 0)
                {
                    if (m_ParsedLengthInBuffer < prevMatched)
                    {
                        BufferSegments.TrimEnd(prevMatched - m_ParsedLengthInBuffer);
                        requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count);
                    }
                    else
                    {
                        if (this.BufferSegments != null && this.BufferSegments.Count > 0)
                        {
                            this.AddArraySegment(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer - prevMatched, toBeCopied);
                            requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count);
                        }
                        else
                        {
                            requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer - prevMatched);
                        }
                    }
                }
                else
                {
                    BufferSegments.TrimEnd(prevMatched);
                    requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count);
                }
            }
            else
            {
                if (this.BufferSegments != null && this.BufferSegments.Count > 0)
                {
                    if (m_ParsedLengthInBuffer > 0)
                    {
                        this.BufferSegments.AddSegment(readBuffer, offset, m_ParsedLengthInBuffer);
                    }

                    requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count);
                }
                else
                {
//在这里解析的时候,返回类型 requestInfo
= ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer); } } InternalReset(); if(rest == 0) { m_OffsetDelta = 0; } else { m_OffsetDelta += (length - rest); } return requestInfo; }

 

 protected override StringRequestInfo ProcessMatchedRequest(byte[] data, int offset, int length)
        {
            if(length == 0)
                return m_RequestParser.ParseRequestInfo(string.Empty);

            return m_RequestParser.ParseRequestInfo(m_Encoding.GetString(data, offset, length));
        }

 

 

SuperSocket\SocketBase\Protocol\TerminatorReceiveFilter.cs

TerminatorReceiveFilter.cs文件包含2个类

 public abstract class TerminatorReceiveFilter<TRequestInfo> : ReceiveFilterBase<TRequestInfo>, IOffsetAdapter, IReceiveFilterInitializer
        where TRequestInfo : IRequestInfo

 

public class TerminatorReceiveFilter : TerminatorReceiveFilter<StringRequestInfo>

 

SuperSocket\SocketBase\Protocol\StringRequestInfo.cs

 public class StringRequestInfo : RequestInfo<string>

 

 

AppSession在初始化的时候,指定了ReceiveFilter

SuperSocket\SocketBase\AppSession.cs

 /// <summary>
        /// Initializes the specified app session by AppServer and SocketSession.
        /// </summary>
        /// <param name="appServer">The app server.</param>
        /// <param name="socketSession">The socket session.</param>
        public virtual void Initialize(IAppServer<TAppSession, TRequestInfo> appServer, ISocketSession socketSession)
        {
            var castedAppServer = (AppServerBase<TAppSession, TRequestInfo>)appServer;
            AppServer = castedAppServer;
            Charset = castedAppServer.TextEncoding;
            SocketSession = socketSession;
            SessionID = socketSession.SessionID;
            m_Connected = true;
            m_ReceiveFilter = castedAppServer.ReceiveFilterFactory.CreateFilter(appServer, this, socketSession.RemoteEndPoint);

            var filterInitializer = m_ReceiveFilter as IReceiveFilterInitializer;
            if (filterInitializer != null)
                filterInitializer.Initialize(castedAppServer, this);

            socketSession.Initialize(this);

            OnInit();
        }

 

F:\CodeForGitBlit\SuperSocket\SocketBase\AppServer.cs

     internal override IReceiveFilterFactory<StringRequestInfo> CreateDefaultReceiveFilterFactory()
        {
            return new CommandLineReceiveFilterFactory(TextEncoding);
        }

F:\CodeForGitBlit\SuperSocket\SocketBase\Protocol\CommandLineReceiveFilterFactory.cs

 public class CommandLineReceiveFilterFactory : TerminatorReceiveFilterFactory

 

 

 return m_RequestParser.ParseRequestInfo(m_Encoding.GetString(data, offset, length));

F:\CodeForGitBlit\SuperSocket\SocketBase\Protocol\BasicRequestInfoParser.cs

  public class BasicRequestInfoParser : IRequestInfoParser<StringRequestInfo>

 

  public StringRequestInfo ParseRequestInfo(string source)
        {
            int pos = source.IndexOf(m_Spliter);

            string name = string.Empty;
            string param = string.Empty;

            if (pos > 0)
            {
                name = source.Substring(0, pos);
                param = source.Substring(pos + 1);
            }
            else
            {
                name = source;
            }

            return new StringRequestInfo(name, param,
                param.Split(m_ParameterSpliters, StringSplitOptions.RemoveEmptyEntries));
        }

 

posted @ 2016-04-25 15:00  ChuckLu  阅读(3739)  评论(0编辑  收藏  举报