DirectoryEntryHeader.cs 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. using System.IO;
  2. using System.Linq;
  3. using System.Text;
  4. namespace SharpCompress.Common.Zip.Headers
  5. {
  6. internal class DirectoryEntryHeader : ZipFileEntry
  7. {
  8. public DirectoryEntryHeader(ArchiveEncoding archiveEncoding)
  9. : base(ZipHeaderType.DirectoryEntry, archiveEncoding)
  10. {
  11. }
  12. internal override void Read(BinaryReader reader)
  13. {
  14. Version = reader.ReadUInt16();
  15. VersionNeededToExtract = reader.ReadUInt16();
  16. Flags = (HeaderFlags)reader.ReadUInt16();
  17. CompressionMethod = (ZipCompressionMethod)reader.ReadUInt16();
  18. LastModifiedTime = reader.ReadUInt16();
  19. LastModifiedDate = reader.ReadUInt16();
  20. Crc = reader.ReadUInt32();
  21. CompressedSize = reader.ReadUInt32();
  22. UncompressedSize = reader.ReadUInt32();
  23. ushort nameLength = reader.ReadUInt16();
  24. ushort extraLength = reader.ReadUInt16();
  25. ushort commentLength = reader.ReadUInt16();
  26. DiskNumberStart = reader.ReadUInt16();
  27. InternalFileAttributes = reader.ReadUInt16();
  28. ExternalFileAttributes = reader.ReadUInt32();
  29. RelativeOffsetOfEntryHeader = reader.ReadUInt32();
  30. byte[] name = reader.ReadBytes(nameLength);
  31. byte[] extra = reader.ReadBytes(extraLength);
  32. byte[] comment = reader.ReadBytes(commentLength);
  33. // According to .ZIP File Format Specification
  34. //
  35. // For example: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
  36. //
  37. // Bit 11: Language encoding flag (EFS). If this bit is set,
  38. // the filename and comment fields for this file
  39. // MUST be encoded using UTF-8. (see APPENDIX D)
  40. if (Flags.HasFlag(HeaderFlags.Efs))
  41. {
  42. Name = ArchiveEncoding.DecodeUTF8(name);
  43. Comment = ArchiveEncoding.DecodeUTF8(comment);
  44. }
  45. else
  46. {
  47. Name = ArchiveEncoding.Decode(name);
  48. Comment = ArchiveEncoding.Decode(comment);
  49. }
  50. LoadExtra(extra);
  51. var unicodePathExtra = Extra.FirstOrDefault(u => u.Type == ExtraDataType.UnicodePathExtraField);
  52. if (unicodePathExtra != null)
  53. {
  54. Name = ((ExtraUnicodePathExtraField)unicodePathExtra).UnicodeName;
  55. }
  56. var zip64ExtraData = Extra.OfType<Zip64ExtendedInformationExtraField>().FirstOrDefault();
  57. if (zip64ExtraData != null)
  58. {
  59. if (CompressedSize == uint.MaxValue)
  60. {
  61. CompressedSize = zip64ExtraData.CompressedSize;
  62. }
  63. if (UncompressedSize == uint.MaxValue)
  64. {
  65. UncompressedSize = zip64ExtraData.UncompressedSize;
  66. }
  67. if (RelativeOffsetOfEntryHeader == uint.MaxValue)
  68. {
  69. RelativeOffsetOfEntryHeader = zip64ExtraData.RelativeOffsetOfEntryHeader;
  70. }
  71. }
  72. }
  73. internal ushort Version { get; private set; }
  74. public ushort VersionNeededToExtract { get; set; }
  75. public long RelativeOffsetOfEntryHeader { get; set; }
  76. public uint ExternalFileAttributes { get; set; }
  77. public ushort InternalFileAttributes { get; set; }
  78. public ushort DiskNumberStart { get; set; }
  79. public string Comment { get; private set; }
  80. }
  81. }