Microsoft.Protocols.TestTools.StackSdk.Compression.Mppc.Compressor.FindMatchInSlidingWindow C# (CSharp) Method

FindMatchInSlidingWindow() private method

private FindMatchInSlidingWindow ( byte input, int startIndex ) : OffsetLengthPair
input byte
startIndex int
return OffsetLengthPair
        private OffsetLengthPair FindMatchInSlidingWindow(byte[] input, int startIndex)
        {
            OffsetLengthPair match = new OffsetLengthPair();

            if ((input.Length - startIndex) < minimumEncodeLength)
            {
                return match;
            }

            //create minimumEncodeLength bytes key
            byte[] threeBytesHashKey = new byte[minimumEncodeLength];
            Array.Copy(input, startIndex, threeBytesHashKey, 0, threeBytesHashKey.Length);
            int[] findedPositions = hashTable.GetKeyMatchPositions(threeBytesHashKey);

            //because hash table does not contain the hash value of last two characters
            //so we need to caculate it after getting hash value from hash table.
            List<int> matchPositions = new List<int>(findedPositions);

            // indicate the match position
            int matchedPosition = -1;
            bool isMatchFound = false;

            // if sliding windows count <=0, there is no match can be found, so do nothing
            if (slidingWindow.Count > 0)
            {
                // test if there is a match at the last position of sliding windows
                if (slidingWindow[slidingWindow.Count - 1] == input[startIndex]
                    && input[startIndex] == input[startIndex + 1]
                    && input[startIndex + 1] == input[startIndex + 2])
                {
                    // the position is the last byte in sliding window
                    matchedPosition  = slidingWindow.Count-1;
                    isMatchFound = true;
                }
                // test if there is a match at the second last position of sliding windows
                if (slidingWindow.Count > 1)
                {
                    if (slidingWindow[slidingWindow.Count - 2] == input[startIndex]
                        && slidingWindow[slidingWindow.Count - 1] == input[startIndex + 1]
                        && input[startIndex] == input[startIndex + 2])
                    {
                        // the position is the second last byte in sliding window
                        matchPositions.Add(slidingWindow.Count - 2);
                        isMatchFound = true;
                    }
                }
            }

            //make sure the position will be added in ascending order.
            if (matchedPosition != -1)
            {
                matchPositions.Add(matchedPosition);
            }

            // translate list to array if match is found from the second last position of sliding window
            if (isMatchFound)
            {
                findedPositions = matchPositions.ToArray();
            }

            // if there is no match, return default match
            if (findedPositions == null || findedPositions.Length == 0)
            {
                return match;
            }

            //caculate the offset and length
            match.Offset = slidingWindow.Count - findedPositions[findedPositions.Length - 1];
            match.Length = minimumEncodeLength;

            for (int i = 0; i < findedPositions.Length; i++)
            {
                //skip already matched 3 characters
                int searchIndex = startIndex + minimumEncodeLength;

                int j;

                for (j = (findedPositions[i]+minimumEncodeLength); j < slidingWindow.Count; j++)
                {
                    // get the last unmatched position
                    if ((searchIndex == input.Length)
                        || (slidingWindow[j] != input[searchIndex++]))
                    {
                        if (match.Length < (searchIndex - startIndex -1))
                        {
                            match.Length = searchIndex - startIndex -1;
                            match.Offset = slidingWindow.Count - findedPositions[i];
                        }
                        break;
                    }
                }

                // if length > offset
                if (j >= slidingWindow.Count)
                {
                    int mark = startIndex;

                    // the last two character case
                    if (j > 0)
                    {
                        mark = startIndex + j - slidingWindow.Count;
                    }

                    //continue find match against the current data
                    while (searchIndex < input.Length)
                    {
                        if (input[mark++] != input[searchIndex++])
                        {
                            // because upper line use searchIndex++, so at this position
                            // we need to reduce it by 1;
                            if (match.Length < (searchIndex - startIndex - 1))
                            {
                                match.Length = searchIndex - startIndex - 1;
                                match.Offset = slidingWindow.Count - findedPositions[i];
                            }
                            break;
                        }
                    }

                    // if searchIndex == inputLength, the way to caculate offset and length
                    // is different with the normal situation.
                    if (searchIndex == input.Length)
                    {
                        if (match.Length < searchIndex - startIndex)
                        {
                            match.Length = searchIndex - startIndex;
                            match.Offset = slidingWindow.Count - findedPositions[i];
                        }
                    }
                }
            }

            return match;
        }