BizHawk/BizHawk.Client.Common/SharpCompress/Common/Rar/Headers/MarkHeader.cs

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");
}
}
}