97 lines
3.3 KiB
C#
97 lines
3.3 KiB
C#
using System;
|
|
using System.IO;
|
|
|
|
namespace SharpCompress.Common.Rar.Headers
|
|
{
|
|
internal class MarkHeader : IRarHeader
|
|
{
|
|
private const int MAX_SFX_SIZE = 0x80000 - 16; //archive.cpp line 136
|
|
|
|
internal bool OldNumberingFormat { get; private set; }
|
|
|
|
public bool IsRar5 { get; }
|
|
|
|
private MarkHeader(bool isRar5)
|
|
{
|
|
IsRar5 = isRar5;
|
|
}
|
|
|
|
public HeaderType HeaderType => HeaderType.Mark;
|
|
|
|
private static byte GetByte(Stream stream)
|
|
{
|
|
var b = stream.ReadByte();
|
|
if (b != -1)
|
|
{
|
|
return (byte)b;
|
|
}
|
|
throw new EndOfStreamException();
|
|
}
|
|
|
|
public static MarkHeader Read(Stream stream, bool leaveStreamOpen, bool lookForHeader)
|
|
{
|
|
int maxScanIndex = lookForHeader ? MAX_SFX_SIZE : 0;
|
|
try
|
|
{
|
|
int start = -1;
|
|
var b = GetByte(stream); start++;
|
|
while (start <= maxScanIndex)
|
|
{
|
|
// Rar old signature: 52 45 7E 5E
|
|
// Rar4 signature: 52 61 72 21 1A 07 00
|
|
// Rar5 signature: 52 61 72 21 1A 07 01 00
|
|
if (b == 0x52)
|
|
{
|
|
b = GetByte(stream); start++;
|
|
if (b == 0x61)
|
|
{
|
|
b = GetByte(stream); start++;
|
|
if (b != 0x72) continue;
|
|
b = GetByte(stream); start++;
|
|
if (b != 0x21) continue;
|
|
b = GetByte(stream); start++;
|
|
if (b != 0x1a) continue;
|
|
b = GetByte(stream); start++;
|
|
if (b != 0x07) continue;
|
|
|
|
b = GetByte(stream); start++;
|
|
if (b == 1)
|
|
{
|
|
b = GetByte(stream); start++;
|
|
if (b != 0) continue;
|
|
return new MarkHeader(true); // Rar5
|
|
}
|
|
else if (b == 0)
|
|
{
|
|
return new MarkHeader(false); // Rar4
|
|
}
|
|
}
|
|
else if (b == 0x45)
|
|
{
|
|
b = GetByte(stream); start++;
|
|
if (b != 0x7e) continue;
|
|
b = GetByte(stream); start++;
|
|
if (b != 0x5e) continue;
|
|
throw new InvalidFormatException("Rar format version pre-4 is unsupported.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
b = GetByte(stream); start++;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (!leaveStreamOpen)
|
|
{
|
|
stream.Dispose();
|
|
}
|
|
throw new InvalidFormatException("Error trying to read rar signature.", e);
|
|
}
|
|
|
|
throw new InvalidFormatException("Rar signature not found");
|
|
}
|
|
}
|
|
}
|