public override Stream OpenEntry(ArcFile arc, Entry entry) { ushort signature = arc.File.View.ReadUInt16(entry.Offset); // C1/D1/E1/F1 if (0x3146 != signature && 0x3143 != signature && 0x3144 != signature && 0x3145 != signature) { return(base.OpenEntry(arc, entry)); } var mkarc = arc as MkArchive; ScrambleScheme scheme = mkarc != null ? mkarc.Scheme : DefaultScheme; uint packed_size = arc.File.View.ReadUInt32(entry.Offset + 2); if (packed_size < scheme.ScrambledSize || packed_size > entry.Size - 10) { return(base.OpenEntry(arc, entry)); } Stream input; // XXX scrambling might be applicable for 'E1' signatures only if (scheme.ScrambledSize > 0) { var prefix = arc.File.View.ReadBytes(entry.Offset + 10, scheme.ScrambledSize); foreach (var pair in scheme.ScrambleMap) { byte t = prefix[pair.Item1]; prefix[pair.Item1] = prefix[pair.Item2]; prefix[pair.Item2] = t; } input = arc.File.CreateStream(entry.Offset + 10 + scheme.ScrambledSize, packed_size - scheme.ScrambledSize); input = new PrefixStream(prefix, input); } else { input = arc.File.CreateStream(entry.Offset + 10, packed_size); } input = new LzssStream(input); var header = new byte[5]; input.Read(header, 0, 5); if (Binary.AsciiEqual(header, "BPR02")) { return(new PackedStream <Bpr02Decompressor> (input)); } if (Binary.AsciiEqual(header, "BPR01")) { return(new PackedStream <Bpr01Decompressor> (input)); } return(new PrefixStream(header, input)); }
public MkArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, ScrambleScheme scheme) : base(arc, impl, dir) { Scheme = scheme; }