コード例 #1
0
        private static int EmitLiteral(byte[] output, int outputIndex, byte[] literal, int literalIndex, int length, bool allowFastPath)
        {
            int n = length - 1;

            if (n < 60)
            {
                output[outputIndex++] = (byte)(LITERAL | n << 2);
                if (allowFastPath && length <= 16)
                {
                    DataHelper.CopyLong(literal, literalIndex, output, outputIndex);
                    DataHelper.CopyLong(literal, literalIndex + 8, output, outputIndex + 8);
                    outputIndex += length;
                    return(outputIndex);
                }
            }
            else if (n < (1 << 8))
            {
                output[outputIndex++] = (byte)(LITERAL | 59 + 1 << 2);
                output[outputIndex++] = (byte)n;
            }
            else if (n < (1 << 16))
            {
                output[outputIndex++] = (byte)(LITERAL | 59 + 2 << 2);
                output[outputIndex++] = (byte)n;
                output[outputIndex++] = (byte)Extensions.BitwiseUnsignedRightShift(n, 8);
            }
            else if (n < (1 << 24))
            {
                output[outputIndex++] = (byte)(LITERAL | 59 + 3 << 2);
                output[outputIndex++] = (byte)n;
                output[outputIndex++] = (byte)Extensions.BitwiseUnsignedRightShift(n, 8);
                output[outputIndex++] = (byte)Extensions.BitwiseUnsignedRightShift(n, 16);
            }
            else
            {
                output[outputIndex++] = (byte)(LITERAL | 59 + 4 << 2);
                output[outputIndex++] = (byte)n;
                output[outputIndex++] = (byte)Extensions.BitwiseUnsignedRightShift(n, 8);
                output[outputIndex++] = (byte)Extensions.BitwiseUnsignedRightShift(n, 16);
                output[outputIndex++] = (byte)Extensions.BitwiseUnsignedRightShift(n, 24);
            }

            Array.Copy(literal, literalIndex, output, outputIndex, length);
            outputIndex += length;
            return(outputIndex);
        }
コード例 #2
0
        private static int EmitCopyLessThan64(byte[] output, int outputIndex, int offset, int length)
        {
            Debug.Assert(offset >= 0);
            Debug.Assert(length <= 64);
            Debug.Assert(length >= 4);
            Debug.Assert(offset < 65536);

            if ((length < 12) && (offset < 2048))
            {
                int lenMinus4 = length - 4;
                Debug.Assert(lenMinus4 < 8);
                output[outputIndex++] = (byte)(COPY_1_BYTE_OFFSET | ((lenMinus4) << 2) | (Extensions.BitwiseUnsignedRightShift(offset, 8) << 5));
                output[outputIndex++] = (byte)offset;
            }
            else
            {
                output[outputIndex++] = (byte)(COPY_2_BYTE_OFFSET | ((length - 1) << 2));
                output[outputIndex++] = (byte)offset;
                output[outputIndex++] = (byte)Extensions.BitwiseUnsignedRightShift(offset, 8);
            }

            return(outputIndex);
        }
コード例 #3
0
        private static int WriteUncompressedLength(byte[] compressed, int compressedOffset, int uncompressedLength)
        {
            int highBitMask = 0x80;

            if (uncompressedLength < (1 << 7) && uncompressedLength >= 0)
            {
                compressed[compressedOffset++] = (byte)uncompressedLength;
            }
            else if (uncompressedLength < (1 << 14) && uncompressedLength > 0)
            {
                compressed[compressedOffset++] = (byte)(uncompressedLength | highBitMask);
                compressed[compressedOffset++] = (byte)Extensions.BitwiseUnsignedRightShift(uncompressedLength, 7);
            }
            else if (uncompressedLength < (1 << 21) && uncompressedLength > 0)
            {
                compressed[compressedOffset++] = (byte)(uncompressedLength | highBitMask);
                compressed[compressedOffset++] = (byte)(Extensions.BitwiseUnsignedRightShift(uncompressedLength, 7) | highBitMask);
                compressed[compressedOffset++] = (byte)Extensions.BitwiseUnsignedRightShift(uncompressedLength, 14);
            }
            else if (uncompressedLength < (1 << 28) && uncompressedLength > 0)
            {
                compressed[compressedOffset++] = (byte)(uncompressedLength | highBitMask);
                compressed[compressedOffset++] = (byte)(Extensions.BitwiseUnsignedRightShift(uncompressedLength, 7) | highBitMask);
                compressed[compressedOffset++] = (byte)(Extensions.BitwiseUnsignedRightShift(uncompressedLength, 14) | highBitMask);
                compressed[compressedOffset++] = (byte)Extensions.BitwiseUnsignedRightShift(uncompressedLength, 21);
            }
            else
            {
                compressed[compressedOffset++] = (byte)(uncompressedLength | highBitMask);
                compressed[compressedOffset++] = (byte)(Extensions.BitwiseUnsignedRightShift(uncompressedLength, 7) | highBitMask);
                compressed[compressedOffset++] = (byte)(Extensions.BitwiseUnsignedRightShift(uncompressedLength, 14) | highBitMask);
                compressed[compressedOffset++] = (byte)(Extensions.BitwiseUnsignedRightShift(uncompressedLength, 21) | highBitMask);
                compressed[compressedOffset++] = (byte)Extensions.BitwiseUnsignedRightShift(uncompressedLength, 28);
            }

            return(compressedOffset);
        }
コード例 #4
0
        private static int HashBytes(int bytes, int shift)
        {
            int multiplier = 0x1e35a7bd;

            return(Extensions.BitwiseUnsignedRightShift(bytes * multiplier, shift));
        }
コード例 #5
0
 private static int BytesBetweenHashLookups(int skip)
 {
     return(Extensions.BitwiseUnsignedRightShift(skip, 5));
 }
コード例 #6
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 = Extensions.BitwiseUnsignedRightShift(entry, 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 });
        }
コード例 #7
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 = Extensions.BitwiseUnsignedRightShift(entry, 11);
                int trailer      = ReadTrailer(input, inputIndex, trailerBytes);

                inputIndex += Extensions.BitwiseUnsignedRightShift(entry, 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);
        }