/// <summary> /// Closes the currently opened file stream and flushes buffered metadata. /// </summary> public void Flush() { FinishCurrentFile(); if (mFiles != null && mFiles.Count != 0) { PrepareFinishFileSet(); if (mEncryptionEncoder != null) { byte[] data; int offset, length; mEncryptionEncoder.FinishEncryption(out data, out offset, out length); WriteOutputInternal(data, offset, length); } mInputHash = CRC.Finish(mInputHash); mOutputHash = CRC.Finish(mOutputHash); FileSet fileset; if (mEncryptionEncoder != null) { // TODO: This is actually wrong, we pass the wrong mOutputSize. FinishFileSet puts the OutputSize // as the original input stream size. However AdjustFilesetForEncryption doesn't properly // redirect the input streams so these two bugs cancel each other out. fileset = FinishFileSet(mFiles.ToArray(), mInputSize, mOutputSize, mInputHash, null); AdjustFilesetForEncryption(fileset, mEncryption, mOutputSize2, null); } else { Debug.Assert(mOutputSize2 == 0); fileset = FinishFileSet(mFiles.ToArray(), mInputSize, mOutputSize, mInputHash, mOutputHash); } mFiles.Clear(); mInputSize = 0; mOutputSize = 0; mOutputSize2 = 0; mInputHash = CRC.kInitCRC; mOutputHash = CRC.kInitCRC; if (IsConnected) { mWriter.Encoder_FinishFileSet(fileset); } else { if (mFlushed == null) mFlushed = new List<BufferedFileSet>(); Debug.Assert(mBuffer != null); mFlushed.Add(new BufferedFileSet(fileset, mBuffer)); mBuffer = null; } } if (mEncryptionEncoder != null) { mEncryptionEncoder.Dispose(); mEncryptionEncoder = null; } }
public Stream BeginWriteFile(IArchiveWriterEntry file) { FinishCurrentFile(); if (file == null) throw new ArgumentNullException("file"); mCurrentFile = new FileEntry { Name = file.Name, CTime = EnsureUTC(file.CreationTime), MTime = EnsureUTC(file.LastWriteTime), ATime = EnsureUTC(file.LastAccessTime), }; var attributes = file.Attributes; if (attributes.HasValue) mCurrentFile.Flags = (uint)attributes.Value; if (mWriter == null && mBuffer == null) mBuffer = new FragmentedMemoryStream(); if (mEncryption != null) mEncryptionEncoder = mEncryption.CreateEncoder(); return mCurrentStream = new EncoderStream(this); }