public async ValueTask <IMemoryOwner <byte> > ReadEntryAsync(PakEntry entry, CancellationToken cancellationToken = default) { var taskData = entry.ReadAsync(SourceStream, cancellationToken); var buf = taskData.IsCompletedSuccessfully ? taskData.Result : await taskData.ConfigureAwait(false); if (entry.IsEncrypted) { if (_aesProvider is null) { throw new PakEncryptedException("Pak file contains encrypted entries. AES encryption key is necessary for reading this asset."); } _aesProvider.Decrypt(buf.Memory); } if (entry.IsCompressed) { var decompressTask = UnrealCompression.DecompressAsync(buf.Memory, entry, cancellationToken); var result = decompressTask.IsCompletedSuccessfully ? decompressTask.Result : await decompressTask.ConfigureAwait(false); buf.Dispose(); return(result); } else { return(buf); } }
public static IMemoryOwner <byte> Decompress(Memory <byte> compressed, PakEntry entry) { var decompressed = PakMemoryPool.Shared.Rent((int)entry.TotalUncompressedSize); if (MemoryMarshal.TryGetArray <byte>(compressed, out var src) && MemoryMarshal.TryGetArray <byte>(decompressed.Memory, out var dst)) { Decompress(src.Array !, src.Offset, src.Count, dst.Array !, dst.Offset, dst.Count, entry); } else { decompressed.Dispose(); throw new NotImplementedException(); //Decompress(data.Memory.ToArray(), 0, data.Memory.Length, buffer, compressionBlocks); } return(decompressed); }
public IMemoryOwner <byte> ReadEntry(PakEntry entry) { var buf = entry.Read(SourceStream); if (entry.IsEncrypted) { if (_aesProvider is null) { throw new PakEncryptedException("Pak file contains encrypted entries. AES encryption key is necessary for reading this asset."); } _aesProvider.Decrypt(buf.Memory); } if (entry.IsCompressed) { var decompressed = UnrealCompression.Decompress(buf.Memory, entry); buf.Dispose(); return(decompressed); } else { return(buf); } }
public static async ValueTask DecompressAsync(byte[] source, int srcOffset, int srcCount, byte[] destination, int dstOffset, int dstCount, PakEntry entry, CancellationToken cancellationToken = default) { using var mem = new MemoryStream(source, srcOffset, srcCount); var progress = 0; foreach (var block in entry.TotalBlocks) { mem.Seek(block.Start, SeekOrigin.Begin); using Stream stream = entry.CompressionMethod switch { 1 => new ZlibStream(mem, CompressionMode.Decompress, true), 2 => new GZipStream(mem, CompressionMode.Decompress, true), _ => throw new NotImplementedException($"CompressionMethod '{entry.CompressionMethod}' not implemented") }; var read = 0; do { read = await stream.ReadAsync(destination, dstOffset + progress, dstCount - progress, cancellationToken).ConfigureAwait(false); progress += read; } while (read > 0); } } }
public static async ValueTask <IMemoryOwner <byte> > DecompressAsync(Memory <byte> compressed, PakEntry entry, CancellationToken cancellationToken = default) { var decompressed = PakMemoryPool.Shared.Rent((int)entry.TotalUncompressedSize); if (MemoryMarshal.TryGetArray <byte>(compressed, out var src) && MemoryMarshal.TryGetArray <byte>(decompressed.Memory, out var dst)) { var task = DecompressAsync(src.Array !, src.Offset, src.Count, dst.Array !, dst.Offset, dst.Count, entry, cancellationToken); if (!task.IsCompletedSuccessfully) { await task.ConfigureAwait(false); } } else { decompressed.Dispose(); throw new NotImplementedException(); } return(decompressed); }
public static void Decompress(byte[] source, int srcOffset, int srcCount, byte[] destination, int dstOffset, int dstCount, PakEntry entry) { using var mem = new MemoryStream(source, srcOffset, srcCount); var progress = 0; foreach (var block in entry.TotalBlocks) { mem.Seek(block.Start, SeekOrigin.Begin); using Stream stream = entry.CompressionMethod switch { 1 => new ZlibStream(mem, CompressionMode.Decompress, true), 2 => new GZipStream(mem, CompressionMode.Decompress, true), _ => throw new NotImplementedException($"CompressionMethod '{entry.CompressionMethod}' not implemented") }; var read = 0; do { read = stream.Read(destination, dstOffset + progress, dstCount - progress); progress += read; } while (read > 0); } }