RarArchiveEntry.cs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using SharpCompress.Common;
  6. using SharpCompress.Common.Rar;
  7. using SharpCompress.Common.Rar.Headers;
  8. using SharpCompress.Compressors.Rar;
  9. namespace SharpCompress.Archives.Rar
  10. {
  11. public class RarArchiveEntry : RarEntry, IArchiveEntry
  12. {
  13. private readonly ICollection<RarFilePart> parts;
  14. private readonly RarArchive archive;
  15. internal RarArchiveEntry(RarArchive archive, IEnumerable<RarFilePart> parts)
  16. {
  17. this.parts = parts.ToList();
  18. this.archive = archive;
  19. }
  20. public override CompressionType CompressionType => CompressionType.Rar;
  21. public IArchive Archive => archive;
  22. internal override IEnumerable<FilePart> Parts => parts.Cast<FilePart>();
  23. internal override FileHeader FileHeader => parts.First().FileHeader;
  24. public override long Crc
  25. {
  26. get
  27. {
  28. CheckIncomplete();
  29. return parts.Select(fp => fp.FileHeader).Single(fh => !fh.IsSplitAfter).FileCrc;
  30. }
  31. }
  32. public override long Size
  33. {
  34. get
  35. {
  36. CheckIncomplete();
  37. return parts.First().FileHeader.UncompressedSize;
  38. }
  39. }
  40. public override long CompressedSize
  41. {
  42. get
  43. {
  44. CheckIncomplete();
  45. return parts.Aggregate(0L, (total, fp) => total + fp.FileHeader.CompressedSize);
  46. }
  47. }
  48. public Stream OpenEntryStream()
  49. {
  50. if (archive.IsSolid)
  51. {
  52. throw new InvalidOperationException("Use ExtractAllEntries to extract SOLID archives.");
  53. }
  54. if (IsRarV3)
  55. {
  56. return new RarStream(archive.UnpackV1.Value, FileHeader, new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>(), archive));
  57. }
  58. return new RarStream(archive.UnpackV2017.Value, FileHeader, new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>(), archive));
  59. }
  60. public bool IsComplete
  61. {
  62. get
  63. {
  64. return parts.Select(fp => fp.FileHeader).Any(fh => !fh.IsSplitAfter);
  65. }
  66. }
  67. private void CheckIncomplete()
  68. {
  69. if (!IsComplete)
  70. {
  71. throw new IncompleteArchiveException("ArchiveEntry is incomplete and cannot perform this operation.");
  72. }
  73. }
  74. }
  75. }