public void Complete() { if (_state == FseCompressorState.Completed) { return; } if (_state == FseCompressorState.NeedInput) { Compress(); } _state = FseCompressorState.WriteOutput; Debug.Assert(_outputBuffer != null); uint checksum = _hash.GetFinalHash(); checksum = (checksum >> 5) & ((1u << 22) - 1); Span <byte> block = _outputBuffer.AsSpan(_outputOffset + _bytesGenerated); block[2] = (byte)checksum; block[1] = (byte)(checksum >> 8); block[0] = (byte)((checksum >> 16) + (0b11 << 6)); _bytesGenerated += 3; _headerWritten = false; _hash = XxHash32.Initialize(); }
public void Reset() { if (_compressor is null) { throw new ObjectDisposedException(nameof(FsePipeCompressor)); } _compressor.Reset(); _state = FseCompressorState.NeedInput; }
public void Reset() { _state = FseCompressorState.NeedInput; _headerWritten = false; _hash = XxHash32.Initialize(); _bytesRead = 0; _outputOffset = 0; _bytesGenerated = 0; }
public void NotifyFlushCompleted() { if (_compressor is null) { throw new ObjectDisposedException(nameof(FsePipeCompressor)); } if (_state == FseCompressorState.WriteOutput) { _state = _compressor.State; return; } throw new InvalidOperationException(); }
public void Complete() { if (_compressor is null) { throw new ObjectDisposedException(nameof(FsePipeCompressor)); } _compressor.Complete(); if (_compressor.State == FseCompressorState.WriteOutput) { ArraySegment <byte> output = _compressor.Output; _writer.Write(output.AsSpan()); _compressor.Advance(output.Count); _state = FseCompressorState.WriteOutput; } }
public void Advance(int count) { if (_state != FseCompressorState.WriteOutput) { throw new InvalidOperationException(); } if ((uint)count > (uint)_bytesGenerated) { throw new ArgumentOutOfRangeException(nameof(count)); } _outputOffset += count; _bytesGenerated -= count; if (_bytesGenerated == 0) { _bytesRead = 0; _outputOffset = 0; _state = _headerWritten ? FseCompressorState.NeedInput : FseCompressorState.Completed; } }
public void Flush() { if (_compressor is null) { throw new ObjectDisposedException(nameof(FsePipeCompressor)); } if (_state != FseCompressorState.NeedInput) { throw new InvalidOperationException(); } _compressor.Flush(); if (_compressor.State == FseCompressorState.WriteOutput) { ArraySegment <byte> output = _compressor.Output; _writer.Write(output.AsSpan()); _compressor.Advance(output.Count); _state = FseCompressorState.WriteOutput; } }
public void Process(ReadOnlySequence <byte> buffer, out SequencePosition consumed, out SequencePosition examined) { if (_compressor is null) { throw new ObjectDisposedException(nameof(FsePipeCompressor)); } if (_state == FseCompressorState.WriteOutput) { throw new InvalidOperationException(); } if (buffer.IsEmpty) { consumed = examined = default; return; } int consumedBytes = 0; foreach (ReadOnlyMemory <byte> segment in buffer) { consumedBytes += _compressor.SetInput(segment.Span); if (_compressor.State == FseCompressorState.WriteOutput) { ArraySegment <byte> output = _compressor.Output; _writer.Write(output.AsSpan()); _compressor.Advance(output.Count); _state = FseCompressorState.WriteOutput; break; } } consumed = examined = buffer.Slice(consumedBytes).Start; }
public FsePipeCompressor(IBufferWriter <byte> writer) { _writer = writer ?? throw new ArgumentNullException(nameof(writer)); _compressor = new FseStreamCompressor(); _state = FseCompressorState.NeedInput; }
private void Compress() { EnsureOutputBufferAllocated(); Debug.Assert(_state == FseCompressorState.NeedInput); Debug.Assert(_bytesGenerated == 0); int inSize = _bytesRead; Span <byte> inputBuffer = _inputBuffer.AsSpan(0, inSize); Span <byte> outputBuffer = _outputBuffer.AsSpan(0, _outputBufferBound); int headerSize; if (inSize == 0) { headerSize = 0; } else { _hash.Update(inputBuffer); int cSize = FseBlockCompressor.Compress(outputBuffer.Slice(10), inputBuffer); if (cSize == 0) { // raw if (inSize == _inputBufferSize) { outputBuffer[9] = (0b01 << 6) + 0x20; headerSize = 1; } else { outputBuffer[7] = (byte)(0b01 << 6); outputBuffer[8] = (byte)(inSize >> 8); outputBuffer[9] = (byte)inSize; headerSize = 3; } inputBuffer.CopyTo(outputBuffer.Slice(10)); _bytesGenerated = inSize; } else if (cSize == 1) { // rle if (inSize == _inputBufferSize) { outputBuffer[9] = (0b10 << 6) + 0x20; headerSize = 1; } else { outputBuffer[7] = (byte)(0b10 << 6); outputBuffer[8] = (byte)(inSize >> 8); outputBuffer[9] = (byte)inSize; headerSize = 3; } outputBuffer[10] = inputBuffer[0]; _bytesGenerated = 1; } else { // compressed if (inSize == _inputBufferSize) { outputBuffer[7] = (0b00 << 6) + 0x20; outputBuffer[8] = (byte)(cSize >> 8); outputBuffer[9] = (byte)cSize; headerSize = 3; } else { outputBuffer[5] = 0b00 << 6; outputBuffer[6] = (byte)(inSize >> 8); outputBuffer[7] = (byte)inSize; outputBuffer[8] = (byte)(cSize >> 8); outputBuffer[9] = (byte)cSize; headerSize = 5; } _bytesGenerated = cSize; } } if (!_headerWritten) { BinaryPrimitives.WriteInt32LittleEndian(outputBuffer.Slice(5 - headerSize, 4), (int)FseCompressingAlgorithm.Fse); outputBuffer[9 - headerSize] = (byte)_blockSizeId; headerSize += 5; _headerWritten = true; } _outputOffset = 10 - headerSize; _bytesGenerated += headerSize; if (_bytesGenerated == 0) { _state = FseCompressorState.NeedInput; } else { _state = FseCompressorState.WriteOutput; } }