Blind update of zip code to newest RVWorld version

This commit is contained in:
Matt Nadareski
2019-12-04 15:42:30 -08:00
parent 1f3420a08f
commit 9c393b12c6
97 changed files with 27794 additions and 13760 deletions

View File

@@ -0,0 +1,30 @@
using System.IO;
using System.Text;
namespace Compress.SevenZip.Structure
{
public class BindPair
{
public ulong InIndex;
public ulong OutIndex;
public void Read(BinaryReader br)
{
InIndex = br.ReadEncodedUInt64();
OutIndex = br.ReadEncodedUInt64();
}
public void Write(BinaryWriter bw)
{
bw.WriteEncodedUInt64(InIndex);
bw.WriteEncodedUInt64(OutIndex);
}
public void Report(ref StringBuilder sb)
{
sb.AppendLine(" InIndex = " + InIndex);
sb.AppendLine(" OutIndex = " + OutIndex);
}
}
}

View File

@@ -0,0 +1,159 @@
using System;
using System.IO;
using System.Text;
using Compress.Utils;
namespace Compress.SevenZip.Structure
{
public enum InStreamSource
{
Unknown,
FileStream,
CompStreamOutput
}
public class InStreamSourceInfo
{
public InStreamSource InStreamSource = InStreamSource.Unknown;
public ulong InStreamIndex;
}
public enum DecompressType
{
Unknown,
Stored,
Delta,
LZMA,
BCJ,
BCJ2,
PPMd,
BZip2,
LZMA2
}
public class Coder
{
public byte[] Method;
public ulong NumInStreams;
public ulong NumOutStreams;
public byte[] Properties;
/************Local Variables***********/
public DecompressType DecoderType;
public bool OutputUsedInternally = false;
public InStreamSourceInfo[] InputStreamsSourceInfo;
public Stream DecoderStream;
public void Read(BinaryReader br)
{
byte flags = br.ReadByte();
int decompressionMethodIdSize = flags & 0xf;
Method = br.ReadBytes(decompressionMethodIdSize);
if ((flags & 0x10) != 0)
{
NumInStreams = br.ReadEncodedUInt64();
NumOutStreams = br.ReadEncodedUInt64();
}
else
{
NumInStreams = 1;
NumOutStreams = 1;
}
if ((flags & 0x20) != 0)
{
ulong propSize = br.ReadEncodedUInt64();
Properties = br.ReadBytes((int)propSize);
}
if ((flags & 0x80) != 0)
{
throw new NotSupportedException("External flag");
}
if ((Method.Length == 1) && (Method[0] == 0))
{
DecoderType = DecompressType.Stored;
}
else if ((Method.Length == 1) && (Method[0] == 3))
{
DecoderType = DecompressType.Delta;
}
else if ((Method.Length == 3) && (Method[0] == 3) && (Method[1] == 1) && (Method[2] == 1))
{
DecoderType = DecompressType.LZMA;
}
else if ((Method.Length == 4) && (Method[0] == 3) && (Method[1] == 3) && (Method[2] == 1) &&
(Method[3] == 3))
{
DecoderType = DecompressType.BCJ;
}
else if ((Method.Length == 4) && (Method[0] == 3) && (Method[1] == 3) && (Method[2] == 1) &&
(Method[3] == 27))
{
DecoderType = DecompressType.BCJ2;
}
else if ((Method.Length == 3) && (Method[0] == 3) && (Method[1] == 4) && (Method[2] == 1))
{
DecoderType = DecompressType.PPMd;
}
else if ((Method.Length == 3) && (Method[0] == 4) && (Method[1] == 2) && (Method[2] == 2))
{
DecoderType = DecompressType.BZip2;
}
else if ((Method.Length == 1) && (Method[0] == 33))
{
DecoderType = DecompressType.LZMA2;
}
InputStreamsSourceInfo = new InStreamSourceInfo[NumInStreams];
for (uint i = 0; i < NumInStreams; i++)
{
InputStreamsSourceInfo[i] = new InStreamSourceInfo();
}
}
public void Write(BinaryWriter bw)
{
byte flags = (byte)Method.Length;
if ((NumInStreams != 1) || (NumOutStreams != 1))
{
flags = (byte)(flags | 0x10);
}
if ((Properties != null) && (Properties.Length > 0))
{
flags = (byte)(flags | 0x20);
}
bw.Write(flags);
bw.Write(Method);
if ((NumInStreams != 1) || (NumOutStreams != 1))
{
bw.WriteEncodedUInt64(NumInStreams);
bw.WriteEncodedUInt64(NumOutStreams);
}
if ((Properties != null) && (Properties.Length > 0))
{
bw.WriteEncodedUInt64((ulong)Properties.Length);
bw.Write(Properties);
}
}
public void Report(ref StringBuilder sb)
{
sb.AppendLine($" Method[] = {Method.ToArrayString()} : {DecoderType}");
sb.AppendLine($" NumInStreams = {NumInStreams}");
sb.AppendLine($" NumOutStreams = {NumOutStreams}");
sb.AppendLine($" Properties[] = {Properties.ToArrayString()}");
}
}
}

