public int Read(byte *p, int length) { var read = 0; while (read < length) { // Read the next block from the underlying stream if (_decodedBuffer.Offset >= _decodedBuffer.End) { _encodedBuffer.Reset(); // Read the payload length if (_underlying.Read(_encodedBuffer.Data, 0, sizeOfHeader) != sizeOfHeader) { return(read); // Ends of stream } var payloadLength = ((PayloadHeader *)_encodedBuffer.Ptr)->PayloadLength; if (_underlying.Read(_encodedBuffer.Data, 0, payloadLength + sizeof(byte)) != payloadLength + sizeof(byte)) { return(read); // Ends of stream } // Decode data _decodedBuffer.Reset(); _decodedBuffer.End += _codec.Decode(_encodedBuffer.Ptr, payloadLength, (T *)_decodedBuffer.Ptr) * sizeof(T); // Checksum coherency if (*(_encodedBuffer.Ptr + payloadLength) != CHECKSUM) { throw new CorruptedDataException("Checksum failed"); } } var bytesToRead = Math.Min(length - read, (int)(_decodedBuffer.End - _decodedBuffer.Offset)); Unsafe.CopyBlock(p, _decodedBuffer.Offset, (uint)bytesToRead); read += bytesToRead; p += bytesToRead; _decodedBuffer.Offset += bytesToRead; #if Debug if ((int)(_blockEnd - _offset) <= remainingBytes) { throw new InvalidOperationException($"The codec {typeof(TCodec)} decoded nothing and the read is fallen in an infinity loop"); } #endif } return(read); }