protected void TryReadInlineArray(FieldGuessData output, BinaryReader reader) { if (output.IsInlineStandard) { return; } if (output.InlineFields?.Length >= 1) { return; } long beforePos = reader.BaseStream.Position; STUInlineArrayInfo inline = reader.Read <STUInlineArrayInfo>(); try { Dictionary <uint, FieldGuessData> inlineFields = new Dictionary <uint, FieldGuessData>(); for (uint i = 0; i < inline.Count; ++i) { uint fieldIndex = reader.ReadUInt32(); foreach (FieldGuessData inlineField in GuessFields(InstanceFields[fieldIndex], reader)) { if (!inlineFields.ContainsKey(inlineField.Checksum)) { inlineFields[inlineField.Checksum] = inlineField; } else { if (inlineFields[inlineField.Checksum].Size < inlineField.Size) { inlineFields[inlineField.Checksum].Size = inlineField.Size; } } } } output.InlineFields = inlineFields.Values.ToArray(); output.IsInlineArray = true; } catch (Exception) { output.IsInlineArray = false; } reader.BaseStream.Position = beforePos; }
private object InitializeObjectArray(STUInstanceField field, Type type, BinaryReader reader, STUFieldAttribute element) { if (field.FieldSize == 0 && field.FieldChecksum != 0) { STUInlineArrayInfo inlineInfo = reader.Read <STUInlineArrayInfo>(); if (inlineInfo.Size > 600000) { return(null); // i feel that it's unlikley that there will be an inline with this count, exceptions if this isn't checked. } Array array = Array.CreateInstance(type, (uint)inlineInfo.Count); // if (inlineInfo.FieldListIndex == 0) return array; for (uint i = 0; i < (uint)inlineInfo.Count; ++i) { Stream.Position += element.Padding; uint fieldIndex = reader.ReadUInt32(); object instance = Activator.CreateInstance(type); if (fieldIndex >= InstanceFieldLists.Length) { continue; } array.SetValue(InitializeObject(instance, type, InstanceFields[fieldIndex], reader), i); STUInstance fieldInstance = array.GetValue(i) as STUInstance; if (fieldInstance != null) { fieldInstance.Usage = InstanceUsage.InlineArray; } HiddenInstances.Add(fieldInstance); } return(array); } if (typeof(STUInstance).IsAssignableFrom(type)) { int embedArrayOffset = reader.ReadInt32(); Metadata.Position = embedArrayOffset; STUEmbedArrayInfo embedArrayInfo = MetadataReader.Read <STUEmbedArrayInfo>(); if (embedArrayInfo.Count == 0) { return(null); } Metadata.Position = embedArrayInfo.Offset; Array array = Array.CreateInstance(type, embedArrayInfo.Count); List <int> request = new List <int>(); for (int i = 0; i < embedArrayInfo.Count; i++) { int instanceIndex = MetadataReader.ReadInt32(); MetadataReader.ReadInt32(); // Padding if (instanceIndex == -1) { return(null); } request.Add(instanceIndex); } EmbedArrayRequests[array] = request.ToArray(); return(array); } int offset = reader.ReadInt32(); Metadata.Position = offset; STUArrayInfo arrayInfo = MetadataReader.Read <STUArrayInfo>(); Metadata.Position = arrayInfo.Offset; return(GetValueArray(type, element, arrayInfo, field)); }