Beispiel #1
0
        private static IEnumerable <CopyToken> RemoveRedundantTokens(IEnumerable <CopyToken> tokens)
        {
            CopyToken previous = null;

            foreach (var next in tokens)
            {
                if (previous == null)
                {
                    previous = next;
                    continue;
                }
                if (previous.OverlapsWith(next))
                {
                    //figure out which one to keep.  There can only be one!
                    if (previous.Length >= next.Length)
                    {
                        yield return(previous);
                        // can't return next.
                    }
                    else
                    {
                        yield return(next);
                    }
                }
                else
                {
                    yield return(previous);

                    previous = next;
                }
            }
        }
Beispiel #2
0
        internal static bool Contains(this CopyToken thisToken, CopyToken otherToken)
        {
            var otherTokenStartsAfterThisToken = thisToken.Position <= otherToken.Position;
            var otherTokenEndsBeforeThisToken  = thisToken.Position + thisToken.Length >=
                                                 otherToken.Position + otherToken.Length;

            return(otherTokenStartsAfterThisToken && otherTokenEndsBeforeThisToken);
        }
Beispiel #3
0
        internal static bool OverlapsWith(this CopyToken thisToken, CopyToken otherToken)
        {
            var firstToken  = thisToken;
            var secondToken = otherToken;

            if (thisToken.Position > otherToken.Position)
            {
                firstToken  = otherToken;
                secondToken = thisToken;
            }

            return(firstToken.Position + firstToken.Length > secondToken.Position);
        }
Beispiel #4
0
        internal static TokenSequence GetFromCompressedData(BinaryReader reader, long position)
        {
            var sequence = new TokenSequence
            {
                _flagByte = reader.ReadByte()
            };

            for (var i = 0; i <= 7; i++)
            {
                if (sequence.GetIsCopyToken(i))
                {
                    var token = new CopyToken(reader, position);
                    sequence._tokens.Add(token);
                    position += Convert.ToInt64(token.Length);
                }
                else
                {
                    sequence._tokens.Add(new LiteralToken(reader));
                    position += 1;
                }
            }
            return(sequence);
        }
Beispiel #5
0
        internal static void Match(byte[] uncompressedData, long position, out UInt16 matchedOffset, out UInt16 matchedLength)
        {
            var        decompressedCurrent    = position;
            var        decompressedEnd        = uncompressedData.Length;
            const long decompressedChunkStart = 0;

            // SET Candidate TO DecompressedCurrent MINUS 1
            var candidate = decompressedCurrent - 1L;
            // SET BestLength TO 0
            var bestLength    = 0L;
            var bestCandidate = 0L;

            // WHILE Candidate is GREATER THAN OR EQUAL TO DecompressedChunkStart
            while (candidate >= decompressedChunkStart)
            {
                // SET C TO Candidate
                var c = candidate;
                // SET D TO DecompressedCurrent
                var d = decompressedCurrent;
                // SET Len TO 0
                var len = 0;

                // WHILE (D is LESS THAN DecompressedEnd)
                // and (the byte at D EQUALS the byte at C)
                while (d < decompressedEnd &&
                       uncompressedData[d] == uncompressedData[c])
                {
                    // INCREMENT Len
                    len++;
                    // INCREMENT C
                    c++;
                    // INCREMENT D
                    d++;
                } // END WHILE

                // IF Len is GREATER THAN BestLength THEN
                if (len > bestLength)
                {
                    // SET BestLength TO Len
                    bestLength = len;
                    // SET BestCandidate TO Candidate
                    bestCandidate = candidate;
                } // ENDIF

                // DECREMENT Candidate
                candidate--;
            } // END WHILE

            // IF BestLength is GREATER THAN OR EQUAL TO 3 THEN
            if (bestLength >= 3)
            {
                // CALL CopyToken Help (section 2.4.1.3.19.1) returning MaximumLength
                var result = CopyToken.CopyTokenHelp(decompressedCurrent);

                // SET Length TO the MINIMUM of BestLength and MaximumLength
                matchedLength = (UInt16)bestLength;
                if (bestLength > result.MaximumLength)
                {
                    matchedLength = result.MaximumLength;
                }

                // SET Offset TO DecompressedCurrent MINUS BestCandidate
                matchedOffset = (UInt16)(decompressedCurrent - bestCandidate);
            }
            else // ELSE
            {
                // SET Length TO 0
                matchedLength = 0;
                // SET Offset TO 0
                matchedOffset = 0;
            } // ENDIF
        }