Gives consecutive, unique identifiers for presented objects during its lifetime. Can also be used to retrive an object by its ID.
The first returned id is 0. For given object, if it was presented to the class earlier, the previously returned identificator is returned again. Note that the objects presented to class are remembered, so they will not be collected until the ObjectIdentifier lives.
コード例 #1
0
        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;
        }
コード例 #2
0
ファイル: ObjectWriter.cs プロジェクト: antmicro/Migrant
        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>();
        }
コード例 #3
0
ファイル: ObjectWriter.cs プロジェクト: antmicro/Migrant
        private void PrepareForNextWrite()
        {
            objectsWrittenInline.Clear();
            parentObjects.Clear();

            if(referencePreservation == ReferencePreservation.UseWeakReference)
            {
                identifierContext = identifier.GetContext();
            }
            if(referencePreservation != ReferencePreservation.Preserve)
            {
                identifier = null;
            }
        }
コード例 #4
0
ファイル: ObjectWriter.cs プロジェクト: antmicro/Migrant
        public void WriteObject(object o)
        {
            if(o == null || Helpers.IsTransient(o.GetType()))
            {
                throw new ArgumentException("Cannot write a null object or a transient object.");
            }
            if(referencePreservation != ReferencePreservation.Preserve)
            {
                identifier = identifierContext == null ? new ObjectIdentifier() : new ObjectIdentifier(identifierContext);
                identifierContext = null;
            }

            try
            {
                var writtenBefore = identifier.Count;
                writeMethods.writeReferenceMethodsProvider.GetOrCreate(typeof(object))(this, o);

                if(writtenBefore != identifier.Count)
                {
                    var refId = identifier.GetId(o);
                    do
                    {
                        if(!objectsWrittenInline.Contains(refId))
                        {
                            var obj = identifier.GetObject(refId);
                            writer.Write(refId);
                            InvokeCallbacksAndExecute(obj, WriteObjectInner);
                        }

                        refId++;
                    }
                    while(identifier.Count > refId);
                }
            }
            finally
            {
                for(var i = identifier.Count - 1; i >= 0; i--)
                {
                    Completed(identifier.GetObject(i));
                }

                foreach(var postHook in postSerializationHooks)
                {
                    postHook();
                }
                PrepareForNextWrite();
            }
        }
コード例 #5
0
ファイル: ObjectWriter.cs プロジェクト: rogeralsing/Migrant
 private void PrepareForNextWrite()
 {
     if(referencePreservation != ReferencePreservation.DoNotPreserve)
     {
         identifierCountPreviousSession = identifier.Count;
     }
     else
     {
         inlineWritten.Clear();
     }
     currentlyWrittenTypes.Clear();
     if(referencePreservation == ReferencePreservation.UseWeakReference)
     {
         identifierContext = identifier.GetContext();
     }
     if(referencePreservation != ReferencePreservation.Preserve)
     {
         identifier = null;
     }
 }
コード例 #6
0
ファイル: ObjectWriter.cs プロジェクト: rogeralsing/Migrant
        /// <summary>
        /// Writes the given object along with the ones referenced by it.
        /// </summary>
        /// <param name='o'>
        /// The object to write.
        /// </param>
        public void WriteObject(object o)
        {
            if(o == null || Helpers.CheckTransientNoCache(o.GetType()))
            {
                throw new ArgumentException("Cannot write a null object or a transient object.");
            }
            objectsWrittenThisSession = 0;
            if(referencePreservation != ReferencePreservation.Preserve)
            {
                identifier = identifierContext == null ? new ObjectIdentifier() : new ObjectIdentifier(identifierContext);
                identifierContext = null;
            }
            var identifiersCount = identifier.Count;
            identifier.GetId(o);
            var firstObjectIsNew = identifiersCount != identifier.Count;

            try
            {
                // first object is always written
                InvokeCallbacksAndWriteObject(o);
                if(firstObjectIsNew)
                {
                    objectsWrittenThisSession++;
                }
                while(identifier.Count - identifierCountPreviousSession > objectsWrittenThisSession)
                {
                    if(!inlineWritten.Contains(identifierCountPreviousSession + objectsWrittenThisSession))
                    {
                        InvokeCallbacksAndWriteObject(identifier[identifierCountPreviousSession + objectsWrittenThisSession]);
                    }
                    objectsWrittenThisSession++;
                }
            }
            finally
            {
                foreach(var postHook in postSerializationHooks)
                {
                    postHook();
                }
                PrepareForNextWrite();
            }
        }
コード例 #7
0
ファイル: ObjectWriter.cs プロジェクト: rogeralsing/Migrant
 /// <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&lt;T, object&gt; 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();
     }
 }