Exemplo n.º 1
0
        public override int Read(byte[] buffer, int bufferOffset, int count)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count");
            }
            if (bufferOffset + count > buffer.LongLength)
            {
                throw new ArgumentOutOfRangeException("bufferOffset");
            }

            if (count == 0)
            {
                return(0);
            }

            lock (locker)
            {
                // If the stream is used for both reading and writing, make sure we're reading everything that was written
                WriteAnyUnwrittenData();

                if (Position >= underlyingStream.Footer.TotalLength)
                {
                    return(0);
                }

                long startingBlock = underlyingStream.Header.GetBlockNumberFromLogicalPosition(Position);
                long blockOffset   = underlyingStream.Header.GetBlockOffsetFromLogicalPosition(Position);

                if (currentReadingBlock == null || currentReadingBlock.BlockNumber != startingBlock)
                {
                    currentReadingBlock = underlyingStream.ReadBlock(startingBlock);
                }

                int blockRead  = (int)Math.Min(currentReadingBlock.TotalStreamLength - Position, currentBlockSize - bufferOffset);
                int actualRead = Math.Min(count, blockRead);
                Array.Copy(currentReadingBlock.Data, blockOffset, buffer, bufferOffset, actualRead);
                // We use the fact that a stream doesn't have to read all data in one go to avoid a loop here.

                Position += actualRead;
                return(actualRead);
            }
        }
Exemplo n.º 2
0
        public override int Read(byte[] buffer, int bufferOffset, int count)
        {
            //precaution, should never be true
            if (underlyingStream.Header.MagicNumber != EncryptedFile.WithTotalSizeMagicNumber &&
                underlyingStream.Header.MagicNumber != EncryptedFile.DefaultMagicNumber)
            {
                throw new ApplicationException("Invalid magic number in the encrypted file. Cannot proceed with reading.");
            }

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count");
            }
            if (bufferOffset + count > buffer.LongLength)
            {
                throw new ArgumentOutOfRangeException("bufferOffset");
            }

            if (count == 0)
            {
                return(0);
            }

            lock (locker)
            {
                // If the stream is used for both reading and writing, make sure we're reading everything that was written
                WriteAnyUnwrittenData();

                if (Position >= underlyingStream.Footer.TotalLength &&
                    underlyingStream.Header.MagicNumber == EncryptedFile.DefaultMagicNumber)
                {
                    return(0);
                }

                if (Position >= underlyingStream.Header.TotalUnencryptedSize &&
                    underlyingStream.Header.MagicNumber == EncryptedFile.WithTotalSizeMagicNumber)
                {
                    return(0);
                }

                if (underlyingStream.Header.MagicNumber != EncryptedFile.WithTotalSizeMagicNumber &&
                    underlyingStream.Header.MagicNumber != EncryptedFile.DefaultMagicNumber)
                {
                    throw new ApplicationException("Invalid magic number in the encrypted file. Cannot proceed with reading.");
                }

                var startingBlock = underlyingStream.Header.GetBlockNumberFromLogicalPosition(Position);
                var blockOffset   = underlyingStream.Header.GetBlockOffsetFromLogicalPosition(Position);

                if (currentReadingBlock == null || currentReadingBlock.BlockNumber != startingBlock)
                {
                    currentReadingBlock = underlyingStream.ReadBlock(startingBlock);
                }

                var blockRead  = (int)Math.Min(underlyingStream.Header.TotalUnencryptedSize - Position, currentBlockSize - blockOffset);
                var actualRead = Math.Min(count, blockRead);
                Array.Copy(currentReadingBlock.Data, blockOffset, buffer, bufferOffset, actualRead);
                // We use the fact that a stream doesn't have to read all data in one go to avoid a loop here.

                Position += actualRead;
                return(actualRead);
            }
        }