/// <summary> /// When overridden in a derived class, reads a sequence of bytes from the current stream and advances the /// position within the stream by the number of bytes read. /// </summary> /// <param name="buffer"> /// An array of bytes. When this method returns, the buffer contains the specified byte array with the /// values between <paramref name="offset" /> and (<paramref name="offset" /> + <paramref name="count" /> - 1) replaced /// by the bytes read from the current source. /// </param> /// <param name="offset"> /// The zero-based byte offset in <paramref name="buffer" /> at which to begin storing the data read /// from the current stream. /// </param> /// <param name="count">The maximum number of bytes to be read from the current stream.</param> /// <returns> /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that /// many bytes are not currently available, or zero (0) if the end of the stream has been reached. /// </returns> public override int Read(byte[] buffer, int offset, int count) { if (!CanRead) { throw NotSupported("Read"); } int total = 0; while (count > 0) { int chunk = Math.Min(count, _bufferLength - _bufferOffset); if (chunk > 0) { #if INCLUDE_UNSAFE unsafe { fixed(byte *srcPtr = _buffer) { fixed(byte *dstPtr = buffer) { LZ4Codec.BlockCopy(srcPtr + _bufferOffset, dstPtr + offset, chunk); } } } #else Buffer.BlockCopy(_buffer, _bufferOffset, buffer, offset, chunk); #endif _bufferOffset += chunk; offset += chunk; count -= chunk; total += chunk; } else { if (!AcquireNextChunk()) { break; } } } return(total); }
/// <summary> /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current /// position within this stream by the number of bytes written. /// </summary> /// <param name="buffer"> /// An array of bytes. This method copies <paramref name="count" /> bytes from /// <paramref name="buffer" /> to the current stream. /// </param> /// <param name="offset"> /// The zero-based byte offset in <paramref name="buffer" /> at which to begin copying bytes to the /// current stream. /// </param> /// <param name="count">The number of bytes to be written to the current stream.</param> public override void Write(byte[] buffer, int offset, int count) { if (!CanWrite) { throw NotSupported("Write"); } if (_buffer == null) { _buffer = new byte[_blockSize]; _bufferLength = _blockSize; _bufferOffset = 0; } while (count > 0) { int chunk = Math.Min(count, _bufferLength - _bufferOffset); if (chunk > 0) { #if INCLUDE_UNSAFE unsafe { fixed(byte *srcPtr = buffer) { fixed(byte *dstPtr = _buffer) { LZ4Codec.BlockCopy(srcPtr + offset, dstPtr + _bufferOffset, chunk); } } } #else Buffer.BlockCopy(buffer, offset, _buffer, _bufferOffset, chunk); #endif offset += chunk; count -= chunk; _bufferOffset += chunk; } else { FlushCurrentChunk(); } } }