LibHac/libhac/Pfs0.cs
2018-06-25 17:44:44 -05:00

111 lines
3.3 KiB
C#

using System.IO;
using System.Text;
namespace libhac
{
public class Pfs0
{
public Pfs0Header Header { get; set; }
public int HeaderSize { get; set; }
public Pfs0FileEntry[] Entries { get; set; }
private Stream Stream { get; set; }
public Pfs0(Stream stream)
{
byte[] headerBytes;
using (var reader = new BinaryReader(stream, Encoding.Default, true))
{
Header = new Pfs0Header(reader);
HeaderSize = (int)(16 + 24 * Header.NumFiles + Header.StringTableSize);
stream.Position = 0;
headerBytes = reader.ReadBytes(HeaderSize);
}
using (var reader = new BinaryReader(new MemoryStream(headerBytes)))
{
reader.BaseStream.Position = 16;
Entries = new Pfs0FileEntry[Header.NumFiles];
for (int i = 0; i < Header.NumFiles; i++)
{
Entries[i] = new Pfs0FileEntry(reader) { Index = i };
}
int stringTableOffset = 16 + 24 * Header.NumFiles;
for (int i = 0; i < Header.NumFiles; i++)
{
reader.BaseStream.Position = stringTableOffset + Entries[i].StringTableOffset;
Entries[i].Name = reader.ReadAsciiZ();
}
}
Stream = stream;
}
public byte[] GetFile(int index)
{
var entry = Entries[index];
var file = new byte[entry.Size];
Stream.Position = HeaderSize + entry.Offset;
Stream.Read(file, 0, file.Length);
return file;
}
}
public class Pfs0Superblock
{
public byte[] MasterHash; /* SHA-256 hash of the hash table. */
public uint BlockSize; /* In bytes. */
public uint Always2;
public long HashTableOffset; /* Normally zero. */
public long HashTableSize;
public long Pfs0Offset;
public long Pfs0Size;
public Pfs0Superblock(BinaryReader reader)
{
MasterHash = reader.ReadBytes(0x20);
BlockSize = reader.ReadUInt32();
Always2 = reader.ReadUInt32();
HashTableOffset = reader.ReadInt64();
HashTableSize = reader.ReadInt64();
Pfs0Offset = reader.ReadInt64();
Pfs0Size = reader.ReadInt64();
reader.BaseStream.Position += 0xF0;
}
}
public class Pfs0Header
{
public string Magic;
public int NumFiles;
public uint StringTableSize;
public long Reserved;
public Pfs0Header(BinaryReader reader)
{
Magic = reader.ReadAscii(4);
NumFiles = reader.ReadInt32();
StringTableSize = reader.ReadUInt32();
Reserved = reader.ReadInt32();
}
}
public class Pfs0FileEntry
{
public int Index;
public long Offset;
public long Size;
public uint StringTableOffset;
public uint Reserved;
public string Name;
public Pfs0FileEntry(BinaryReader reader)
{
Offset = reader.ReadInt64();
Size = reader.ReadInt64();
StringTableOffset = reader.ReadUInt32();
Reserved = reader.ReadUInt32();
}
}
}