internal Func <int, string> CreateEntryNameDelegate(string arc_name) { var index = Sec5Opener.LookupIndex(arc_name); string base_name = Path.GetFileNameWithoutExtension(arc_name); if (null == index) { return(n => GetDefaultName(base_name, n)); } else { return (n) => { Entry entry; if (index.TryGetValue(n, out entry)) { return entry.Name; } return GetDefaultName(base_name, n); } }; }
public override ArcFile TryOpen(ArcView file) { int version = file.View.ReadInt16(4); if (version < 1 || version > 4) { return(null); } int file_count = file.View.ReadInt32(0x18); int count = file.View.ReadInt32(0x1C); if (count < file_count || !IsSaneCount(count)) { return(null); } var index = Sec5Opener.LookupIndex(file.Name); string base_name = Path.GetFileNameWithoutExtension(file.Name); Func <int, Entry> CreateEntry; if (null == index) { CreateEntry = n => GetDefaultEntry(base_name, n); } else { CreateEntry = (n) => { Entry entry; if (index.TryGetValue(n, out entry)) { return new Entry { Name = entry.Name, Type = entry.Type } } ; return(GetDefaultEntry(base_name, n)); } }; uint offset_size = version < 3 ? 4u : 8u; Func <uint, long> ReadOffset; if (version < 3) { ReadOffset = x => file.View.ReadUInt32(x); } else { ReadOffset = x => file.View.ReadInt64(x); } uint index_offset = 0x20; var dir = new List <Entry> (count); var next_offset = ReadOffset(index_offset); for (int i = 0; i < count; ++i) { var entry = CreateEntry(i); entry.Offset = next_offset; index_offset += offset_size; next_offset = (i + 1) == count ? file.MaxOffset : ReadOffset(index_offset); entry.Size = (uint)(next_offset - entry.Offset); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } return(new IarArchive(file, this, dir, version)); }