View File

@@ -0,0 +1,140 @@
using System;
using System.IO;
using System.Text;
namespace Compress.SevenZip.Structure
{
public class FileInfo
{
public string[] Names;
public bool[] EmptyStreamFlags;
public bool[] EmptyFileFlags;
public uint[] Attributes;
public void Read(BinaryReader br)
{
ulong size = br.ReadEncodedUInt64();
Names = new string[size];
ulong numEmptyFiles = 0;
for (;;)
{
HeaderProperty hp = (HeaderProperty) br.ReadByte();
if (hp == HeaderProperty.kEnd)
{
return;
}
ulong bytessize = br.ReadEncodedUInt64();
switch (hp)
{
case HeaderProperty.kName:
if (br.ReadByte() != 0)
{
throw new Exception("Cannot be external");
}
for (ulong i = 0; i < size; i++)
{
Names[i] = br.ReadName();
}
continue;
case HeaderProperty.kEmptyStream:
EmptyStreamFlags = Util.ReadBoolFlags(br, (ulong) Names.Length);
for (ulong i = 0; i < size; i++)
{
if (EmptyStreamFlags[i])
{
numEmptyFiles++;
}
}
continue;
case HeaderProperty.kEmptyFile:
EmptyFileFlags = Util.ReadBoolFlags(br, numEmptyFiles);
continue;
case HeaderProperty.kWinAttributes:
Attributes = Util.ReadUInt32Def(br, size);
continue;
// don't know what this is.
case HeaderProperty.kAnti:
br.ReadBytes((int)bytessize);
continue;
case HeaderProperty.kCreationTime:
case HeaderProperty.kLastAccessTime:
case HeaderProperty.kLastWriteTime:
br.ReadBytes((int) bytessize);
continue;
case HeaderProperty.kDummy:
br.ReadBytes((int) bytessize);
continue;
default:
throw new Exception(hp.ToString());
}
}
}
public void Write(BinaryWriter bw)
{
bw.Write((byte) HeaderProperty.kFilesInfo);
bw.WriteEncodedUInt64((ulong) Names.Length);
byte[] namebyte;
using (MemoryStream nameMem = new MemoryStream())
{
using (BinaryWriter nameBw = new BinaryWriter(nameMem,Encoding.UTF8,true))
{
nameBw.Write((byte) 0); //not external
foreach (string name in Names)
{
nameBw.WriteName(name);
}
namebyte = new byte[nameMem.Length];
nameMem.Position = 0;
nameMem.Read(namebyte, 0, namebyte.Length);
}
}
bw.Write((byte) HeaderProperty.kName);
bw.WriteEncodedUInt64((ulong) namebyte.Length);
bw.Write(namebyte);
if (EmptyStreamFlags != null)
{
bw.Write((byte) HeaderProperty.kEmptyStream);
Util.WriteBoolFlags(bw, EmptyStreamFlags);
}
if (EmptyFileFlags != null)
{
bw.Write((byte) HeaderProperty.kEmptyFile);
Util.WriteBoolFlags(bw, EmptyFileFlags);
}
if (Attributes != null)
{
bw.Write((byte) HeaderProperty.kWinAttributes);
Util.WriteUint32Def(bw, Attributes);
}
bw.Write((byte) HeaderProperty.kEnd);
}
public void Report(ref StringBuilder sb)
{
sb.AppendLine(" FileInfo");
sb.AppendLine(" ------");
}
}
}

