mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-23 23:45:14 +00:00
factory the headers instead of creating
This commit is contained in:
@@ -4,13 +4,14 @@ namespace SharpCompress.Common.Rar.Headers;
|
||||
|
||||
internal class AvHeader : RarHeader
|
||||
{
|
||||
public AvHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Av)
|
||||
public static AvHeader Create(RarHeader header, RarCrcBinaryReader reader)
|
||||
{
|
||||
if (IsRar5)
|
||||
var c = CreateChild<AvHeader>(header, reader, HeaderType.Av);
|
||||
if (c.IsRar5)
|
||||
{
|
||||
throw new InvalidFormatException("unexpected rar5 record");
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
protected override void ReadFinish(MarkingBinaryReader reader)
|
||||
|
||||
@@ -6,8 +6,8 @@ namespace SharpCompress.Common.Rar.Headers;
|
||||
|
||||
internal class ArchiveCryptHeader : RarHeader
|
||||
{
|
||||
public ArchiveCryptHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Crypt) { }
|
||||
public static ArchiveCryptHeader Create(RarHeader header, RarCrcBinaryReader reader) =>
|
||||
CreateChild<ArchiveCryptHeader>(header, reader, HeaderType.Crypt);
|
||||
|
||||
public Rar5CryptoInfo CryptInfo = new();
|
||||
|
||||
|
||||
@@ -4,9 +4,8 @@ namespace SharpCompress.Common.Rar.Headers;
|
||||
|
||||
internal sealed class ArchiveHeader : RarHeader
|
||||
{
|
||||
public ArchiveHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Archive) { }
|
||||
|
||||
public static ArchiveHeader Create(RarHeader header, RarCrcBinaryReader reader) =>
|
||||
CreateChild<ArchiveHeader>(header, reader, HeaderType.Archive);
|
||||
protected override void ReadFinish(MarkingBinaryReader reader)
|
||||
{
|
||||
if (IsRar5)
|
||||
|
||||
@@ -4,13 +4,14 @@ namespace SharpCompress.Common.Rar.Headers;
|
||||
|
||||
internal class CommentHeader : RarHeader
|
||||
{
|
||||
protected CommentHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Comment)
|
||||
public static CommentHeader Create(RarHeader header, RarCrcBinaryReader reader)
|
||||
{
|
||||
if (IsRar5)
|
||||
var c = CreateChild<CommentHeader>(header, reader, HeaderType.Comment);
|
||||
if (c.IsRar5)
|
||||
{
|
||||
throw new InvalidFormatException("unexpected rar5 record");
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
protected override void ReadFinish(MarkingBinaryReader reader)
|
||||
|
||||
@@ -4,8 +4,8 @@ namespace SharpCompress.Common.Rar.Headers;
|
||||
|
||||
internal class EndArchiveHeader : RarHeader
|
||||
{
|
||||
public EndArchiveHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.EndArchive) { }
|
||||
public static EndArchiveHeader Create(RarHeader header, RarCrcBinaryReader reader) =>
|
||||
CreateChild<EndArchiveHeader>(header, reader, HeaderType.EndArchive);
|
||||
|
||||
protected override void ReadFinish(MarkingBinaryReader reader)
|
||||
{
|
||||
|
||||
@@ -17,8 +17,8 @@ internal class FileHeader : RarHeader
|
||||
{
|
||||
private byte[]? _hash;
|
||||
|
||||
public FileHeader(RarHeader header, RarCrcBinaryReader reader, HeaderType headerType)
|
||||
: base(header, reader, headerType) { }
|
||||
public static FileHeader Create(RarHeader header, RarCrcBinaryReader reader, HeaderType headerType) =>
|
||||
CreateChild<FileHeader>(header, reader, headerType);
|
||||
|
||||
protected override void ReadFinish(MarkingBinaryReader reader)
|
||||
{
|
||||
|
||||
@@ -5,13 +5,14 @@ namespace SharpCompress.Common.Rar.Headers;
|
||||
// ProtectHeader is part of the Recovery Record feature
|
||||
internal sealed class ProtectHeader : RarHeader
|
||||
{
|
||||
public ProtectHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Protect)
|
||||
public static ProtectHeader Create(RarHeader header, RarCrcBinaryReader reader)
|
||||
{
|
||||
if (IsRar5)
|
||||
var c = CreateChild<ProtectHeader>(header, reader, HeaderType.Protect);
|
||||
if (c.IsRar5)
|
||||
{
|
||||
throw new InvalidFormatException("unexpected rar5 record");
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
protected override void ReadFinish(MarkingBinaryReader reader)
|
||||
|
||||
@@ -7,8 +7,13 @@ namespace SharpCompress.Common.Rar.Headers;
|
||||
// https://www.rarlab.com/technote.htm
|
||||
internal class RarHeader : IRarHeader
|
||||
{
|
||||
private readonly HeaderType _headerType;
|
||||
private readonly bool _isRar5;
|
||||
private HeaderType _headerType;
|
||||
private bool _isRar5;
|
||||
|
||||
protected RarHeader()
|
||||
{
|
||||
ArchiveEncoding = new ArchiveEncoding();
|
||||
}
|
||||
|
||||
internal static RarHeader? TryReadBase(
|
||||
RarCrcBinaryReader reader,
|
||||
@@ -18,7 +23,9 @@ internal class RarHeader : IRarHeader
|
||||
{
|
||||
try
|
||||
{
|
||||
return new RarHeader(reader, isRar5, archiveEncoding);
|
||||
var header = new RarHeader();
|
||||
header.Initialize(reader, isRar5, archiveEncoding);
|
||||
return header;
|
||||
}
|
||||
catch (InvalidFormatException)
|
||||
{
|
||||
@@ -26,7 +33,7 @@ internal class RarHeader : IRarHeader
|
||||
}
|
||||
}
|
||||
|
||||
private RarHeader(RarCrcBinaryReader reader, bool isRar5, IArchiveEncoding archiveEncoding)
|
||||
private void Initialize(RarCrcBinaryReader reader, bool isRar5, IArchiveEncoding archiveEncoding)
|
||||
{
|
||||
_headerType = HeaderType.Null;
|
||||
_isRar5 = isRar5;
|
||||
@@ -64,26 +71,31 @@ internal class RarHeader : IRarHeader
|
||||
}
|
||||
}
|
||||
|
||||
protected RarHeader(RarHeader header, RarCrcBinaryReader reader, HeaderType headerType)
|
||||
internal static T CreateChild<T>(RarHeader header, RarCrcBinaryReader reader, HeaderType headerType)
|
||||
where T : RarHeader, new()
|
||||
{
|
||||
_headerType = headerType;
|
||||
_isRar5 = header.IsRar5;
|
||||
HeaderCrc = header.HeaderCrc;
|
||||
HeaderCode = header.HeaderCode;
|
||||
HeaderFlags = header.HeaderFlags;
|
||||
HeaderSize = header.HeaderSize;
|
||||
ExtraSize = header.ExtraSize;
|
||||
AdditionalDataSize = header.AdditionalDataSize;
|
||||
ArchiveEncoding = header.ArchiveEncoding;
|
||||
ReadFinish(reader);
|
||||
var child = new T()
|
||||
{
|
||||
ArchiveEncoding = header.ArchiveEncoding
|
||||
};
|
||||
child. _headerType = headerType;
|
||||
child. _isRar5 = header.IsRar5;
|
||||
child. HeaderCrc = header.HeaderCrc;
|
||||
child. HeaderCode = header.HeaderCode;
|
||||
child. HeaderFlags = header.HeaderFlags;
|
||||
child.HeaderSize = header.HeaderSize;
|
||||
child.ExtraSize = header.ExtraSize;
|
||||
child. AdditionalDataSize = header.AdditionalDataSize;
|
||||
child.ReadFinish(reader);
|
||||
|
||||
var n = RemainingHeaderBytes(reader);
|
||||
var n = child.RemainingHeaderBytes(reader);
|
||||
if (n > 0)
|
||||
{
|
||||
reader.ReadBytes(n);
|
||||
}
|
||||
|
||||
VerifyHeaderCrc(reader.GetCrc32());
|
||||
child. VerifyHeaderCrc(reader.GetCrc32());
|
||||
return child;
|
||||
}
|
||||
|
||||
protected int RemainingHeaderBytes(MarkingBinaryReader reader) =>
|
||||
@@ -103,27 +115,27 @@ internal class RarHeader : IRarHeader
|
||||
|
||||
public HeaderType HeaderType => _headerType;
|
||||
|
||||
protected bool IsRar5 => _isRar5;
|
||||
internal bool IsRar5 => _isRar5;
|
||||
|
||||
protected uint HeaderCrc { get; }
|
||||
protected uint HeaderCrc { get;private set; }
|
||||
|
||||
internal byte HeaderCode { get; }
|
||||
internal byte HeaderCode { get;private set; }
|
||||
|
||||
protected ushort HeaderFlags { get; }
|
||||
protected ushort HeaderFlags { get;private set; }
|
||||
|
||||
protected bool HasHeaderFlag(ushort flag) => (HeaderFlags & flag) == flag;
|
||||
|
||||
protected int HeaderSize { get; }
|
||||
protected int HeaderSize { get;private set; }
|
||||
|
||||
internal IArchiveEncoding ArchiveEncoding { get; }
|
||||
internal IArchiveEncoding ArchiveEncoding { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Extra header size.
|
||||
/// </summary>
|
||||
protected uint ExtraSize { get; }
|
||||
protected uint ExtraSize { get;private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Size of additional data (eg file contents)
|
||||
/// </summary>
|
||||
protected long AdditionalDataSize { get; }
|
||||
protected long AdditionalDataSize { get;private set; }
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ public class RarHeaderFactory
|
||||
case HeaderCodeV.RAR5_ARCHIVE_HEADER:
|
||||
case HeaderCodeV.RAR4_ARCHIVE_HEADER:
|
||||
{
|
||||
var ah = new ArchiveHeader(header, reader);
|
||||
var ah = ArchiveHeader.Create(header, reader);
|
||||
if (ah.IsEncrypted == true)
|
||||
{
|
||||
//!!! rar5 we don't know yet
|
||||
@@ -91,7 +91,7 @@ public class RarHeaderFactory
|
||||
|
||||
case HeaderCodeV.RAR4_PROTECT_HEADER:
|
||||
{
|
||||
var ph = new ProtectHeader(header, reader);
|
||||
var ph = ProtectHeader.Create(header, reader);
|
||||
// skip the recovery record data, we do not use it.
|
||||
switch (StreamingMode)
|
||||
{
|
||||
@@ -116,7 +116,7 @@ public class RarHeaderFactory
|
||||
|
||||
case HeaderCodeV.RAR5_SERVICE_HEADER:
|
||||
{
|
||||
var fh = new FileHeader(header, reader, HeaderType.Service);
|
||||
var fh = FileHeader.Create(header, reader, HeaderType.Service);
|
||||
if (fh.FileName == "CMT")
|
||||
{
|
||||
fh.PackedStream = new ReadOnlySubStream(reader.BaseStream, fh.CompressedSize);
|
||||
@@ -130,7 +130,7 @@ public class RarHeaderFactory
|
||||
|
||||
case HeaderCodeV.RAR4_NEW_SUB_HEADER:
|
||||
{
|
||||
var fh = new FileHeader(header, reader, HeaderType.NewSub);
|
||||
var fh = FileHeader.Create(header, reader, HeaderType.NewSub);
|
||||
SkipData(fh, reader);
|
||||
return fh;
|
||||
}
|
||||
@@ -138,7 +138,7 @@ public class RarHeaderFactory
|
||||
case HeaderCodeV.RAR5_FILE_HEADER:
|
||||
case HeaderCodeV.RAR4_FILE_HEADER:
|
||||
{
|
||||
var fh = new FileHeader(header, reader, HeaderType.File);
|
||||
var fh = FileHeader.Create(header, reader, HeaderType.File);
|
||||
switch (StreamingMode)
|
||||
{
|
||||
case StreamingMode.Seekable:
|
||||
@@ -181,11 +181,11 @@ public class RarHeaderFactory
|
||||
case HeaderCodeV.RAR5_END_ARCHIVE_HEADER:
|
||||
case HeaderCodeV.RAR4_END_ARCHIVE_HEADER:
|
||||
{
|
||||
return new EndArchiveHeader(header, reader);
|
||||
return EndArchiveHeader.Create(header, reader);
|
||||
}
|
||||
case HeaderCodeV.RAR5_ARCHIVE_ENCRYPTION_HEADER:
|
||||
{
|
||||
var cryptoHeader = new ArchiveCryptHeader(header, reader);
|
||||
var cryptoHeader = ArchiveCryptHeader.Create(header, reader);
|
||||
IsEncrypted = true;
|
||||
_cryptInfo = cryptoHeader.CryptInfo;
|
||||
|
||||
|
||||
@@ -4,13 +4,14 @@ namespace SharpCompress.Common.Rar.Headers;
|
||||
|
||||
internal class SignHeader : RarHeader
|
||||
{
|
||||
protected SignHeader(RarHeader header, RarCrcBinaryReader reader)
|
||||
: base(header, reader, HeaderType.Sign)
|
||||
public static SignHeader Create(RarHeader header, RarCrcBinaryReader reader)
|
||||
{
|
||||
if (IsRar5)
|
||||
{
|
||||
throw new InvalidFormatException("unexpected rar5 record");
|
||||
}
|
||||
var c = CreateChild<SignHeader>(header, reader, HeaderType.Sign);
|
||||
if (c.IsRar5)
|
||||
{
|
||||
throw new InvalidFormatException("unexpected rar5 record");
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
protected override void ReadFinish(MarkingBinaryReader reader)
|
||||
|
||||
Reference in New Issue
Block a user