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); } }
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); } }