public void Write(Stream inputStream, bool encrypt = false, bool seek = true) { _header.ArchiveFlags = encrypt ? 4U : 0U; _header.TOCEntrySize = 30U; WriteManifest(); //Pack entries List <uint> zLengths; Dictionary <Entry, byte[]> zStreams; DeflateEntries(out zStreams, out zLengths); //Build zLengths _writer = new BigEndianBinaryWriter(inputStream); _header.TotalTOCSize = (uint)(32 + _toc.Count * _header.TOCEntrySize + zLengths.Count * bNum); _toc[0].Offset = _header.TotalTOCSize; for (int i = 1; i < _toc.Count; i++) { _toc[i].Offset = _toc[i - 1].Offset + (ulong)(zStreams[_toc[i - 1]].Length); } //Write Header _writer.Write(_header.MagicNumber); _writer.Write(_header.VersionNumber); _writer.Write(_header.CompressionMethod); _writer.Write(_header.TotalTOCSize); _writer.Write(_header.TOCEntrySize); _writer.Write(_toc.Count); _writer.Write(_header.BlockSizeAlloc); _writer.Write(_header.ArchiveFlags); //Write Table of contents foreach (Entry current in _toc) { current.UpdateNameMD5(); _writer.Write(current.MD5); _writer.Write(current.zIndexBegin); _writer.WriteUInt40((ulong)current.Data.Length); //current.Length _writer.WriteUInt40(current.Offset); } foreach (uint zLen in zLengths) { switch (bNum) { case 2: _writer.Write((ushort)zLen); break; case 3: _writer.WriteUInt24(zLen); break; case 4: _writer.Write(zLen); break; } } zLengths = null; // Write zData var ndx = 0; // for debugging var step = Math.Round(1.0 / (this.TOC.Count + 2) * 100, 3); double progress = 0; // GlobalExtension.ShowProgress("Writing Zipped Data ..."); foreach (Entry current in _toc) { _writer.Write(zStreams[current]); progress += step; // GlobalExtension.UpdateProgress.Value = (int)progress; Debug.WriteLine("Zipped: " + ndx++); current.Data.Close(); } zStreams = null; if (encrypt) // Encrypt TOC { using (var outputStream = new MemoryStreamExtension()) { var encStream = new MemoryStreamExtension(); inputStream.Position = 32L; RijndaelEncryptor.EncryptPSARC(inputStream, outputStream, _header.TotalTOCSize); inputStream.Position = 0L; // quick copy header from input stream var buffer = new byte[32]; encStream.Write(buffer, 0, inputStream.Read(buffer, 0, buffer.Length)); encStream.Position = 32; //sainty check ofc inputStream.Flush(); int tocSize = (int)_header.TotalTOCSize - 32; int decSize = 0; buffer = new byte[1024 * 16]; // more effecient use of memory ndx = 0; // for debuging step = Math.Round(1.0 / ((tocSize / buffer.Length) + 2) * 100, 3); progress = 0; // GlobalExtension.ShowProgress("Writing Encrypted Data ..."); int bytesRead; while ((bytesRead = outputStream.Read(buffer, 0, buffer.Length)) > 0) { decSize += bytesRead; if (decSize > tocSize) { bytesRead = tocSize - (decSize - bytesRead); } encStream.Write(buffer, 0, bytesRead); progress += step; // GlobalExtension.UpdateProgress.Value = (int)progress; Debug.WriteLine("Encrypted: " + ndx++); } inputStream.Position = 0; encStream.Position = 0; encStream.CopyTo(inputStream, (int)_header.BlockSizeAlloc); } } if (seek) // May be redundant { inputStream.Flush(); inputStream.Position = 0; } // GlobalExtension.HideProgress(); }