StreamingZipHeaderFactory.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. using System.Collections.Generic;
  2. using System.IO;
  3. using SharpCompress.Common.Zip.Headers;
  4. using SharpCompress.IO;
  5. using System.Text;
  6. namespace SharpCompress.Common.Zip
  7. {
  8. internal class StreamingZipHeaderFactory : ZipHeaderFactory
  9. {
  10. internal StreamingZipHeaderFactory(string password, ArchiveEncoding archiveEncoding)
  11. : base(StreamingMode.Streaming, password, archiveEncoding)
  12. {
  13. }
  14. internal IEnumerable<ZipHeader> ReadStreamHeader(Stream stream)
  15. {
  16. RewindableStream rewindableStream;
  17. if (stream is RewindableStream)
  18. {
  19. rewindableStream = stream as RewindableStream;
  20. }
  21. else
  22. {
  23. rewindableStream = new RewindableStream(stream);
  24. }
  25. while (true)
  26. {
  27. ZipHeader header = null;
  28. BinaryReader reader = new BinaryReader(rewindableStream);
  29. if (_lastEntryHeader != null &&
  30. (FlagUtility.HasFlag(_lastEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor) || _lastEntryHeader.IsZip64))
  31. {
  32. reader = (_lastEntryHeader.Part as StreamingZipFilePart).FixStreamedFileLocation(ref rewindableStream);
  33. long? pos = rewindableStream.CanSeek ? (long?)rewindableStream.Position : null;
  34. uint crc = reader.ReadUInt32();
  35. if (crc == POST_DATA_DESCRIPTOR)
  36. {
  37. crc = reader.ReadUInt32();
  38. }
  39. _lastEntryHeader.Crc = crc;
  40. _lastEntryHeader.CompressedSize = reader.ReadUInt32();
  41. _lastEntryHeader.UncompressedSize = reader.ReadUInt32();
  42. if (pos.HasValue)
  43. {
  44. _lastEntryHeader.DataStartPosition = pos - _lastEntryHeader.CompressedSize;
  45. }
  46. }
  47. _lastEntryHeader = null;
  48. uint headerBytes = reader.ReadUInt32();
  49. header = ReadHeader(headerBytes, reader);
  50. //entry could be zero bytes so we need to know that.
  51. if (header.ZipHeaderType == ZipHeaderType.LocalEntry)
  52. {
  53. bool isRecording = rewindableStream.IsRecording;
  54. if (!isRecording)
  55. {
  56. rewindableStream.StartRecording();
  57. }
  58. uint nextHeaderBytes = reader.ReadUInt32();
  59. header.HasData = !IsHeader(nextHeaderBytes);
  60. rewindableStream.Rewind(!isRecording);
  61. }
  62. yield return header;
  63. }
  64. }
  65. }
  66. }