MultiVolumeRarReader.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using SharpCompress.Common;
  6. using SharpCompress.Common.Rar;
  7. namespace SharpCompress.Readers.Rar
  8. {
  9. internal class MultiVolumeRarReader : RarReader
  10. {
  11. private readonly IEnumerator<Stream> streams;
  12. private Stream tempStream;
  13. internal MultiVolumeRarReader(IEnumerable<Stream> streams, ReaderOptions options)
  14. : base(options)
  15. {
  16. this.streams = streams.GetEnumerator();
  17. }
  18. internal override void ValidateArchive(RarVolume archive)
  19. {
  20. }
  21. protected override Stream RequestInitialStream()
  22. {
  23. if (streams.MoveNext())
  24. {
  25. return streams.Current;
  26. }
  27. throw new MultiVolumeExtractionException("No stream provided when requested by MultiVolumeRarReader");
  28. }
  29. internal override bool NextEntryForCurrentStream()
  30. {
  31. if (!base.NextEntryForCurrentStream()) {
  32. // if we're got another stream to try to process then do so
  33. return streams.MoveNext() && LoadStreamForReading(streams.Current);
  34. }
  35. return true;
  36. }
  37. protected override IEnumerable<FilePart> CreateFilePartEnumerableForCurrentEntry()
  38. {
  39. var enumerator = new MultiVolumeStreamEnumerator(this, streams, tempStream);
  40. tempStream = null;
  41. return enumerator;
  42. }
  43. private class MultiVolumeStreamEnumerator : IEnumerable<FilePart>, IEnumerator<FilePart>
  44. {
  45. private readonly MultiVolumeRarReader reader;
  46. private readonly IEnumerator<Stream> nextReadableStreams;
  47. private Stream tempStream;
  48. private bool isFirst = true;
  49. internal MultiVolumeStreamEnumerator(MultiVolumeRarReader r, IEnumerator<Stream> nextReadableStreams,
  50. Stream tempStream)
  51. {
  52. reader = r;
  53. this.nextReadableStreams = nextReadableStreams;
  54. this.tempStream = tempStream;
  55. }
  56. public IEnumerator<FilePart> GetEnumerator()
  57. {
  58. return this;
  59. }
  60. IEnumerator IEnumerable.GetEnumerator()
  61. {
  62. return this;
  63. }
  64. public FilePart Current { get; private set; }
  65. public void Dispose()
  66. {
  67. }
  68. object IEnumerator.Current => Current;
  69. public bool MoveNext()
  70. {
  71. if (isFirst)
  72. {
  73. Current = reader.Entry.Parts.First();
  74. isFirst = false; //first stream already to go
  75. return true;
  76. }
  77. if (!reader.Entry.IsSplitAfter)
  78. {
  79. return false;
  80. }
  81. if (tempStream != null)
  82. {
  83. reader.LoadStreamForReading(tempStream);
  84. tempStream = null;
  85. }
  86. else if (!nextReadableStreams.MoveNext())
  87. {
  88. throw new MultiVolumeExtractionException("No stream provided when requested by MultiVolumeRarReader");
  89. }
  90. else
  91. {
  92. reader.LoadStreamForReading(nextReadableStreams.Current);
  93. }
  94. Current = reader.Entry.Parts.First();
  95. return true;
  96. }
  97. public void Reset()
  98. {
  99. }
  100. }
  101. }
  102. }