private void AddObjectHolder(ObjectHolder holder) { if ((holder.m_id >= this.m_objects.Length) && (this.m_objects.Length != 0x1000)) { int num = 0x1000; if (holder.m_id < 0x800L) { num = this.m_objects.Length * 2; while ((num <= holder.m_id) && (num < 0x1000)) { num *= 2; } if (num > 0x1000) { num = 0x1000; } } ObjectHolder[] destinationArray = new ObjectHolder[num]; Array.Copy(this.m_objects, destinationArray, this.m_objects.Length); this.m_objects = destinationArray; } int index = (int) (holder.m_id & 0xfffL); ObjectHolder holder2 = this.m_objects[index]; holder.m_next = holder2; this.m_objects[index] = holder; }
internal ObjectHolder(object obj, long objID, System.Runtime.Serialization.SerializationInfo info, ISerializationSurrogate surrogate, long idOfContainingObj, FieldInfo field, int[] arrayIndex) { this.m_object = obj; this.m_id = objID; this.m_flags = 0; this.m_missingElementsRemaining = 0; this.m_missingDecendents = 0; this.m_dependentObjects = null; this.m_next = null; this.m_serInfo = info; this.m_surrogate = surrogate; this.m_markForFixupWhenAvailable = false; if (obj is TypeLoadExceptionHolder) { this.m_typeLoad = (TypeLoadExceptionHolder) obj; } if ((idOfContainingObj != 0L) && (((field != null) && field.FieldType.IsValueType) || (arrayIndex != null))) { if (idOfContainingObj == objID) { throw new SerializationException(Environment.GetResourceString("Serialization_ParentChildIdentical")); } this.m_valueFixup = new ValueTypeFixupInfo(idOfContainingObj, field, arrayIndex); } this.SetFlags(); }
internal virtual void Add(ObjectHolder value) { if (this.m_count == this.m_values.Length) { this.EnlargeArray(); } this.m_values[this.m_count++] = value; }
internal ObjectHolder FindOrCreateObjectHolder(long objectID) { ObjectHolder holder; holder = FindObjectHolder(objectID); if (holder == null) { holder = new ObjectHolder(objectID); AddObjectHolder(holder); } return holder; }
private void EnlargeArray() { int num = this.m_values.Length * 2; if (num < 0) { if (num == 0x7fffffff) { throw new SerializationException(Environment.GetResourceString("Serialization_TooManyElements")); } num = 0x7fffffff; } ObjectHolder[] destinationArray = new ObjectHolder[num]; Array.Copy(this.m_values, destinationArray, this.m_count); this.m_values = destinationArray; }
internal ObjectHolder FindObjectHolder(long objectID) { int index = (int)(objectID & 0xfffL); if (index >= this.m_objects.Length) { return(null); } ObjectHolder next = this.m_objects[index]; while (next != null) { if (next.m_id == objectID) { return(next); } next = next.m_next; } return(next); }
internal ObjectHolder(string obj, long objID, System.Runtime.Serialization.SerializationInfo info, ISerializationSurrogate surrogate, long idOfContainingObj, FieldInfo field, int[] arrayIndex) { this.m_object = obj; this.m_id = objID; this.m_flags = 0; this.m_missingElementsRemaining = 0; this.m_missingDecendents = 0; this.m_dependentObjects = null; this.m_next = null; this.m_serInfo = info; this.m_surrogate = surrogate; this.m_markForFixupWhenAvailable = false; if ((idOfContainingObj != 0L) && (arrayIndex != null)) { this.m_valueFixup = new ValueTypeFixupInfo(idOfContainingObj, field, arrayIndex); } if (this.m_valueFixup != null) { this.m_flags |= 8; } }
private bool ResolveObjectReference(ObjectHolder holder) { int num = 0; try { object objectValue; for (;;) { objectValue = holder.ObjectValue; holder.SetObjectValue(((IObjectReference)holder.ObjectValue).GetRealObject(this.m_context), this); if (holder.ObjectValue == null) { break; } if (num++ == 100) { goto Block_3; } if (!(holder.ObjectValue is IObjectReference) || objectValue == holder.ObjectValue) { goto IL_69; } } holder.SetObjectValue(objectValue, this); return(false); Block_3: throw new SerializationException(Environment.GetResourceString("Serialization_TooManyReferences")); IL_69 :; } catch (NullReferenceException) { return(false); } holder.IsIncompleteObjectReference = false; this.DoNewlyRegisteredObjectFixups(holder); return(true); }
internal ObjectHolder(string obj, long objID, SerializationInfo info, ISerializationSurrogate surrogate, long idOfContainingObj, FieldInfo field, int[] arrayIndex) { this.m_object = (object)obj; this.m_id = objID; this.m_flags = 0; this.m_missingElementsRemaining = 0; this.m_missingDecendents = 0; this.m_dependentObjects = (LongList)null; this.m_next = (ObjectHolder)null; this.m_serInfo = info; this.m_surrogate = surrogate; this.m_markForFixupWhenAvailable = false; if (idOfContainingObj != 0L && arrayIndex != null) { this.m_valueFixup = new ValueTypeFixupInfo(idOfContainingObj, field, arrayIndex); } if (this.m_valueFixup == null) { return; } this.m_flags = this.m_flags | 8; }
// Token: 0x0600514E RID: 20814 RVA: 0x0011CCB4 File Offset: 0x0011AEB4 private bool GetCompletionInfo(FixupHolder fixup, out ObjectHolder holder, out object member, bool bThrowIfMissing) { member = fixup.m_fixupInfo; holder = this.FindObjectHolder(fixup.m_id); if (!holder.CompletelyFixed && holder.ObjectValue != null && holder.ObjectValue is ValueType) { this.SpecialFixupObjects.Add(holder); return(false); } if (holder != null && !holder.CanObjectValueChange && holder.ObjectValue != null) { return(true); } if (!bThrowIfMissing) { return(false); } if (holder == null) { throw new SerializationException(Environment.GetResourceString("Serialization_NeverSeen", new object[] { fixup.m_id })); } if (holder.IsIncompleteObjectReference) { throw new SerializationException(Environment.GetResourceString("Serialization_IORIncomplete", new object[] { fixup.m_id })); } throw new SerializationException(Environment.GetResourceString("Serialization_ObjectNotSupplied", new object[] { fixup.m_id })); }
private bool ResolveObjectReference(ObjectHolder holder) { int num = 0; try { object objectValue; do { objectValue = holder.ObjectValue; ObjectHolder objectHolder = holder; object realObject = ((IObjectReference)objectHolder.ObjectValue).GetRealObject(this.m_context); objectHolder.SetObjectValue(realObject, this); if (holder.ObjectValue == null) { holder.SetObjectValue(objectValue, this); return(false); } if (num++ == 100) { throw new SerializationException(Environment.GetResourceString("Serialization_TooManyReferences")); } if (!(holder.ObjectValue is IObjectReference)) { break; } }while (objectValue != holder.ObjectValue); } catch (NullReferenceException ex) { return(false); } holder.IsIncompleteObjectReference = false; this.DoNewlyRegisteredObjectFixups(holder); return(true); }
/*================================CompleteObject================================ **Action: **Returns: **Arguments: **Exceptions: ==============================================================================*/ internal void CompleteObject(ObjectHolder holder, bool bObjectFullyComplete) { FixupHolderList fixups=holder.m_missingElements; FixupHolder currentFixup; SerializationInfo si; Object fixupInfo=null; ObjectHolder tempObjectHolder=null; int fixupsPerformed=0; BCLDebug.Assert(holder!=null,"[ObjectManager.CompleteObject]holder.m_object!=null"); if (holder.ObjectValue==null) { throw new SerializationException(Environment.GetResourceString("Serialization_MissingObject", holder.m_id)); } if (fixups==null) { return; } //If either one of these conditions is true, we need to update the data in the //SerializationInfo before calling SetObjectData. if (holder.HasSurrogate || holder.HasISerializable) { si = holder.m_serInfo; if (si==null) { throw new SerializationException(Environment.GetResourceString("Serialization_InvalidFixupDiscovered")); } BCLDebug.Trace("SER", "[ObjectManager.CompleteObject]Complete object ", holder.m_id, " of SI Type: ", si.FullTypeName); //Walk each of the fixups and complete the name-value pair in the SerializationInfo. if (fixups!=null) { for (int i=0; i<fixups.m_count; i++) { if (fixups.m_values[i]==null) { continue; } BCLDebug.Assert(fixups.m_values[i].m_fixupType==FixupHolder.DelayedFixup,"fixups.m_values[i].m_fixupType==FixupHolder.DelayedFixup"); if (GetCompletionInfo(fixups.m_values[i], out tempObjectHolder, out fixupInfo, bObjectFullyComplete)) { //Walk the SerializationInfo and find the member needing completion. All we have to do //at this point is set the member into the Object BCLDebug.Trace("SER", "[ObjectManager.CompleteObject]Updating object ", holder.m_id, " with object ", tempObjectHolder.m_id); Object holderValue = tempObjectHolder.ObjectValue; if (CanCallGetType(holderValue)) { si.UpdateValue((String)fixupInfo, holderValue, holderValue.GetType()); } else { si.UpdateValue((String)fixupInfo, holderValue, typeof(MarshalByRefObject)); } //Decrement our total number of fixups left to do. fixupsPerformed++; fixups.m_values[i]=null; if (!bObjectFullyComplete) { holder.DecrementFixupsRemaining(this); tempObjectHolder.RemoveDependency(holder.m_id); } } } } } else { BCLDebug.Trace("SER", "[ObjectManager.CompleteObject]Non-ISerializableObject: ", holder.m_id); for (int i=0; i<fixups.m_count; i++) { currentFixup = fixups.m_values[i]; if (currentFixup==null) { continue; } BCLDebug.Trace("SER", "[ObjectManager.CompleteObject]Getting fixup info for object: ", currentFixup.m_id); if (GetCompletionInfo(currentFixup, out tempObjectHolder, out fixupInfo, bObjectFullyComplete)) { BCLDebug.Trace("SER", "[ObjectManager.CompleteObject]Fixing up: ", currentFixup.m_id); //There are two types of fixups that we could be doing: array or member. //Delayed Fixups should be handled by the above branch. switch(currentFixup.m_fixupType) { case FixupHolder.ArrayFixup: BCLDebug.Assert(holder.ObjectValue is Array,"holder.ObjectValue is Array"); if (holder.RequiresValueTypeFixup) { throw new SerializationException(Environment.GetResourceString("Serialization_ValueTypeFixup")); } else { ((Array)(holder.ObjectValue)).SetValue(tempObjectHolder.ObjectValue, ((int[])fixupInfo)); } break; case FixupHolder.MemberFixup: BCLDebug.Assert(fixupInfo is MemberInfo,"fixupInfo is MemberInfo"); //Fixup the member directly. MemberInfo tempMember = (MemberInfo)fixupInfo; if (tempMember.MemberType==MemberTypes.Field) { BCLDebug.Trace("SER", "[ObjectManager.CompleteObject]Fixing member: ", tempMember.Name, " in object ", holder.m_id, " with object ", tempObjectHolder.m_id); // If we have a valuetype that's been boxed to an object and requires a fixup, // there are two possible states: // (a)The valuetype has never been fixed up into it's container. In this case, we should // just fix up the boxed valuetype. The task of pushing that valuetype into it's container // will be handled later. This case is handled by the else clause of the following statement. // (b)The valuetype has already been inserted into it's container. In that case, we need // to go through the more complicated path laid out in DoValueTypeFixup. We can tell that the // valuetype has already been inserted into it's container because we set ValueTypeFixupPerformed // to true when we do this. if (holder.RequiresValueTypeFixup && holder.ValueTypeFixupPerformed) { if (!DoValueTypeFixup((FieldInfo)tempMember, holder, tempObjectHolder.ObjectValue)) { throw new SerializationException(Environment.GetResourceString("Serialization_PartialValueTypeFixup")); } } else { FormatterServices.SerializationSetValue(tempMember, holder.ObjectValue, tempObjectHolder.ObjectValue); if (tempObjectHolder.RequiresValueTypeFixup) { tempObjectHolder.ValueTypeFixupPerformed = true; } } } else { throw new SerializationException(Environment.GetResourceString("Serialization_UnableToFixup")); } break; default: throw new SerializationException(Environment.GetResourceString("Serialization_UnableToFixup")); } //Decrement our total number of fixups left to do. fixupsPerformed++; fixups.m_values[i]=null; if (!bObjectFullyComplete) { holder.DecrementFixupsRemaining(this); tempObjectHolder.RemoveDependency(holder.m_id); } } } } m_fixupCount-=fixupsPerformed; if (fixups.m_count==fixupsPerformed) { holder.m_missingElements=null; } }
internal void RegisterString(String obj, long objectID, SerializationInfo info, long idOfContainingObj, MemberInfo member) { ObjectHolder temp; BCLDebug.Assert(member == null || member is FieldInfo, "RegisterString - member is FieldInfo"); BCLDebug.Assert((FindObjectHolder(objectID) == null), "RegisterString - FindObjectHolder(objectID) == null"); temp = new ObjectHolder(obj, objectID, info, null, idOfContainingObj, (FieldInfo)member, null); AddObjectHolder(temp); return; }
private bool GetCompletionInfo(FixupHolder fixup, out ObjectHolder holder, out Object member, bool bThrowIfMissing) { //Set the member id (String or MemberInfo) for the member being fixed up. member = fixup.m_fixupInfo; //Find the object required for the fixup. Throw if we can't find it. holder = FindObjectHolder(fixup.m_id); BCLDebug.Trace("SER", "[ObjectManager.GetCompletionInfo]Getting fixup info for: ", fixup.m_id); // CompletelyFixed is our poorly named property which indicates if something requires a SerializationInfo fixup // or is an incomplete object reference. We have this particular branch to handle valuetypes which implement // ISerializable. In that case, we can't do any fixups on them later, so we need to delay the fixups further. if (!holder.CompletelyFixed) { if (holder.ObjectValue!=null && holder.ObjectValue is ValueType) { BCLDebug.Trace("SER", "[ObjectManager.GetCompletionInfo]ValueType implementing ISerializable. Delaying fixup."); SpecialFixupObjects.Add(holder); return false; } } if (holder==null || holder.IsIncompleteObjectReference || holder.ObjectValue==null) { if (bThrowIfMissing) { BCLDebug.Trace("SER", "[GetCompletionInfo]Unable to find fixup for: ", fixup.m_id); BCLDebug.Trace("SER", "[GetCompletionInfo]Holder: ", ((holder==null)?"<null>":"Non Null")); BCLDebug.Trace("SER", "[GetCompletionInfo]IsIncomplete: ", (holder.IsIncompleteObjectReference)); BCLDebug.Trace("SER", "[GetCompletionInfo]Object: ", ((holder.ObjectValue==null)?"<null>":"Non Null")); if (holder==null) { throw new SerializationException(String.Format(Environment.GetResourceString("Serialization_NeverSeen"), fixup.m_id)); } if (holder.IsIncompleteObjectReference) { throw new SerializationException(String.Format(Environment.GetResourceString("Serialization_IORIncomplete"), fixup.m_id)); } throw new SerializationException(String.Format(Environment.GetResourceString("Serialization_ObjectNotSupplied"), fixup.m_id)); } return false; } return true; }
/*============================ResolveObjectReference============================ **Action:Unfortunately, an ObjectReference could actually be a reference to another ** object reference and we don't know how far we have to tunnel until we can find the real object. While ** we're still getting instances of IObjectReference back and we're still getting new objects, keep calling ** GetRealObject. Once we've got the new object, take care of all of the fixups ** that we can do now that we've got it. ==============================================================================*/ private bool ResolveObjectReference(ObjectHolder holder) { Object tempObject; BCLDebug.Assert(holder.IsIncompleteObjectReference,"holder.IsIncompleteObjectReference"); //In the pathological case, an Object implementing IObjectReference could return a reference //to a different object which implements IObjectReference. This makes us vulnerable to a //denial of service attack and stack overflow. If the depthCount becomes greater than //MaxReferenceDepth, we'll throw a SerializationException. int depthCount = 0; //We wrap this in a try/catch block to handle the case where we're trying to resolve a chained //list of object reference (e.g. an IObjectReference can't resolve itself without some information //that's currently missing from the graph). We'll catch the NullReferenceException and come back //and try again later. The downside of this scheme is that if the object actually needed to throw //a NullReferenceException, it's being caught and turned into a SerializationException with a //fairly cryptic message. try { do { tempObject = holder.ObjectValue; BCLDebug.Trace("SER", "[ResolveObjectReference]ID: ", holder.m_id); BCLDebug.Trace("SER", "[ResolveObjectReference]HasISerializable: ", holder.HasISerializable); holder.SetObjectValue(((IObjectReference)(holder.ObjectValue)).GetRealObject(m_context), this); //The object didn't yet have enough information to resolve the reference, so we'll //return false and the graph walker should call us back again after more objects have //been resolved. if (holder.ObjectValue==null) { holder.SetObjectValue(tempObject, this); BCLDebug.Trace("SER", "Object: ", holder.m_id, " did NOT have enough information to resolve the IObjectReference."); return false; } if (depthCount++==MaxReferenceDepth) { throw new SerializationException(Environment.GetResourceString("Serialization_TooManyReferences")); } } while ((holder.ObjectValue is IObjectReference) && (tempObject!=holder.ObjectValue)); } catch (NullReferenceException) { BCLDebug.Trace("SER", "[ResolveObjectReference]Caught exception trying to call GetRealObject."); return false; } BCLDebug.Trace("SER", "Object: ", holder.m_id, " resolved the IObjectReference."); holder.IsIncompleteObjectReference=false; DoNewlyRegisteredObjectFixups(holder); return true; }
[System.Security.SecurityCritical] // auto-generated private bool DoValueTypeFixup(FieldInfo memberToFix, ObjectHolder holder, Object value) { TypedReference typedRef; FieldInfo[] fieldsTemp=new FieldInfo[4]; FieldInfo[] fields=null; int currentFieldIndex=0; int[] arrayIndex = null; ValueTypeFixupInfo currFixup=null; Object fixupObj=holder.ObjectValue; ObjectHolder originalHolder = holder; Contract.Assert(holder!=null, "[TypedReferenceBuilder.ctor]holder!=null"); Contract.Assert(holder.RequiresValueTypeFixup, "[TypedReferenceBuilder.ctor]holder.RequiresValueTypeFixup"); //In order to get a TypedReference, we need to get a list of all of the FieldInfos to //create the path from our outermost containing object down to the actual field which //we'd like to set. This loop is used to build up that list. while (holder.RequiresValueTypeFixup) { BCLDebug.Trace("SER", "[DoValueTypeFixup] valueType fixsite = ", holder.ObjectValue, " fixobj=",value); //Enlarge the array if required (this is actually fairly unlikely as it would require that we //be nested more than 4 deep. if ((currentFieldIndex + 1)>=fieldsTemp.Length) { FieldInfo[] temp = new FieldInfo[fieldsTemp.Length * 2]; Array.Copy(fieldsTemp, temp, fieldsTemp.Length); fieldsTemp = temp; } //Get the fixup information. If we have data for our parent field, add it to our list //and continue the walk up to find the next outermost containing object. We cache the //object that we have. In most cases, we could have just grabbed it after this loop finished. //However, if the outermost containing object is an array, we need the object one further //down the chain, so we have to do a lot of caching. currFixup = holder.ValueFixup; fixupObj = holder.ObjectValue; //Save the most derived if (currFixup.ParentField!=null) { FieldInfo parentField = currFixup.ParentField; ObjectHolder tempHolder = FindObjectHolder(currFixup.ContainerID); if (tempHolder.ObjectValue == null) { break; } if (Nullable.GetUnderlyingType(parentField.FieldType) != null) { fieldsTemp[currentFieldIndex] = parentField.FieldType.GetField("value", BindingFlags.NonPublic|BindingFlags.Instance); currentFieldIndex++; } fieldsTemp[currentFieldIndex] = parentField; holder = tempHolder; currentFieldIndex++; } else { //If we find an index into an array, save that information. Contract.Assert(currFixup.ParentIndex!=null, "[ObjectManager.DoValueTypeFixup]currFixup.ParentIndex!=null"); holder = FindObjectHolder(currFixup.ContainerID); //find the array to fix. arrayIndex = currFixup.ParentIndex; if (holder.ObjectValue==null) { break; } break; } } //If the outermost container isn't an array, we need to grab it. Otherwise, we just need to hang onto //the boxed object that we already grabbed. We'll assign the boxed object back into the array as the //last step. if (!(holder.ObjectValue is Array) && holder.ObjectValue!=null) { fixupObj = holder.ObjectValue; Contract.Assert(fixupObj!=null, "[ObjectManager.DoValueTypeFixup]FixupObj!=null"); } #if false //We thought that the valuetype had already been placed into it's parent, but when we started //walking the track, we discovered a null, so that's clearly impossible. At this point, revert //to just poking it into the most boxed version that we can. if (fixupObj==null) { fixupObj = originalHolder.ObjectValue; FormatterServices.SerializationSetValue(memberToFix, fixupObj, value); return true; } #endif if (currentFieldIndex!=0) { //MakeTypedReference requires an array of exactly the correct size that goes from the outermost object //in to the innermost field. We currently have an array of arbitrary size that goes from the innermost //object outwards. We create an array of the right size and do the copy. fields = new FieldInfo[currentFieldIndex]; for (int i=0; i<currentFieldIndex; i++) { FieldInfo fieldInfo = fieldsTemp[(currentFieldIndex - 1 - i)]; SerializationFieldInfo serInfo = fieldInfo as SerializationFieldInfo; fields[i] = serInfo == null ? fieldInfo : serInfo.FieldInfo; } Contract.Assert(fixupObj!=null, "[ObjectManager.DoValueTypeFixup]fixupObj!=null"); DumpValueTypeFixup(fixupObj, fields, memberToFix, value); //Make the TypedReference and use it to set the value. typedRef = TypedReference.MakeTypedReference(fixupObj, fields); if (memberToFix != null) //((RuntimeFieldInfo)memberToFix).SetValueDirectImpl(value, false, typedRef); ((RuntimeFieldInfo)memberToFix).SetValueDirect(typedRef, value); else TypedReference.SetTypedReference(typedRef, value); } else if (memberToFix != null){ DumpValueTypeFixup(fixupObj, null, memberToFix, value); FormatterServices.SerializationSetValue(memberToFix, fixupObj, value); } //If we have an array index, it means that our outermost container was an array. We don't have //any way to build a TypedReference into an array, so we'll use the array functions to set the value. //< if (arrayIndex!=null && holder.ObjectValue!=null) { ((Array)(holder.ObjectValue)).SetValue(fixupObj, arrayIndex); } return true; }
private bool GetCompletionInfo(FixupHolder fixup, out ObjectHolder holder, out object member, bool bThrowIfMissing) { //Set the member id (String or MemberInfo) for the member being fixed up. member = fixup._fixupInfo; //Find the object required for the fixup. Throw if we can't find it. holder = FindObjectHolder(fixup._id); // CompletelyFixed is our poorly named property which indicates if something requires a SerializationInfo fixup // or is an incomplete object reference. We have this particular branch to handle valuetypes which implement // ISerializable. In that case, we can't do any fixups on them later, so we need to delay the fixups further. if (!holder.CompletelyFixed) { if (holder.ObjectValue != null && holder.ObjectValue is ValueType) { SpecialFixupObjects.Add(holder); return false; } } if (holder == null || holder.CanObjectValueChange || holder.ObjectValue == null) { if (bThrowIfMissing) { if (holder == null) { throw new SerializationException(SR.Format(SR.Serialization_NeverSeen, fixup._id)); } if (holder.IsIncompleteObjectReference) { throw new SerializationException(SR.Format(SR.Serialization_IORIncomplete, fixup._id)); } throw new SerializationException(SR.Format(SR.Serialization_ObjectNotSupplied, fixup._id)); } return false; } return true; }
private void AddObjectHolder(ObjectHolder holder) { Debug.Assert(holder != null, "holder!=null"); Debug.Assert(holder._id >= 0, "holder.m_id>=0"); //If the id that we need to place is greater than our current length, and less //than the maximum allowable size of the array. We need to double the size //of the array. If the array has already reached it's maximum allowable size, //we chain elements off of the buckets. if (holder._id >= _objects.Length && _objects.Length != MaxArraySize) { int newSize = MaxArraySize; if (holder._id < (MaxArraySize / 2)) { newSize = (_objects.Length * 2); //Keep doubling until we're larger than our target size. //We could also do this with log operations, but that would //be slower than the brute force approach. while (newSize <= holder._id && newSize < MaxArraySize) { newSize *= 2; } if (newSize > MaxArraySize) { newSize = MaxArraySize; } } ObjectHolder[] temp = new ObjectHolder[newSize]; Array.Copy(_objects, 0, temp, 0, _objects.Length); _objects = temp; } //Find the bin in which we live and make this new element the first element in the bin. int index = (int)(holder._id & ArrayMask); ObjectHolder tempHolder = _objects[index]; holder._next = tempHolder; _objects[index] = holder; }
private bool DoValueTypeFixup(FieldInfo memberToFix, ObjectHolder holder, object value) { FieldInfo[] fieldInfoArray1 = new FieldInfo[4]; int length = 0; int[] numArray = (int[])null; object objectValue = holder.ObjectValue; while (holder.RequiresValueTypeFixup) { if (length + 1 >= fieldInfoArray1.Length) { FieldInfo[] fieldInfoArray2 = new FieldInfo[fieldInfoArray1.Length * 2]; Array.Copy((Array)fieldInfoArray1, (Array)fieldInfoArray2, fieldInfoArray1.Length); fieldInfoArray1 = fieldInfoArray2; } ValueTypeFixupInfo valueFixup = holder.ValueFixup; objectValue = holder.ObjectValue; if (valueFixup.ParentField != (FieldInfo)null) { FieldInfo parentField = valueFixup.ParentField; ObjectHolder objectHolder = this.FindObjectHolder(valueFixup.ContainerID); if (objectHolder.ObjectValue != null) { if (Nullable.GetUnderlyingType(parentField.FieldType) != (Type)null) { fieldInfoArray1[length] = parentField.FieldType.GetField("value", BindingFlags.Instance | BindingFlags.NonPublic); ++length; } fieldInfoArray1[length] = parentField; holder = objectHolder; ++length; } else { break; } } else { holder = this.FindObjectHolder(valueFixup.ContainerID); numArray = valueFixup.ParentIndex; if (holder.ObjectValue != null) { break; } break; } } if (!(holder.ObjectValue is Array) && holder.ObjectValue != null) { objectValue = holder.ObjectValue; } if (length != 0) { FieldInfo[] flds = new FieldInfo[length]; for (int index = 0; index < length; ++index) { FieldInfo fieldInfo = fieldInfoArray1[length - 1 - index]; SerializationFieldInfo serializationFieldInfo = fieldInfo as SerializationFieldInfo; flds[index] = (FieldInfo)serializationFieldInfo == (FieldInfo)null ? fieldInfo : (FieldInfo)serializationFieldInfo.FieldInfo; } TypedReference target = TypedReference.MakeTypedReference(objectValue, flds); if (memberToFix != (FieldInfo)null) { memberToFix.SetValueDirect(target, value); } else { TypedReference.SetTypedReference(target, value); } } else if (memberToFix != (FieldInfo)null) { FormatterServices.SerializationSetValue((MemberInfo)memberToFix, objectValue, value); } if (numArray != null && holder.ObjectValue != null) { ((Array)holder.ObjectValue).SetValue(objectValue, numArray); } return(true); }
public void RegisterObject(object obj, long objectID, SerializationInfo info, long idOfContainingObj, MemberInfo member, int[] arrayIndex) { if (obj == null) { throw new ArgumentNullException(nameof(obj)); } if (objectID <= 0) { throw new ArgumentOutOfRangeException(nameof(objectID), SR.ArgumentOutOfRange_ObjectID); } if (member != null && !(member is FieldInfo)) { throw new SerializationException(SR.Serialization_UnknownMemberInfo); } ObjectHolder temp; ISerializationSurrogate surrogate = null; ISurrogateSelector useless; if (_selector != null) { Type selectorType = CanCallGetType(obj) ? obj.GetType() : typeof(MarshalByRefObject); //If we need a surrogate for this object, lets find it now. surrogate = _selector.GetSurrogate(selectorType, _context, out useless); } //The object is interested in DeserializationEvents so lets register it. if (obj is IDeserializationCallback) { DeserializationEventHandler d = new DeserializationEventHandler(((IDeserializationCallback)obj).OnDeserialization); AddOnDeserialization(d); } //Formatter developers may cache and reuse arrayIndex in their code. //So that we don't get bitten by this, take a copy up front. if (arrayIndex != null) { arrayIndex = (int[])arrayIndex.Clone(); } //This is the first time which we've seen the object, we need to create a new holder. temp = FindObjectHolder(objectID); if (temp == null) { temp = new ObjectHolder(obj, objectID, info, surrogate, idOfContainingObj, (FieldInfo)member, arrayIndex); AddObjectHolder(temp); if (temp.RequiresDelayedFixup) { SpecialFixupObjects.Add(temp); } // We cannot compute whether this has any fixups required or not AddOnDeserialized(obj); return; } //If the object isn't null, we've registered this before. Not good. if (temp.ObjectValue != null) { throw new SerializationException(SR.Serialization_RegisterTwice); } //Complete the data in the ObjectHolder temp.UpdateData(obj, info, surrogate, idOfContainingObj, (FieldInfo)member, arrayIndex, this); // The following case will only be true when somebody has registered a fixup on an object before // registering the object itself. I don't believe that most well-behaved formatters will do this, // but we need to allow it anyway. We will walk the list of fixups which have been recorded on // the new object and fix those that we can. Because the user could still register later fixups // on this object, we won't call any implementations of ISerializable now. If that's required, // it will have to be handled by the code in DoFixups. // README README: We have to do the UpdateData before if (temp.DirectlyDependentObjects > 0) { CompleteObject(temp, false); } if (temp.RequiresDelayedFixup) { SpecialFixupObjects.Add(temp); } if (temp.CompletelyFixed) { //Here's where things get tricky. If this isn't an instance of IObjectReference, we need to walk it's fixup //chain and decrement the counters on anything that has reached 0. Once we've notified all of the dependencies, //we can simply clear the list of dependent objects. DoNewlyRegisteredObjectFixups(temp); temp.DependentObjects = null; } //Register the OnDeserialized methods to be invoked after deserialization is complete if (temp.TotalDependentObjects > 0) { AddOnDeserialized(obj); } else { RaiseOnDeserializedEvent(obj); } }
private bool ResolveObjectReference(ObjectHolder holder) { int num = 0; try { object objectValue; do { objectValue = holder.ObjectValue; holder.SetObjectValue(((IObjectReference) holder.ObjectValue).GetRealObject(this.m_context), this); if (holder.ObjectValue == null) { holder.SetObjectValue(objectValue, this); return false; } if (num++ == 100) { throw new SerializationException(Environment.GetResourceString("Serialization_TooManyReferences")); } } while ((holder.ObjectValue is IObjectReference) && (objectValue != holder.ObjectValue)); } catch (NullReferenceException) { return false; } holder.IsIncompleteObjectReference = false; this.DoNewlyRegisteredObjectFixups(holder); return true; }
/// <summary> /// This is called immediately after we register a new object. Walk that objects /// dependency list (if it has one) and decrement the counters on each object for /// the number of unsatisfiable references. If the count reaches 0, go ahead /// and process the object. /// </summary> /// <param name="holder">dependencies The list of dependent objects</param> private void DoNewlyRegisteredObjectFixups(ObjectHolder holder) { if (holder.CanObjectValueChange) { return; } //If we don't have any dependencies, we're done. LongList dependencies = holder.DependentObjects; if (dependencies == null) { return; } //Walk all of the dependencies and decrement the counter on each of uncompleted objects. //If one of the counters reaches 0, all of it's fields have been completed and we should //go take care of its fixups. dependencies.StartEnumeration(); while (dependencies.MoveNext()) { ObjectHolder temp = FindObjectHolder(dependencies.Current); Debug.Assert(temp.DirectlyDependentObjects > 0, "temp.m_missingElementsRemaining>0"); temp.DecrementFixupsRemaining(this); if (((temp.DirectlyDependentObjects)) == 0) { // If this is null, we have the case where a fixup was registered for a child, the object // required by the fixup was provided, and the object to be fixed hasn't yet been seen. if (temp.ObjectValue != null) { CompleteObject(temp, true); } else { temp.MarkForCompletionWhenAvailable(); } } } }
private void EnlargeArray() { int newLength = _values.Length * 2; if (newLength < 0) { if (newLength == int.MaxValue) { throw new SerializationException(SR.Serialization_TooManyElements); } newLength = int.MaxValue; } ObjectHolder[] temp = new ObjectHolder[newLength]; Array.Copy(_values, 0, temp, 0, _count); _values = temp; }
internal void Add(ObjectHolder value) { if (_count == _values.Length) { EnlargeArray(); } _values[_count++] = value; }
internal void CompleteObject(ObjectHolder holder, bool bObjectFullyComplete) { FixupHolderList missingElements = holder.m_missingElements; object member = null; ObjectHolder holder3 = null; int num = 0; if (holder.ObjectValue == null) { throw new SerializationException(Environment.GetResourceString("Serialization_MissingObject", new object[] { holder.m_id })); } if (missingElements != null) { if (holder.HasSurrogate || holder.HasISerializable) { SerializationInfo serInfo = holder.m_serInfo; if (serInfo == null) { throw new SerializationException(Environment.GetResourceString("Serialization_InvalidFixupDiscovered")); } if (missingElements != null) { for (int i = 0; i < missingElements.m_count; i++) { if ((missingElements.m_values[i] != null) && this.GetCompletionInfo(missingElements.m_values[i], out holder3, out member, bObjectFullyComplete)) { object objectValue = holder3.ObjectValue; if (this.CanCallGetType(objectValue)) { serInfo.UpdateValue((string)member, objectValue, objectValue.GetType()); } else { serInfo.UpdateValue((string)member, objectValue, typeof(MarshalByRefObject)); } num++; missingElements.m_values[i] = null; if (!bObjectFullyComplete) { holder.DecrementFixupsRemaining(this); holder3.RemoveDependency(holder.m_id); } } } } } else { for (int j = 0; j < missingElements.m_count; j++) { MemberInfo info2; FixupHolder fixup = missingElements.m_values[j]; if ((fixup == null) || !this.GetCompletionInfo(fixup, out holder3, out member, bObjectFullyComplete)) { continue; } if (holder3.TypeLoadExceptionReachable) { holder.TypeLoadException = holder3.TypeLoadException; if (holder.Reachable) { throw new SerializationException(string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Serialization_TypeLoadFailure"), new object[] { holder.TypeLoadException.TypeName })); } } if (holder.Reachable) { holder3.Reachable = true; } switch (fixup.m_fixupType) { case 1: if (holder.RequiresValueTypeFixup) { throw new SerializationException(Environment.GetResourceString("Serialization_ValueTypeFixup")); } break; case 2: info2 = (MemberInfo)member; if (info2.MemberType != MemberTypes.Field) { throw new SerializationException(Environment.GetResourceString("Serialization_UnableToFixup")); } if (!holder.RequiresValueTypeFixup || !holder.ValueTypeFixupPerformed) { goto Label_024C; } if (!this.DoValueTypeFixup((FieldInfo)info2, holder, holder3.ObjectValue)) { throw new SerializationException(Environment.GetResourceString("Serialization_PartialValueTypeFixup")); } goto Label_0260; default: throw new SerializationException(Environment.GetResourceString("Serialization_UnableToFixup")); } ((Array)holder.ObjectValue).SetValue(holder3.ObjectValue, (int[])member); goto Label_0293; Label_024C: FormatterServices.SerializationSetValue(info2, holder.ObjectValue, holder3.ObjectValue); Label_0260: if (holder3.RequiresValueTypeFixup) { holder3.ValueTypeFixupPerformed = true; } Label_0293: num++; missingElements.m_values[j] = null; if (!bObjectFullyComplete) { holder.DecrementFixupsRemaining(this); holder3.RemoveDependency(holder.m_id); } } } this.m_fixupCount -= num; if (missingElements.m_count == num) { holder.m_missingElements = null; } } }
internal void RegisterString(string obj, long objectID, SerializationInfo info, long idOfContainingObj, MemberInfo member) { ObjectHolder holder = new ObjectHolder(obj, objectID, info, null, idOfContainingObj, (FieldInfo) member, null); this.AddObjectHolder(holder); }
internal void CompleteObject(ObjectHolder holder, bool bObjectFullyComplete) { FixupHolderList fixupHolderList = holder.m_missingElements; object member = (object)null; ObjectHolder holder1 = (ObjectHolder)null; int num = 0; if (holder.ObjectValue == null) { throw new SerializationException(Environment.GetResourceString("Serialization_MissingObject", (object)holder.m_id)); } if (fixupHolderList == null) { return; } if (holder.HasSurrogate || holder.HasISerializable) { SerializationInfo serializationInfo1 = holder.m_serInfo; if (serializationInfo1 == null) { throw new SerializationException(Environment.GetResourceString("Serialization_InvalidFixupDiscovered")); } if (fixupHolderList != null) { for (int index = 0; index < fixupHolderList.m_count; ++index) { if (fixupHolderList.m_values[index] != null && this.GetCompletionInfo(fixupHolderList.m_values[index], out holder1, out member, bObjectFullyComplete)) { object objectValue = holder1.ObjectValue; if (this.CanCallGetType(objectValue)) { SerializationInfo serializationInfo2 = serializationInfo1; string name = (string)member; object obj = objectValue; Type type = obj.GetType(); serializationInfo2.UpdateValue(name, obj, type); } else { serializationInfo1.UpdateValue((string)member, objectValue, typeof(MarshalByRefObject)); } ++num; fixupHolderList.m_values[index] = (FixupHolder)null; if (!bObjectFullyComplete) { holder.DecrementFixupsRemaining(this); holder1.RemoveDependency(holder.m_id); } } } } } else { for (int index = 0; index < fixupHolderList.m_count; ++index) { FixupHolder fixup = fixupHolderList.m_values[index]; if (fixup != null && this.GetCompletionInfo(fixup, out holder1, out member, bObjectFullyComplete)) { if (holder1.TypeLoadExceptionReachable) { holder.TypeLoadException = holder1.TypeLoadException; if (holder.Reachable) { throw new SerializationException(Environment.GetResourceString("Serialization_TypeLoadFailure", (object)holder.TypeLoadException.TypeName)); } } if (holder.Reachable) { holder1.Reachable = true; } switch (fixup.m_fixupType) { case 1: if (holder.RequiresValueTypeFixup) { throw new SerializationException(Environment.GetResourceString("Serialization_ValueTypeFixup")); } ((Array)holder.ObjectValue).SetValue(holder1.ObjectValue, (int[])member); break; case 2: MemberInfo fi = (MemberInfo)member; if (fi.MemberType != MemberTypes.Field) { throw new SerializationException(Environment.GetResourceString("Serialization_UnableToFixup")); } if (holder.RequiresValueTypeFixup && holder.ValueTypeFixupPerformed) { if (!this.DoValueTypeFixup((FieldInfo)fi, holder, holder1.ObjectValue)) { throw new SerializationException(Environment.GetResourceString("Serialization_PartialValueTypeFixup")); } } else { FormatterServices.SerializationSetValue(fi, holder.ObjectValue, holder1.ObjectValue); } if (holder1.RequiresValueTypeFixup) { holder1.ValueTypeFixupPerformed = true; break; } break; default: throw new SerializationException(Environment.GetResourceString("Serialization_UnableToFixup")); } ++num; fixupHolderList.m_values[index] = (FixupHolder)null; if (!bObjectFullyComplete) { holder.DecrementFixupsRemaining(this); holder1.RemoveDependency(holder.m_id); } } } } this.m_fixupCount = this.m_fixupCount - (long)num; if (fixupHolderList.m_count != num) { return; } holder.m_missingElements = (FixupHolderList)null; }
internal ObjectHolder(String obj, long objID, SerializationInfo info, ISerializationSurrogate surrogate, long idOfContainingObj, FieldInfo field, int[] arrayIndex) { BCLDebug.Assert(objID>=0,"objID>=0"); m_object=obj; //May be null; m_id=objID; m_flags=0; m_missingElementsRemaining=0; m_missingDecendents = 0; m_dependentObjects=null; m_next=null; m_serInfo = info; m_surrogate = surrogate; m_markForFixupWhenAvailable = false; if (idOfContainingObj!=0 && arrayIndex!=null) { m_valueFixup = new ValueTypeFixupInfo(idOfContainingObj, field, arrayIndex); } if (m_valueFixup!=null) { m_flags|=REQUIRES_VALUETYPE_FIXUP; } }
[System.Security.SecurityCritical] // auto-generated private void FixupSpecialObject(ObjectHolder holder) { ISurrogateSelector uselessSelector=null; Contract.Assert(holder.RequiresSerInfoFixup,"[ObjectManager.FixupSpecialObject]holder.HasSurrogate||holder.HasISerializable"); if (holder.HasSurrogate) { ISerializationSurrogate surrogate = holder.Surrogate; Contract.Assert(surrogate!=null,"surrogate!=null"); object returnValue = surrogate.SetObjectData(holder.ObjectValue, holder.SerializationInfo, m_context, uselessSelector); if (returnValue != null) { if (!holder.CanSurrogatedObjectValueChange && returnValue != holder.ObjectValue) throw new SerializationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Serialization_NotCyclicallyReferenceableSurrogate"), surrogate.GetType().FullName)); holder.SetObjectValue(returnValue, this); } holder.m_surrogate = null; holder.SetFlags(); } else { //Set the object data Contract.Assert(holder.ObjectValue is ISerializable,"holder.m_object is ISerializable"); BCLDebug.Trace("SER","[ObjectManager.FixupSpecialObject]Fixing up ISerializable object ",holder.ObjectValue," with id ",holder.m_id); CompleteISerializableObject(holder.ObjectValue, holder.SerializationInfo, m_context); } //Clear anything that we know that we're not going to need. holder.SerializationInfo=null; holder.RequiresSerInfoFixup = false; // For value types, fixups would have been done. So the newly fixed object must be copied // to its container. if (holder.RequiresValueTypeFixup && holder.ValueTypeFixupPerformed){ DoValueTypeFixup(null, holder, holder.ObjectValue); } DoNewlyRegisteredObjectFixups(holder); }
internal virtual void Add(ObjectHolder value) { if (m_count==m_values.Length) { EnlargeArray(); } m_values[m_count++]=value; }
internal ObjectHolder(Object obj, long objID, SerializationInfo info, ISerializationSurrogate surrogate, long idOfContainingObj, FieldInfo field, int[] arrayIndex) { BCLDebug.Assert(objID>=0,"objID>=0"); m_object=obj; //May be null; m_id=objID; m_flags=0; m_missingElementsRemaining=0; m_missingDecendents = 0; m_dependentObjects=null; m_next=null; m_serInfo = info; m_surrogate = surrogate; m_markForFixupWhenAvailable = false; if (idOfContainingObj!=0 && ((field!=null && field.FieldType.IsValueType) || arrayIndex!=null)) { if (idOfContainingObj == objID) { throw new SerializationException(Environment.GetResourceString("Serialization_ParentChildIdentical")); } m_valueFixup = new ValueTypeFixupInfo(idOfContainingObj, field, arrayIndex); } SetFlags(); }
internal ObjectHolder( object obj, long objID, SerializationInfo info, ISerializationSurrogate surrogate, long idOfContainingObj, FieldInfo field, int[] arrayIndex) { Debug.Assert(objID >= 0, "objID>=0"); _object = obj; //May be null; _id = objID; _flags = 0; _missingElementsRemaining = 0; _missingDecendents = 0; _dependentObjects = null; _next = null; _serInfo = info; _surrogate = surrogate; _markForFixupWhenAvailable = false; if (obj is TypeLoadExceptionHolder) { _typeLoad = (TypeLoadExceptionHolder)obj; } if (idOfContainingObj != 0 && ((field != null && field.FieldType.IsValueType) || arrayIndex != null)) { if (idOfContainingObj == objID) { throw new SerializationException(SR.Serialization_ParentChildIdentical); } _valueFixup = new ValueTypeFixupInfo(idOfContainingObj, field, arrayIndex); } SetFlags(); }
/*===============================AddObjectHolder================================ **Action: Add the provided ObjectHolder to collection of ObjectHolders. ** Enlarges the collection as appropriate. **Returns: void **Arguments: holder The ObjectHolder to be added. **Exceptions: Internal only. Caller should verify that <CODE>holder</CODE> is ** not null. ==============================================================================*/ private void AddObjectHolder(ObjectHolder holder) { BCLDebug.Assert(holder!=null,"holder!=null"); BCLDebug.Trace("SER", "[AddObjectHolder]Adding ObjectHolder with id: ", holder.m_id, " Current Bins: ", m_objects.Length); BCLDebug.Assert(holder.m_id>=0,"holder.m_id>=0"); //If the id that we need to place is greater than our current length, and less //than the maximum allowable size of the array. We need to double the size //of the array. If the array has already reached it's maximum allowable size, //we chain elements off of the buckets. if (holder.m_id>=m_objects.Length && m_objects.Length != MaxArraySize) { int newSize=MaxArraySize; if (holder.m_id<(MaxArraySize/2)) { newSize = (m_objects.Length * 2); //Keep doubling until we're larger than our target size. //We could also do this with log operations, but that would //be slower than the brute force approach. while (newSize<=holder.m_id && newSize<MaxArraySize) { newSize*=2; } if (newSize>MaxArraySize) { newSize=MaxArraySize; } } BCLDebug.Trace("SER", "[AddObjectHolder]Reallocating m_objects to have ", newSize, " bins"); ObjectHolder[] temp = new ObjectHolder[newSize]; Array.Copy(m_objects, temp, m_objects.Length); m_objects = temp; } //Find the bin in which we live and make this new element the first element in the bin. int index = (int)(holder.m_id & ArrayMask); BCLDebug.Trace("SER", "[AddObjectHolder]Trying to put an object in bin ", index); ObjectHolder tempHolder = m_objects[index]; holder.m_next = tempHolder; m_objects[index] = holder; }
private bool DoValueTypeFixup(FieldInfo memberToFix, ObjectHolder holder, object value) { FieldInfo[] array = new FieldInfo[4]; int num = 0; int[] array2 = null; object objectValue = holder.ObjectValue; while (holder.RequiresValueTypeFixup) { if (num + 1 >= array.Length) { FieldInfo[] array3 = new FieldInfo[array.Length * 2]; Array.Copy(array, array3, array.Length); array = array3; } ValueTypeFixupInfo valueFixup = holder.ValueFixup; objectValue = holder.ObjectValue; if (valueFixup.ParentField != null) { FieldInfo parentField = valueFixup.ParentField; ObjectHolder objectHolder = this.FindObjectHolder(valueFixup.ContainerID); if (objectHolder.ObjectValue == null) { break; } if (Nullable.GetUnderlyingType(parentField.FieldType) != null) { array[num] = parentField.FieldType.GetField("value", BindingFlags.Instance | BindingFlags.NonPublic); num++; } array[num] = parentField; holder = objectHolder; num++; } else { holder = this.FindObjectHolder(valueFixup.ContainerID); array2 = valueFixup.ParentIndex; if (holder.ObjectValue == null) { break; } break; } } if (!(holder.ObjectValue is Array) && holder.ObjectValue != null) { objectValue = holder.ObjectValue; } if (num != 0) { FieldInfo[] array4 = new FieldInfo[num]; for (int i = 0; i < num; i++) { FieldInfo fieldInfo = array[num - 1 - i]; SerializationFieldInfo serializationFieldInfo = fieldInfo as SerializationFieldInfo; array4[i] = ((serializationFieldInfo == null) ? fieldInfo : serializationFieldInfo.FieldInfo); } TypedReference typedReference = TypedReference.MakeTypedReference(objectValue, array4); if (memberToFix != null) { ((RuntimeFieldInfo)memberToFix).SetValueDirect(typedReference, value); } else { TypedReference.SetTypedReference(typedReference, value); } } else if (memberToFix != null) { FormatterServices.SerializationSetValue(memberToFix, objectValue, value); } if (array2 != null && holder.ObjectValue != null) { ((Array)holder.ObjectValue).SetValue(objectValue, array2); } return(true); }
private void EnlargeArray() { BCLDebug.Trace("SER", "[ObjectHolderList.EnlargeArray]Enlarging array of size ", m_values.Length); int newLength = m_values.Length*2; if (newLength<0) { if (newLength==Int32.MaxValue) { throw new SerializationException(Environment.GetResourceString("Serialization_TooManyElements")); } newLength=Int32.MaxValue; } ObjectHolder[] temp = new ObjectHolder[newLength]; Array.Copy(m_values, temp, m_count); m_values = temp; }
internal void CompleteObject(ObjectHolder holder, bool bObjectFullyComplete) { FixupHolderList missingElements = holder.m_missingElements; object obj = null; ObjectHolder objectHolder = null; int num = 0; if (holder.ObjectValue == null) { throw new SerializationException(Environment.GetResourceString("Serialization_MissingObject", new object[] { holder.m_id })); } if (missingElements == null) { return; } if (holder.HasSurrogate || holder.HasISerializable) { SerializationInfo serInfo = holder.m_serInfo; if (serInfo == null) { throw new SerializationException(Environment.GetResourceString("Serialization_InvalidFixupDiscovered")); } if (missingElements != null) { for (int i = 0; i < missingElements.m_count; i++) { if (missingElements.m_values[i] != null && this.GetCompletionInfo(missingElements.m_values[i], out objectHolder, out obj, bObjectFullyComplete)) { object objectValue = objectHolder.ObjectValue; if (this.CanCallGetType(objectValue)) { serInfo.UpdateValue((string)obj, objectValue, objectValue.GetType()); } else { serInfo.UpdateValue((string)obj, objectValue, typeof(MarshalByRefObject)); } num++; missingElements.m_values[i] = null; if (!bObjectFullyComplete) { holder.DecrementFixupsRemaining(this); objectHolder.RemoveDependency(holder.m_id); } } } } } else { for (int j = 0; j < missingElements.m_count; j++) { FixupHolder fixupHolder = missingElements.m_values[j]; if (fixupHolder != null && this.GetCompletionInfo(fixupHolder, out objectHolder, out obj, bObjectFullyComplete)) { if (objectHolder.TypeLoadExceptionReachable) { holder.TypeLoadException = objectHolder.TypeLoadException; if (holder.Reachable) { throw new SerializationException(Environment.GetResourceString("Serialization_TypeLoadFailure", new object[] { holder.TypeLoadException.TypeName })); } } if (holder.Reachable) { objectHolder.Reachable = true; } int fixupType = fixupHolder.m_fixupType; if (fixupType != 1) { if (fixupType != 2) { throw new SerializationException(Environment.GetResourceString("Serialization_UnableToFixup")); } MemberInfo memberInfo = (MemberInfo)obj; if (memberInfo.MemberType != MemberTypes.Field) { throw new SerializationException(Environment.GetResourceString("Serialization_UnableToFixup")); } if (holder.RequiresValueTypeFixup && holder.ValueTypeFixupPerformed) { if (!this.DoValueTypeFixup((FieldInfo)memberInfo, holder, objectHolder.ObjectValue)) { throw new SerializationException(Environment.GetResourceString("Serialization_PartialValueTypeFixup")); } } else { FormatterServices.SerializationSetValue(memberInfo, holder.ObjectValue, objectHolder.ObjectValue); } if (objectHolder.RequiresValueTypeFixup) { objectHolder.ValueTypeFixupPerformed = true; } } else { if (holder.RequiresValueTypeFixup) { throw new SerializationException(Environment.GetResourceString("Serialization_ValueTypeFixup")); } ((Array)holder.ObjectValue).SetValue(objectHolder.ObjectValue, (int[])obj); } num++; missingElements.m_values[j] = null; if (!bObjectFullyComplete) { holder.DecrementFixupsRemaining(this); objectHolder.RemoveDependency(holder.m_id); } } } } this.m_fixupCount -= (long)num; if (missingElements.m_count == num) { holder.m_missingElements = null; } }
private void FixupSpecialObject(ObjectHolder holder) { ISurrogateSelector uselessSelector=null; BCLDebug.Assert(holder.RequiresSerInfoFixup,"[ObjectManager.FixupSpecialObject]holder.HasSurrogate||holder.HasISerializable"); if (holder.HasSurrogate) { ISerializationSurrogate surrogate = holder.Surrogate; BCLDebug.Assert(surrogate!=null,"surrogate!=null"); surrogate.SetObjectData(holder.ObjectValue, holder.SerializationInfo, m_context, uselessSelector); } else { //Set the object data BCLDebug.Assert(holder.ObjectValue is ISerializable,"holder.m_object is ISerializable"); BCLDebug.Trace("SER","[ObjectManager.FixupSpecialObject]Fixing up ISerializable object ",holder.ObjectValue," with id ",holder.m_id); CompleteISerializableObject(holder.ObjectValue, holder.SerializationInfo, m_context); } //Clear anything that we know that we're not going to need. holder.SerializationInfo=null; holder.RequiresSerInfoFixup = false; DoNewlyRegisteredObjectFixups(holder); }
// Token: 0x06005159 RID: 20825 RVA: 0x0011D4FC File Offset: 0x0011B6FC internal void RegisterString(string obj, long objectID, SerializationInfo info, long idOfContainingObj, MemberInfo member) { ObjectHolder holder = new ObjectHolder(obj, objectID, info, null, idOfContainingObj, (FieldInfo)member, null); this.AddObjectHolder(holder); }
/*===============================DoValueTypeFixup=============================== **Action: **Returns: **Arguments: ** memberToFix -- the member in the object contained in holder being fixed up. ** holder -- the ObjectHolder for the object (a value type in this case) being completed. ** value -- the data to set into the field. **Exceptions: ==============================================================================*/ private bool DoValueTypeFixup(FieldInfo memberToFix, ObjectHolder holder, Object value) { TypedReference typedRef; FieldInfo[] fieldsTemp=new FieldInfo[4]; FieldInfo[] fields=null; int currentFieldIndex=0; int[] arrayIndex = null; ValueTypeFixupInfo currFixup=null; Object fixupObj=holder.ObjectValue; ObjectHolder originalHolder = holder; BCLDebug.Assert(holder!=null, "[TypedReferenceBuilder.ctor]holder!=null"); BCLDebug.Assert(holder.RequiresValueTypeFixup, "[TypedReferenceBuilder.ctor]holder.RequiresValueTypeFixup"); //In order to get a TypedReference, we need to get a list of all of the FieldInfos to //create the path from our outermost containing object down to the actual field which //we'd like to set. This loop is used to build up that list. while (holder.RequiresValueTypeFixup) { //Enlarge the array if required (this is actually fairly unlikely as it would require that we //be nested more than 4 deep. if (currentFieldIndex>=fieldsTemp.Length) { FieldInfo[] temp = new FieldInfo[fieldsTemp.Length * 2]; Array.Copy(fieldsTemp, temp, fieldsTemp.Length); fieldsTemp = temp; } //Get the fixup information. If we have data for our parent field, add it to our list //and continue the walk up to find the next outermost containing object. We cache the //object that we have. In most cases, we could have just grabbed it after this loop finished. //However, if the outermost containing object is an array, we need the object one further //down the chain, so we have to do a lot of caching. currFixup = holder.ValueFixup; fixupObj = holder.ObjectValue; //Save the most derived if (currFixup.ParentField!=null) { fieldsTemp[currentFieldIndex] = currFixup.ParentField; holder = FindObjectHolder(currFixup.ContainerID); if (holder.ObjectValue==null) { return false; } currentFieldIndex++; } else { //If we find an index into an array, save that information. BCLDebug.Assert(currFixup.ParentIndex!=null, "[ObjectManager.DoValueTypeFixup]currFixup.ParentIndex!=null"); holder = FindObjectHolder(currFixup.ContainerID); //find the array to fix. arrayIndex = currFixup.ParentIndex; if (holder.ObjectValue==null) { break; } break; } } //If the outermost container isn't an array, we need to grab it. Otherwise, we just need to hang onto //the boxed object that we already grabbed. We'll assign the boxed object back into the array as the //last step. if (!(holder.ObjectValue is Array) && holder.ObjectValue!=null) { fixupObj = holder.ObjectValue; BCLDebug.Assert(fixupObj!=null, "[ObjectManager.DoValueTypeFixup]FixupObj!=null"); } if (currentFieldIndex!=0) { //MakeTypedReference requires an array of exactly the correct size that goes from the outermost object //in to the innermost field. We currently have an array of arbitrary size that goes from the innermost //object outwards. We create an array of the right size and do the copy. fields = new FieldInfo[currentFieldIndex]; for (int i=0; i<currentFieldIndex; i++) { fields[i] = fieldsTemp[(currentFieldIndex - 1 - i)]; } BCLDebug.Assert(fixupObj!=null, "[ObjectManager.DoValueTypeFixup]fixupObj!=null"); //Make the TypedReference and use it to set the value. typedRef = TypedReference.MakeTypedReference(fixupObj, fields); ((RuntimeFieldInfo)memberToFix).SetValueDirectImpl(typedRef, value, false); } else { FormatterServices.SerializationSetValue(memberToFix, fixupObj, value); } //If we have an array index, it means that our outermost container was an array. We don't have //any way to build a TypedReference into an array, so we'll use the array functions to set the value. if (arrayIndex!=null && holder.ObjectValue!=null) { ((Array)(holder.ObjectValue)).SetValue(fixupObj, arrayIndex); } return true; }
public void RegisterObject(object obj, long objectID, SerializationInfo info, long idOfContainingObj, MemberInfo member, int[] arrayIndex) { if (obj == null) { throw new ArgumentNullException("obj"); } if (objectID <= 0L) { throw new ArgumentOutOfRangeException("objectID", Environment.GetResourceString("ArgumentOutOfRange_ObjectID")); } if (member != null && !(member is RuntimeFieldInfo) && !(member is SerializationFieldInfo)) { throw new SerializationException(Environment.GetResourceString("Serialization_UnknownMemberInfo")); } ISerializationSurrogate surrogate = null; if (this.m_selector != null) { Type type; if (this.CanCallGetType(obj)) { type = obj.GetType(); } else { type = typeof(MarshalByRefObject); } ISurrogateSelector surrogateSelector; surrogate = this.m_selector.GetSurrogate(type, this.m_context, out surrogateSelector); } if (obj is IDeserializationCallback) { DeserializationEventHandler handler = new DeserializationEventHandler(((IDeserializationCallback)obj).OnDeserialization); this.AddOnDeserialization(handler); } if (arrayIndex != null) { arrayIndex = (int[])arrayIndex.Clone(); } ObjectHolder objectHolder = this.FindObjectHolder(objectID); if (objectHolder == null) { objectHolder = new ObjectHolder(obj, objectID, info, surrogate, idOfContainingObj, (FieldInfo)member, arrayIndex); this.AddObjectHolder(objectHolder); if (objectHolder.RequiresDelayedFixup) { this.SpecialFixupObjects.Add(objectHolder); } this.AddOnDeserialized(obj); return; } if (objectHolder.ObjectValue != null) { throw new SerializationException(Environment.GetResourceString("Serialization_RegisterTwice")); } objectHolder.UpdateData(obj, info, surrogate, idOfContainingObj, (FieldInfo)member, arrayIndex, this); if (objectHolder.DirectlyDependentObjects > 0) { this.CompleteObject(objectHolder, false); } if (objectHolder.RequiresDelayedFixup) { this.SpecialFixupObjects.Add(objectHolder); } if (objectHolder.CompletelyFixed) { this.DoNewlyRegisteredObjectFixups(objectHolder); objectHolder.DependentObjects = null; } if (objectHolder.TotalDependentObjects > 0) { this.AddOnDeserialized(obj); return; } this.RaiseOnDeserializedEvent(obj); }
/*========================DoNewlyRegisteredObjectFixups========================= **Action: This is called immediately after we register a new object. Walk that objects ** dependency list (if it has one) and decrement the counters on each object for ** the number of unsatisfiable references. If the count reaches 0, go ahead ** and process the object. **Returns: void **Arguments: dependencies The list of dependent objects **Exceptions: None. ==============================================================================*/ private void DoNewlyRegisteredObjectFixups(ObjectHolder holder) { ObjectHolder temp; if (holder.IsIncompleteObjectReference) { BCLDebug.Trace("SER","[ObjectManager.DoNewlyRegisteredObjectFixups]Object is an Incomplete Object Reference. Exiting."); return; } LongList dependencies = holder.DependentObjects; //If we don't have any dependencies, we're done. if (dependencies==null) { BCLDebug.Trace("SER", "[DoNewlyRegisteredObjectFixups]Exiting with no dependencies"); return; } //Walk all of the dependencies and decrement the counter on each of uncompleted objects. //If one of the counters reaches 0, all of it's fields have been completed and we should //go take care of its fixups. BCLDebug.Trace("SER", "[ObjectManager.DoNewlyRegisteredObjectFixups]Object has ", dependencies.Count, " fixups registered"); dependencies.StartEnumeration(); while (dependencies.MoveNext()) { temp = FindObjectHolder(dependencies.Current); BCLDebug.Trace("SER", "[ObjectManager.DoNewlyRegisteredObjectFixups]Doing a fixup on object: ", temp.m_id); BCLDebug.Assert(temp.DirectlyDependentObjects>0,"temp.m_missingElementsRemaining>0"); temp.DecrementFixupsRemaining(this); if (((temp.DirectlyDependentObjects))==0) { BCLDebug.Trace("SER", "[DoNewlyRegisteredObjectFixups]Doing fixup for object ", temp.m_id); BCLDebug.Trace("SER", "[DoNewlyRegisteredObjectFixups]ObjectValue ", ((temp.ObjectValue==null)?"<null>":temp.ObjectValue)); // If this is null, we have the case where a fixup was registered for a child, the object // required by the fixup was provided, and the object to be fixed hasn't yet been seen. if (temp.ObjectValue!=null) { CompleteObject(temp, true); } else { temp.MarkForCompletionWhenAvailable(); } } } BCLDebug.Trace("SER", "[ObjectManager.DoNewlyRegisteredObjectFixups]Exiting."); }
public virtual void DoFixups() { int num = -1; while (num != 0) { num = 0; ObjectHolderListEnumerator fixupEnumerator = this.SpecialFixupObjects.GetFixupEnumerator(); while (fixupEnumerator.MoveNext()) { ObjectHolder objectHolder = fixupEnumerator.Current; if (objectHolder.ObjectValue == null) { throw new SerializationException(Environment.GetResourceString("Serialization_ObjectNotSupplied", new object[] { objectHolder.m_id })); } if (objectHolder.TotalDependentObjects == 0) { if (objectHolder.RequiresSerInfoFixup) { this.FixupSpecialObject(objectHolder); num++; } else if (!objectHolder.IsIncompleteObjectReference) { this.CompleteObject(objectHolder, true); } if (objectHolder.IsIncompleteObjectReference && this.ResolveObjectReference(objectHolder)) { num++; } } } } if (this.m_fixupCount != 0L) { for (int i = 0; i < this.m_objects.Length; i++) { for (ObjectHolder objectHolder = this.m_objects[i]; objectHolder != null; objectHolder = objectHolder.m_next) { if (objectHolder.TotalDependentObjects > 0) { this.CompleteObject(objectHolder, true); } } if (this.m_fixupCount == 0L) { return; } } throw new SerializationException(Environment.GetResourceString("Serialization_IncorrectNumberOfFixups")); } if (this.TopObject is TypeLoadExceptionHolder) { throw new SerializationException(Environment.GetResourceString("Serialization_TypeLoadFailure", new object[] { ((TypeLoadExceptionHolder)this.TopObject).TypeName })); } }
/// <include file='doc\ObjectManager.uex' path='docs/doc[@for="ObjectManager.RegisterObject3"]/*' /> public void RegisterObject(Object obj, long objectID, SerializationInfo info, long idOfContainingObj, MemberInfo member, int[] arrayIndex) { ObjectHolder temp; ISerializationSurrogate surrogate = null; ISurrogateSelector useless; if (obj==null) { throw new ArgumentNullException("obj"); } if (objectID<=0) { throw new ArgumentOutOfRangeException("objectID", Environment.GetResourceString("ArgumentOutOfRange_ObjectID")); } if (member!=null && !(member is RuntimeFieldInfo) && !(member is SerializationFieldInfo)) { throw new SerializationException(Environment.GetResourceString("Serialization_UnknownMemberInfo")); } if (m_selector != null) { Type selectorType=null; if (CanCallGetType(obj)) { selectorType = obj.GetType(); } else { selectorType = typeof(MarshalByRefObject); } BCLDebug.Trace("SER", "[ObjectManager.RegisterObject]ID: ", objectID, "\tType: ", selectorType, "\tValue: ", obj); //If we need a surrogate for this object, lets find it now. surrogate = m_selector.GetSurrogate(selectorType, m_context, out useless); } //The object is interested in DeserializationEvents so lets register it. if (obj is IDeserializationCallback) { DeserializationEventHandler d = new DeserializationEventHandler(((IDeserializationCallback)obj).OnDeserialization); AddOnDeserialization(d); } temp = FindObjectHolder(objectID); //This is the first time which we've seen the object, we need to create a new holder. if (temp==null) { BCLDebug.Trace("SER", "[ObjectManager.RegisterObject]Adding a new object holder for ", objectID); //Formatter developers may cache and reuse arrayIndex in their code. //So that we don't get bitten by this, take a copy up front. int [] arrayTemp=null; if (arrayIndex!=null) { arrayTemp = (int[])arrayIndex.Clone(); } temp = new ObjectHolder(obj, objectID, info, surrogate, idOfContainingObj, (FieldInfo)member, arrayTemp); AddObjectHolder(temp); if (temp.RequiresDelayedFixup) { SpecialFixupObjects.Add(temp); } return; } //If the object isn't null, we've registered this before. Not good. if (temp.ObjectValue!=null) { throw new SerializationException(Environment.GetResourceString("Serialization_RegisterTwice")); } //Complete the data in the ObjectHolder temp.UpdateData(obj, info, surrogate, idOfContainingObj, (FieldInfo)member, arrayIndex, this); // The following case will only be true when somebody has registered a fixup on an object before // registering the object itself. I don't believe that most well-behaved formatters will do this, // but we need to allow it anyway. We will walk the list of fixups which have been recorded on // the new object and fix those that we can. Because the user could still register later fixups // on this object, we won't call any implementations of ISerializable now. If that's required, // it will have to be handled by the code in DoFixups. // README README: We have to do the UpdateData before if (temp.DirectlyDependentObjects>0) { CompleteObject(temp, false); } if (temp.RequiresDelayedFixup) { BCLDebug.Trace("SER", "[ObjectManager.RegisterObject]Tracking incomplete objref for element: ", temp.m_id); SpecialFixupObjects.Add(temp); } if (!(temp.IsIncompleteObjectReference)) { //Here's where things get tricky. If this isn't an instance of IObjectReference, we need to walk it's fixup //chain and decrement the counters on anything that has reached 0. Once we've notified all of the dependencies, //we can simply clear the list of dependent objects. BCLDebug.Trace("SER", "[ObjectManager.RegisterObject]Calling DoNewlyRegisteredObjectFixups for element: ", temp.m_id); DoNewlyRegisteredObjectFixups(temp); temp.DependentObjects=null; } BCLDebug.Trace("SER", "[ObjectManager.RegisterObject]Exiting."); }
private bool DoValueTypeFixup(FieldInfo memberToFix, ObjectHolder holder, object value) { FieldInfo[] sourceArray = new FieldInfo[4]; FieldInfo[] flds = null; int index = 0; int[] indices = null; ValueTypeFixupInfo valueFixup = null; object objectValue = holder.ObjectValue; while (holder.RequiresValueTypeFixup) { if ((index + 1) >= sourceArray.Length) { FieldInfo[] destinationArray = new FieldInfo[sourceArray.Length * 2]; Array.Copy(sourceArray, destinationArray, sourceArray.Length); sourceArray = destinationArray; } valueFixup = holder.ValueFixup; objectValue = holder.ObjectValue; if (valueFixup.ParentField != null) { FieldInfo parentField = valueFixup.ParentField; ObjectHolder holder2 = this.FindObjectHolder(valueFixup.ContainerID); if (holder2.ObjectValue == null) { break; } if (Nullable.GetUnderlyingType(parentField.FieldType) != null) { sourceArray[index] = parentField.FieldType.GetField("value", BindingFlags.NonPublic | BindingFlags.Instance); index++; } sourceArray[index] = parentField; holder = holder2; index++; } else { holder = this.FindObjectHolder(valueFixup.ContainerID); indices = valueFixup.ParentIndex; if (holder.ObjectValue != null) { } break; } } if (!(holder.ObjectValue is Array) && (holder.ObjectValue != null)) { objectValue = holder.ObjectValue; } if (index != 0) { flds = new FieldInfo[index]; for (int i = 0; i < index; i++) { FieldInfo info3 = sourceArray[(index - 1) - i]; SerializationFieldInfo info4 = info3 as SerializationFieldInfo; flds[i] = (info4 == null) ? info3 : info4.FieldInfo; } TypedReference reference = TypedReference.MakeTypedReference(objectValue, flds); if (memberToFix != null) { ((RuntimeFieldInfo)memberToFix).SetValueDirect(reference, value); } else { TypedReference.SetTypedReference(reference, value); } } else if (memberToFix != null) { FormatterServices.SerializationSetValue(memberToFix, objectValue, value); } if ((indices != null) && (holder.ObjectValue != null)) { ((Array)holder.ObjectValue).SetValue(objectValue, indices); } return(true); }