/// <summary> /// Reads header part 2 from an input stream. /// </summary> /// <param name="stream">The stream to read from.</param> /// <param name="offset">The offset to the header part from the beginning of the stream.</param> /// <param name="size">The size of the header part.</param> /// <param name="p">Progress info.</param> /// <returns>The loaded header part.</returns> internal async Task <NefsHeaderPart2> ReadHeaderPart2Async(Stream stream, uint offset, uint size, NefsProgress p) { var entries = new List <NefsHeaderPart2Entry>(); // Validate inputs if (!this.ValidateHeaderPartStream(stream, offset, size, "2")) { return(new NefsHeaderPart2(entries)); } // Get entries in part 2 var numEntries = size / NefsHeaderPart2Entry.Size; var entryOffset = offset; for (var i = 0; i < numEntries; ++i) { using (p.BeginTask(1.0f / numEntries)) { var entry = new NefsHeaderPart2Entry(); await FileData.ReadDataAsync(stream, entryOffset, entry, NefsVersion.Version200, p); entryOffset += NefsHeaderPart2Entry.Size; entries.Add(entry); } } return(new NefsHeaderPart2(entries)); }
/// <summary> /// Reads header part 2 from an input stream. /// </summary> /// <param name="stream">The stream to read from.</param> /// <param name="offset">The offset to the header part from the beginning of the stream.</param> /// <param name="size">The size of the header part.</param> /// <param name="p">Progress info.</param> /// <returns>The loaded header part.</returns> internal async Task <NefsHeaderPart2> ReadHeaderPart2Async(Stream stream, uint offset, uint size, NefsProgress p) { var entries = new List <NefsHeaderPart2Entry>(); var ids = new HashSet <NefsItemId>(); // Validate inputs if (!this.ValidateHeaderPartStream(stream, offset, size, "2")) { return(new NefsHeaderPart2(entries)); } // Get entries in part 2 var numEntries = size / NefsHeaderPart2Entry.Size; var entryOffset = offset; for (var i = 0; i < numEntries; ++i) { using (p.BeginTask(1.0f / numEntries)) { var entry = new NefsHeaderPart2Entry(); await FileData.ReadDataAsync(stream, entryOffset, entry, p); // Check for duplicate item ids var id = new NefsItemId(entry.Id.Value); if (ids.Contains(id)) { Log.LogError($"Found duplicate item id in part 2: {id.Value}"); continue; } ids.Add(id); entries.Add(entry); entryOffset += NefsHeaderPart2Entry.Size; } } return(new NefsHeaderPart2(entries)); }
public async void ReadHeaderPart4Async_ValidData_DataRead() { // Item 1 has 2 chunk sizes var e1p1 = new NefsHeaderPart1Entry(); e1p1.Data0x10_Id.Value = 0; e1p1.Data0x0c_IndexIntoPart4.Value = 0; var e1p2 = new NefsHeaderPart2Entry(); e1p1.Data0x10_Id.Value = e1p1.Id.Value; e1p2.Data0x0c_ExtractedSize.Value = NefsHeader.ChunkSize * 2; // Item 2 has 1 chunk size var e2p1 = new NefsHeaderPart1Entry(); e2p1.Data0x10_Id.Value = 1; e2p1.Data0x0c_IndexIntoPart4.Value = 2; var e2p2 = new NefsHeaderPart2Entry(); e2p2.Data0x10_Id.Value = e2p1.Id.Value; e2p2.Data0x0c_ExtractedSize.Value = NefsHeader.ChunkSize; // Item 3 has no chunks var e3p1 = new NefsHeaderPart1Entry(); e3p1.Data0x10_Id.Value = 2; e3p1.Data0x0c_IndexIntoPart4.Value = 0xFFFFFFFF; var e3p2 = new NefsHeaderPart2Entry(); e3p2.Data0x10_Id.Value = e3p1.Id.Value; e3p2.Data0x0c_ExtractedSize.Value = NefsHeader.ChunkSize; // Item 4 is a directory (extracted size == 0) var e4p1 = new NefsHeaderPart1Entry(); e4p1.Data0x10_Id.Value = 3; e4p1.Data0x0c_IndexIntoPart4.Value = 0; var e4p2 = new NefsHeaderPart2Entry(); e4p2.Data0x10_Id.Value = e4p1.Id.Value; e4p2.Data0x0c_ExtractedSize.Value = 0; // Item 5 has 3 chunks var e5p1 = new NefsHeaderPart1Entry(); e5p1.Data0x10_Id.Value = 4; e5p1.Data0x0c_IndexIntoPart4.Value = 3; var e5p2 = new NefsHeaderPart2Entry(); e5p2.Data0x10_Id.Value = e5p1.Id.Value; e5p2.Data0x0c_ExtractedSize.Value = (NefsHeader.ChunkSize * 2) + 5; var part1Items = new List <NefsHeaderPart1Entry> { e1p1, e2p1, e3p1, e4p1, e5p1, }; var part2Items = new List <NefsHeaderPart2Entry> { e1p2, e2p2, e3p2, e4p2, e5p2, }; var part1 = new NefsHeaderPart1(part1Items); var part2 = new NefsHeaderPart2(part2Items); // Setup data byte[] bytes = { // Offset 0xFF, 0xFF, // Item 1 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, // Item 2 0x21, 0x22, 0x23, 0x24, // Item 5 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, // Last four bytes 0x01, 0x02, 0x03, 0x04, }; var stream = new MemoryStream(bytes); var reader = new NefsReader(this.fileSystem); var size = (uint)28; var offset = (uint)2; // Test var part4 = await reader.ReadHeaderPart4Async(stream, offset, size, part1, part2, this.p); // Verify Assert.Equal(3, part4.EntriesByIndex.Count); Assert.Equal((uint)0x14131211, part4.EntriesByIndex[0].ChunkSizes[0]); Assert.Equal((uint)0x18171615, part4.EntriesByIndex[0].ChunkSizes[1]); Assert.Equal((uint)0x24232221, part4.EntriesByIndex[2].ChunkSizes[0]); Assert.Equal((uint)0x34333231, part4.EntriesByIndex[3].ChunkSizes[0]); Assert.Equal((uint)0x38373635, part4.EntriesByIndex[3].ChunkSizes[1]); Assert.Equal((uint)0x3C3B3A39, part4.EntriesByIndex[3].ChunkSizes[2]); }