public PackagedFileInfo WriteFile(AbstractFileInfo info) { // Assume that all files are written uncompressed (worst-case) when calculating package sizes uint size = info.Size(); if (_streams.Last().Position + size > MaxPackageSize) { // Start a new package file if the current one is full. string partPath = Package.MakePartFilename(_path, _streams.Count); var nextPart = File.Open(partPath, FileMode.Create, FileAccess.Write); _streams.Add(nextPart); } Stream stream = _streams.Last(); var packaged = new PackagedFileInfo { PackageStream = stream, Name = info.Name, UncompressedSize = size, ArchivePart = (UInt32)(_streams.Count - 1), OffsetInFile = (UInt32)stream.Position, Flags = BinUtils.MakeCompressionFlags(Compression, CompressionLevel) }; Stream packagedStream = info.MakeStream(); byte[] compressed; try { using (var reader = new BinaryReader(packagedStream, Encoding.UTF8, true)) { byte[] uncompressed = reader.ReadBytes((int)reader.BaseStream.Length); compressed = BinUtils.Compress(uncompressed, Compression, CompressionLevel); stream.Write(compressed, 0, compressed.Length); } } finally { info.ReleaseStream(); } packaged.SizeOnDisk = (UInt32)(stream.Position - packaged.OffsetInFile); packaged.Crc = Crc32.Compute(compressed, 0); int padLength = PaddingLength(); if (stream.Position % padLength <= 0) { return(packaged); } if ((_package.Metadata.Flags & PackageFlags.Solid) == 0) { // Pad the file to a multiple of 64 bytes var pad = new byte[padLength - stream.Position % padLength]; for (var i = 0; i < pad.Length; i++) { pad[i] = 0xAD; } stream.Write(pad, 0, pad.Length); } return(packaged); }