예제 #1
0
        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);
        }