View File

@@ -0,0 +1,434 @@
using System;
using System.IO;
using System.Text;
using Compress.Utils;
namespace Compress.SevenZip.Structure
{
public class Folder
{
public Coder[] Coders;
public BindPair[] BindPairs;
public ulong PackedStreamIndexBase;
public ulong[] PackedStreamIndices;
public ulong[] UnpackedStreamSizes;
public uint? UnpackCRC;
public UnpackedStreamInfo[] UnpackedStreamInfo;
private void ReadFolder(BinaryReader br)
{
ulong numCoders = br.ReadEncodedUInt64();
Coders = new Coder[numCoders];
int numInStreams = 0;
int numOutStreams = 0;
for (ulong i = 0; i < numCoders; i++)
{
Coders[i] = new Coder();
Coders[i].Read(br);
numInStreams += (int) Coders[i].NumInStreams;
numOutStreams += (int) Coders[i].NumOutStreams;
}
int numBindPairs = numOutStreams - 1;
BindPairs = new BindPair[numBindPairs];
for (int i = 0; i < numBindPairs; i++)
{
BindPairs[i] = new BindPair();
BindPairs[i].Read(br);
}
if (numInStreams < numBindPairs)
{
throw new NotSupportedException("Error");
}
int numPackedStreams = numInStreams - numBindPairs;
PackedStreamIndices = new ulong[numPackedStreams];
if (numPackedStreams == 1)
{
uint pi = 0;
for (uint j = 0; j < numInStreams; j++)
{
for (uint k = 0; k < BindPairs.Length; k++)
{
if (BindPairs[k].InIndex == j)
{
continue;
}
PackedStreamIndices[pi++] = j;
break;
}
}
}
else
{
for (uint i = 0; i < numPackedStreams; i++)
{
PackedStreamIndices[i] = br.ReadEncodedUInt64();
}
}
}
private void ReadUnpackedStreamSize(BinaryReader br)
{
ulong outStreams = 0;
foreach (Coder c in Coders)
{
outStreams += c.NumOutStreams;
}
UnpackedStreamSizes = new ulong[outStreams];
for (uint j = 0; j < outStreams; j++)
{
UnpackedStreamSizes[j] = br.ReadEncodedUInt64();
}
}
private ulong GetUnpackSize()
{
ulong outStreams = 0;
foreach (Coder coder in Coders)
{
outStreams += coder.NumInStreams;
}
for (ulong j = 0; j < outStreams; j++)
{
bool found = false;
foreach (BindPair bindPair in BindPairs)
{
if (bindPair.OutIndex != j)
{
continue;
}
found = true;
break;
}
if (!found)
{
return UnpackedStreamSizes[j];
}
}
return 0;
}
public static void ReadUnPackInfo(BinaryReader br, out Folder[] Folders)
{
Folders = null;
for (;;)
{
HeaderProperty hp = (HeaderProperty) br.ReadByte();
switch (hp)
{
case HeaderProperty.kFolder:
{
ulong numFolders = br.ReadEncodedUInt64();
Folders = new Folder[numFolders];
byte external = br.ReadByte();
switch (external)
{
case 0:
{
ulong folderIndex = 0;
for (uint i = 0; i < numFolders; i++)
{
Folders[i] = new Folder();
Folders[i].ReadFolder(br);
Folders[i].PackedStreamIndexBase = folderIndex;
folderIndex += (ulong) Folders[i].PackedStreamIndices.Length;
}
break;
}
case 1:
throw new NotSupportedException("External flag");
}
continue;
}
case HeaderProperty.kCodersUnPackSize:
{
for (uint i = 0; i < Folders.Length; i++)
{
Folders[i].ReadUnpackedStreamSize(br);
}
continue;
}
case HeaderProperty.kCRC:
{
uint?[] crcs;
Util.UnPackCRCs(br, (ulong) Folders.Length, out crcs);
for (int i = 0; i < Folders.Length; i++)
{
Folders[i].UnpackCRC = crcs[i];
}
continue;
}
case HeaderProperty.kEnd:
return;
default:
throw new Exception(hp.ToString());
}
}
}
public static void ReadSubStreamsInfo(BinaryReader br, ref Folder[] Folders)
{
for (;;)
{
HeaderProperty hp = (HeaderProperty) br.ReadByte();
switch (hp)
{
case HeaderProperty.kNumUnPackStream:
{
for (int f = 0; f < Folders.Length; f++)
{
int numStreams = (int) br.ReadEncodedUInt64();
Folders[f].UnpackedStreamInfo = new UnpackedStreamInfo[numStreams];
for (int i = 0; i < numStreams; i++)
{
Folders[f].UnpackedStreamInfo[i] = new UnpackedStreamInfo();
}
}
continue;
}
case HeaderProperty.kSize:
{
for (int f = 0; f < Folders.Length; f++)
{
Folder folder = Folders[f];
if (folder.UnpackedStreamInfo.Length == 0)
{
continue;
}
ulong sum = 0;
for (int i = 0; i < folder.UnpackedStreamInfo.Length - 1; i++)
{
ulong size = br.ReadEncodedUInt64();
folder.UnpackedStreamInfo[i].UnpackedSize = size;
sum += size;
}
folder.UnpackedStreamInfo[folder.UnpackedStreamInfo.Length - 1].UnpackedSize =
folder.GetUnpackSize() - sum;
}
continue;
}
case HeaderProperty.kCRC:
{
ulong numCRC = 0;
foreach (Folder folder in Folders)
{
if (folder.UnpackedStreamInfo == null)
{
folder.UnpackedStreamInfo = new UnpackedStreamInfo[1];
folder.UnpackedStreamInfo[0] = new UnpackedStreamInfo();
folder.UnpackedStreamInfo[0].UnpackedSize = folder.GetUnpackSize();
}
if ((folder.UnpackedStreamInfo.Length != 1) || !folder.UnpackCRC.HasValue)
{
numCRC += (ulong) folder.UnpackedStreamInfo.Length;
}
}
int crcIndex = 0;
uint?[] crc;
Util.UnPackCRCs(br, numCRC, out crc);
for (uint i = 0; i < Folders.Length; i++)
{
Folder folder = Folders[i];
if ((folder.UnpackedStreamInfo.Length == 1) && folder.UnpackCRC.HasValue)
{
folder.UnpackedStreamInfo[0].Crc = folder.UnpackCRC;
}
else
{
for (uint j = 0; j < folder.UnpackedStreamInfo.Length; j++, crcIndex++)
{
folder.UnpackedStreamInfo[j].Crc = crc[crcIndex];
}
}
}
continue;
}
case HeaderProperty.kEnd:
return;
default:
throw new Exception(hp.ToString());
}
}
}
private void WriteFolder(BinaryWriter bw)
{
ulong numCoders = (ulong) Coders.Length;
bw.WriteEncodedUInt64(numCoders);
for (ulong i = 0; i < numCoders; i++)
{
Coders[i].Write(bw);
}
ulong numBindingPairs = BindPairs == null ? 0 : (ulong) BindPairs.Length;
for (ulong i = 0; i < numBindingPairs; i++)
{
BindPairs[i].Write(bw);
}
//need to look at PAckedStreamIndices but don't need them for basic writing I am doing
}
private void WriteUnpackedStreamSize(BinaryWriter bw)
{
ulong numUnpackedStreamSizes = (ulong) UnpackedStreamSizes.Length;
for (ulong i = 0; i < numUnpackedStreamSizes; i++)
{
bw.WriteEncodedUInt64(UnpackedStreamSizes[i]);
}
}
public static void WriteUnPackInfo(BinaryWriter bw, Folder[] Folders)
{
bw.Write((byte) HeaderProperty.kUnPackInfo);
bw.Write((byte) HeaderProperty.kFolder);
ulong numFolders = (ulong) Folders.Length;
bw.WriteEncodedUInt64(numFolders);
bw.Write((byte) 0); //External Flag
for (ulong i = 0; i < numFolders; i++)
{
Folders[i].WriteFolder(bw);
}
bw.Write((byte) HeaderProperty.kCodersUnPackSize);
for (ulong i = 0; i < numFolders; i++)
{
Folders[i].WriteUnpackedStreamSize(bw);
}
if (Folders[0].UnpackCRC != null)
{
bw.Write((byte) HeaderProperty.kCRC);
throw new NotImplementedException();
}
bw.Write((byte) HeaderProperty.kEnd);
}
public static void WriteSubStreamsInfo(BinaryWriter bw, Folder[] Folders)
{
bw.Write((byte) HeaderProperty.kSubStreamsInfo);
bw.Write((byte) HeaderProperty.kNumUnPackStream);
for (int f = 0; f < Folders.Length; f++)
{
ulong numStreams = (ulong) Folders[f].UnpackedStreamInfo.Length;
bw.WriteEncodedUInt64(numStreams);
}
bw.Write((byte) HeaderProperty.kSize);
for (int f = 0; f < Folders.Length; f++)
{
Folder folder = Folders[f];
for (int i = 0; i < folder.UnpackedStreamInfo.Length - 1; i++)
{
bw.WriteEncodedUInt64(folder.UnpackedStreamInfo[i].UnpackedSize);
}
}
bw.Write((byte) HeaderProperty.kCRC);
bw.Write((byte) 1); // crc flags default to true
for (int f = 0; f < Folders.Length; f++)
{
Folder folder = Folders[f];
for (int i = 0; i < folder.UnpackedStreamInfo.Length; i++)
{
bw.Write(Util.uinttobytes(folder.UnpackedStreamInfo[i].Crc));
}
}
bw.Write((byte) HeaderProperty.kEnd);
}
public void Report(ref StringBuilder sb)
{
if (Coders == null)
{
sb.AppendLine(" Coders[] = null");
}
else
{
sb.AppendLine($" Coders[] = ({Coders.Length})");
foreach (Coder c in Coders)
{
c.Report(ref sb);
}
}
if (BindPairs == null)
{
sb.AppendLine(" BindPairs[] = null");
}
else
{
sb.AppendLine($" BindPairs[] = ({BindPairs.Length})");
foreach (BindPair bp in BindPairs)
{
bp.Report(ref sb);
}
}
sb.AppendLine($" PackedStreamIndexBase = {PackedStreamIndexBase}");
sb.AppendLine($" PackedStreamIndices[] = {PackedStreamIndices.ToArrayString()}");
sb.AppendLine($" UnpackedStreamSizes[] = {UnpackedStreamSizes.ToArrayString()}");
sb.AppendLine($" UnpackCRC = {UnpackCRC.ToHex()}");
if (UnpackedStreamInfo == null)
{
sb.AppendLine(" UnpackedStreamInfo[] = null");
}
else
{
sb.AppendLine($" UnpackedStreamInfo[{UnpackedStreamInfo.Length}]");
foreach (UnpackedStreamInfo usi in UnpackedStreamInfo)
{
usi.Report(ref sb);
}
}
}
}
}

