/// <summary> /// Writes every listed file entry based on its offset to the file, getting the contents from the generator /// </summary> /// <param name="stream">The stream to write to</param> /// <param name="fileGenerator">The file generator</param> public void WriteArchiveContent(Stream stream, IArchiveFileGenerator <Rayman1PCArchiveEntry> fileGenerator) { // Make sure we have a generator for each file if (fileGenerator.Count != Files.Length) { throw new BinarySerializableException("The .dat file can't be serialized without a file generator for each file"); } // Write the file contents foreach (var file in Files) { // Get the file stream using var fileStream = fileGenerator.GetFileStream(file); // Set the position to the pointer stream.Position = file.FileOffset; // Write the contents from the generator fileStream.CopyTo(stream); } }
private void WriteArchiveContent(BundleFile bundle, Stream stream, IArchiveFileGenerator <BundleFile_FileEntry> fileGenerator, bool compressBlock) { // Make sure we have a generator for each file if (fileGenerator.Count != bundle.FilePack.Files.Length) { throw new Exception("The .ipk file can't be serialized without a file generator for each file"); } TempFile? tempDecompressedBlockFile = null; FileStream?tempDecompressedBlockFileStream = null; try { // Create a temporary file to use if the block should be compressed if (compressBlock) { tempDecompressedBlockFile = new TempFile(true); tempDecompressedBlockFileStream = new FileStream(tempDecompressedBlockFile.TempPath, FileMode.Open); } // Get the stream to write the files to Stream currentStream = compressBlock ? tempDecompressedBlockFileStream ! : stream; // Write the file contents foreach (BundleFile_FileEntry file in bundle.FilePack.Files) { // Get the file stream from the generator using Stream fileStream = fileGenerator.GetFileStream(file); // Make sure the size matches if (fileStream.Length != file.ArchiveSize) { throw new Exception("The archived file size does not match the bytes retrieved from the generator"); } // Handle every file offset foreach (ulong offset in file.Offsets) { // Set the position currentStream.Position = (long)(compressBlock ? offset : (offset + bundle.BootHeader.BaseOffset)); // Write the bytes fileStream.CopyTo(currentStream); fileStream.Position = 0; } } // Handle the data if it should be compressed if (compressBlock) { // Get the length long decompressedSize = tempDecompressedBlockFileStream !.Length; // Create a temporary file for the final compressed data using TempFile tempCompressedBlockFile = new(true); using FileStream tempCompressedBlockFileStream = new(tempCompressedBlockFile.TempPath, FileMode.Open); tempDecompressedBlockFileStream.Position = 0; // Compress the data BundleBootHeader.GetEncoder(bundle.BootHeader.Version, -1).EncodeStream(tempDecompressedBlockFileStream, tempCompressedBlockFileStream); tempCompressedBlockFileStream.Position = 0; // Set the .ipk stream position stream.Position = bundle.BootHeader.BaseOffset; // Write the data to main stream tempCompressedBlockFileStream.CopyTo(stream); // Update the size bundle.BootHeader.BlockCompressedSize = (uint)tempCompressedBlockFileStream.Length; bundle.BootHeader.BlockSize = (uint)decompressedSize; } else { // Reset the size bundle.BootHeader.BlockCompressedSize = 0; bundle.BootHeader.BlockSize = 0; } } finally { tempDecompressedBlockFile?.Dispose(); tempDecompressedBlockFileStream?.Dispose(); } }
/// <summary> /// Writes every listed file entry based on its offset to the file, getting the contents from the generator /// </summary> /// <param name="stream">The stream to write to</param> /// <param name="fileGenerator">The file generator</param> /// <param name="compressBlock">Indicates if the block should be compressed</param> public void WriteArchiveContent(Stream stream, IArchiveFileGenerator <UbiArtIPKFileEntry> fileGenerator, bool compressBlock) { // Make sure we have a generator for each file if (fileGenerator.Count != Files.Length) { throw new BinarySerializableException("The .ipk file can't be serialized without a file generator for each file"); } TempFile tempDecompressedBlockFile = null; FileStream tempDecompressedBlockFileStream = null; try { // Create a temporary file to use if the block should be compressed if (compressBlock) { tempDecompressedBlockFile = new TempFile(true); tempDecompressedBlockFileStream = new FileStream(tempDecompressedBlockFile.TempPath, FileMode.Open); } // Get the stream to write the files to var currentStream = compressBlock ? tempDecompressedBlockFileStream : stream; // Write the file contents foreach (var file in Files) { // Get the file stream from the generator using var fileStream = fileGenerator.GetFileStream(file); // Make sure the size matches if (fileStream.Length != file.ArchiveSize) { throw new BinarySerializableException("The archived file size does not match the bytes retrieved from the generator"); } // Handle every file offset foreach (var offset in file.Offsets) { // Set the position currentStream.Position = (long)(compressBlock ? offset : (offset + BaseOffset)); // Write the bytes fileStream.CopyTo(currentStream); fileStream.Position = 0; } } // Handle the data if it should be compressed if (compressBlock) { // Get the length var decompressedSize = tempDecompressedBlockFileStream.Length; // Create a temporary file for the final compressed data using var tempCompressedBlockFile = new TempFile(true); using var tempCompressedBlockFileStream = new FileStream(tempCompressedBlockFile.TempPath, FileMode.Open); tempDecompressedBlockFileStream.Position = 0; // Compress the data GetEncoder(Version, -1).Encode(tempDecompressedBlockFileStream, tempCompressedBlockFileStream); tempCompressedBlockFileStream.Position = 0; // Set the .ipk stream position stream.Position = BaseOffset; // Write the data to main stream tempCompressedBlockFileStream.CopyTo(stream); // Update the size BlockCompressedSize = (uint)tempCompressedBlockFileStream.Length; BlockSize = (uint)decompressedSize; } else { // Reset the size BlockCompressedSize = 0; BlockSize = 0; } } finally { tempDecompressedBlockFile?.Dispose(); tempDecompressedBlockFileStream?.Dispose(); } }
/// <summary> /// Writes every listed file entry based on its offset to the file, getting the contents from the generator and compressing the block if it is set as compressed /// </summary> /// <param name="stream">The stream to write to</param> /// <param name="fileGenerator">The file generator</param> public void WriteArchiveContent(Stream stream, IArchiveFileGenerator <UbiArtIPKFileEntry> fileGenerator) { WriteArchiveContent(stream, fileGenerator, IsBlockCompressed); }