public void SaveGpkPackage(GpkPackage package, string savepath, bool addPadding) { //Header //Namelist //Imports //Exports logger = LogManager.GetLogger("[Save:" + package.Filename + "]"); logger.Info(String.Format("Attemping to save {0}...", package.Filename)); Stopwatch watch = new Stopwatch(); watch.Start(); stat = new Status(); stat.name = package.Filename; package.PrepareWriting(CoreSettings.Default.EnableCompression); int compuSize = package.GetSize(false); stat.totalobjects = package.Header.NameCount + package.Header.ExportCount * 2 + package.Header.ImportCount; //Export, ExportData = x2 Stream dataStream; if (CoreSettings.Default.EnableCompression) { //write to mem, write empty header, generate final blocks, compress, write to file dataStream = new MemoryStream(); } else { dataStream = new FileStream(savepath, FileMode.Create); } using (BinaryWriter writer = new BinaryWriter(dataStream)) { WriteHeader(writer, package, CoreSettings.Default.EnableCompression); WriteNamelist(writer, package); WriteImports(writer, package); WriteExports(writer, package); WriteDepends(writer, package); WriteHeaderSize(writer, package); WriteExportsData(writer, package); if (addPadding && !CoreSettings.Default.EnableCompression) { WriteFilePadding(writer, package, compuSize); } else { WriteFileEnding(writer, package, compuSize); } } if (CoreSettings.Default.EnableCompression) { var data = ((MemoryStream)dataStream).ToArray(); //only compress data after the header, starting with the namelist package.GenerateChunkHeaders(data.Length - package.Header.NameOffset, package.Header.NameOffset, data); if (package.Header.EstimatedChunkHeaderCount != package.Header.ChunkHeaders.Count) { logger.Error("ChunkCount estimation was wrong. Estimated {0} vs {1}", package.Header.EstimatedChunkHeaderCount, package.Header.ChunkHeaders.Count); return; } logger.Debug("UncompressedSize {0}, DataSize {1}, Chunkcount {2}", data.Length, data.Length - package.Header.NameOffset, package.Header.ChunkHeaders.Count); using (BinaryWriter writer = new BinaryWriter(new FileStream(savepath, FileMode.Create))) { writer.Write(new byte[package.Header.GetSize()]); //reserve header space WriteChunkContent(writer, package); int endOfData = (int)writer.BaseStream.Position; writer.Seek(0, SeekOrigin.Begin); WriteHeader(writer, package, false); //writer header, now with correct offsets of the chunks logger.Debug("Compressed gpk written. Compu Size: {0}, Diff: {1} -", compuSize, writer.BaseStream.Length - compuSize); if (addPadding) { writer.Seek(endOfData, SeekOrigin.Begin); WriteFilePadding(writer, package, compuSize); } } } watch.Stop(); stat.time = watch.ElapsedMilliseconds; stat.finished = true; logger.Info(String.Format("Saved the package '{0} to {1}', took {2}ms!", package.Filename, savepath, stat.time)); }