View File

@@ -0,0 +1,133 @@
using System;
using System.IO;
using System.Text;
using Compress.SevenZip.Compress.LZMA;
using Compress.Utils;
namespace Compress.SevenZip.Structure
{
public class Header
{
public StreamsInfo StreamsInfo;
public FileInfo FileInfo;
public void Read(BinaryReader br)
{
for (; ; )
{
HeaderProperty hp = (HeaderProperty)br.ReadByte();
switch (hp)
{
case HeaderProperty.kMainStreamsInfo:
StreamsInfo = new StreamsInfo();
StreamsInfo.Read(br);
break;
case HeaderProperty.kFilesInfo:
FileInfo = new FileInfo();
FileInfo.Read(br);
break;
case HeaderProperty.kEnd:
return;
default:
throw new Exception(hp.ToString());
}
}
}
private void Write(BinaryWriter bw)
{
bw.Write((byte)HeaderProperty.kHeader);
StreamsInfo.Write(bw);
FileInfo.Write(bw);
bw.Write((byte)HeaderProperty.kEnd);
}
public void WriteHeader(BinaryWriter bw)
{
Write(bw);
}
public static ZipReturn ReadHeaderOrPackedHeader(Stream stream, long baseOffset, out Header header)
{
header = null;
using (BinaryReader br = new BinaryReader(stream, Encoding.UTF8, true))
{
HeaderProperty hp = (HeaderProperty)br.ReadByte();
switch (hp)
{
case HeaderProperty.kEncodedHeader:
{
StreamsInfo streamsInfo = new StreamsInfo();
streamsInfo.Read(br);
if (streamsInfo.Folders.Length > 1)
{
return ZipReturn.ZipUnsupportedCompression;
}
Folder firstFolder = streamsInfo.Folders[0];
if (firstFolder.Coders.Length > 1)
{
return ZipReturn.ZipUnsupportedCompression;
}
byte[] method = firstFolder.Coders[0].Method;
if (!((method.Length == 3) && (method[0] == 3) && (method[1] == 1) && (method[2] == 1))) // LZMA
{
return ZipReturn.ZipUnsupportedCompression;
}
stream.Seek(baseOffset + (long)streamsInfo.PackPosition, SeekOrigin.Begin);
using (LzmaStream decoder = new LzmaStream(firstFolder.Coders[0].Properties, stream))
{
ZipReturn zr = ReadHeaderOrPackedHeader(decoder, baseOffset, out header);
if (zr != ZipReturn.ZipGood)
{
return zr;
}
}
return ZipReturn.ZipGood;
}
case HeaderProperty.kHeader:
{
header = new Header();
header.Read(br);
return ZipReturn.ZipGood;
}
}
return ZipReturn.ZipCentralDirError;
}
}
public void Report(ref StringBuilder sb)
{
sb.AppendLine("Header");
sb.AppendLine("------");
if (StreamsInfo == null)
{
sb.AppendLine("StreamsInfo == null");
}
else
{
StreamsInfo.Report(ref sb);
}
if (FileInfo == null)
{
sb.AppendLine("FileInfo == null");
}
else
{
FileInfo.Report(ref sb);
}
}
}
}

