Example #1
0
        /// <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);
 }