using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; namespace SongCore.Arcache { public class Lz4ArchiveReader : Lz4ArchiveBase { public Dictionary Entries { get; } private readonly byte[] _blob; public Lz4ArchiveReader(string pathAndBaseName, bool readBlobToMemory) : base(pathAndBaseName) { //read entries var entries = new List(); var bufLz4 = File.ReadAllBytes(IndexFilePath); var bufRaw = DecompressPickle(bufLz4); using (var fs = new MemoryStream(bufRaw)) { while (fs.Position < fs.Length) { var entry = new Lz4ArchiveEntry(); entry.ReadFromStream(fs); entries.Add(entry); } } Entries = entries.ToDictionary(p => p.FileName); //open file / or read all into memory if (readBlobToMemory) { _blob = File.ReadAllBytes(BlobFilePath); } } private byte[] FetchData(long offset, long size) { byte[] buf; if (_blob != null) { buf = new byte[size]; Buffer.BlockCopy(_blob, (int)offset, buf, 0, (int)size); } else { using var fs = File.OpenRead(BlobFilePath); fs.Position = offset; using var br = new BinaryReader(fs); buf = br.ReadBytes((int)size); } return buf; } public byte[] ReadData(Lz4ArchiveEntry entry) { var compressed = FetchData(entry.Offset, entry.CompressedSize); var data = Decompress(compressed, (int)entry.OriginalSize); return data; } public string ReadText(Lz4ArchiveEntry entry, Encoding encoding) { var data = ReadData(entry); return encoding.GetString(data); } } }