Esempio n. 1
0
        /// <summary>
        /// Deserialize a set of core objects from a BinaryReader.
        /// </summary>
        /// <param name="reader">Source stream</param>
        /// <param name="ignoreUnknownChunks">If set to true and an unknown RTTI type is encountered, read the object as
        /// an array of bytes. Otherwise, raise an exception.</param>
        public static CoreBinary FromData(BinaryReader reader, bool ignoreUnknownChunks = true)
        {
            var core = new CoreBinary();

            while (reader.StreamRemainder() > 0)
            {
#if COREFILE_DEBUG
                System.Diagnostics.Debugger.Log(0, "Info", $"Beginning chunk parse at {reader.BaseStream.Position:X}\n");
#endif

                var  entry = RTTI.DeserializeType <CoreEntry>(reader);
                var  topLevelObjectType = RTTI.GetTypeById(entry.TypeId);
                long expectedStreamPos  = reader.BaseStream.Position + entry.ChunkSize;

                if (entry.ChunkSize > reader.StreamRemainder())
                {
                    throw new InvalidDataException($"Invalid chunk size {entry.ChunkSize} was supplied in Core file at offset {entry.ChunkOffset:X}");
                }

                if (topLevelObjectType != null)
                {
                    entry.ContainedObject = RTTI.DeserializeType(reader, topLevelObjectType);
                }
                else
                {
                    if (!ignoreUnknownChunks)
                    {
                        throw new InvalidDataException($"Unknown type ID {entry.TypeId:X16} found in Core file at offset {entry.ChunkOffset:X}");
                    }

                    // Invalid or unknown chunk ID hit - create an array of bytes "object" and try to continue with the rest of the file
                    entry.ContainedObject = reader.ReadBytes(entry.ChunkSize);
                }

#if COREFILE_DEBUG
                if (reader.BaseStream.Position < expectedStreamPos)
                {
                    System.Diagnostics.Debugger.Log(0, "Warn", $"Short read of a chunk while deserializing object. {reader.BaseStream.Position} < {expectedStreamPos}. TypeId = {entry.TypeId:X16}\n");
                }
#endif

                // Check for overflows and underflows
                if (reader.BaseStream.Position > expectedStreamPos)
                {
                    throw new Exception("Read past the end of a chunk while deserializing object");
                }
                else if (reader.BaseStream.Position < expectedStreamPos)
                {
                    throw new Exception("Short read of a chunk while deserializing object");
                }

                reader.BaseStream.Position = expectedStreamPos;
                core._entries.Add(entry);
            }

            return(core);
        }
Esempio n. 2
0
        public static List <object> Load(string filePath, bool ignoreUnknownChunks = false)
        {
            var coreFileObjects = new List <object>();

            using (var reader = new BinaryReader(File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)))
            {
                while (reader.BaseStream.Position != reader.BaseStream.Length)
                {
                    //Console.WriteLine($"Beginning chunk parse at {reader.BaseStream.Position:X}");

                    var entry = RTTI.DeserializeType <Entry>(reader);

                    long currentFilePos  = reader.BaseStream.Position;
                    long expectedFilePos = currentFilePos + entry.ChunkSize;

                    if ((currentFilePos + entry.ChunkSize) > reader.StreamRemainder())
                    {
                        throw new InvalidDataException($"Invalid chunk size {entry.ChunkSize} was supplied in Core file at offset {currentFilePos:X}");
                    }

                    // TODO: This needs to be part of Entry
                    Type   topLevelObjectType = RTTI.GetTypeById(entry.TypeId);
                    object topLevelObject     = null;

                    if (topLevelObjectType != null)
                    {
                        topLevelObject = RTTI.DeserializeType(reader, topLevelObjectType);
                    }
                    else
                    {
                        if (!ignoreUnknownChunks)
                        {
                            throw new InvalidDataException($"Unknown type ID {entry.TypeId:X16} found in Core file at offset {currentFilePos:X}");
                        }

                        // Invalid or unknown chunk ID hit - create an array of bytes "object" and try to continue with the rest of the file
                        topLevelObject = reader.ReadBytes(entry.ChunkSize);
                    }

                    if (reader.BaseStream.Position > expectedFilePos)
                    {
                        throw new Exception("Read past the end of a chunk while deserializing object");
                    }
                    else if (reader.BaseStream.Position < expectedFilePos)
                    {
                        throw new Exception("Short read of a chunk while deserializing object");
                    }

                    reader.BaseStream.Position = expectedFilePos;
                    coreFileObjects.Add(topLevelObject);
                }
            }

            return(coreFileObjects);
        }
Esempio n. 3
0
        public void Deserialize(BinaryReader reader)
        {
            uint itemCount = reader.ReadUInt32();

            if (itemCount > reader.StreamRemainder())
            {
                throw new Exception("HashMap item count is out of bounds");
            }

            for (uint i = 0; i < itemCount; i++)
            {
                uint entryHash = reader.ReadUInt32();
                var  newObj    = RTTI.DeserializeType <T>(reader);

                // Hash is derived from the key member in T
                Add(entryHash, newObj);
            }
        }
Esempio n. 4
0
        public void Deserialize(BinaryReader reader)
        {
            uint itemCount = reader.ReadUInt32();

            if (itemCount > reader.StreamRemainder())
            {
                throw new Exception("HashSet item count is out of bounds");
            }

            for (uint i = 0; i < itemCount; i++)
            {
                uint entryHash = reader.ReadUInt32();
                var  newObj    = RTTI.DeserializeType <T>(reader);

                // TODO: is entryHash actually a hash?
                Add(entryHash, newObj);
            }
        }
Esempio n. 5
0
        public void Deserialize(BinaryReader reader)
        {
            uint itemCount = reader.ReadUInt32();

            if (itemCount > reader.StreamRemainder())
            {
                throw new Exception("Array item count is out of bounds");
            }

            if (itemCount == 0)
            {
                return;
            }

            if (typeof(T) == typeof(int))
            {
                var bytes = reader.ReadBytesStrict(itemCount * sizeof(int));
                var ints  = new int[itemCount];
                Buffer.BlockCopy(bytes, 0, ints, 0, bytes.Length);
                (this as List <int>).AddRange(ints);
            }
            else if (typeof(T) == typeof(byte))
            {
                // Avoid wasting time on large arrays
                (this as List <byte>).AddRange(reader.ReadBytesStrict(itemCount));
            }
            else
            {
                for (uint i = 0; i < itemCount; i++)
                {
                    var newObj = RTTI.DeserializeType <T>(reader);

                    Add(newObj);
                }
            }
        }