/// <summary> /// Writes a reference to another savable output that is external to this output. Externals /// may or may not be written separately, such as there exists no writer for the savable type. /// In this case, the external is in fact written as a regular savable object to the same stream. /// </summary> /// <typeparam name="T">Type of object to write</typeparam> /// <param name="name">Name of the value</param> /// <param name="value">Savable object</param> public void WriteExternal <T>(String name, T value) where T : ISavable { if (value == null) { _output.Write(NULL_OBJECT); return; } else { if (!(value is T)) { throw new InvalidCastException("Cannot write savable as the requested type."); } if (DetectRecurse(value)) { throw new InvalidOperationException("Cyclic reference detected."); } _output.Write(A_OK); } if (_writeExternals) { Type type = typeof(T); ExternalWriter writer = FindSuitableWriter(type); //Possible to remove the default loader, so skip externalization if this is the case if (writer != null) { //Writer should supply the reference that we'll write ourselves ExternalReference extReference = writer.Write(name, value, type); if (extReference != null) { _output.Write(true); WriteSavable <ExternalReference>(null, extReference); return; } } } //Fall back, either not writing externals -or- couldn't find a suitable writer _output.Write(false); this.Write(null, value.GetType().AssemblyQualifiedName); AddRecurse(value); value.Write(this); RemoveRecurse(value); }
/// <summary> /// Registers an external writer to be used by the savable writer when an external /// reference is asked to be written for a specific savable type. /// </summary> /// <param name="writer">External reader</param> public void RegisterExternalWriter(ExternalWriter writer) { _externalWriters[writer.TargetType] = writer; writer.Initialize(this); }