/// <summary> /// Writes a block to its correct place in the file. /// The block's TotalStreamLength is saved as the total length of the stream IF AND ONLY IF the written block is the last block in the stream. /// </summary> public void WriteBlock(EncryptedFile.Block block, long size) { if (isReadonly) throw new InvalidOperationException("The current stream is read-only."); lock (locker) { if (block == null) throw new ArgumentNullException("block"); if (block.BlockNumber < 0) throw new ArgumentOutOfRangeException("block", "Block number be non negative."); if (block.Data == null || block.Data.Length != header.DecryptedBlockSize) throw new ArgumentException("Block must have data with length == " + header.DecryptedBlockSize); long position = header.GetPhysicalPositionFromBlockNumber(block.BlockNumber); if (stream.Length - EncryptedFile.Footer.FooterSize < position) throw new InvalidOperationException("Write past end of file."); stream.Position = position; var encrypted = settings.Codec.EncodeBlock(key, block.Data); Debug.Assert(encrypted.Data.Length == header.EncryptedBlockSize); stream.Write(encrypted.IV, 0, encrypted.IV.Length); stream.Write(encrypted.Data, 0, encrypted.Data.Length); totalUnencryptedSize += size; if (stream.Length <= stream.Position + EncryptedFile.Footer.FooterSize) { footer.TotalLength = block.TotalEncryptedStreamLength; WriteFooterInCurrentPosition(footer); } } }
private void WriteHeaderInCurrentPositionIfNotReadonly(EncryptedFile.Header fileHeader, ulong magicNumber) { if (isReadonly) return; var headerSize = GetHeaderSizeByMagicNumber(magicNumber); var headerBytes = StructConverter.ConvertStructToBits(fileHeader, headerSize); stream.Write(headerBytes, 0, headerSize); }
private void WriteFooterInCurrentPosition(EncryptedFile.Footer footer) { var footerBytes = StructConverter.ConvertStructToBits(footer); if (!isReadonly) stream.Write(footerBytes, 0, EncryptedFile.Footer.FooterSize); }
private void WriteHeaderInCurrentPositionIfNotReadonly(EncryptedFile.Header fileHeader) { if (isReadonly) return; var headerBytes = StructConverter.ConvertStructToBits(fileHeader); stream.Write(headerBytes, 0, EncryptedFile.Header.HeaderSize); }