Esempio n. 1
0
        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;
 }