View File

@@ -0,0 +1,98 @@
using System;
using System.IO;
using System.Text;
using Compress.Utils;
namespace Compress.SevenZip.Structure
{
public class PackedStreamInfo
{
public ulong PackedSize;
public ulong? Crc;
public ulong StreamPosition;
public Stream PackedStream;
public static void Read(BinaryReader br, out ulong packPosition, out PackedStreamInfo[] packedStreams)
{
packPosition = br.ReadEncodedUInt64();
ulong numPackStreams = br.ReadEncodedUInt64();
packedStreams = new PackedStreamInfo[numPackStreams];
for (ulong i = 0; i < numPackStreams; i++)
{
packedStreams[i] = new PackedStreamInfo();
}
ulong streamPosition = 0;
for (;;)
{
HeaderProperty hp = (HeaderProperty) br.ReadByte();
switch (hp)
{
case HeaderProperty.kSize:
for (ulong i = 0; i < numPackStreams; i++)
{
packedStreams[i].StreamPosition = streamPosition;
packedStreams[i].PackedSize = br.ReadEncodedUInt64();
streamPosition += packedStreams[i].PackedSize;
}
continue;
case HeaderProperty.kCRC:
for (ulong i = 0; i < numPackStreams; i++)
{
packedStreams[i].Crc = br.ReadEncodedUInt64();
}
continue;
case HeaderProperty.kEnd:
return;
default:
throw new Exception(hp.ToString());
}
}
}
public static void Write(BinaryWriter bw, ulong packPosition, PackedStreamInfo[] packedStreams)
{
ulong numPackStreams = (ulong) packedStreams.Length;
bw.Write((byte) HeaderProperty.kPackInfo);
bw.WriteEncodedUInt64(packPosition);
bw.WriteEncodedUInt64(numPackStreams);
bw.Write((byte) HeaderProperty.kSize);
ulong streamPosition = 0;
for (ulong i = 0; i < numPackStreams; i++)
{
packedStreams[i].StreamPosition = streamPosition;
bw.WriteEncodedUInt64(packedStreams[i].PackedSize);
streamPosition += packedStreams[i].PackedSize;
}
// Only checking the first CRC assuming all the reset will be the same
if (packedStreams[0].Crc != null)
{
bw.Write((byte) HeaderProperty.kCRC);
for (ulong i = 0; i < numPackStreams; i++)
{
bw.WriteEncodedUInt64(packedStreams[i].Crc ?? 0);
}
}
bw.Write((byte) HeaderProperty.kEnd);
}
public void Report(ref StringBuilder sb)
{
sb.AppendLine($" PackedSize = {PackedSize}");
sb.AppendLine($" Crc = {Crc.ToHex()}");
sb.AppendLine($" StreamPosition = {StreamPosition}");
}
}
}

