81 lines
2.8 KiB
C#
81 lines
2.8 KiB
C#
using SharpCompress.IO;
|
|
|
|
namespace SharpCompress.Common.Rar.Headers
|
|
{
|
|
internal class ArchiveHeader : RarHeader
|
|
{
|
|
public ArchiveHeader(RarHeader header, RarCrcBinaryReader reader)
|
|
: base(header, reader, HeaderType.Archive)
|
|
{
|
|
}
|
|
|
|
protected override void ReadFinish(MarkingBinaryReader reader)
|
|
{
|
|
if (IsRar5)
|
|
{
|
|
Flags = reader.ReadRarVIntUInt16();
|
|
if (HasFlag(ArchiveFlagsV5.HAS_VOLUME_NUMBER))
|
|
{
|
|
VolumeNumber = (int)reader.ReadRarVIntUInt32();
|
|
}
|
|
// later: we may have a locator record if we need it
|
|
//if (ExtraSize != 0) {
|
|
// ReadLocator(reader);
|
|
//}
|
|
}
|
|
else
|
|
{
|
|
Flags = HeaderFlags;
|
|
HighPosAv = reader.ReadInt16();
|
|
PosAv = reader.ReadInt32();
|
|
if (HasFlag(ArchiveFlagsV4.ENCRYPT_VER))
|
|
{
|
|
EncryptionVersion = reader.ReadByte();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ReadLocator(MarkingBinaryReader reader) {
|
|
var size = reader.ReadRarVIntUInt16();
|
|
var type = reader.ReadRarVIntUInt16();
|
|
if (type != 1) throw new InvalidFormatException("expected locator record");
|
|
var flags = reader.ReadRarVIntUInt16();
|
|
const ushort hasQuickOpenOffset = 0x01;
|
|
const ushort hasRecoveryOffset = 0x02;
|
|
ulong quickOpenOffset = 0;
|
|
if ((flags & hasQuickOpenOffset) == hasQuickOpenOffset) {
|
|
quickOpenOffset = reader.ReadRarVInt();
|
|
}
|
|
ulong recoveryOffset = 0;
|
|
if ((flags & hasRecoveryOffset) == hasRecoveryOffset) {
|
|
recoveryOffset = reader.ReadRarVInt();
|
|
}
|
|
}
|
|
|
|
private ushort Flags { get; set; }
|
|
|
|
private bool HasFlag(ushort flag)
|
|
{
|
|
return (Flags & flag) == flag;
|
|
}
|
|
|
|
internal int? VolumeNumber { get; private set; }
|
|
|
|
internal short? HighPosAv { get; private set; }
|
|
|
|
internal int? PosAv { get; private set; }
|
|
|
|
private byte? EncryptionVersion { get; set; }
|
|
|
|
public bool? IsEncrypted => IsRar5 ? (bool?)null : HasFlag(ArchiveFlagsV4.PASSWORD);
|
|
|
|
public bool OldNumberingFormat => !IsRar5 && !HasFlag(ArchiveFlagsV4.NEW_NUMBERING);
|
|
|
|
public bool IsVolume => HasFlag(IsRar5 ? ArchiveFlagsV5.VOLUME : ArchiveFlagsV4.VOLUME);
|
|
|
|
// RAR5: Volume number field is present. True for all volumes except first.
|
|
public bool IsFirstVolume => IsRar5 ? VolumeNumber == null : HasFlag(ArchiveFlagsV4.FIRST_VOLUME);
|
|
|
|
public bool IsSolid => HasFlag(IsRar5 ? ArchiveFlagsV5.SOLID : ArchiveFlagsV4.SOLID);
|
|
}
|
|
} |