RarReader.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. using System.Collections.Generic;
  2. using System.IO;
  3. using System.Linq;
  4. using SharpCompress.Common;
  5. using SharpCompress.Common.Rar;
  6. using SharpCompress.Compressors.Rar;
  7. namespace SharpCompress.Readers.Rar
  8. {
  9. /// <summary>
  10. /// This class faciliates Reading a Rar Archive in a non-seekable forward-only manner
  11. /// </summary>
  12. public abstract class RarReader : AbstractReader<RarReaderEntry, RarVolume>
  13. {
  14. private RarVolume volume;
  15. internal Lazy<IRarUnpack> UnpackV2017 { get; } = new Lazy<IRarUnpack>(() => new SharpCompress.Compressors.Rar.UnpackV2017.Unpack());
  16. internal Lazy<IRarUnpack> UnpackV1 { get; } = new Lazy<IRarUnpack>(() => new SharpCompress.Compressors.Rar.UnpackV1.Unpack());
  17. internal RarReader(ReaderOptions options)
  18. : base(options, ArchiveType.Rar)
  19. {
  20. }
  21. internal abstract void ValidateArchive(RarVolume archive);
  22. public override RarVolume Volume => volume;
  23. /// <summary>
  24. /// Opens a RarReader for Non-seeking usage with a single volume
  25. /// </summary>
  26. /// <param name="stream"></param>
  27. /// <param name="options"></param>
  28. /// <returns></returns>
  29. public static RarReader Open(Stream stream, ReaderOptions options = null)
  30. {
  31. stream.CheckNotNull("stream");
  32. return new SingleVolumeRarReader(stream, options ?? new ReaderOptions());
  33. }
  34. /// <summary>
  35. /// Opens a RarReader for Non-seeking usage with multiple volumes
  36. /// </summary>
  37. /// <param name="streams"></param>
  38. /// <param name="options"></param>
  39. /// <returns></returns>
  40. public static RarReader Open(IEnumerable<Stream> streams, ReaderOptions options = null)
  41. {
  42. streams.CheckNotNull("streams");
  43. return new MultiVolumeRarReader(streams, options ?? new ReaderOptions());
  44. }
  45. protected override IEnumerable<RarReaderEntry> GetEntries(Stream stream)
  46. {
  47. volume = new RarReaderVolume(stream, Options);
  48. foreach (RarFilePart fp in volume.ReadFileParts())
  49. {
  50. ValidateArchive(volume);
  51. yield return new RarReaderEntry(volume.IsSolidArchive, fp);
  52. }
  53. }
  54. protected virtual IEnumerable<FilePart> CreateFilePartEnumerableForCurrentEntry()
  55. {
  56. return Entry.Parts;
  57. }
  58. protected override EntryStream GetEntryStream()
  59. {
  60. var stream = new MultiVolumeReadOnlyStream(CreateFilePartEnumerableForCurrentEntry().Cast<RarFilePart>(), this);
  61. if (Entry.IsRarV3)
  62. {
  63. return CreateEntryStream(new RarCrcStream(UnpackV1.Value, Entry.FileHeader, stream));
  64. }
  65. return CreateEntryStream(new RarCrcStream(UnpackV2017.Value, Entry.FileHeader, stream));
  66. }
  67. }
  68. }