public static TypeLayout GetLayout(Type type, TypeLayoutCache cache = null, bool includePaddings = true) { if (cache != null && cache.LayoutCache.TryGetValue(type, out var result)) { return(result); } try { result = DoGetLayout(); cache?.LayoutCache.TryAdd(type, result); return(result); } catch { Console.WriteLine($"Failed to create an instance of type {type}"); throw; } TypeLayout DoGetLayout() { var(size, overhead) = InspectorHelper.GetSize(type); var fieldsOffsets = InspectorHelper.GetFieldOffsets(type); var fields = new List <FieldLayoutBase>(); if (includePaddings && fieldsOffsets.Length != 0 && fieldsOffsets[0].offset != 0) { fields.Add(new Padding(fieldsOffsets[0].offset, 0)); } for (var index = 0; index < fieldsOffsets.Length; index++) { var fieldOffset = fieldsOffsets[index]; var fieldInfo = new FieldLayout(fieldOffset.offset, fieldOffset.fieldInfo); fields.Add(fieldInfo); if (includePaddings) { int nextOffsetOrSize = size; if (index != fieldsOffsets.Length - 1) { // This is not a last field. nextOffsetOrSize = fieldsOffsets[index + 1].offset; } var nextSectionOffsetCandidate = fieldInfo.Offset + fieldInfo.Size; if (nextSectionOffsetCandidate < nextOffsetOrSize) { // we have padding fields.Add(new Padding(nextOffsetOrSize - nextSectionOffsetCandidate, nextSectionOffsetCandidate)); } } } return(new TypeLayout(type, size, overhead, fields.ToArray(), cache)); } }
public FieldLayout(int offset, FieldInfo fieldInfo) : base(InspectorHelper.GetFieldSize(fieldInfo.FieldType), offset) { FieldInfo = fieldInfo; }