private T DeserialiseNewObject <T>(MfcClass mfcClass) where T : MfcObject { MfcObject newObject = mfcClass.CreateNewObject <MfcObject>(); _loadedObjects.Add(newObject); newObject.Deserialise(this); return((T)newObject); }
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); }
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); }
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)); }
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); }
internal ushort GetSerialisedClassIndexHack <T>(T item) where T : MfcObject { MfcClass mfcClass = _classRegistry.GetMfcClass(item.GetType()); return((ushort)(_loadedClasses.IndexOf(mfcClass) | ClassTag)); }
/// <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)); }