private FileSet ReadFileSet(Stream stream, string name) { FileSet fileSet = new FileSet(name); using (BinaryReader reader = new BinaryReader(stream)) { SectionSet fileSetSections = SectionIO.ReadAll(reader); PACKFSHD fileSetHeader = fileSetSections.Get <PACKFSHD>(); GENESTRT fileSetNameTable = fileSetSections.Get <GENESTRT>(); foreach (PACKFSHD.FileEntry fEntry in fileSetHeader.Files) { string fName = fileSetNameTable.Strings[(int)fEntry.NameIndex]; byte[] rawData = new byte[fEntry.CompressedSize]; stream.Seek((long)fEntry.Offset, SeekOrigin.Begin); stream.Read(rawData); if (fEntry.Unknown != 0x2) { throw new Exception("Unsupported value of unknown file set file entry field: " + fEntry.Unknown); } fileSet.Files.Add(new File(fName, rawData, true, fEntry.UncompressedSize)); } } return(fileSet); }
private void WriteFileSet(Stream stream, FileSet fileSet) { PACKFSHD fileSetHeader = new PACKFSHD(); GENESTRT fileSetNameTable = new GENESTRT(); fileSetHeader.Unknown = 0x10000; fileSetHeader.DataOffset = 0; // Filled in later. foreach (File file in fileSet.Files) { PACKFSHD.FileEntry fileEntry = new PACKFSHD.FileEntry(); fileEntry.NameIndex = fileSetNameTable.AddString(file.Name); fileEntry.Unknown = 0x2; fileEntry.Offset = 0; // Filled in later. fileEntry.UncompressedSize = file.UncompressedSize; fileEntry.CompressedSize = (uint)file.RawData.Length; fileSetHeader.Files.Add(fileEntry); } SectionSet fileSetSections = new SectionSet(); fileSetSections.Add(new ENDILTLE()); fileSetSections.Add(fileSetHeader); fileSetSections.Add(fileSetNameTable); fileSetSections.Add(new GENEEOF()); ulong headersSize; using (MemoryStream sizeTestStream = new MemoryStream()) { SectionIO.WriteAll(sizeTestStream, fileSetSections); headersSize = (ulong)sizeTestStream.Length; } ulong currOffset = NumberUtil.Align(headersSize, 0x10); fileSetHeader.DataOffset = (uint)currOffset - 0x10; // Offset excludes ENDILTLE. foreach (PACKFSHD.FileEntry fileEntry in fileSetHeader.Files) { fileEntry.Offset = currOffset; currOffset = NumberUtil.Align(currOffset + fileEntry.CompressedSize, 0x10); } SectionIO.WriteAll(stream, fileSetSections); foreach (File file in fileSet.Files) { stream.Write(file.RawData); stream.PadTo(0x10); } }