/// <summary>
 /// This is the static constructor.
 /// </summary>
 static TerminatorHolder()
 {
     CRLF = new TerminatorHolder(new byte[] { 13, 10 },
                                 TerminatorHolderMatchType.MatchSequence, TerminatorHolderActionType.Termination);
     LWSPEx = new TerminatorHolder(new byte[] { 9, 32 },
                                   TerminatorHolderMatchType.MatchAny, TerminatorHolderActionType.Exception);
 }
        /// <summary>
        /// This method matches a the teminator in the byte buffer provided.
        /// </summary>
        /// <param name="buffer">The byte buffer.</param>
        /// <param name="offset">The offset position in the byte buffer that the search should begin.</param>
        /// <param name="count">The number of bytes in the buffer to search.</param>
        /// <param name="terminatorOffset">The offset parameter within the terminator.</param>
        /// <param name="carryOver">The carry over value. This is needed when there is a partial match to
        /// the terminator at the end of the byte buffer, it will be passed as the terminatorOffset when the
        /// next set of data is received from the data stream.</param>
        /// <param name="bytesRead">This is the number of bytes to be read from the buffer.</param>
        /// <returns>Returns true if there is a full match, or true along with a carryOver value greater than
        /// 0 when there is a partial match at the end of the byte buffer.</returns>
        protected bool MatchTerminator(byte[] buffer, int offset, int count,
                                       int terminatorOffset, out int carryOver, out int bytesRead, out bool matchBoundaryPartCondition)
        {
            TerminatorHolder currentTH = TerminatorHolderGetCurrent().Value;

            carryOver = 0;
            bytesRead = 0;
            matchBoundaryPartCondition = false;
            bool result = false;

            try
            {
                switch (currentTH.MatchType)
                {
                case TerminatorHolderMatchType.MatchSequence:
                    result = ByteMatchSequence(currentTH.Terminator, buffer, offset, count, terminatorOffset, out carryOver, out bytesRead);

                    if (result && carryOver == 0)
                    {
                        //OK, we have matched a full terminator sequence.
                        //Now we need to check whether there are additional sequences to match.
                        TerminatorHolder?nextTH = TerminatorHolderGetNext();
                        if (nextTH.HasValue)
                        {
                            int newOffset = offset + bytesRead;
                            int newCount  = count - bytesRead;

                            if (newCount == 0)
                            {
                                if (ValidateBoundaryPartCondition(buffer, offset, count, carryOver, bytesRead))
                                {
                                    matchBoundaryPartCondition = true;
                                    return(result);
                                }
                                else
                                {
                                    matchBoundaryPartCondition = false;
                                }
                            }

                            int newCarryOver, newBytesRead;
                            //Ok, we have further sequences, so we need to pass recursively to this method.
                            result = MatchTerminator(buffer, newOffset, newCount, 0, out newCarryOver, out newBytesRead, out matchBoundaryPartCondition);

                            if (result)
                            {
                                bytesRead += newBytesRead;
                                if (newCarryOver > 0)
                                {
                                    carryOver += newCarryOver;
                                }
                                else
                                {
                                    carryOver = 0;
                                }
                            }
                        }
                    }
                    break;

                case TerminatorHolderMatchType.MatchAny:
                    result = ByteMatchAny(currentTH.Terminator, buffer, offset, count, out bytesRead,
                                          currentTH.ActionType != TerminatorHolderActionType.Exception);
                    break;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                //bytesRead
                if (!result)
                {
                    TerminatorHolderGetFirst();
                }
            }

            //OK, we have a match.
            return(result);
        }
 /// <summary>
 /// This is the static constructor.
 /// </summary>
 static TerminatorHolder()
 {
     CRLF = new TerminatorHolder(new byte[] { 13, 10 },
         TerminatorHolderMatchType.MatchSequence, TerminatorHolderActionType.Termination);
     LWSPEx = new TerminatorHolder(new byte[] { 9, 32 },
         TerminatorHolderMatchType.MatchAny, TerminatorHolderActionType.Exception);
 }