View File

@@ -0,0 +1,110 @@
using System.IO;
using System.Text;
namespace Compress.SevenZip.Structure
{
internal class SignatureHeader
{
private static readonly byte[] Signature = {(byte) '7', (byte) 'z', 0xBC, 0xAF, 0x27, 0x1C};
private byte _major;
private byte _minor;
private uint _startHeaderCRC;
public ulong NextHeaderOffset;
public ulong NextHeaderSize;
public uint NextHeaderCRC;
private long _crcOffset;
public long BaseOffset { get; private set; }
public bool Read(Stream stream)
{
using (BinaryReader br = new BinaryReader(stream, Encoding.UTF8, true))
{
byte[] signatureBytes = br.ReadBytes(6);
if (!signatureBytes.Compare(Signature))
{
return false;
}
_major = br.ReadByte();
_minor = br.ReadByte();
_startHeaderCRC = br.ReadUInt32();
long pos = br.BaseStream.Position;
byte[] mainHeader = new byte[8 + 8 + 4];
br.BaseStream.Read(mainHeader, 0, mainHeader.Length);
if (!Utils.CRC.VerifyDigest(_startHeaderCRC, mainHeader, 0, (uint) mainHeader.Length))
{
return false;
}
br.BaseStream.Seek(pos, SeekOrigin.Begin);
NextHeaderOffset = br.ReadUInt64();
NextHeaderSize = br.ReadUInt64();
NextHeaderCRC = br.ReadUInt32();
return true;
}
}
public void Write(BinaryWriter bw)
{
//SignatureHeader
//~~~~~~~~~~~~~~~
bw.Write(Signature);
//ArchiveVersion
//{
bw.Write((byte) 0); // BYTE Major
bw.Write((byte) 3); // BYTE Minor
//};
_crcOffset = bw.BaseStream.Position;
bw.Write((uint) 0); //HeaderCRC
//StartHeader
//{
bw.Write((ulong) 0); //NextHeaderOffset
bw.Write((ulong) 0); //NextHeaderSize
bw.Write((uint) 0); //NextHeaderCRC
//}
BaseOffset = bw.BaseStream.Position;
}
public void WriteFinal(BinaryWriter bw, ulong headerpos, ulong headerLength, uint headerCRC)
{
long fileEnd = bw.BaseStream.Position;
byte[] sigHeaderBytes;
using (MemoryStream sigHeaderMem = new MemoryStream())
{
using (BinaryWriter sigHeaderBw = new BinaryWriter(sigHeaderMem,Encoding.UTF8,true))
{
sigHeaderBw.Write((ulong) ((long) headerpos - BaseOffset)); //NextHeaderOffset
sigHeaderBw.Write(headerLength); //NextHeaderSize
sigHeaderBw.Write(headerCRC); //NextHeaderCRC
sigHeaderBytes = new byte[sigHeaderMem.Length];
sigHeaderMem.Position = 0;
sigHeaderMem.Read(sigHeaderBytes, 0, sigHeaderBytes.Length);
}
}
uint sigHeaderCRC = Utils.CRC.CalculateDigest(sigHeaderBytes, 0, (uint) sigHeaderBytes.Length);
bw.BaseStream.Position = _crcOffset;
bw.Write(sigHeaderCRC); //Header CRC
bw.Write(sigHeaderBytes);
bw.BaseStream.Seek(fileEnd, SeekOrigin.Begin);
}
}
}

