Beispiel #1
0
        /// <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));
        }
Beispiel #2
0
        /// <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]);
        }