Continuing to implement SevenZIP file format

This commit is contained in:
Michael Becker 2014-07-01 23:19:06 -04:00
parent 250dc386cb
commit c3c0e6dc34
9 changed files with 322 additions and 1 deletions

View File

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.DataFormats.FileSystem.SevenZip
{
public enum SevenZipBlockType : long
{
End = 0x00,
Header = 0x01,
ArchiveProperties = 0x02,
AdditionalStreamsInfo = 0x03,
MainStreamsInfo = 0x04,
FilesInfo = 0x05,
PackInfo = 0x06,
UnpackInfo = 0x07,
SubStreamsInfo = 0x08,
Size = 0x09,
CRC = 0x0A,
Folder = 0x0B,
CodersUnpackSize = 0x0C,
NumUnpackStream = 0x0D,
EmptyStream = 0x0E,
EmptyFile = 0x0F,
Anti = 0x10,
Name = 0x11,
CTime = 0x12,
ATime = 0x13,
MTime = 0x14,
WinAttributes = 0x15,
Comment = 0x16,
EncodedHeader = 0x17,
StartPos = 0x18,
Dummy = 0x19
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.DataFormats.FileSystem.SevenZip
{
public struct SevenZipCoder
{
public string CodecID;
public SevenZipCoderFlags Flags;
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.DataFormats.FileSystem.SevenZip
{
[Flags()]
public enum SevenZipCoderFlags : byte
{
IsComplex = 0x01,
HasAttributes = 0x02,
Reserved = 0x04,
AlternativeMethods = 0x08
}
}

View File

@ -35,6 +35,35 @@ namespace UniversalEditor.DataFormats.FileSystem.SevenZip
int signature2 = br.ReadInt32();
if (signature2 != 0x1C27AFBC) throw new InvalidDataFormatException("File does not begin with LE: 0x1C27AFBC");
byte formatVersionMajor = br.ReadByte();
byte formatVersionMinor = br.ReadByte();
uint startHeaderCRC = br.ReadUInt32();
ulong nextHeaderOffset = br.ReadUInt64();
ulong nextHeaderSize = br.ReadUInt64();
uint nextHeaderCRC = br.ReadUInt32();
br.Accessor.Seek((long)nextHeaderOffset, IO.SeekOrigin.Current);
while (true)
{
SevenZipBlockType blockID = (SevenZipBlockType)ReadNumber(br);
switch (blockID)
{
case SevenZipBlockType.EncodedHeader:
{
SevenZipHeader header = ReadEncodedHeader(br);
break;
}
case SevenZipBlockType.PackInfo:
{
SevenZipPackInfo packInfo = ReadPackInfo(br);
break;
}
}
}
short u1a = br.ReadInt16(); // 1024 1024
int u1b = br.ReadInt16(); // 25464 -6047
short u2a = br.ReadInt16(); // 24321 7104
@ -81,6 +110,168 @@ namespace UniversalEditor.DataFormats.FileSystem.SevenZip
int u27 = br.ReadInt32();
}
private SevenZipHeader ReadEncodedHeader(IO.Reader br)
{
SevenZipHeader header = new SevenZipHeader();
while (true)
{
SevenZipBlockType blockID = (SevenZipBlockType)ReadNumber(br);
if (blockID == SevenZipBlockType.End) break;
switch (blockID)
{
case SevenZipBlockType.PackInfo:
{
SevenZipPackInfo packInfo = ReadPackInfo(br);
break;
}
case SevenZipBlockType.UnpackInfo:
{
SevenZipUnpackInfo unpackInfo = ReadUnpackInfo(br);
break;
}
case SevenZipBlockType.Size:
{
break;
}
}
}
return header;
}
private SevenZipUnpackInfo ReadUnpackInfo(IO.Reader br)
{
while (true)
{
SevenZipBlockType blockID = (SevenZipBlockType)ReadNumber(br);
switch (blockID)
{
case SevenZipBlockType.Folder:
{
ulong folderCount = ReadNumber(br);
byte external = br.ReadByte();
switch (external)
{
case 0:
{
for (ulong i = 0; i < folderCount; i++)
{
SevenZipFolder folder = ReadFolder(br);
}
break;
}
case 1:
{
ulong dataStreamIndex = ReadNumber(br);
break;
}
}
break;
}
}
}
}
private SevenZipFolder ReadFolder(IO.Reader br)
{
ulong coderCount = ReadNumber(br);
for (ulong i = 0; i < coderCount; i++)
{
SevenZipCoder coder = ReadCodersInfo(br);
}
NumBindPairs
BindPairsInfo[NumBindPairs]
{
InIndex;
OutIndex;
}
PackedIndices
}
private SevenZipCoder ReadCodersInfo(IO.Reader br)
{
SevenZipCoder retval = new SevenZipCoder();
byte idSizeAndFlags = br.ReadByte();
byte idSize = (byte)idSizeAndFlags.GetBits(0, 4);
retval.Flags = (SevenZipCoderFlags)idSizeAndFlags.GetBits(4, 4);
retval.CodecID = br.ReadFixedLengthString(idSize);
if ((retval.Flags & SevenZipCoderFlags.IsComplex) == SevenZipCoderFlags.IsComplex)
{
ulong inputStreamCount = ReadNumber(br);
ulong outputStreamCount = ReadNumber(br);
}
if ((retval.Flags & SevenZipCoderFlags.HasAttributes) == SevenZipCoderFlags.HasAttributes)
{
ulong propertiesSize = ReadNumber(br);
byte[] properties = br.ReadBytes(propertiesSize);
}
return retval;
}
private SevenZipPackInfo ReadPackInfo(IO.Reader br)
{
SevenZipPackInfo packInfo = new SevenZipPackInfo();
packInfo.packPos = ReadNumber(br);
packInfo.packStreamCount = ReadNumber(br);
packInfo.packSizes = new ulong[packInfo.packStreamCount];
packInfo.packStreamDigests = new uint[packInfo.packStreamCount];
while (true)
{
SevenZipBlockType blockType = (SevenZipBlockType)ReadNumber(br);
if (blockType == SevenZipBlockType.End) break;
switch (blockType)
{
case SevenZipBlockType.Size:
{
for (ulong i = 0; i < packInfo.packStreamCount; i++)
{
packInfo.packSizes[i] = ReadNumber(br);
}
break;
}
case SevenZipBlockType.CRC:
{
for (ulong i = 0; i < packInfo.packStreamCount; i++)
{
packInfo.packStreamDigests[i] = br.ReadUInt32();
}
break;
}
default:
{
break;
}
}
}
return packInfo;
}
private ulong ReadNumber(IO.Reader br)
{
if (br.EndOfStream) throw new System.IO.EndOfStreamException();
byte firstByte = br.ReadByte();
byte mask = 0x80;
ulong value = 0;
for (int i = 0; i < 8; i++)
{
if ((firstByte & mask) == 0)
{
ulong highPart = ((ulong)firstByte & ((ulong)mask - 1));
value += (highPart << (i * 8));
return value;
}
if (br.EndOfStream) throw new System.IO.EndOfStreamException();
value |= ((ulong)br.ReadByte() << (8 * i));
mask >>= 1;
}
return value;
}
protected override void SaveInternal(ObjectModel objectModel)
{
throw new NotImplementedException();

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.DataFormats.FileSystem.SevenZip
{
class SevenZipFolder
{
}
}

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.DataFormats.FileSystem.SevenZip
{
public struct SevenZipHeader
{
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.DataFormats.FileSystem.SevenZip
{
public struct SevenZipPackInfo
{
public ulong packPos;
public ulong packStreamCount;
public ulong[] packSizes;
public uint[] packStreamDigests;
}
}

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.DataFormats.FileSystem.SevenZip
{
class SevenZipUnpackInfo
{
}
}

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
@ -129,7 +129,14 @@
<Compile Include="DataFormats\FileSystem\PRF\PRFDataFormat.cs" />
<Compile Include="DataFormats\FileSystem\ProDOS\ProDOSDataFormat.cs" />
<Compile Include="DataFormats\FileSystem\REEVEsoft\Freeze\ICEDataFormat.cs" />
<Compile Include="DataFormats\FileSystem\SevenZip\SevenZipBlockType.cs" />
<Compile Include="DataFormats\FileSystem\SevenZip\SevenZipCoder.cs" />
<Compile Include="DataFormats\FileSystem\SevenZip\SevenZipCoderFlags.cs" />
<Compile Include="DataFormats\FileSystem\SevenZip\SevenZipDataFormat.cs" />
<Compile Include="DataFormats\FileSystem\SevenZip\SevenZipFolder.cs" />
<Compile Include="DataFormats\FileSystem\SevenZip\SevenZipHeader.cs" />
<Compile Include="DataFormats\FileSystem\SevenZip\SevenZipPackInfo.cs" />
<Compile Include="DataFormats\FileSystem\SevenZip\SevenZipUnpackInfo.cs" />
<Compile Include="DataFormats\FileSystem\SilentHill\ARC\SilentHillARCDataFormat.cs" />
<Compile Include="DataFormats\FileSystem\SPIS\SPISDataFormat.cs" />
<Compile Include="DataFormats\FileSystem\StuffIt\StuffItDataFormat.cs" />