Ejemplo n.º 1
0
        private static int[] DecompressTagSlow(byte[] input, int inputIndex, byte[] output, int outputLimit, int outputOffset, int outputIndex)
        {
            int opCode       = DataHelper.LoadByte(input, inputIndex++);
            int entry        = DataHelper.LookupShort(_opLookupTable, opCode);
            int trailerBytes = entry.BitwiseUnsignedRightShift(11);

            int trailer = 0;

            switch (trailerBytes)
            {
            case 4:
                trailer = (input[inputIndex + 3] & 0xff) << 24;
                break;

            case 3:
                trailer |= (input[inputIndex + 2] & 0xff) << 16;
                break;

            case 2:
                trailer |= (input[inputIndex + 1] & 0xff) << 8;
                break;

            case 1:
                trailer |= (input[inputIndex] & 0xff);
                break;
            }

            inputIndex += trailerBytes;
            int length = entry & 0xff;

            if ((opCode & 0x3) == LITERAL)
            {
                int literalLength = length + trailer;
                CopyLiteral(input, inputIndex, output, outputIndex, literalLength);
                inputIndex  += literalLength;
                outputIndex += literalLength;
            }
            else
            {
                int copyOffset = entry & 0x700;
                copyOffset += trailer;

                int spaceLeft = outputLimit - outputIndex;
                int srcIndex  = outputIndex - copyOffset;

                if (srcIndex < outputOffset)
                {
                    throw new CorruptionException("Invalid copy offset for opcode starting at " + (inputIndex - trailerBytes - 1));
                }

                if (length <= 16 && copyOffset >= 8 && spaceLeft >= 16)
                {
                    DataHelper.CopyLong(output, srcIndex, output, outputIndex);
                    DataHelper.CopyLong(output, srcIndex + 8, output, outputIndex + 8);
                }
                else if (spaceLeft >= length + MAX_INCREMENT_COPY_OVERFLOW)
                {
                    IncrementalCopyFastPath(output, srcIndex, outputIndex, length);
                }
                else
                {
                    IncrementalCopy(output, srcIndex, output, outputIndex, length);
                }

                outputIndex += length;
            }

            return(new int[] { inputIndex, outputIndex });
        }
Ejemplo n.º 2
0
        private static int DecompressAllTags(byte[] input, int inputOffset, int inputSize, byte[] output, int outputOffset)
        {
            int outputLimit = output.Length;
            int inputLimit  = inputOffset + inputSize;
            int outputIndex = outputOffset;
            int inputIndex  = inputOffset;

            while (inputIndex < inputLimit - 5)
            {
                int opCode       = DataHelper.LoadByte(input, inputIndex++);
                int entry        = DataHelper.LookupShort(_opLookupTable, opCode);
                int trailerBytes = entry.BitwiseUnsignedRightShift(11);
                int trailer      = ReadTrailer(input, inputIndex, trailerBytes);

                inputIndex += entry.BitwiseUnsignedRightShift(11);
                int length = entry & 0xff;

                if ((opCode & 0x3) == LITERAL)
                {
                    int literalLength = length + trailer;
                    CopyLiteral(input, inputIndex, output, outputIndex, literalLength);
                    inputIndex  += literalLength;
                    outputIndex += literalLength;
                }
                else
                {
                    int copyOffset = entry & 0x700;
                    copyOffset += trailer;

                    int spaceLeft = outputLimit - outputIndex;
                    int srcIndex  = outputIndex - copyOffset;
                    if (srcIndex < outputOffset)
                    {
                        throw new CorruptionException("Invalid copy offset for opcode starting at " + (inputIndex - trailerBytes - 1));
                    }

                    if (length <= 16 && copyOffset >= 8 && spaceLeft >= 16)
                    {
                        DataHelper.CopyLong(output, srcIndex, output, outputIndex);
                        DataHelper.CopyLong(output, srcIndex + 8, output, outputIndex + 8);
                    }
                    else if (spaceLeft >= length + MAX_INCREMENT_COPY_OVERFLOW)
                    {
                        IncrementalCopyFastPath(output, srcIndex, outputIndex, length);
                    }
                    else
                    {
                        IncrementalCopy(output, srcIndex, output, outputIndex, length);
                    }

                    outputIndex += length;
                }
            }

            while (inputIndex < inputLimit)
            {
                int[] result = DecompressTagSlow(input, inputIndex, output, outputLimit, outputOffset, outputIndex);
                inputIndex  = result[0];
                outputIndex = result[1];
            }

            return(outputIndex - outputOffset);
        }