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 override void Save(PrimitiveWriter writer) { var present = Placeholder != null; writer.Write(present); if(present) { writer.Write(Placeholder); } }
public void Save(PrimitiveWriter writer) { writer.Write(Id); writer.Write(Message); writer.Write(SourceId); writer.Write(ThreadId ?? -1); writer.Write(Time.Ticks); writer.Write(numericLogLevel); }
public void ReuseWithNewStream(Stream stream) { postSerializationHooks.Clear(); types.Clear(); Methods.Clear(); Assemblies.Clear(); Modules.Clear(); writer = new PrimitiveWriter(stream, writer.IsBuffered); identifier.Clear(); }
public void Save(PrimitiveWriter writer) { var globalStopwatch = Stopwatch.StartNew(); var realSegmentsCount = 0; // magic writer.Write(Magic); // saving size of the memory segment writer.Write(SegmentSize); // saving size of the memory writer.Write(size); byte[][] outputBuffers = new byte[segments.Length][]; int[] outputLengths = new int[segments.Length]; Parallel.For(0, segments.Length, i => { if(segments[i] == IntPtr.Zero) { return; } Interlocked.Increment(ref realSegmentsCount); var compressedBuffer = new byte[LZ4Codec.MaximumOutputLength(SegmentSize)]; var length = LZ4Codec.Encode64(segments[i], compressedBuffer, SegmentSize); outputBuffers[i] = compressedBuffer; outputLengths[i] = length; }); for(var i = 0; i < segments.Length; i++) { if(segments[i] == IntPtr.Zero) { writer.Write(false); continue; } writer.Write(true); writer.Write(outputLengths[i]); writer.Write(outputBuffers[i], 0, outputLengths[i]); } this.NoisyLog(string.Format("{0} segments saved to stream, of which {1} had contents.", segments.Length, realSegmentsCount)); globalStopwatch.Stop(); this.NoisyLog("Memory serialization ended in {0}s.", Misc.NormalizeDecimal(globalStopwatch.Elapsed.TotalSeconds)); }
public virtual void Save(PrimitiveWriter writer) { }
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>(); }
private static void WriteObjectUsingReflection(ObjectWriter objectWriter, PrimitiveWriter primitiveWriter, object o) { objectWriter.TouchAndWriteTypeId(o.GetType()); // the primitiveWriter and parameter is not used here in fact, it is only to have // signature compatible with the generated method Helpers.InvokeAttribute(typeof(PreSerializationAttribute), o); try { var type = o.GetType(); objectWriter.currentlyWrittenTypes.Push(type); if(!objectWriter.WriteSpecialObject(o)) { objectWriter.WriteObjectsFields(o, type); } objectWriter.currentlyWrittenTypes.Pop(); } finally { Helpers.InvokeAttribute(typeof(PostSerializationAttribute), o); var postHook = Helpers.GetDelegateWithAttribute(typeof(LatePostSerializationAttribute), o); if(postHook != null) { objectWriter.postSerializationHooks.Add(postHook); } } }
/// <summary> /// Releases all resource used by the <see cref="Antmicro.Migrant.ObjectWriter"/> object. Note that this is not necessary /// if buffering is not used. /// </summary> /// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="Antmicro.Migrant.ObjectWriter"/>. The /// <see cref="Dispose"/> method leaves the <see cref="Antmicro.Migrant.ObjectWriter"/> in an unusable state. /// After calling <see cref="Dispose"/>, you must release all references to the /// <see cref="Antmicro.Migrant.ObjectWriter"/> so the garbage collector can reclaim the memory that the /// <see cref="Antmicro.Migrant.ObjectWriter"/> was occupying.</remarks> public void Dispose() { writer.Dispose(); writer = null; }
/// <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 void WriteTo(PrimitiveWriter writer) { writer.Write(Name); writer.Write(TypeAQN); }