|
1 | 1 | using System; |
2 | 2 | using System.IO; |
| 3 | +using ObjectInfo = UnityDataTools.FileSystem.ObjectInfo; |
3 | 4 |
|
4 | 5 | namespace UnityDataTools.Analyzer.Util; |
5 | 6 |
|
@@ -166,6 +167,12 @@ public class SerializedFileMetadata |
166 | 167 | /// Empty array for files with version < 20. |
167 | 168 | /// </summary> |
168 | 169 | public TypeTreeInfo[] SerializedReferenceTypeTrees { get; set; } |
| 170 | + |
| 171 | + /// <summary> |
| 172 | + /// List of all objects recorded in the file's object table. |
| 173 | + /// Null until the metadata section has been parsed. |
| 174 | + /// </summary> |
| 175 | + public ObjectInfo[] ObjectList { get; set; } |
169 | 176 | } |
170 | 177 |
|
171 | 178 | /// <summary> |
@@ -567,28 +574,41 @@ private static void ParseExtendedMetadata(BinaryReader reader, SerializedFileInf |
567 | 574 | typeTrees[i] = ReadTypeEntry(reader, version, swap, isRefType: false, enableTypeTree); |
568 | 575 | metadata.TypeTrees = typeTrees; |
569 | 576 |
|
570 | | - // m_RefTypes (version >= 20) is not located immediately after m_Types. |
571 | | - // It appears at the end of the metadata section, after the object list, |
572 | | - // script type list, and externals list. We must skip those three sections. |
573 | | - if (version < SupportsRefObjectVersion) |
574 | | - return; |
575 | | - |
576 | | - // --- Skip the object list --- |
| 577 | + // --- Object list --- |
577 | 578 | // Per-object layout (version >= 19): |
578 | 579 | // [4-byte alignment relative to metadata start] |
579 | 580 | // [int64 fileID] |
580 | 581 | // [uint32 byteStart] or [uint64 byteStart] (version >= 22) |
581 | 582 | // [uint32 byteSize] |
582 | 583 | // [uint32 typeID] |
583 | 584 | int objectCount = BinaryFileHelper.ReadInt32(reader, swap); |
| 585 | + var objectList = new ObjectInfo[objectCount]; |
584 | 586 | for (int i = 0; i < objectCount; i++) |
585 | 587 | { |
586 | 588 | BinaryFileHelper.AlignTo4(stream, metadataOffset); |
587 | | - stream.Seek(8, SeekOrigin.Current); // int64 fileID |
588 | | - stream.Seek(version >= LargeFilesSupportVersion ? 8 : 4, SeekOrigin.Current); // byteStart |
589 | | - stream.Seek(4, SeekOrigin.Current); // uint32 byteSize |
590 | | - stream.Seek(4, SeekOrigin.Current); // uint32 typeID |
| 589 | + long fileID = BinaryFileHelper.ReadInt64(reader, swap); |
| 590 | + // byteStart is relative to the data section; add DataOffset to get the absolute file offset, |
| 591 | + // matching the behaviour of the native DLL which returns the absolute offset in ObjectInfo.Offset. |
| 592 | + long byteStart = version >= LargeFilesSupportVersion |
| 593 | + ? (long)BinaryFileHelper.ReadUInt64(reader, swap) |
| 594 | + : BinaryFileHelper.ReadUInt32(reader, swap); |
| 595 | + byteStart += (long)headerInfo.DataOffset; |
| 596 | + long byteSize = BinaryFileHelper.ReadUInt32(reader, swap); |
| 597 | + // typeIndex is a 0-based index into the m_Types array, not the persistent type ID. |
| 598 | + // Resolve it to the persistent type ID to match the behaviour of the native DLL. |
| 599 | + int typeIndex = BinaryFileHelper.ReadInt32(reader, swap); |
| 600 | + int persistentTypeID = (typeIndex >= 0 && typeIndex < typeTrees.Length) |
| 601 | + ? typeTrees[typeIndex].PersistentTypeID |
| 602 | + : typeIndex; |
| 603 | + objectList[i] = new ObjectInfo(fileID, byteStart, byteSize, persistentTypeID); |
591 | 604 | } |
| 605 | + metadata.ObjectList = objectList; |
| 606 | + |
| 607 | + // m_RefTypes (version >= 20) is not located immediately after m_Types. |
| 608 | + // It appears at the end of the metadata section, after the object list, |
| 609 | + // script type list, and externals list. We must skip those three sections. |
| 610 | + if (version < SupportsRefObjectVersion) |
| 611 | + return; |
592 | 612 |
|
593 | 613 | // --- Skip the script type list --- |
594 | 614 | // Per-entry layout (version >= 14, applies to all our versions): |
|
0 commit comments