Lz4ArchiveReader.cs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. namespace SongCore.Arcache
  7. {
  8. public class Lz4ArchiveReader : Lz4ArchiveBase
  9. {
  10. public Dictionary<string, Lz4ArchiveEntry> Entries { get; }
  11. private readonly byte[] _blob;
  12. public Lz4ArchiveReader(string pathAndBaseName, bool readBlobToMemory) : base(pathAndBaseName)
  13. {
  14. //read entries
  15. var entries = new List<Lz4ArchiveEntry>();
  16. var bufLz4 = File.ReadAllBytes(IndexFilePath);
  17. var bufRaw = DecompressPickle(bufLz4);
  18. using (var fs = new MemoryStream(bufRaw))
  19. {
  20. while (fs.Position < fs.Length)
  21. {
  22. var entry = new Lz4ArchiveEntry();
  23. entry.ReadFromStream(fs);
  24. entries.Add(entry);
  25. }
  26. }
  27. Entries = entries.ToDictionary(p => p.FileName);
  28. //open file / or read all into memory
  29. if (readBlobToMemory)
  30. {
  31. _blob = File.ReadAllBytes(BlobFilePath);
  32. }
  33. }
  34. private byte[] FetchData(long offset, long size)
  35. {
  36. byte[] buf;
  37. if (_blob != null)
  38. {
  39. buf = new byte[size];
  40. Buffer.BlockCopy(_blob, (int)offset, buf, 0, (int)size);
  41. }
  42. else
  43. {
  44. using var fs = File.OpenRead(BlobFilePath);
  45. fs.Position = offset;
  46. using var br = new BinaryReader(fs);
  47. buf = br.ReadBytes((int)size);
  48. }
  49. return buf;
  50. }
  51. public byte[] ReadData(Lz4ArchiveEntry entry)
  52. {
  53. var compressed = FetchData(entry.Offset, entry.CompressedSize);
  54. var data = Decompress(compressed, (int)entry.OriginalSize);
  55. return data;
  56. }
  57. public string ReadText(Lz4ArchiveEntry entry, Encoding encoding)
  58. {
  59. var data = ReadData(entry);
  60. return encoding.GetString(data);
  61. }
  62. }
  63. }