@@ -191,24 +191,8 @@ void OutputSerializedFile(string path)
191191
192192 var root = m_SerializedFile . GetTypeTreeRoot ( obj . Id ) ;
193193
194- if ( m_TypeFilter != null )
195- {
196- if ( m_FilterByTypeId )
197- {
198- if ( obj . TypeId != m_FilterTypeId )
199- continue ;
200- }
201- else
202- {
203- var typeName = TypeIdRegistry . GetTypeName ( obj . TypeId ) ;
204- // GetTypeName returns the id as a string when the type is unknown;
205- // fall back to the TypeTree root node for script types.
206- if ( typeName == obj . TypeId . ToString ( ) )
207- typeName = root . Type ;
208- if ( ! string . Equals ( typeName , m_TypeFilter , StringComparison . OrdinalIgnoreCase ) )
209- continue ;
210- }
211- }
194+ if ( ! ObjectMatchesTypeFilter ( obj , root ) )
195+ continue ;
212196
213197 var offset = obj . Offset ;
214198
@@ -247,7 +231,7 @@ void RecursiveDump(TypeTreeNode node, ref long offset, int level, int arrayIndex
247231 }
248232 else
249233 {
250- m_StringBuilder . Append ( ' ' , level * 2 ) ;
234+ AppendIndent ( level ) ;
251235
252236 if ( level != 0 )
253237 {
@@ -268,7 +252,6 @@ void RecursiveDump(TypeTreeNode node, ref long offset, int level, int arrayIndex
268252 m_StringBuilder . Append ( node . Type ) ;
269253 }
270254
271- // Basic data type.
272255 if ( node . IsBasicType )
273256 {
274257 m_StringBuilder . Append ( ' ' ) ;
@@ -314,7 +297,7 @@ void RecursiveDump(TypeTreeNode node, ref long offset, int level, int arrayIndex
314297 ( ( int ) node . MetaFlags & ( int ) TypeTreeMetaFlags . AnyChildUsesAlignBytes ) != 0
315298 )
316299 {
317- offset = ( offset + 3 ) & ~ ( 3 ) ;
300+ offset = AlignTo4 ( offset ) ;
318301 }
319302 }
320303
@@ -331,7 +314,7 @@ void DumpArray(TypeTreeNode node, ref long offset, int level)
331314 var arraySize = m_Reader . ReadInt32 ( offset ) ;
332315 offset += 4 ;
333316
334- m_StringBuilder . Append ( ' ' , level * 2 ) ;
317+ AppendIndent ( level ) ;
335318 m_StringBuilder . Append ( "Array" ) ;
336319 m_StringBuilder . Append ( '<' ) ;
337320 m_StringBuilder . Append ( dataNode . Type ) ;
@@ -346,7 +329,7 @@ void DumpArray(TypeTreeNode node, ref long offset, int level)
346329 {
347330 if ( dataNode . IsBasicType )
348331 {
349- m_StringBuilder . Append ( ' ' , ( level + 1 ) * 2 ) ;
332+ AppendIndent ( level + 1 ) ;
350333
351334 if ( arraySize > 256 && m_Options . SkipLargeArrays )
352335 {
@@ -449,8 +432,8 @@ bool DumpManagedReferenceData(TypeTreeNode refTypeNode, TypeTreeNode referencedT
449432 if ( refTypeNode . Children . Count < 3 )
450433 throw new Exception ( "Invalid ReferencedManagedType" ) ;
451434
452- m_StringBuilder . Append ( ' ' , level * 2 ) ;
453- m_StringBuilder . Append ( $ "rid(") ;
435+ AppendIndent ( level ) ;
436+ m_StringBuilder . Append ( "rid(" ) ;
454437 m_StringBuilder . Append ( id ) ;
455438 m_StringBuilder . Append ( ") ReferencedObject" ) ;
456439
@@ -460,28 +443,17 @@ bool DumpManagedReferenceData(TypeTreeNode refTypeNode, TypeTreeNode referencedT
460443 ++ level ;
461444
462445 var refTypeOffset = offset ;
463- var stringSize = m_Reader . ReadInt32 ( offset ) ;
464- var className = m_Reader . ReadString ( offset + 4 , stringSize ) ;
465- offset += stringSize + 4 ;
466- offset = ( offset + 3 ) & ~ ( 3 ) ;
467-
468- stringSize = m_Reader . ReadInt32 ( offset ) ;
469- var namespaceName = m_Reader . ReadString ( offset + 4 , stringSize ) ;
470- offset += stringSize + 4 ;
471- offset = ( offset + 3 ) & ~ ( 3 ) ;
472-
473- stringSize = m_Reader . ReadInt32 ( offset ) ;
474- var assemblyName = m_Reader . ReadString ( offset + 4 , stringSize ) ;
475- offset += stringSize + 4 ;
476- offset = ( offset + 3 ) & ~ ( 3 ) ;
477-
478- if ( className == "Terminus" && namespaceName == "UnityEngine.DMAT" && assemblyName == "FAKE_ASM" )
446+ var className = ReadPascalStringAndAlign ( ref offset ) ;
447+ var namespaceName = ReadPascalStringAndAlign ( ref offset ) ;
448+ var assemblyName = ReadPascalStringAndAlign ( ref offset ) ;
449+
450+ if ( IsTerminusSentinel ( className , namespaceName , assemblyName ) )
479451 return false ;
480452
481453 // Not the most efficient way, but it simplifies the code.
482454 RecursiveDump ( refTypeNode , ref refTypeOffset , level ) ;
483455
484- m_StringBuilder . Append ( ' ' , level * 2 ) ;
456+ AppendIndent ( level ) ;
485457 m_StringBuilder . Append ( referencedTypeDataNode . Name ) ;
486458 m_StringBuilder . Append ( ' ' ) ;
487459 m_StringBuilder . Append ( referencedTypeDataNode . Type ) ;
@@ -492,7 +464,7 @@ bool DumpManagedReferenceData(TypeTreeNode refTypeNode, TypeTreeNode referencedT
492464
493465 if ( id == - 1 || id == - 2 )
494466 {
495- m_StringBuilder . Append ( ' ' , level * 2 ) ;
467+ AppendIndent ( level ) ;
496468 m_StringBuilder . Append ( id == - 1 ? " unknown" : " null" ) ;
497469
498470 m_Writer . WriteLine ( m_StringBuilder ) ;
@@ -512,6 +484,38 @@ bool DumpManagedReferenceData(TypeTreeNode refTypeNode, TypeTreeNode referencedT
512484 return true ;
513485 }
514486
487+ static long AlignTo4 ( long offset ) => ( offset + 3 ) & ~ 3L ;
488+
489+ void AppendIndent ( int level ) => m_StringBuilder . Append ( ' ' , level * 2 ) ;
490+
491+ string ReadPascalStringAndAlign ( ref long offset )
492+ {
493+ var size = m_Reader . ReadInt32 ( offset ) ;
494+ var value = m_Reader . ReadString ( offset + 4 , size ) ;
495+ offset = AlignTo4 ( offset + 4 + size ) ;
496+ return value ;
497+ }
498+
499+ // Sentinel record that marks the end of the v1 ReferencedObject sequence.
500+ static bool IsTerminusSentinel ( string className , string namespaceName , string assemblyName ) =>
501+ className == "Terminus" && namespaceName == "UnityEngine.DMAT" && assemblyName == "FAKE_ASM" ;
502+
503+ bool ObjectMatchesTypeFilter ( ObjectInfo obj , TypeTreeNode root )
504+ {
505+ if ( m_TypeFilter == null )
506+ return true ;
507+
508+ if ( m_FilterByTypeId )
509+ return obj . TypeId == m_FilterTypeId ;
510+
511+ var typeName = TypeIdRegistry . GetTypeName ( obj . TypeId ) ;
512+ // GetTypeName returns the id as a string when the type is unknown;
513+ // fall back to the TypeTree root node for script types.
514+ if ( typeName == obj . TypeId . ToString ( ) )
515+ typeName = root . Type ;
516+ return string . Equals ( typeName , m_TypeFilter , StringComparison . OrdinalIgnoreCase ) ;
517+ }
518+
515519 string ReadValue ( TypeTreeNode node , long offset )
516520 {
517521 switch ( Type . GetTypeCode ( node . CSharpType ) )
@@ -557,28 +561,17 @@ string ReadValue(TypeTreeNode node, long offset)
557561
558562 Array ReadBasicTypeArray ( TypeTreeNode node , long offset , int arraySize )
559563 {
560- // Special case for boolean arrays.
564+ // bool isn't blittable into Array.CreateInstance(typeof(bool), ...) the way other basic types
565+ // are, so read into a byte buffer and convert.
561566 if ( node . CSharpType == typeof ( bool ) )
562567 {
563568 var tmpArray = new byte [ arraySize ] ;
564- var boolArray = new bool [ arraySize ] ;
565-
566569 m_Reader . ReadArray ( offset , arraySize * node . Size , tmpArray ) ;
567-
568- for ( int i = 0 ; i < arraySize ; ++ i )
569- {
570- boolArray [ i ] = tmpArray [ i ] != 0 ;
571- }
572-
573- return boolArray ;
570+ return Array . ConvertAll ( tmpArray , b => b != 0 ) ;
574571 }
575- else
576- {
577- var array = Array . CreateInstance ( node . CSharpType , arraySize ) ;
578-
579- m_Reader . ReadArray ( offset , arraySize * node . Size , array ) ;
580572
581- return array ;
582- }
573+ var array = Array . CreateInstance ( node . CSharpType , arraySize ) ;
574+ m_Reader . ReadArray ( offset , arraySize * node . Size , array ) ;
575+ return array ;
583576 }
584577}
0 commit comments