View File

@@ -0,0 +1,84 @@
using System;
using System.IO;
using System.Security.Permissions;
using System.Text;
using Compress.Utils;
namespace Compress.SevenZip.Structure
{
public class StreamsInfo
{
public ulong PackPosition;
public PackedStreamInfo[] PackedStreams;
public Folder[] Folders;
public void Read(BinaryReader br)
{
for (;;)
{
HeaderProperty hp = (HeaderProperty) br.ReadByte();
switch (hp)
{
case HeaderProperty.kPackInfo:
PackedStreamInfo.Read(br, out PackPosition, out PackedStreams);
continue;
case HeaderProperty.kUnPackInfo:
Folder.ReadUnPackInfo(br, out Folders);
continue;
case HeaderProperty.kSubStreamsInfo:
Folder.ReadSubStreamsInfo(br, ref Folders);
continue;
case HeaderProperty.kEnd:
return;
default:
throw new Exception(hp.ToString());
}
}
}
public void Write(BinaryWriter bw)
{
bw.Write((byte) HeaderProperty.kMainStreamsInfo);
PackedStreamInfo.Write(bw, PackPosition, PackedStreams);
Folder.WriteUnPackInfo(bw, Folders);
Folder.WriteSubStreamsInfo(bw, Folders);
bw.Write((byte) HeaderProperty.kEnd);
}
public void Report(ref StringBuilder sb)
{
sb.AppendLine(" StreamsInfo");
sb.AppendLine(" -----------");
sb.AppendLine($" PackPosition = {PackPosition}");
if (PackedStreams == null)
{
sb.AppendLine($" PackedStreams[] = null");
}
else
{
sb.AppendLine($" PackedStreams[] = ({PackedStreams.Length})");
foreach (PackedStreamInfo psi in PackedStreams)
{
psi.Report(ref sb);
}
}
if (Folders == null)
{
sb.AppendLine($" Folders[] = null");
}
else
{
sb.AppendLine($" Folders[] = ({Folders.Length})");
foreach (Folder f in Folders)
{
f.Report(ref sb);
}
}
}
}
}

View File

@@ -0,0 +1,16 @@
using System.Text;
using Compress.Utils;
namespace Compress.SevenZip.Structure
{
public class UnpackedStreamInfo
{
public ulong UnpackedSize;
public uint? Crc;
public void Report(ref StringBuilder sb)
{
sb.AppendLine($" Crc = {Crc.ToHex()} , Size = {UnpackedSize}");
}
}
}