Пример #1
0
        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);
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        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
            }
        }
Пример #4
0
 public StructReference ReadStructReference()
 {
     var reference = new StructReference();
     if (Magic.Is32Bit)
         reference.Offset = Reader.ReadUInt32();
     else
         reference.Offset = Reader.ReadUInt64();
     return reference;
 }
Пример #5
0
 private void Remove(StructReference reference)
 {
     ref var removeEntity = ref entities.Buffer[reference.Index];