RocksmithToolkitLib.PsarcLoader.PSARC.Write C# (CSharp) Method

Write() public method

public Write ( Stream inputStream, bool encrypt = false, bool seek = true ) : void
inputStream Stream
encrypt bool
seek bool
return void
        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();
        }

Usage Example

        public static bool RemoveArchiveEntry(string psarcPath, string entryName)
        {
            if (!File.Exists(psarcPath))
            {
                return(false);
            }

            using (PSARC archive = new PSARC(true))
                using (var psarcStream = File.OpenRead(psarcPath))
                {
                    archive.Read(psarcStream);
                    psarcStream.Dispose(); // CRITICAL

                    var tocEntry = archive.TOC.FirstOrDefault(entry => entry.Name == entryName);

                    if (tocEntry == null)
                    {
                        archive.Dispose(); // CRITICAL
                        return(true);
                    }

                    archive.TOC.Remove(tocEntry);
                    archive.TOC.Insert(0, new Entry()
                    {
                        Name = "NamesBlock.bin"
                    });

                    using (var fs = File.Create(psarcPath))
                        archive.Write(fs, true);

                    archive.Dispose(); // CRITICAL
                    return(true);
                }
        }
All Usage Examples Of RocksmithToolkitLib.PsarcLoader.PSARC::Write