SevenZipFilePart.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using SharpCompress.IO;
  5. namespace SharpCompress.Common.SevenZip
  6. {
  7. internal class SevenZipFilePart : FilePart
  8. {
  9. private CompressionType? _type;
  10. private readonly Stream _stream;
  11. private readonly ArchiveDatabase _database;
  12. internal SevenZipFilePart(Stream stream, ArchiveDatabase database, int index, CFileItem fileEntry, ArchiveEncoding archiveEncoding)
  13. : base(archiveEncoding)
  14. {
  15. _stream = stream;
  16. _database = database;
  17. Index = index;
  18. Header = fileEntry;
  19. if (Header.HasStream)
  20. {
  21. Folder = database._folders[database._fileIndexToFolderIndexMap[index]];
  22. }
  23. }
  24. internal CFileItem Header { get; }
  25. internal CFolder Folder { get; }
  26. internal int Index { get; }
  27. internal override string FilePartName => Header.Name;
  28. internal override Stream GetRawStream()
  29. {
  30. return null;
  31. }
  32. internal override Stream GetCompressedStream()
  33. {
  34. if (!Header.HasStream)
  35. {
  36. return null;
  37. }
  38. var folderStream = _database.GetFolderStream(_stream, Folder, _database.PasswordProvider);
  39. int firstFileIndex = _database._folderStartFileIndex[_database._folders.IndexOf(Folder)];
  40. int skipCount = Index - firstFileIndex;
  41. long skipSize = 0;
  42. for (int i = 0; i < skipCount; i++)
  43. {
  44. skipSize += _database._files[firstFileIndex + i].Size;
  45. }
  46. if (skipSize > 0)
  47. {
  48. folderStream.Skip(skipSize);
  49. }
  50. return new ReadOnlySubStream(folderStream, Header.Size);
  51. }
  52. public CompressionType CompressionType
  53. {
  54. get
  55. {
  56. if (_type == null)
  57. {
  58. _type = GetCompression();
  59. }
  60. return _type.Value;
  61. }
  62. }
  63. //copied from DecoderRegistry
  64. private const uint K_COPY = 0x0;
  65. private const uint K_DELTA = 3;
  66. private const uint K_LZMA2 = 0x21;
  67. private const uint K_LZMA = 0x030101;
  68. private const uint K_PPMD = 0x030401;
  69. private const uint K_BCJ = 0x03030103;
  70. private const uint K_BCJ2 = 0x0303011B;
  71. private const uint K_DEFLATE = 0x040108;
  72. private const uint K_B_ZIP2 = 0x040202;
  73. internal CompressionType GetCompression()
  74. {
  75. var coder = Folder._coders.First();
  76. switch (coder._methodId._id)
  77. {
  78. case K_LZMA:
  79. case K_LZMA2:
  80. {
  81. return CompressionType.LZMA;
  82. }
  83. case K_PPMD:
  84. {
  85. return CompressionType.PPMd;
  86. }
  87. case K_B_ZIP2:
  88. {
  89. return CompressionType.BZip2;
  90. }
  91. default:
  92. throw new NotImplementedException();
  93. }
  94. }
  95. }
  96. }