private U8Directory ReadFileTable(uint nodeOffset) { U8Directory root = new U8Directory(null, ROOT_DIR); filestream.Position = nodeOffset; U8Node rootNode = new U8Node() { type = filestream.ReadUInt8(), nameOffset = filestream.ReadUInt24BE(), dataOffset = filestream.ReadUInt32BE(), size = filestream.ReadUInt32BE() }; if (rootNode.type != DIR) { throw new InvalidDataException("Root node of U8 archive was not a directory"); } var stringTableOffset = nodeOffset + 12 * rootNode.size; var lastNodes = new Stack <uint>(); lastNodes.Push(rootNode.size); U8Directory currentDir = root; for (var i = 1; i < rootNode.size; i++) { if (i == lastNodes.Peek()) { lastNodes.Pop(); currentDir = currentDir.Parent as U8Directory; } var node = new U8Node() { type = filestream.ReadUInt8(), nameOffset = filestream.ReadUInt24BE(), dataOffset = filestream.ReadUInt32BE(), size = filestream.ReadUInt32BE() }; var pos = filestream.Position; filestream.Position = stringTableOffset + node.nameOffset; var name = filestream.ReadASCIINullTerminated(); filestream.Position = pos; if (node.type == DIR) { var newDir = new U8Directory(currentDir, name); currentDir.AddDir(newDir); currentDir = newDir; lastNodes.Push(node.size); } else { currentDir.AddFile(new OffsetFile(name, currentDir, filestream, node.dataOffset, node.size)); } } return(root); }
/// <summary> /// Open the .far archive which is the given file. /// </summary> /// <param name="path"></param> private U8Package(IFile f) { FileName = f.Name; filestream = f.GetStream(); if (filestream.ReadUInt32BE() != MAGIC) { throw new InvalidDataException("Package is not a U8 package."); } uint rootNode = filestream.ReadUInt32BE(); uint dataOffset = filestream.ReadUInt32BE(); root = ReadFileTable(rootNode); }
public U8Directory(U8Directory parent, string name) : base(parent, name) { }