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); }
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); }
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); }
private static int HashBytes(int bytes, int shift) { int multiplier = 0x1e35a7bd; return(Extensions.BitwiseUnsignedRightShift(bytes * multiplier, shift)); }
private static int BytesBetweenHashLookups(int skip) { return(Extensions.BitwiseUnsignedRightShift(skip, 5)); }
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 }); }
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); }