public void Read(object root) { using (this.InputReader = new BinaryReader(InputStream)) { Magic = ReadMagic(); if (Magic.format != Magic.Format.LittleEndian32 && Magic.format != Magic.Format.LittleEndian64) throw new ParsingException("Only little-endian GR2 files are supported"); Header = ReadHeader(); for (int i = 0; i < Header.numSections; i++) { var section = new Section(); section.Header = ReadSectionHeader(); Sections.Add(section); } Debug.Assert(InputStream.Position == Magic.headersSize); UncompressStream(); foreach (var section in Sections) { ReadSectionRelocations(section); } if (Magic.IsLittleEndian != BitConverter.IsLittleEndian) { // TODO: This should be done before applying relocations? foreach (var section in Sections) { ReadSectionMixedMarshallingRelocations(section); } } var rootStruct = new StructReference(); rootStruct.Offset = Sections[(int)Header.rootType.Section].Header.offsetInFile + Header.rootType.Offset; Seek(Header.rootNode); ReadStruct(rootStruct.Resolve(this), MemberType.Inline, root, null); } }
private StructInfo Register <T>(Type t, ulong nameHash) where T : struct { StructInfo info; if (_cache.TryGetValue(nameHash, out info)) { return(info); } #if WINRT || NETCORE var props = t.GetRuntimeProperties(); #else var props = t.GetProperties( BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.SetProperty); #endif List <PropertyInfo> accepted = new List <PropertyInfo>(); foreach (var prop in props) { if (_acceptedTypes.Contains(prop.PropertyType) || (prop.PropertyType.IsArray && _registeredCustomTypes.ContainsKey(prop.PropertyType.GetElementType()))) { accepted.Add(prop); } } if (accepted.Count < 0) { throw new ArgumentException("Type does not contain acceptable fields"); } info = new StructInfo(accepted.Count); var sref = new StructReference <T>(); info.Reference = sref; for (int i = 0; i < accepted.Count; i++) { #if WINRT || NETCORE var getMethod = accepted[i].GetMethod; var setMethod = accepted[i].SetMethod; #else var getMethod = accepted[i].GetGetMethod(); var setMethod = accepted[i].GetSetMethod(); #endif var propertyType = accepted[i].PropertyType; if (propertyType == typeof(string)) { var setDelegate = ExtractSetDelegate <T, string>(setMethod); var getDelegate = ExtractGetDelegate <T, string>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetString(MaxStringLenght)); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure), MaxStringLenght); } else if (propertyType == typeof(byte)) { var setDelegate = ExtractSetDelegate <T, byte>(setMethod); var getDelegate = ExtractGetDelegate <T, byte>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetByte()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(sbyte)) { var setDelegate = ExtractSetDelegate <T, sbyte>(setMethod); var getDelegate = ExtractGetDelegate <T, sbyte>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetSByte()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(short)) { var setDelegate = ExtractSetDelegate <T, short>(setMethod); var getDelegate = ExtractGetDelegate <T, short>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetShort()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(ushort)) { var setDelegate = ExtractSetDelegate <T, ushort>(setMethod); var getDelegate = ExtractGetDelegate <T, ushort>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetUShort()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(int)) { var setDelegate = ExtractSetDelegate <T, int>(setMethod); var getDelegate = ExtractGetDelegate <T, int>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetInt()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(uint)) { var setDelegate = ExtractSetDelegate <T, uint>(setMethod); var getDelegate = ExtractGetDelegate <T, uint>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetUInt()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(long)) { var setDelegate = ExtractSetDelegate <T, long>(setMethod); var getDelegate = ExtractGetDelegate <T, long>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetLong()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(ulong)) { var setDelegate = ExtractSetDelegate <T, ulong>(setMethod); var getDelegate = ExtractGetDelegate <T, ulong>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetULong()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(float)) { var setDelegate = ExtractSetDelegate <T, float>(setMethod); var getDelegate = ExtractGetDelegate <T, float>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetFloat()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(double)) { var setDelegate = ExtractSetDelegate <T, double>(setMethod); var getDelegate = ExtractGetDelegate <T, double>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetDouble()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } // Array types else if (propertyType == typeof(string[])) { var setDelegate = ExtractSetDelegate <T, string[]>(setMethod); var getDelegate = ExtractGetDelegate <T, string[]>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetStringArray(MaxStringLenght)); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure), MaxStringLenght); } else if (propertyType == typeof(byte[])) { var setDelegate = ExtractSetDelegate <T, byte[]>(setMethod); var getDelegate = ExtractGetDelegate <T, byte[]>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetBytes()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(short[])) { var setDelegate = ExtractSetDelegate <T, short[]>(setMethod); var getDelegate = ExtractGetDelegate <T, short[]>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetShortArray()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(ushort[])) { var setDelegate = ExtractSetDelegate <T, ushort[]>(setMethod); var getDelegate = ExtractGetDelegate <T, ushort[]>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetUShortArray()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(int[])) { var setDelegate = ExtractSetDelegate <T, int[]>(setMethod); var getDelegate = ExtractGetDelegate <T, int[]>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetIntArray()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(uint[])) { var setDelegate = ExtractSetDelegate <T, uint[]>(setMethod); var getDelegate = ExtractGetDelegate <T, uint[]>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetUIntArray()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(long[])) { var setDelegate = ExtractSetDelegate <T, long[]>(setMethod); var getDelegate = ExtractGetDelegate <T, long[]>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetLongArray()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(ulong[])) { var setDelegate = ExtractSetDelegate <T, ulong[]>(setMethod); var getDelegate = ExtractGetDelegate <T, ulong[]>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetULongArray()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(float[])) { var setDelegate = ExtractSetDelegate <T, float[]>(setMethod); var getDelegate = ExtractGetDelegate <T, float[]>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetFloatArray()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else if (propertyType == typeof(double[])) { var setDelegate = ExtractSetDelegate <T, double[]>(setMethod); var getDelegate = ExtractGetDelegate <T, double[]>(getMethod); info.ReadDelegate[i] = reader => setDelegate(ref sref.Structure, reader.GetDoubleArray()); info.WriteDelegate[i] = writer => writer.Put(getDelegate(ref sref.Structure)); } else { RWDelegates registeredCustomType; PropertyInfo property = accepted[i]; Type arrayType = null; if (propertyType.IsArray) { arrayType = propertyType; propertyType = arrayType.GetElementType(); } if (_registeredCustomTypes.TryGetValue(propertyType, out registeredCustomType)) { if (arrayType != null) //Array type serialize/deserialize { info.ReadDelegate[i] = reader => { ushort arrLength = reader.GetUShort(); Array arr = Array.CreateInstance(propertyType, arrLength); for (int k = 0; k < arrLength; k++) { arr.SetValue(registeredCustomType.ReadDelegate(reader), k); } object boxedStruct = sref.Structure; property.SetValue(boxedStruct, arr, null); sref.Structure = (T)boxedStruct; }; info.WriteDelegate[i] = writer => { Array arr = (Array)property.GetValue(sref.Structure, null); writer.Put((ushort)arr.Length); for (int k = 0; k < arr.Length; k++) { registeredCustomType.WriteDelegate(writer, arr.GetValue(k)); } }; } else //Simple { info.ReadDelegate[i] = reader => { object boxedStruct = sref.Structure; property.SetValue(boxedStruct, registeredCustomType.ReadDelegate(reader), null); sref.Structure = (T)boxedStruct; }; info.WriteDelegate[i] = writer => { registeredCustomType.WriteDelegate(writer, property.GetValue(sref.Structure, null)); }; } } else { throw new ArgumentException("Unregistered argument type: " + propertyType); } } } _cache.Add(nameHash, info); return(info); }
private void ReadSectionMixedMarshallingRelocations(Section section) { #if DEBUG_GR2_SERIALIZATION System.Console.WriteLine(String.Format(" ===== Mixed marshalling relocations for section at {0:X8} ===== ", section.Header.offsetInFile)); #endif InputStream.Seek(section.Header.mixedMarshallingDataOffset, SeekOrigin.Begin); for (int i = 0; i < section.Header.numMixedMarshallingData; i++) { UInt32 count = InputReader.ReadUInt32(); UInt32 offsetInSection = InputReader.ReadUInt32(); Debug.Assert(offsetInSection <= section.Header.uncompressedSize); var type = ReadSectionReference(); var typeDefn = new StructReference(); typeDefn.Offset = Sections[(int)type.Section].Header.offsetInFile + type.Offset; Seek(section, offsetInSection); MixedMarshal(count, typeDefn.Resolve(this)); #if DEBUG_GR2_SERIALIZATION System.Console.WriteLine(String.Format(" {0:X8} [{1}] --> {2}:{3:X8}", offsetInSection, count, (SectionType)type.Section, type.Offset)); #endif } }
public StructReference ReadStructReference() { var reference = new StructReference(); if (Magic.Is32Bit) reference.Offset = Reader.ReadUInt32(); else reference.Offset = Reader.ReadUInt64(); return reference; }
private void Remove(StructReference reference) { ref var removeEntity = ref entities.Buffer[reference.Index];