public void FindMaps(int startPos, int lastPos, out IList <Table2D> list2D, out IList <Table3D> list3D) { this.startPos = startPos; // smallest 2D table record size is 12 bytes lastPos = Math.Min(lastPos, Size - 1 - 12); this.lastPos = lastPos; // Restricting pointers to a realistic range improves detection accuracy. // Using conservative settings here: // In Subaru ROMs at least first 8 KiB usually contain low level stuff, no maps. Table.PosMin = 8 * KiB; Table.PosMax = Size - 1; // default capacities suitable for current (MY2015 2MiB) diesel ROMs list2D = new List <Table2D> (1500); list3D = new List <Table3D> (1300); OnProgressChanged(0); this.percentDoneLastReport = 0; // records need to be 4-byte-aligned anyway // --> much faster than just ++pos, also skips a few false positives for (long pos = startPos; pos <= lastPos; pos = NextAlignedPos(pos, 4)) { stream.Position = pos; CheckProgress(pos); // try Table3D first as it contains more struct info; more info to validate = better detection Table3D info3D = Table3D.TryParseValid(this.stream); if (info3D != null) { list3D.Add(info3D); // this is often a valid next pos, already aligned pos = stream.Position; } else { // must back off stream.Position = pos; // not 3D, try 2D Table2D info2D = Table2D.TryParseValid(this.stream); if (info2D != null) { list2D.Add(info2D); // this is often a valid next pos, already aligned pos = stream.Position; } else { // nothing valid, try at next possible location pos++; } } } OnProgressChanged(100); }
/* * public IList<Table3D> FindMaps3D () * { * return FindMaps3D (0); * } * * public IList<Table3D> FindMaps3D (int startPos) * { * // should stop at EOF * return FindMaps3D (startPos, (int)fs.Length); * } * * public IList<Table3D> FindMaps3D (int startPos, int lastPos) * { * this.startPos = startPos; * lastPos = Math.Min (lastPos, (int)fs.Length); * this.lastPos = lastPos; * OnProgressChanged (0); * this.percentDoneLastReport = 0; * List<Table3D> list3D = new List<Table3D> (800); * * for (long pos = startPos; pos <= lastPos;) { * // check for end of file * if (pos >= fs.Length) * break; * fs.Position = pos; * CheckProgress (pos); * * Table3D info3D = Table3D.TryParseValid (this.fs); * if (info3D != null) { * list3D.Add (info3D); * pos = fs.Position; * } else { * // not valid, try at next possible location * pos++; * } * } * OnProgressChanged (100); * return list3D; * } */ public void FindMaps(int startPos, int lastPos, out IList <Table2D> list2D, out IList <Table3D> list3D) { this.startPos = startPos; lastPos = Math.Min(lastPos, (int)fs.Length); this.lastPos = lastPos; // Restricting pointers to a range can improve detection accuracy. // Using conservative settings here: Table.PosMin = 8 * 1024; Table.PosMax = (int)fs.Length - 1; // default capacities suitable for SH7059 diesel ROMs list2D = new List <Table2D> (800); list3D = new List <Table3D> (1000); OnProgressChanged(0); this.percentDoneLastReport = 0; for (long pos = startPos; pos <= lastPos;) { // check for end of file if (pos >= fs.Length) { break; } fs.Position = pos; CheckProgress(pos); // try Table3D first as it contains more struct info; more info to validate = better detection Table3D info3D = Table3D.TryParseValid(this.fs); if (info3D != null) { list3D.Add(info3D); pos = fs.Position; } else { // must back off fs.Position = pos; // not 3D, try 2D Table2D info2D = Table2D.TryParseValid(this.fs); if (info2D != null) { list2D.Add(info2D); pos = fs.Position; } else { // nothing valid, try at next possible location pos++; } } } OnProgressChanged(100); }