public void ShouldPreserveReferences( [Values(ReferencePreservation.Preserve, ReferencePreservation.UseWeakReference)] ReferencePreservation referencePreservation) { var localSettings = settings.With(referencePreservation: referencePreservation); var someObject = Tuple.Create(0, 1); var otherObject = Tuple.Create(1, 2); var serializer = new Serializer(localSettings); var stream = new MemoryStream(); using (var osSerializer = serializer.ObtainOpenStreamSerializer(stream)) { osSerializer.Serialize(someObject); osSerializer.Serialize(someObject); osSerializer.Serialize(otherObject); } stream.Seek(0, SeekOrigin.Begin); using (var osDeserializer = serializer.ObtainOpenStreamDeserializer(stream)) { var objs = new object[3]; for (var i = 0; i < objs.Length; i++) { objs[i] = osDeserializer.Deserialize <Tuple <int, int> >(); } Assert.AreSame(objs[0], objs[1]); Assert.AreNotSame(objs[1], objs[2]); } }
/// <summary> /// Initializes a new instance of the <see cref="Antmicro.Migrant.ObjectWriter" /> class. /// </summary> /// <param name='stream'> /// Stream to which data will be written. /// </param> /// <param name='preSerializationCallback'> /// Callback which is called once on every unique object before its serialization. Contains this object in its only parameter. /// </param> /// <param name='postSerializationCallback'> /// Callback which is called once on every unique object after its serialization. Contains this object in its only parameter. /// </param> /// <param name='writeMethodCache'> /// Cache in which generated write methods are stored and reused between instances of <see cref="Antmicro.Migrant.ObjectWriter" />. /// Can be null if one does not want to use the cache. Note for the life of the cache you always have to provide the same /// <paramref name="surrogatesForObjects"/>. /// </param> /// <param name='surrogatesForObjects'> /// Dictionary, containing callbacks that provide surrogate for given type. Callbacks have to be of type Func<T, object> where /// typeof(T) is given type. Note that the list always have to be in sync with <paramref name="writeMethodCache"/>. /// </param> /// <param name='isGenerating'> /// True if write methods are to be generated, false if one wants to use reflection. /// </param> /// <param name = "treatCollectionAsUserObject"> /// True if collection objects are to be serialized without optimization (treated as normal user objects). /// </param> /// <param name="useBuffering"> /// True if buffering is used. False if all writes should directly go to the stream and no padding should be used. /// </param> /// <param name="referencePreservation"> /// Tells serializer how to treat object identity between the calls to <see cref="Antmicro.Migrant.ObjectWriter.WriteObject" />. /// </param> public ObjectWriter(Stream stream, Action <object> preSerializationCallback = null, Action <object> postSerializationCallback = null, IDictionary <Type, DynamicMethod> writeMethodCache = null, InheritanceAwareList <Delegate> surrogatesForObjects = null, bool isGenerating = true, bool treatCollectionAsUserObject = false, bool useBuffering = true, ReferencePreservation referencePreservation = ReferencePreservation.Preserve) { if (surrogatesForObjects == null) { surrogatesForObjects = new InheritanceAwareList <Delegate>(); } currentlyWrittenTypes = new Stack <Type>(); transientTypeCache = new Dictionary <Type, bool>(); writeMethods = new Dictionary <Type, Action <PrimitiveWriter, object> >(); postSerializationHooks = new List <Action>(); this.writeMethodCache = writeMethodCache; this.isGenerating = isGenerating; this.treatCollectionAsUserObject = treatCollectionAsUserObject; this.surrogatesForObjects = surrogatesForObjects; typeIndices = new Dictionary <TypeDescriptor, int>(); methodIndices = new Dictionary <MethodInfo, int>(); assemblyIndices = new Dictionary <AssemblyDescriptor, int>(); this.preSerializationCallback = preSerializationCallback; this.postSerializationCallback = postSerializationCallback; writer = new PrimitiveWriter(stream, useBuffering); inlineWritten = new HashSet <int>(); this.referencePreservation = referencePreservation; if (referencePreservation == ReferencePreservation.Preserve) { identifier = new ObjectIdentifier(); } }
public ObjectWriter(Stream stream, Serializer.WriteMethods writeMethods, Action <object> preSerializationCallback = null, Action <object> postSerializationCallback = null, SwapList surrogatesForObjects = null, SwapList objectsForSurrogates = null, bool treatCollectionAsUserObject = false, bool useBuffering = true, bool disableStamping = false, ReferencePreservation referencePreservation = ReferencePreservation.Preserve) { this.treatCollectionAsUserObject = treatCollectionAsUserObject; this.objectsForSurrogates = objectsForSurrogates; this.referencePreservation = referencePreservation; this.preSerializationCallback = preSerializationCallback; this.postSerializationCallback = postSerializationCallback; this.writeMethods = writeMethods; this.surrogatesForObjects = surrogatesForObjects ?? new SwapList(); parentObjects = new Dictionary <object, object>(); postSerializationHooks = new List <Action>(); types = new IdentifiedElementsDictionary <TypeDescriptor>(this); Methods = new IdentifiedElementsDictionary <MethodDescriptor>(this); Assemblies = new IdentifiedElementsDictionary <AssemblyDescriptor>(this); Modules = new IdentifiedElementsDictionary <ModuleDescriptor>(this); writer = new PrimitiveWriter(stream, useBuffering); if (referencePreservation == ReferencePreservation.Preserve) { identifier = new ObjectIdentifier(); } touchTypeMethod = disableStamping ? (Func <Type, int>)TouchAndWriteTypeIdWithSimpleStamp : TouchAndWriteTypeIdWithFullStamp; objectsWrittenInline = new HashSet <int>(); }
public ObjectReader(Stream stream, Serializer.ReadMethods readMethods, SwapList objectsForSurrogates, IDictionary <Type, Recipe> recipes, Action <object> postDeserializationCallback, bool treatCollectionAsUserObject, VersionToleranceLevel versionToleranceLevel, bool useBuffering, bool disableStamping, ReferencePreservation referencePreservation, bool forceStampVerification) { this.readMethods = readMethods; this.postDeserializationCallback = postDeserializationCallback; this.treatCollectionAsUserObject = treatCollectionAsUserObject; this.referencePreservation = referencePreservation; this.objectsForSurrogates = objectsForSurrogates; this.recipes = recipes; VersionToleranceLevel = versionToleranceLevel; types = new List <TypeDescriptor>(); Methods = new IdentifiedElementsList <MethodDescriptor>(this); Assemblies = new IdentifiedElementsList <AssemblyDescriptor>(this); Modules = new IdentifiedElementsList <ModuleDescriptor>(this); HashCodeBasedWaitingValues = new Dictionary <int, (object Dictionary, object Value)>(); latePostDeserializationHooks = new List <Action>(); reader = new PrimitiveReader(stream, useBuffering); surrogatesWhileReading = new OneToOneMap <int, object>(); readTypeMethod = disableStamping ? (Func <TypeDescriptor>)ReadSimpleTypeDescriptor : ReadFullTypeDescriptor; ForceStampVerification = forceStampVerification; }
public void ShouldReadPreservationOptionFromTheStream( [Values(ReferencePreservation.Preserve, ReferencePreservation.DoNotPreserve)] ReferencePreservation referencePreservation) { var localSettings = settings.With(referencePreservation: referencePreservation); var oppositeSettings = settings.With(referencePreservation: referencePreservation == ReferencePreservation.Preserve ? ReferencePreservation.DoNotPreserve : ReferencePreservation.Preserve); var someObject = Tuple.Create(0, 1); var serializer = new Serializer(localSettings); var stream = new MemoryStream(); using (var osSerializer = serializer.ObtainOpenStreamSerializer(stream)) { osSerializer.Serialize(someObject); osSerializer.Serialize(someObject); } stream.Seek(0, SeekOrigin.Begin); serializer = new Serializer(oppositeSettings); using (var osDeserializer = serializer.ObtainOpenStreamDeserializer(stream)) { var first = osDeserializer.Deserialize <object>(); var second = osDeserializer.Deserialize <object>(); Assert.AreEqual(first, second); Assert.AreEqual(first, someObject); } }
public ObjectWriter(Stream stream, Action<object> preSerializationCallback = null, Action<object> postSerializationCallback = null, IDictionary<Type, Action<ObjectWriter, PrimitiveWriter, object>> writeMethods = null, SwapList surrogatesForObjects = null, bool isGenerating = true, bool treatCollectionAsUserObject = false, bool useBuffering = true, bool disableStamping = false, ReferencePreservation referencePreservation = ReferencePreservation.Preserve) { if(surrogatesForObjects == null) { surrogatesForObjects = new SwapList(); } currentlyWrittenTypes = new Stack<Type>(); this.writeMethods = writeMethods ?? new Dictionary<Type, Action<ObjectWriter, PrimitiveWriter, object>>(); postSerializationHooks = new List<Action>(); this.isGenerating = isGenerating; this.treatCollectionAsUserObject = treatCollectionAsUserObject; this.surrogatesForObjects = surrogatesForObjects; types = new IdentifiedElementsDictionary<TypeDescriptor>(this); Methods = new IdentifiedElementsDictionary<MethodDescriptor>(this); Assemblies = new IdentifiedElementsDictionary<AssemblyDescriptor>(this); Modules = new IdentifiedElementsDictionary<ModuleDescriptor>(this); this.preSerializationCallback = preSerializationCallback; this.postSerializationCallback = postSerializationCallback; writer = new PrimitiveWriter(stream, useBuffering); this.referencePreservation = referencePreservation; if(referencePreservation == ReferencePreservation.Preserve) { identifier = new ObjectIdentifier(); } touchTypeMethod = disableStamping ? (Func<Type, int>)TouchAndWriteTypeIdWithSimpleStamp : TouchAndWriteTypeIdWithFullStamp; }
public ObjectReader(Stream stream, Serializer.ReadMethods readMethods, SwapList objectsForSurrogates = null, Action <object> postDeserializationCallback = null, bool treatCollectionAsUserObject = false, VersionToleranceLevel versionToleranceLevel = 0, bool useBuffering = true, bool disableStamping = false, ReferencePreservation referencePreservation = ReferencePreservation.Preserve, bool forceStampVerification = false) { this.readMethods = readMethods; this.postDeserializationCallback = postDeserializationCallback; this.treatCollectionAsUserObject = treatCollectionAsUserObject; this.referencePreservation = referencePreservation; this.objectsForSurrogates = objectsForSurrogates ?? new SwapList(); VersionToleranceLevel = versionToleranceLevel; types = new List <TypeDescriptor>(); Methods = new IdentifiedElementsList <MethodDescriptor>(this); Assemblies = new IdentifiedElementsList <AssemblyDescriptor>(this); Modules = new IdentifiedElementsList <ModuleDescriptor>(this); latePostDeserializationHooks = new List <Action>(); reader = new PrimitiveReader(stream, useBuffering); surrogatesWhileReading = new OneToOneMap <int, object>(); readTypeMethod = disableStamping ? (Func <TypeDescriptor>)ReadSimpleTypeDescriptor : ReadFullTypeDescriptor; ForceStampVerification = forceStampVerification; }
/// <summary> /// Initializes a new instance of the <see cref="Antmicro.Migrant.Customization.Settings"/> class. /// </summary> /// <param name='serializationMethod'> /// Method used for serialization. /// </param> /// <param name='deserializationMethod'> /// Method used for deserialization. /// </param> /// <param name='versionTolerance'> /// Specifies the possible level of difference between class layout when it was serialized and in the /// moment of deserialization. /// </param> /// <param name = "treatCollectionAsUserObject"> /// Specifies if collection objects are to be deserialized without optimization (treated as normal user objects). /// </param> /// <param name = "supportForISerializable"> /// Specifies whether Migrant should use GetObjectData approach for serialization. /// </param> /// <param name="useBuffering"> /// True if buffering should be used, false if writes should directly go to the stream and reads should never read /// data in advance. Disabling buffering also disables padding. /// </param> /// <param name="referencePreservation"> /// Tells serializer how to treat references between sessions of open stream serialization. /// </param> public Settings(Method serializationMethod = Method.Generated, Method deserializationMethod = Method.Generated, VersionToleranceLevel versionTolerance = 0, bool supportForISerializable = false, bool treatCollectionAsUserObject = false, bool useBuffering = true, ReferencePreservation referencePreservation = ReferencePreservation.Preserve) { SerializationMethod = serializationMethod; DeserializationMethod = deserializationMethod; VersionTolerance = versionTolerance; SupportForISerializable = supportForISerializable; TreatCollectionAsUserObject = treatCollectionAsUserObject; UseBuffering = useBuffering; ReferencePreservation = referencePreservation; }
/// <summary> /// Initializes a new instance of the <see cref="Antmicro.Migrant.Customization.Settings"/> class. /// </summary> /// <param name='serializationMethod'> /// Method used for serialization. /// </param> /// <param name='deserializationMethod'> /// Method used for deserialization. /// </param> /// <param name='versionTolerance'> /// Specifies the possible level of difference between class layout when it was serialized and in the /// moment of deserialization. /// </param> /// <param name = "treatCollectionAsUserObject"> /// Specifies if collection objects are to be deserialized without optimization (treated as normal user objects). /// </param> /// <param name = "supportForISerializable"> /// Specifies whether Migrant should use GetObjectData approach for serialization. /// </param> /// <param name="supportForIXmlSerializable"> /// Specifies whether Migrant should use xml serialization on objects implementing IXmlSerializable. /// </param> /// <param name="useBuffering"> /// True if buffering should be used, false if writes should directly go to the stream and reads should never read /// data in advance. Disabling buffering also disables padding. /// </param> /// <param name="disableTypeStamping"> /// Specifies if type stamping should be disabled in order to improve performance and limit output stream size. /// </param> /// <param name="referencePreservation"> /// Tells serializer how to treat references between sessions of open stream serialization. /// </param> public Settings(Method serializationMethod = Method.Generated, Method deserializationMethod = Method.Generated, VersionToleranceLevel versionTolerance = 0, bool supportForISerializable = false, bool supportForIXmlSerializable = false, bool treatCollectionAsUserObject = false, bool useBuffering = true, bool disableTypeStamping = false, ReferencePreservation referencePreservation = ReferencePreservation.Preserve) { SerializationMethod = serializationMethod; DeserializationMethod = deserializationMethod; VersionTolerance = versionTolerance; SupportForISerializable = supportForISerializable; SupportForIXmlSerializable = supportForIXmlSerializable; TreatCollectionAsUserObject = treatCollectionAsUserObject; UseBuffering = useBuffering; ReferencePreservation = referencePreservation; DisableTypeStamping = disableTypeStamping; }
/// <summary> /// Initializes a new instance of the <see cref="Antmicro.Migrant.Customization.Settings"/> class. /// </summary> /// <param name='serializationMethod'> /// Method used for serialization. /// </param> /// <param name='deserializationMethod'> /// Method used for deserialization. /// </param> /// <param name='versionTolerance'> /// Specifies the possible level of difference between class layout when it was serialized and in the /// moment of deserialization. /// </param> /// <param name = "treatCollectionAsUserObject"> /// Specifies if collection objects are to be deserialized without optimization (treated as normal user objects). /// </param> /// <param name = "supportForISerializable"> /// Specifies whether Migrant should use GetObjectData approach for serialization. /// </param> /// <param name="useBuffering"> /// True if buffering should be used, false if writes should directly go to the stream and reads should never read /// data in advance. Disabling buffering also disables padding. /// </param> /// <param name="referencePreservation"> /// Tells serializer how to treat references between sessions of open stream serialization. /// </param> public Settings With(Method serializationMethod = Method.Generated, Method deserializationMethod = Method.Generated, VersionToleranceLevel versionTolerance = 0, bool supportForISerializable = false, bool treatCollectionAsUserObject = false, bool useBuffering = true, ReferencePreservation referencePreservation = ReferencePreservation.Preserve) { var result = new Settings { SerializationMethod = serializationMethod, DeserializationMethod = deserializationMethod, VersionTolerance = versionTolerance, SupportForISerializable = supportForISerializable, TreatCollectionAsUserObject = treatCollectionAsUserObject, UseBuffering = useBuffering, ReferencePreservation = referencePreservation }; return(result); }
/// <summary> /// Initializes a new instance of the <see cref="Antmicro.Migrant.ObjectReader" /> class. /// </summary> /// <param name='stream'> /// Stream from which objects will be read. /// </param> /// <param name='objectsForSurrogates'> /// Dictionary, containing callbacks that provide objects for given type of surrogate. Callbacks have to be of type Func<T, object> where /// typeof(T) is type of surrogate. /// </param> /// <param name='postDeserializationCallback'> /// Callback which will be called after deserialization of every unique object. Deserialized /// object is given in the callback's only parameter. /// </param> /// <param name='readMethods'> /// Cache in which generated read methods are stored and reused between instances of <see cref="Antmicro.Migrant.ObjectReader" />. /// Can be null if one does not want to use the cache. /// </param> /// <param name='isGenerating'> /// True if read methods are to be generated, false if one wants to use reflection. /// </param> /// <param name = "treatCollectionAsUserObject"> /// True if collection objects are to be deserialized without optimization (treated as normal user objects). /// </param> /// <param name="versionToleranceLevel"> /// Describes the tolerance level of this reader when handling discrepancies in type description (new or missing fields, etc.). /// </param> /// <param name="useBuffering"> /// True if buffering was used with the corresponding ObjectWriter or false otherwise - i.e. when no padding and buffering is used. /// </param> /// <param name="referencePreservation"> /// Tells deserializer whether open stream serialization preserved objects identieties between serialization. Note that this option should /// be consistent with what was used during serialization. /// </param> public ObjectReader(Stream stream, InheritanceAwareList <Delegate> objectsForSurrogates = null, Action <object> postDeserializationCallback = null, IDictionary <Type, DynamicMethod> readMethods = null, bool isGenerating = false, bool treatCollectionAsUserObject = false, VersionToleranceLevel versionToleranceLevel = 0, bool useBuffering = true, ReferencePreservation referencePreservation = ReferencePreservation.Preserve) { if (objectsForSurrogates == null) { objectsForSurrogates = new InheritanceAwareList <Delegate>(); } this.objectsForSurrogates = objectsForSurrogates; this.readMethodsCache = readMethods ?? new Dictionary <Type, DynamicMethod>(); this.useGeneratedDeserialization = isGenerating; typeList = new List <Type>(); methodList = new List <MethodInfo>(); postDeserializationHooks = new List <Action>(); this.postDeserializationCallback = postDeserializationCallback; this.treatCollectionAsUserObject = treatCollectionAsUserObject; delegatesCache = new Dictionary <Type, Func <int, object> >(); reader = new PrimitiveReader(stream, useBuffering); stamper = new TypeStampReader(reader, versionToleranceLevel); this.referencePreservation = referencePreservation; }
/// <summary> /// Initializes a new instance of the <see cref="Antmicro.Migrant.Customization.Settings"/> class. /// </summary> /// <param name='serializationMethod'> /// Method used for serialization. /// </param> /// <param name='deserializationMethod'> /// Method used for deserialization. /// </param> /// <param name='versionTolerance'> /// Specifies the possible level of difference between class layout when it was serialized and in the /// moment of deserialization. /// </param> /// <param name = "treatCollectionAsUserObject"> /// Specifies if collection objects are to be deserialized without optimization (treated as normal user objects). /// </param> /// <param name = "supportForISerializable"> /// Specifies whether Migrant should use GetObjectData approach for serialization. /// </param> /// <param name="useBuffering"> /// True if buffering should be used, false if writes should directly go to the stream and reads should never read /// data in advance. Disabling buffering also disables padding. /// </param> /// <param name="disableTypeStamping"> /// Specifies if type stamping should be disabled in order to improve performance and limit output stream size. /// </param> /// <param name="referencePreservation"> /// Tells serializer how to treat references between sessions of open stream serialization. /// </param> public Settings With(Method serializationMethod = Method.Generated, Method deserializationMethod = Method.Generated, VersionToleranceLevel versionTolerance = 0, bool supportForISerializable = false, bool treatCollectionAsUserObject = false, bool useBuffering = true, bool disableTypeStamping = false, ReferencePreservation referencePreservation = ReferencePreservation.Preserve) { var result = new Settings { SerializationMethod = serializationMethod, DeserializationMethod = deserializationMethod, VersionTolerance = versionTolerance, SupportForISerializable = supportForISerializable, TreatCollectionAsUserObject = treatCollectionAsUserObject, UseBuffering = useBuffering, DisableTypeStamping = disableTypeStamping, ReferencePreservation = referencePreservation }; return result; }
public ObjectWriter(Stream stream, Serializer.WriteMethods writeMethods, Action<object> preSerializationCallback = null, Action<object> postSerializationCallback = null, SwapList surrogatesForObjects = null, SwapList objectsForSurrogates = null, bool treatCollectionAsUserObject = false, bool useBuffering = true, bool disableStamping = false, ReferencePreservation referencePreservation = ReferencePreservation.Preserve) { this.treatCollectionAsUserObject = treatCollectionAsUserObject; this.objectsForSurrogates = objectsForSurrogates; this.referencePreservation = referencePreservation; this.preSerializationCallback = preSerializationCallback; this.postSerializationCallback = postSerializationCallback; this.writeMethods = writeMethods; this.surrogatesForObjects = surrogatesForObjects ?? new SwapList(); parentObjects = new Dictionary<object, object>(); postSerializationHooks = new List<Action>(); types = new IdentifiedElementsDictionary<TypeDescriptor>(this); Methods = new IdentifiedElementsDictionary<MethodDescriptor>(this); Assemblies = new IdentifiedElementsDictionary<AssemblyDescriptor>(this); Modules = new IdentifiedElementsDictionary<ModuleDescriptor>(this); writer = new PrimitiveWriter(stream, useBuffering); if(referencePreservation == ReferencePreservation.Preserve) { identifier = new ObjectIdentifier(); } touchTypeMethod = disableStamping ? (Func<Type, int>)TouchAndWriteTypeIdWithSimpleStamp : TouchAndWriteTypeIdWithFullStamp; objectsWrittenInline = new HashSet<int>(); }
/// <summary> /// Initializes a new instance of the <see cref="Antmicro.Migrant.Customization.Settings"/> class. /// </summary> /// <param name='serializationMethod'> /// Method used for serialization. /// </param> /// <param name='deserializationMethod'> /// Method used for deserialization. /// </param> /// <param name='versionTolerance'> /// Specifies the possible level of difference between class layout when it was serialized and in the /// moment of deserialization. /// </param> /// <param name = "treatCollectionAsUserObject"> /// Specifies if collection objects are to be deserialized without optimization (treated as normal user objects). /// </param> /// <param name = "supportForISerializable"> /// Specifies whether Migrant should use GetObjectData approach for serialization. /// </param> /// <param name="useBuffering"> /// True if buffering should be used, false if writes should directly go to the stream and reads should never read /// data in advance. Disabling buffering also disables padding. /// </param> /// <param name="disableTypeStamping"> /// Specifies if type stamping should be disabled in order to improve performance and limit output stream size. /// </param> /// <param name="referencePreservation"> /// Tells serializer how to treat references between sessions of open stream serialization. /// </param> public Settings With(Method? serializationMethod = null, Method? deserializationMethod = null, VersionToleranceLevel? versionTolerance = null, bool? supportForISerializable = null, bool? treatCollectionAsUserObject = null, bool? useBuffering = null, bool? disableTypeStamping = null, ReferencePreservation? referencePreservation = null) { var result = new Settings { SerializationMethod = serializationMethod ?? SerializationMethod, DeserializationMethod = deserializationMethod ?? DeserializationMethod, VersionTolerance = versionTolerance ?? VersionTolerance, SupportForISerializable = supportForISerializable ?? SupportForISerializable, TreatCollectionAsUserObject = treatCollectionAsUserObject ?? TreatCollectionAsUserObject, UseBuffering = useBuffering ?? UseBuffering, DisableTypeStamping = disableTypeStamping ?? DisableTypeStamping, ReferencePreservation = referencePreservation ?? ReferencePreservation }; return result; }
/// <summary> /// Initializes a new instance of the <see cref="Antmicro.Migrant.ObjectWriter" /> class. /// </summary> /// <param name='stream'> /// Stream to which data will be written. /// </param> /// <param name='preSerializationCallback'> /// Callback which is called once on every unique object before its serialization. Contains this object in its only parameter. /// </param> /// <param name='postSerializationCallback'> /// Callback which is called once on every unique object after its serialization. Contains this object in its only parameter. /// </param> /// <param name='writeMethodCache'> /// Cache in which generated write methods are stored and reused between instances of <see cref="Antmicro.Migrant.ObjectWriter" />. /// Can be null if one does not want to use the cache. Note for the life of the cache you always have to provide the same /// <paramref name="surrogatesForObjects"/>. /// </param> /// <param name='surrogatesForObjects'> /// Dictionary, containing callbacks that provide surrogate for given type. Callbacks have to be of type Func<T, object> where /// typeof(T) is given type. Note that the list always have to be in sync with <paramref name="writeMethodCache"/>. /// </param> /// <param name='isGenerating'> /// True if write methods are to be generated, false if one wants to use reflection. /// </param> /// <param name = "treatCollectionAsUserObject"> /// True if collection objects are to be serialized without optimization (treated as normal user objects). /// </param> /// <param name="useBuffering"> /// True if buffering is used. False if all writes should directly go to the stream and no padding should be used. /// </param> /// <param name="referencePreservation"> /// Tells serializer how to treat object identity between the calls to <see cref="Antmicro.Migrant.ObjectWriter.WriteObject" />. /// </param> public ObjectWriter(Stream stream, Action<object> preSerializationCallback = null, Action<object> postSerializationCallback = null, IDictionary<Type, DynamicMethod> writeMethodCache = null, InheritanceAwareList<Delegate> surrogatesForObjects = null, bool isGenerating = true, bool treatCollectionAsUserObject = false, bool useBuffering = true, ReferencePreservation referencePreservation = ReferencePreservation.Preserve) { if(surrogatesForObjects == null) { surrogatesForObjects = new InheritanceAwareList<Delegate>(); } currentlyWrittenTypes = new Stack<Type>(); transientTypeCache = new Dictionary<Type, bool>(); writeMethods = new Dictionary<Type, Action<PrimitiveWriter, object>>(); postSerializationHooks = new List<Action>(); this.writeMethodCache = writeMethodCache; this.isGenerating = isGenerating; this.treatCollectionAsUserObject = treatCollectionAsUserObject; this.surrogatesForObjects = surrogatesForObjects; typeIndices = new Dictionary<TypeDescriptor, int>(); methodIndices = new Dictionary<MethodInfo, int>(); assemblyIndices = new Dictionary<AssemblyDescriptor, int>(); this.preSerializationCallback = preSerializationCallback; this.postSerializationCallback = postSerializationCallback; writer = new PrimitiveWriter(stream, useBuffering); inlineWritten = new HashSet<int>(); this.referencePreservation = referencePreservation; if(referencePreservation == ReferencePreservation.Preserve) { identifier = new ObjectIdentifier(); } }