示例#1
0
        private T DeserialiseNewObject <T>(MfcClass mfcClass) where T : MfcObject
        {
            MfcObject newObject = mfcClass.CreateNewObject <MfcObject>();

            _loadedObjects.Add(newObject);
            newObject.Deserialise(this);
            return((T)newObject);
        }
示例#2
0
        public void SerialiseObject(MfcObject mfcObject)
        {
            if (mfcObject == null)
            {
                _stream.Write((ushort)NullTag);
                return;
            }

            int prevObjectIndex = _loadedObjects.IndexOf(mfcObject);

            if (prevObjectIndex >= 0)
            {
                // We have already serialised this object and do not need to do so again
                if (prevObjectIndex >= BigObjectTag)
                {
                    throw new NotImplementedException("Object count >= 0x7fff not yet supported");
                }
                _stream.Write((ushort)prevObjectIndex);
                return;
            }

            // A new object, possibly with a new class
            _loadedObjects.Add(mfcObject);
            MfcClass mfcClass       = _classRegistry.GetMfcClass(mfcObject.GetType());
            int      prevClassIndex = _loadedClasses.IndexOf(mfcClass);

            if (prevClassIndex <= 0)
            {
                // A new class
                _loadedClasses.Add(mfcClass);
                _stream.Write((ushort)NewClassTag);
                _stream.Write((ushort)mfcClass.SchemaVersion);
                _stream.Write((ushort)mfcClass.Name.Length);
                _stream.WriteAsciiString(mfcClass.Name);
            }
            else
            {
                // A previously written class
                _stream.Write((ushort)(prevClassIndex | ClassTag));
            }

            mfcObject.Serialise(this);
        }
示例#3
0
        private MfcClass ReadNewClass()
        {
            ushort schemaVersion   = _stream.ReadUInt16();
            ushort classNameLength = _stream.ReadUInt16();
            string className       = _stream.ReadAsciiString(classNameLength);

            MfcClass mfcClass = _classRegistry.GetMfcClass(className);

            if (mfcClass == null)
            {
                throw new InvalidDataException("No registered class for MfcObject " + className);
            }
            if (mfcClass.SchemaVersion != schemaVersion)
            {
                throw new InvalidDataException("Schema mismatch: file = " + schemaVersion + ", registered = " + mfcClass.SchemaVersion);
            }

            return(mfcClass);
        }
示例#4
0
        public T DeserialiseObject <T>() where T : MfcObject
        {
            uint     objectTag;
            MfcClass mfcClass = ReadClass(out objectTag);

            if (mfcClass == null)
            {
                // An object we've already loaded
                if (objectTag > _loadedObjects.Count)
                {
                    throw new InvalidDataException("Got an object tag larger than the count of loaded objects: " + objectTag);
                }

                return((T)_loadedObjects[(int)objectTag]);
            }

            // An object we haven't yet loaded.  Create a new instance and deserialise it.
            // Make sure to add it to the list of loaded objects before deserialising in
            // case it has (possibly indirect) references to itself.
            return(DeserialiseNewObject <T>(mfcClass));
        }
示例#5
0
        public string PeekNextObjectType()
        {
            string nextObjectType;
            var    savedPosition = _stream.BaseStream.Position;

            uint     objectTag;
            MfcClass mfcClass = ReadClass(out objectTag);

            if (mfcClass == null)
            {
                if (objectTag > _loadedObjects.Count)
                {
                    throw new InvalidDataException("Got an object tag larger than the count of loaded objects: " + objectTag);
                }
                nextObjectType = _loadedObjects[(int)objectTag].GetType().Name;
            }
            else
            {
                nextObjectType = mfcClass.Name;
            }

            _stream.BaseStream.Position = savedPosition;
            return(nextObjectType);
        }
示例#6
0
        internal ushort GetSerialisedClassIndexHack <T>(T item) where T : MfcObject
        {
            MfcClass mfcClass = _classRegistry.GetMfcClass(item.GetType());

            return((ushort)(_loadedClasses.IndexOf(mfcClass) | ClassTag));
        }
示例#7
0
        /// <summary>
        /// Deserialises an object of type T without reading in the header.
        /// This implies it must be a new object and not one that has already
        /// been loaded since there is no object tag to reference the loaded list.
        /// </summary>
        public T DeserialiseObjectNoHeader <T>() where T : MfcObject
        {
            MfcClass mfcClass = _classRegistry.GetMfcClass(typeof(T));

            return(DeserialiseNewObject <T>(mfcClass));
        }