public A5rStream(ArcView file, A5rEntry entry) { m_file = file; m_entry = entry; m_segment = entry.Segments.GetEnumerator(); NextSegment(); }
public override ArcFile TryOpen(ArcView file) { uint id = file.View.ReadUInt32(0); if (file.View.ReadUInt32(4) != ~id) { return(null); } int count = file.View.ReadInt32(0x30); if (!IsSaneCount(count)) { return(null); } uint index_offset = file.View.ReadUInt32(0x34); if (index_offset >= file.MaxOffset) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); uint next_offset = file.View.ReadUInt32(index_offset); var segments = new A5Segment[count]; for (int i = 0; i < count; ++i) { var segment = new A5Segment { Offset = next_offset, UnpackedSize = file.View.ReadUInt32(index_offset + 4), Type = file.View.ReadByte(index_offset + 8), Compression = file.View.ReadByte(index_offset + 9), }; next_offset = file.View.ReadUInt32(index_offset + 0xA); if (next_offset > file.MaxOffset || next_offset < segment.Offset) { return(null); } segment.Size = (uint)(next_offset - segment.Offset); segments[i] = segment; index_offset += 0xA; } var dir = new List <Entry> (count); var riff_buffer = new byte[8]; for (int i = 0; i < count;) { A5rEntry entry; var segment = segments[i]; var name = string.Format("{0}#{1:D5}", base_name, i); if (0x3C == segment.Type) { Stream input = file.CreateStream(segment.Offset, segment.Size); if (3 == segment.Compression) { input = new ZLibStream(input, CompressionMode.Decompress); } using (input) { if (8 == input.Read(riff_buffer, 0, 8) && riff_buffer.AsciiEqual("RIFF")) { uint riff_size = riff_buffer.ToUInt32(4); entry = new A5rEntry { Name = name + ".wav", Type = "audio", Offset = segment.Offset, Size = 0, UnpackedSize = 0, }; var segment_list = new List <A5Segment>(); for (;;) { entry.Size += segment.Size; entry.UnpackedSize += segment.UnpackedSize; entry.IsPacked |= segment.Compression == 3; segment_list.Add(segment); ++i; if (i >= count || entry.UnpackedSize >= riff_size) { break; } segment = segments[i]; if (segment.Type != 0x3C) { break; } } entry.Segments = segment_list; dir.Add(entry); continue; } } } if (0x3E == segment.Type) { name += ".bmp"; } entry = new A5rEntry { Name = name, Type = 0x3E == segment.Type ? "image" : "", Offset = segment.Offset, Size = segment.Size, UnpackedSize = segment.UnpackedSize, IsPacked = segment.Compression == 3, Segments = new A5Segment[1] { segment }, }; dir.Add(entry); ++i; } return(new ArcFile(file, this, dir)); }