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); } }
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); } }