using System;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;
namespace System.Runtime.Serialization
{
/// Keeps track of objects as they are deserialized.
// Token: 0x02000483 RID: 1155
[ComVisible(true)]
public class ObjectManager
{
/// Initializes a new instance of the class.
/// The surrogate selector to use. The determines the correct surrogate to use when deserializing objects of a given type. At deserialization time, the surrogate selector creates a new instance of the object from the information transmitted on the stream.
/// The streaming context. The is not used by ObjectManager, but is passed as a parameter to any objects implementing or having a . These objects can take specific actions depending on the source of the information to deserialize.
/// The caller does not have the required permission.
// Token: 0x06002C09 RID: 11273 RVA: 0x00090CEC File Offset: 0x0008EEEC
public ObjectManager(ISurrogateSelector selector, StreamingContext context)
{
this._selector = selector;
this._context = context;
}
/// Performs all the recorded fixups.
/// A fixup was not successfully completed.
// Token: 0x06002C0A RID: 11274 RVA: 0x00090D24 File Offset: 0x0008EF24
public virtual void DoFixups()
{
this._finalFixup = true;
try
{
if (this._registeredObjectsCount < this._objectRecords.Count)
{
throw new SerializationException("There are some fixups that refer to objects that have not been registered");
}
ObjectRecord lastObjectRecord = this._lastObjectRecord;
bool flag = true;
ObjectRecord objectRecord2;
for (ObjectRecord objectRecord = this._objectRecordChain; objectRecord != null; objectRecord = objectRecord2)
{
bool flag2 = !objectRecord.IsUnsolvedObjectReference || !flag;
if (flag2)
{
flag2 = objectRecord.DoFixups(true, this, true);
}
if (flag2)
{
flag2 = objectRecord.LoadData(this, this._selector, this._context);
}
if (flag2)
{
if (objectRecord.OriginalObject is IDeserializationCallback)
{
this._deserializedRecords.Add(objectRecord);
}
SerializationCallbacks serializationCallbacks = SerializationCallbacks.GetSerializationCallbacks(objectRecord.OriginalObject.GetType());
if (serializationCallbacks.HasDeserializedCallbacks)
{
this._onDeserializedCallbackRecords.Add(objectRecord);
}
objectRecord2 = objectRecord.Next;
}
else
{
if (objectRecord.ObjectInstance is IObjectReference && !flag)
{
if (objectRecord.Status == ObjectRecordStatus.ReferenceSolvingDelayed)
{
throw new SerializationException("The object with ID " + objectRecord.ObjectID + " could not be resolved");
}
objectRecord.Status = ObjectRecordStatus.ReferenceSolvingDelayed;
}
if (objectRecord != this._lastObjectRecord)
{
objectRecord2 = objectRecord.Next;
objectRecord.Next = null;
this._lastObjectRecord.Next = objectRecord;
this._lastObjectRecord = objectRecord;
}
else
{
objectRecord2 = objectRecord;
}
}
if (objectRecord == lastObjectRecord)
{
flag = false;
}
}
}
finally
{
this._finalFixup = false;
}
}
// Token: 0x06002C0B RID: 11275 RVA: 0x00090EC0 File Offset: 0x0008F0C0
internal ObjectRecord GetObjectRecord(long objectID)
{
ObjectRecord objectRecord = (ObjectRecord)this._objectRecords[objectID];
if (objectRecord == null)
{
if (this._finalFixup)
{
throw new SerializationException("The object with Id " + objectID + " has not been registered");
}
objectRecord = new ObjectRecord();
objectRecord.ObjectID = objectID;
this._objectRecords[objectID] = objectRecord;
}
if (!objectRecord.IsRegistered && this._finalFixup)
{
throw new SerializationException("The object with Id " + objectID + " has not been registered");
}
return objectRecord;
}
/// Returns the object with the specified object ID.
/// The object with the specified object ID if it has been previously stored or null if no such object has been registered.
/// The ID of the requested object.
/// The parameter is less than or equal to zero.
// Token: 0x06002C0C RID: 11276 RVA: 0x00090F64 File Offset: 0x0008F164
public virtual object GetObject(long objectID)
{
if (objectID <= 0L)
{
throw new ArgumentOutOfRangeException("objectID", "The objectID parameter is less than or equal to zero");
}
ObjectRecord objectRecord = (ObjectRecord)this._objectRecords[objectID];
if (objectRecord == null || !objectRecord.IsRegistered)
{
return null;
}
return objectRecord.ObjectInstance;
}
/// Raises the deserialization event to any registered object that implements .
// Token: 0x06002C0D RID: 11277 RVA: 0x00090FBC File Offset: 0x0008F1BC
public virtual void RaiseDeserializationEvent()
{
for (int i = this._onDeserializedCallbackRecords.Count - 1; i >= 0; i--)
{
ObjectRecord objectRecord = (ObjectRecord)this._onDeserializedCallbackRecords[i];
this.RaiseOnDeserializedEvent(objectRecord.OriginalObject);
}
for (int j = this._deserializedRecords.Count - 1; j >= 0; j--)
{
ObjectRecord objectRecord2 = (ObjectRecord)this._deserializedRecords[j];
IDeserializationCallback deserializationCallback = objectRecord2.OriginalObject as IDeserializationCallback;
if (deserializationCallback != null)
{
deserializationCallback.OnDeserialization(this);
}
}
}
/// Invokes the method marked with the .
/// The instance of the type that contains the method to be invoked.
// Token: 0x06002C0E RID: 11278 RVA: 0x00091054 File Offset: 0x0008F254
public void RaiseOnDeserializingEvent(object obj)
{
SerializationCallbacks serializationCallbacks = SerializationCallbacks.GetSerializationCallbacks(obj.GetType());
serializationCallbacks.RaiseOnDeserializing(obj, this._context);
}
// Token: 0x06002C0F RID: 11279 RVA: 0x0009107C File Offset: 0x0008F27C
private void RaiseOnDeserializedEvent(object obj)
{
SerializationCallbacks serializationCallbacks = SerializationCallbacks.GetSerializationCallbacks(obj.GetType());
serializationCallbacks.RaiseOnDeserialized(obj, this._context);
}
// Token: 0x06002C10 RID: 11280 RVA: 0x000910A4 File Offset: 0x0008F2A4
private void AddFixup(BaseFixupRecord record)
{
record.ObjectToBeFixed.ChainFixup(record, true);
record.ObjectRequired.ChainFixup(record, false);
}
/// Records a fixup for one element in an array.
/// The ID of the array used to record a fixup.
/// The index within that a fixup is requested for.
/// The ID of the object that the current array element will point to after fixup is completed.
/// The or parameter is less than or equal to zero.
/// The parameter is null.
// Token: 0x06002C11 RID: 11281 RVA: 0x000910C0 File Offset: 0x0008F2C0
public virtual void RecordArrayElementFixup(long arrayToBeFixed, int index, long objectRequired)
{
if (arrayToBeFixed <= 0L)
{
throw new ArgumentOutOfRangeException("arrayToBeFixed", "The arrayToBeFixed parameter is less than or equal to zero");
}
if (objectRequired <= 0L)
{
throw new ArgumentOutOfRangeException("objectRequired", "The objectRequired parameter is less than or equal to zero");
}
ArrayFixupRecord arrayFixupRecord = new ArrayFixupRecord(this.GetObjectRecord(arrayToBeFixed), index, this.GetObjectRecord(objectRequired));
this.AddFixup(arrayFixupRecord);
}
/// Records fixups for the specified elements in an array, to be executed later.
/// The ID of the array used to record a fixup.
/// The indexes within the multidimensional array that a fixup is requested for.
/// The ID of the object the array elements will point to after fixup is completed.
/// The or parameter is less than or equal to zero.
/// The parameter is null.
// Token: 0x06002C12 RID: 11282 RVA: 0x0009111C File Offset: 0x0008F31C
public virtual void RecordArrayElementFixup(long arrayToBeFixed, int[] indices, long objectRequired)
{
if (arrayToBeFixed <= 0L)
{
throw new ArgumentOutOfRangeException("arrayToBeFixed", "The arrayToBeFixed parameter is less than or equal to zero");
}
if (objectRequired <= 0L)
{
throw new ArgumentOutOfRangeException("objectRequired", "The objectRequired parameter is less than or equal to zero");
}
if (indices == null)
{
throw new ArgumentNullException("indices");
}
MultiArrayFixupRecord multiArrayFixupRecord = new MultiArrayFixupRecord(this.GetObjectRecord(arrayToBeFixed), indices, this.GetObjectRecord(objectRequired));
this.AddFixup(multiArrayFixupRecord);
}
/// Records a fixup for an object member, to be executed later.
/// The ID of the object that needs the reference to .
/// The member name of where the fixup will be performed.
/// The ID of the object required by .
///
/// or parameter is less than or equal to zero.
/// The parameter is null.
// Token: 0x06002C13 RID: 11283 RVA: 0x00091188 File Offset: 0x0008F388
public virtual void RecordDelayedFixup(long objectToBeFixed, string memberName, long objectRequired)
{
if (objectToBeFixed <= 0L)
{
throw new ArgumentOutOfRangeException("objectToBeFixed", "The objectToBeFixed parameter is less than or equal to zero");
}
if (objectRequired <= 0L)
{
throw new ArgumentOutOfRangeException("objectRequired", "The objectRequired parameter is less than or equal to zero");
}
if (memberName == null)
{
throw new ArgumentNullException("memberName");
}
DelayedFixupRecord delayedFixupRecord = new DelayedFixupRecord(this.GetObjectRecord(objectToBeFixed), memberName, this.GetObjectRecord(objectRequired));
this.AddFixup(delayedFixupRecord);
}
/// Records a fixup for a member of an object, to be executed later.
/// The ID of the object that needs the reference to the object.
/// The member of where the fixup will be performed.
/// The ID of the object required by .
/// The or parameter is less than or equal to zero.
/// The parameter is null.
// Token: 0x06002C14 RID: 11284 RVA: 0x000911F4 File Offset: 0x0008F3F4
public virtual void RecordFixup(long objectToBeFixed, MemberInfo member, long objectRequired)
{
if (objectToBeFixed <= 0L)
{
throw new ArgumentOutOfRangeException("objectToBeFixed", "The objectToBeFixed parameter is less than or equal to zero");
}
if (objectRequired <= 0L)
{
throw new ArgumentOutOfRangeException("objectRequired", "The objectRequired parameter is less than or equal to zero");
}
if (member == null)
{
throw new ArgumentNullException("member");
}
FixupRecord fixupRecord = new FixupRecord(this.GetObjectRecord(objectToBeFixed), member, this.GetObjectRecord(objectRequired));
this.AddFixup(fixupRecord);
}
// Token: 0x06002C15 RID: 11285 RVA: 0x00091260 File Offset: 0x0008F460
private void RegisterObjectInternal(object obj, ObjectRecord record)
{
if (obj == null)
{
throw new ArgumentNullException("obj");
}
if (!record.IsRegistered)
{
record.ObjectInstance = obj;
record.OriginalObject = obj;
if (obj is IObjectReference)
{
record.Status = ObjectRecordStatus.ReferenceUnsolved;
}
else
{
record.Status = ObjectRecordStatus.ReferenceSolved;
}
if (this._selector != null)
{
record.Surrogate = this._selector.GetSurrogate(obj.GetType(), this._context, out record.SurrogateSelector);
if (record.Surrogate != null)
{
record.Status = ObjectRecordStatus.ReferenceUnsolved;
}
}
record.DoFixups(true, this, false);
record.DoFixups(false, this, false);
this._registeredObjectsCount++;
if (this._objectRecordChain == null)
{
this._objectRecordChain = record;
this._lastObjectRecord = record;
}
else
{
this._lastObjectRecord.Next = record;
this._lastObjectRecord = record;
}
return;
}
if (record.OriginalObject != obj)
{
throw new SerializationException("An object with Id " + record.ObjectID + " has already been registered");
}
}
/// Registers an object as it is deserialized, associating it with .
/// The object to register.
/// The ID of the object to register.
/// The parameter is null.
/// The parameter is less than or equal to zero.
/// The has already been registered for an object other than .
///
///
///
// Token: 0x06002C16 RID: 11286 RVA: 0x00091378 File Offset: 0x0008F578
public virtual void RegisterObject(object obj, long objectID)
{
if (obj == null)
{
throw new ArgumentNullException("obj", "The obj parameter is null.");
}
if (objectID <= 0L)
{
throw new ArgumentOutOfRangeException("objectID", "The objectID parameter is less than or equal to zero");
}
this.RegisterObjectInternal(obj, this.GetObjectRecord(objectID));
}
/// Registers an object as it is deserialized, associating it with , and recording the used with it.
/// The object to register.
/// The ID of the object to register.
/// The used if implements or has a . will be completed with any required fixup information and then passed to the required object when that object is completed.
/// The parameter is null.
/// The parameter is less than or equal to zero.
/// The has already been registered for an object other than .
///
///
///
// Token: 0x06002C17 RID: 11287 RVA: 0x000913C4 File Offset: 0x0008F5C4
public void RegisterObject(object obj, long objectID, SerializationInfo info)
{
if (obj == null)
{
throw new ArgumentNullException("obj", "The obj parameter is null.");
}
if (objectID <= 0L)
{
throw new ArgumentOutOfRangeException("objectID", "The objectID parameter is less than or equal to zero");
}
ObjectRecord objectRecord = this.GetObjectRecord(objectID);
objectRecord.Info = info;
this.RegisterObjectInternal(obj, objectRecord);
}
/// Registers a member of an object as it is deserialized, associating it with , and recording the .
/// The object to register.
/// The ID of the object to register.
/// The used if implements or has a . will be completed with any required fixup information and then passed to the required object when that object is completed.
/// The ID of the object that contains . This parameter is required only if is a value type.
/// The field in the containing object where exists. This parameter has meaning only if is a value type.
/// The parameter is null.
/// The parameter is less than or equal to zero.
/// The has already been registered for an object other than , or is not a and is not null.
///
///
///
// Token: 0x06002C18 RID: 11288 RVA: 0x00091418 File Offset: 0x0008F618
public void RegisterObject(object obj, long objectID, SerializationInfo info, long idOfContainingObj, MemberInfo member)
{
this.RegisterObject(obj, objectID, info, idOfContainingObj, member, null);
}
/// Registers a member of an array contained in an object while it is deserialized, associating it with , and recording the .
/// The object to register.
/// The ID of the object to register.
/// The used if implements or has a . will be completed with any required fixup information and then passed to the required object when that object is completed.
/// The ID of the object that contains . This parameter is required only if is a value type.
/// The field in the containing object where exists. This parameter has meaning only if is a value type.
/// If is a and a member of an array, contains the index within that array where exists. is ignored if is not both a and a member of an array.
/// The parameter is null.
/// The parameter is less than or equal to zero.
/// The has already been registered for an object other than , or is not a and isn't null.
///
///
///
// Token: 0x06002C19 RID: 11289 RVA: 0x00091428 File Offset: 0x0008F628
public void RegisterObject(object obj, long objectID, SerializationInfo info, long idOfContainingObj, MemberInfo member, int[] arrayIndex)
{
if (obj == null)
{
throw new ArgumentNullException("obj", "The obj parameter is null.");
}
if (objectID <= 0L)
{
throw new ArgumentOutOfRangeException("objectID", "The objectID parameter is less than or equal to zero");
}
ObjectRecord objectRecord = this.GetObjectRecord(objectID);
objectRecord.Info = info;
objectRecord.IdOfContainingObj = idOfContainingObj;
objectRecord.Member = member;
objectRecord.ArrayIndex = arrayIndex;
this.RegisterObjectInternal(obj, objectRecord);
}
// Token: 0x04001103 RID: 4355
private ObjectRecord _objectRecordChain;
// Token: 0x04001104 RID: 4356
private ObjectRecord _lastObjectRecord;
// Token: 0x04001105 RID: 4357
private ArrayList _deserializedRecords = new ArrayList();
// Token: 0x04001106 RID: 4358
private ArrayList _onDeserializedCallbackRecords = new ArrayList();
// Token: 0x04001107 RID: 4359
private Hashtable _objectRecords = new Hashtable();
// Token: 0x04001108 RID: 4360
private bool _finalFixup;
// Token: 0x04001109 RID: 4361
private ISurrogateSelector _selector;
// Token: 0x0400110A RID: 4362
private StreamingContext _context;
// Token: 0x0400110B RID: 4363
private int _registeredObjectsCount;
}
}