コード例 #1
0
 /// <summary>
 /// Adds support for reading types derived from Pointer<,>
 /// </summary>
 public static LayoutManager AddPointerTypes(this LayoutManager layouts)
 {
     layouts.AddLayoutProvider(GetPointerLayout);
     return(layouts);
 }
コード例 #2
0
 public T Read <T>(ulong position)
 {
     return((T)LayoutManager.GetLayout <T>().Read(DataSource, position));
 }
コード例 #3
0
 public uint SizeOf <T>()
 {
     return(LayoutManager.GetLayout <T>().Size);
 }
コード例 #4
0
 public Reader(IAddressSpace dataSource, LayoutManager layoutManager)
 {
     DataSource    = dataSource;
     LayoutManager = layoutManager;
 }
コード例 #5
0
 public T[] ReadArray <T>(ulong position, uint elementCount)
 {
     return((T[])LayoutManager.GetArrayLayout <T[]>(elementCount).Read(DataSource, position));
 }
コード例 #6
0
 /// <summary>
 /// Adds support for parsing types derived from _requiredBaseType_ by using reflection to interpret their fields.
 /// All field types used within these types must also have layouts available from the LayoutManager.
 /// </summary>
 /// <param name="layouts"></param>
 /// <param name="enabledDefines">
 /// The set of defines that can be used to enabled optional fields decorated with the IfAttribute
 /// </param>
 /// <param name="requiredBaseType"></param>
 /// <returns></returns>
 public static LayoutManager AddReflectionTypes(this LayoutManager layouts, IEnumerable <string> enabledDefines, Type requiredBaseType)
 {
     layouts.AddLayoutProvider((type, layoutManager) => GetTStructLayout(type, layoutManager, enabledDefines, requiredBaseType));
     return(layouts);
 }
コード例 #7
0
        private static ILayout GetTStructLayout(Type tStructType, LayoutManager layoutManager, IEnumerable <string> enabledDefines, Type requiredBaseType)
        {
            if (!requiredBaseType.GetTypeInfo().IsAssignableFrom(tStructType))
            {
                return(null);
            }
            if (enabledDefines == null)
            {
                enabledDefines = Array.Empty <string>();
            }

            TypeInfo typeInfo = tStructType.GetTypeInfo();

            PackAttribute pack = typeInfo.GetCustomAttributes().Where(attr => attr is PackAttribute).Cast <PackAttribute>().SingleOrDefault();

            FieldInfo[] reflectionFields = typeInfo.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            reflectionFields = reflectionFields.OrderBy(f => f.MetadataToken).ToArray();
            reflectionFields = reflectionFields.Where(f => !f.DeclaringType.Equals(typeof(TStruct))).ToArray();
            reflectionFields = reflectionFields.Where(f => IsFieldIncludedInDefines(f, enabledDefines)).ToArray();
            TField[] tFields = new TField[reflectionFields.Length];

            uint alignCeiling          = pack?.Pack ?? 8;
            uint biggestAlignmentSoFar = 1;
            uint curOffset             = 0;

            ILayout parentLayout = null;
            Type    baseType     = tStructType.GetTypeInfo().BaseType;

            if (!baseType.Equals(typeof(TStruct)))
            {
                // Treat base type as first member.
                parentLayout = layoutManager.GetLayout(baseType);
                uint align = Math.Min(parentLayout.NaturalAlignment, alignCeiling);
                biggestAlignmentSoFar = Math.Max(biggestAlignmentSoFar, align);
                curOffset            += parentLayout.SizeAsBaseType;
            }

            // build the field list
            for (int i = 0; i < reflectionFields.Length; i++)
            {
                ILayout fieldLayout = GetFieldLayout(reflectionFields[i], layoutManager);
                uint    fieldSize   = fieldLayout.Size;
                uint    align       = fieldLayout.NaturalAlignment;
                align = Math.Min(align, alignCeiling);
                biggestAlignmentSoFar = Math.Max(biggestAlignmentSoFar, align);
                curOffset             = AlignUp(curOffset, align);
                tFields[i]            = new TField(reflectionFields[i], fieldLayout, curOffset);
                curOffset            += fieldSize;
            }
            curOffset = AlignUp(curOffset, biggestAlignmentSoFar);

            uint sizeAsBaseType = curOffset;

            if (curOffset == 0)
            {
                curOffset = 1;    // As with C++, zero-length struct not allowed (except as parent of another struct).
            }
            IField[] totalFields;
            if (parentLayout != null)
            {
                totalFields = parentLayout.Fields.Concat(tFields).ToArray();
            }
            else
            {
                totalFields = tFields;
            }
            TLayout layout = new TLayout(tStructType, curOffset, biggestAlignmentSoFar, sizeAsBaseType, totalFields);

            foreach (TField field in tFields)
            {
                field.DeclaringLayout = layout;
            }
            return(layout);
        }
コード例 #8
0
 /// <summary>
 /// Adds support for parsing types derived from TStruct. All the field types used within the TStruct types
 /// must also have layouts available from the LayoutManager.
 /// </summary>
 /// <param name="layouts">The layout manager that will hold the new layout</param>
 /// <param name="enabledDefines">
 /// The set of defines that can be used to enabled optional fields decorated with the IfAttribute
 /// </param>
 public static LayoutManager AddTStructTypes(this LayoutManager layouts, IEnumerable <string> enabledDefines)
 {
     return(AddReflectionTypes(layouts, enabledDefines, typeof(TStruct)));
 }
コード例 #9
0
 /// <summary>
 /// Adds support for parsing types derived from TStruct. All the field types used within the TStruct types
 /// must also have layouts available from the LayoutManager.
 /// </summary>
 public static LayoutManager AddTStructTypes(this LayoutManager layouts)
 {
     return(AddTStructTypes(layouts, null));
 }
コード例 #10
0
 public static LayoutManager AddEnumTypes(this LayoutManager layoutManager)
 {
     layoutManager.AddLayoutProvider(GetEnumLayout);
     return(layoutManager);
 }
コード例 #11
0
 /// <summary>
 /// Add support for parsing null terminated strings as System.String
 /// </summary>
 /// <param name="layouts">The layout manager that will hold the new layout</param>
 /// <param name="encoding">The encoding used to parse string characters. Currently only UTF8 and ASCII are supported</param>
 public static LayoutManager AddNullTerminatedString(this LayoutManager layouts, Encoding encoding)
 {
     layouts.AddLayout(new NullTerminatedStringLayout(encoding));
     return(layouts);
 }
コード例 #12
0
 /// <summary>
 /// Add support for parsing null terminated strings as System.String
 /// </summary>
 public static LayoutManager AddNullTerminatedString(this LayoutManager layouts)
 {
     return(AddNullTerminatedString(layouts, Encoding.UTF8));
 }