Beispiel #1
0
        private static void InvokeFields(BinaryReader binaryReader, object item, IList <FieldInfo> fields, List <FieldDelegateInformation> fieldsMethodInfo)
        {
            var fieldSetDataAddress = binaryReader.BaseStream.Position;

            for (var i = 0; i < fields.Count; ++i)
            {
                var field           = fields[i];
                var fieldMethodInfo = fieldsMethodInfo[i];

                binaryReader.BaseStream.Position = fieldSetDataAddress + fieldMethodInfo.StreamOffset;
                ProcessFieldInfo fieldDeletegate = (ProcessFieldInfo)fieldMethodInfo.MethodDelegate;
                fieldDeletegate(binaryReader, item, field);
            }
        }
Beispiel #2
0
        private static void ProcessFieldTypes(IList <FieldInfo> fields, out List <FieldDelegateInformation> fieldMethodInfo)
        {
            fieldMethodInfo = new List <FieldDelegateInformation>(fields.Count);
            var fieldOffset = 0;

            foreach (var field in fields)
            {
                var tagFieldAttribute = field.Attributes <TagFieldAttribute>().FirstOrDefault();

                if (tagFieldAttribute != null)
                {
                    if (tagFieldAttribute.UsesFieldOffset)
                    {
                        fieldOffset = tagFieldAttribute.Offset;
                    }
                    if (tagFieldAttribute.UsesCustomFunction)
                    {
                        fieldMethodInfo.Add(new FieldDelegateInformation(field, new ProcessFieldInfo(PostProcessField), fieldOffset));
                        fieldOffset += SizeOf(field);
                        continue;
                    }
                }
                if (field.FieldType.IsArray)
                {
                    var elementType = field.FieldType.GetElementType();
                    var elementSize = 0;
                    try
                    {
                        elementSize = SizeOf(elementType);
                    }
                    catch (ArgumentException)
                    {
                        var layoutAttribute = elementType.Attribute(typeof(LayoutAttribute)) as LayoutAttribute;
                        if (layoutAttribute != null)
                        {
                            elementSize = layoutAttribute.Size;
                        }
                    }

                    if (field.IsDefined(typeof(TagBlockFieldAttribute), false))
                    {
                        fieldMethodInfo.Add(new FieldDelegateInformation(field, new ProcessFieldInfo(ProcessTagBlockArray), fieldOffset));
                    }
                    else if (field.IsDefined(typeof(MarshalAsAttribute), false))
                    {
                        var marhsalAsAttribute = field.Attribute(typeof(MarshalAsAttribute)) as MarshalAsAttribute;
                        if (marhsalAsAttribute.Value == UnmanagedType.ByValArray)
                        {
                            var count = marhsalAsAttribute.SizeConst;

                            var basicTypes = new List <Type>()
                            {
                                typeof(sbyte),
                                typeof(byte),
                                typeof(short),
                                typeof(ushort),
                                typeof(int),
                                typeof(uint),
                                typeof(float),
                            };
                            if (basicTypes.Any(x => x == elementType))
                            {
                                fieldMethodInfo.Add(new FieldDelegateInformation(field, new ProcessFieldInfo(ReadFixedArrayField), fieldOffset));
                            }
                            else
                            {
                                var deserializeMethod = typeof(Deserializer).Method("ProcessFixedStructArray", new Type[] { typeof(BinaryReader), typeof(Object), typeof(FieldInfo) }, Flags.Static | Flags.NonPublic | Flags.Public);
                                fieldMethodInfo.Add(new FieldDelegateInformation(field, ProcessFieldInfo.CreateDelegate(typeof(ProcessFieldInfo), deserializeMethod), fieldOffset));
                            }
                        }
                        else
                        {
                            throw new MarshalDirectiveException();
                        }
                    }
                }
                else if (field.IsDefined(typeof(TagReferenceAttribute), false) && field.FieldType != typeof(TagReference))
                {
                    var deserializeMethod = typeof(Deserializer).Method("DeserializeTag", new Type[] { typeof(BinaryReader), typeof(Object), typeof(FieldInfo) }, Flags.Static | Flags.NonPublic | Flags.Public);
                    fieldMethodInfo.Add(new FieldDelegateInformation(field, ProcessFieldInfo.CreateDelegate(typeof(ProcessFieldInfo), deserializeMethod), fieldOffset));
                }
                else if (field.IsDefined(typeof(TagStructFieldAttribute), false))
                {
                    var deserializeMethod = typeof(Deserializer).Method("Deserialize", new Type[] { typeof(BinaryReader), typeof(Object), typeof(FieldInfo) }, Flags.Static | Flags.NonPublic | Flags.Public);
                    fieldMethodInfo.Add(new FieldDelegateInformation(field, ProcessFieldInfo.CreateDelegate(typeof(ProcessFieldInfo), deserializeMethod), fieldOffset));
                }
                else if (field.FieldType.IsEnum)
                {
                    var readEnumMethod = typeof(Deserializer).Method("ReadEnum", Flags.Static | Flags.NonPublic | Flags.Public);
                    fieldMethodInfo.Add(new FieldDelegateInformation(field, ProcessFieldInfo.CreateDelegate(typeof(ProcessFieldInfo), readEnumMethod), fieldOffset));
                }
                else
                {
                    var readFieldMethod = typeof(Deserializer).Method("ReadField", new Type[] { typeof(BinaryReader), typeof(Object), typeof(FieldInfo) }, Flags.Static | Flags.NonPublic | Flags.Public);
                    fieldMethodInfo.Add(new FieldDelegateInformation(field, ProcessFieldInfo.CreateDelegate(typeof(ProcessFieldInfo), readFieldMethod), fieldOffset));
                }
                fieldOffset += SizeOf(field);
            }
        }