private void FixupSpecialObject(ObjectHolder holder) { ISurrogateSelector selector = null; if (holder.HasSurrogate) { ISerializationSurrogate surrogate = holder.Surrogate; object obj = surrogate.SetObjectData(holder.ObjectValue, holder.SerializationInfo, this.m_context, selector); if (obj != null) { if (!holder.CanSurrogatedObjectValueChange && obj != holder.ObjectValue) { throw new SerializationException(string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Serialization_NotCyclicallyReferenceableSurrogate"), surrogate.GetType().FullName)); } holder.SetObjectValue(obj, this); } holder.m_surrogate = null; holder.SetFlags(); } else { this.CompleteISerializableObject(holder.ObjectValue, holder.SerializationInfo, this.m_context); } holder.SerializationInfo = null; holder.RequiresSerInfoFixup = false; if (holder.RequiresValueTypeFixup && holder.ValueTypeFixupPerformed) { this.DoValueTypeFixup(null, holder, holder.ObjectValue); } this.DoNewlyRegisteredObjectFixups(holder); }
/// <summary> /// /// </summary> /// <param name="surrogate"></param> /// <param name="obj"></param> /// <param name="firstChild"></param> /// <returns></returns> protected object DeserializeSurrogate(ISerializationSurrogate surrogate, XmlDeserializer.DeserializeContext context, Component comp, Type objType, int objId, XmlNode firstChild) { SerializationInfo info = new SerializationInfo(objType, new DummyConverter()); var cnt = new XmlDeserializer.DeserializeContext(); cnt.Deserializer = context.Deserializer; cnt.ElementBeingParsed = (XmlElement)firstChild; cnt.ObjectType = objType; cnt.deserializationObjCache = context.deserializationObjCache; cnt.deserializationTypeCache = context.deserializationTypeCache; //we need to store the component in the cache now otherwise we might //not be able to reference it within itself. if (objId >= 0) { context.deserializationObjCache[objId] = comp; } //float through the xml nodes and see what items we need to collect. for (XmlNode node = firstChild; node != null; node = node.NextSibling) { if (cnt.Deserializer.CheckForDeferedDeserialization(comp, node.Name, (XmlElement)node)) { continue; } //Take Note! We are passing the component as the owner object. This is so that we //can defer deserialization of reference back to this gameObject since we haven't added //it to the cache just yet. object val = context.Deserializer.DeserializeCore((XmlElement)node, null);// comp); if (val != null) { info.AddValue(node.Name, val, val.GetType()); } else { info.AddValue(node.Name, null, typeof(object)); } } var obj = surrogate.SetObjectData(comp, info, new StreamingContext(StreamingContextStates.File, context), context.Deserializer); return(obj); }
private object deserializeObject(XmlReader xmlReader, int id, Type objectType, SerializationInfo info, IFormatterConverter converter) { System.Diagnostics.Debug.Assert(null != xmlReader, "The 'xmlReader' argument cannot be null."); System.Diagnostics.Debug.Assert(null != objectType, "The 'objectType' argument cannot be null."); System.Diagnostics.Debug.Assert(null != info, "The 'info' argument cannot be null."); System.Diagnostics.Debug.Assert(null != converter, "The 'converter' argument cannot be null."); object deserialized = null; // Return value if (!objectType.IsValueType) { deserialized = FormatterServices.GetUninitializedObject(objectType); // Register object this.registeredReferenceObjects.Add(deserialized, id); } bool hasSerializableMembers = this.hasSerializableMembers(objectType, this.context); if (hasSerializableMembers) { while (xmlReader.IsStartElement()) { SerializationEntry entry = this.deserialize(xmlReader, converter); info.AddValue(entry.Name, entry.Value, entry.ObjectType); } } else { if (XmlNodeType.Element == xmlReader.NodeType) { xmlReader.ReadStartElement(); } } ISurrogateSelector selector = null; ISerializationSurrogate surrogate = this.getSerializationSurrogate(objectType, out selector); deserialized = surrogate.SetObjectData(deserialized, info, this.context, selector); return(deserialized); }
public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector?selector) { return(_innerSurrogate.SetObjectData(obj, info, context, selector)); }
/// <summary> /// Reads the object. /// </summary> /// <returns>The object.</returns> /// <param name="type">Type.</param> protected virtual object ReadObject(Type type) { object result = null; if (type.IsValueType) { result = Activator.CreateInstance(type); } else { result = FormatterServices.GetUninitializedObject(type); } ISurrogateSelector selector = null; SerializationInfo info = null; ISerializationSurrogate surrogate = null; if (m_SurrogateSelector != null) { surrogate = m_SurrogateSelector.GetSurrogate(type, m_Context, out selector); if (surrogate != null) { info = new SerializationInfo(type, new FormatterConverter()); } } if (result != null) { int length = m_Reader.ReadInt32(); for (int i = 0; i < length; i++) { string name = m_Reader.ReadString(); FieldInfo field = type.GetField(name); if (field != null) { if (info != null) { info.AddValue(name, Read(field.FieldType), field.FieldType); } else { field.SetValue(result, Read(field.FieldType)); } } } length = m_Reader.ReadInt32(); for (int i = 0; i < length; i++) { string name = m_Reader.ReadString(); PropertyInfo property = type.GetProperty(name); if (property != null) { if (info != null) { info.AddValue(name, Read(property.PropertyType), property.PropertyType); } else { property.SetValue(result, Read(property.PropertyType), BindingFlags.Default, null, null, null); } } } } if (surrogate != null) { surrogate.SetObjectData(result, info, m_Context, selector); } return(result); }
/// <summary> /// Reads the object. /// </summary> /// <returns>The object.</returns> /// <param name="type">Type.</param> /// <param name="json">Json.</param> protected virtual object ReadObject(Type type, string json) { object result = null; if (type.IsValueType) { result = Activator.CreateInstance(type); } else { result = FormatterServices.GetUninitializedObject(type); } ISurrogateSelector selector = null; SerializationInfo info = null; ISerializationSurrogate surrogate = null; if (m_SurrogateSelector != null) { surrogate = m_SurrogateSelector.GetSurrogate(type, m_Context, out selector); if (surrogate != null) { info = new SerializationInfo(type, new FormatterConverter()); } } if (result != null) { string [] items = json.SplitJson(); for (int i = 0; i < items.Length; i += 2) { string name = Read <string> (items [i]); FieldInfo field = type.GetField(name); if (field != null) { if (info != null) { info.AddValue(name, Read(field.FieldType, items [i + 1])); } else { field.SetValue(result, Read(field.FieldType, items [i + 1])); } continue; } PropertyInfo property = type.GetProperty(name); if (property != null) { if (info != null) { info.AddValue(name, Read(property.PropertyType, items [i + 1])); } else { property.SetValue( result, Read(property.PropertyType, items [i + 1]), BindingFlags.Default, null, null, null); } continue; } } if (surrogate != null) { surrogate.SetObjectData(result, info, m_Context, selector); } } return(result); }
//Reads an object from the XML and initializes the object. private object InitializeObject(XmlTextReader reader, FormatterConverter converter) { Type actualType; int id; //Check if a type or ref attribute is present if (!reader.HasAttributes) { throw new SerializationException("A non-primitive element was found without attributes."); } //Check for a ref attribute string reference = reader.GetAttribute("ref"); //, "http://www.w3.org/2001/XMLSchema-instance"); //References require a previously deserialized object if (reference != null) { if (!int.TryParse(reference, out id)) { throw new SerializationException("Non numeric reference id found."); } object existing = null; if (!_idObjects.TryGetValue(id, out existing)) { throw new SerializationException(string.Format("An object reference with id {0} was not previously deserialized.", reference)); } return(existing); } //Get the type name string actualTypeName = reader.GetAttribute("type"); // "http://www.w3.org/2001/XMLSchema-instance"); actualType = Binder.BindToType("", actualTypeName); //Get the id attribute string objectId = reader.GetAttribute("id"); //, "http://www.w3.org/2001/XMLSchema-instance"); //If the id is null then the object reference is null so return null if (objectId == null) { return(null); } //Convert to an integer value if (!int.TryParse(objectId, out id)) { throw new SerializationException("An object id could not be converted to an integer value."); } ISurrogateSelector selector1 = null; ISerializationSurrogate serializationSurrogate = null; SerializationInfo info = null; if (SurrogateSelector == null) { throw new NullReferenceException("An error occurred deserializing an object. The SurrogateSelector property may not be null."); } serializationSurrogate = SurrogateSelector.GetSurrogate(actualType, Context, out selector1); if (serializationSurrogate == null) { throw new NullReferenceException(string.Format("An error occurred deserializing an object. A surrogate was not found for type {0}", actualType.Name)); } //Use surrogate info = new SerializationInfo(actualType, converter); //Create a instance of the type, or use the existing object graph object initializedObject; if (Target == null) { initializedObject = FormatterServices.GetUninitializedObject(actualType); //Call the default constructor //Formatter could be expanded to use non default constructors at some later stage ConstructorInfo ci = actualType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, System.Type.EmptyTypes, null); if (ci == null) { throw new SerializationException(string.Format("Type {0} must implement a parameterless constructor.", actualType.FullName)); } ci.Invoke(initializedObject, null); } else { initializedObject = Target; Target = null; //Reset target so that it cannot be used recursively } //Add the object to the list of id objects _idObjects.Add(id, initializedObject); //Determine if a list or collection IDictionary dictionary = null; IList list = null; int index = 0; //Read the first element reader.ReadStartElement(); while (reader.IsStartElement()) { //Determine type string typeName = reader.GetAttribute("type"); //, "http://www.w3.org/2001/XMLSchema-instance"); Type childType = Binder.BindToType("", typeName); //Get a key, if any string key = reader.GetAttribute("key"); //Check for a uri attribute string uri = reader.GetAttribute("uri"); //Check if a collection if (reader.Name == "Collection" && reader.IsStartElement()) { if (typeName == "IDictionary") { dictionary = initializedObject as IDictionary; list = null; } else if (typeName == "IList") { list = initializedObject as IList; dictionary = null; } reader.ReadStartElement(); } //Check for a resource entry else if (uri != null) { //Uris require a resource preloaded in the _resources collection ResourceEntry resourceEntry; if (!_resources.TryGetValue(uri, out resourceEntry)) { throw new SerializationException(string.Format("A resource with uri {0} was not found in the resources collection.", uri)); } info.AddValue(resourceEntry.Name, resourceEntry.Value); reader.Read(); } //Process all other elements else { object parsedObject = null; //Check if the value can be directly determined or that the type is a complex type. if (childType.IsPrimitive || childType == typeof(string) || childType.IsEnum || childType == typeof(DateTime) || childType == typeof(object)) { //Directly parse parsedObject = converter.Convert(reader.ReadString(), childType); } else { //Recurse down the object graph parsedObject = InitializeObject(reader, converter); } //Add to parent collection or add the key value pair to the info object for the serialization surrogate to use if (dictionary != null && key != null) { dictionary.Add(key, parsedObject); } else if (list != null) { list.Add(parsedObject); } else { info.AddValue(reader.Name, parsedObject); //Use info object } //Move to next element reader.Read(); //Read past collection if (reader.Name == "Collection" && !reader.IsStartElement()) { reader.Read(); } } } //Use the surrogate to populate the instance initializedObject = serializationSurrogate.SetObjectData(initializedObject, info, Context, SurrogateSelector); return(initializedObject); }
public bool LoadData(ObjectManager manager, ISurrogateSelector selector, StreamingContext context) { if (Info != null) { if (Surrogate != null) { object new_obj = Surrogate.SetObjectData(ObjectInstance, Info, context, SurrogateSelector); if (new_obj != null) { ObjectInstance = new_obj; } Status = ObjectRecordStatus.ReferenceSolved; } else if (ObjectInstance is ISerializable) { object[] pars = new object[] { Info, context }; ConstructorInfo con = ObjectInstance.GetType().GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }, null); if (con == null) { throw new SerializationException("The constructor to deserialize an object of type " + ObjectInstance.GetType().FullName + " was not found."); } con.Invoke(ObjectInstance, pars); } else { throw new SerializationException("No surrogate selector was found for type " + ObjectInstance.GetType().FullName); } Info = null; } if (ObjectInstance is IObjectReference && Status != ObjectRecordStatus.ReferenceSolved) { try { ObjectInstance = ((IObjectReference)ObjectInstance).GetRealObject(context); int n = 100; while (ObjectInstance is IObjectReference && n > 0) { object ob = ((IObjectReference)ObjectInstance).GetRealObject(context); if (ob == ObjectInstance) { break; } ObjectInstance = ob; n--; } if (n == 0) { throw new SerializationException("The implementation of the IObjectReference interface returns too many nested references to other objects that implement IObjectReference."); } Status = ObjectRecordStatus.ReferenceSolved; } catch (NullReferenceException) { // Give a second chance return(false); } } if (Member != null) { // If this object is a value object embedded in another object, the parent // object must be updated ObjectRecord containerRecord = manager.GetObjectRecord(IdOfContainingObj); containerRecord.SetMemberValue(manager, Member, ObjectInstance); } else if (ArrayIndex != null) { ObjectRecord containerRecord = manager.GetObjectRecord(IdOfContainingObj); containerRecord.SetArrayValue(manager, ObjectInstance, ArrayIndex); } return(true); }
public object Deserialize(Type expectedType) { TypeCode code = (TypeCode)this._reader.ReadByte(); if (code == TypeCode.Object) { ushort objId = this._reader.ReadUInt16(); object returnGraph = null; if (this._readObjects.ContainsKey(objId)) { returnGraph = this._readObjects[objId]; } else { Type graphType = this.typeReader(expectedType); object graph = null; ISurrogateSelector selector = null; ISerializationSurrogate surrogate = this._selector == null ? null : this._selector.GetSurrogate(graphType, this._context, out selector); this._selector = selector == null ? this._selector : selector; if (graphType.IsArray) { object[] dimensions = new object[graphType.GetArrayRank()]; for (int i = 0; i < dimensions.Length; i++) { dimensions[i] = this._reader.ReadInt32(); } graph = Activator.CreateInstance(graphType, dimensions); this._readObjects.Add(objId, graph); this.setArrayValues((Array)graph, graphType); } else if (SerializationStaticHelpers.TypeOfISerializable.IsAssignableFrom(graphType)) { graph = FormatterServices.GetUninitializedObject(graphType); this._readObjects.Add(objId, graph); ConstructorInfo serializableConstructor = SerializationStaticHelpers.GetSerializationCtor(graphType); SerializationInfo info = new SerializationInfo(graphType, SerializationStaticHelpers.FormatterConverter); this.setISerializableValues(info, graphType); serializableConstructor.Invoke(graph, new object[] { info, this._context }); if (graph is IObjectReference) { object realGraph = ((IObjectReference)graph).GetRealObject(this._context); this._readObjects[objId] = realGraph; graph = realGraph; } if (graph is IDeserializationCallback) { ((IDeserializationCallback)graph).OnDeserialization(graph); } } else if (surrogate == null) { graph = FormatterServices.GetUninitializedObject(graphType); this._readObjects.Add(objId, graph); this.setObjectValues(graph, graphType); if (graph is IDeserializationCallback) { ((IDeserializationCallback)graph).OnDeserialization(graph); } } else { graph = FormatterServices.GetUninitializedObject(graphType); SerializationInfo info = new SerializationInfo(graphType, SerializationStaticHelpers.FormatterConverter); this.setISerializableValues(info, graphType); surrogate.SetObjectData(graph, info, this._context, this._selector); this._readObjects.Add(objId, graph); } returnGraph = graph; } if (returnGraph is IObjectReference) { object realGraph = ((IObjectReference)returnGraph).GetRealObject(this._context); this._readObjects[objId] = realGraph; returnGraph = realGraph; } return(returnGraph); } else if (code == TypeCode.String) { short index = this._reader.ReadInt16(); if (index == -1) { return(this._reader.ReadString()); } else { return(this._stringContents[index]); } } else { if (code == (TypeCode)19) { return(this.typeReader(expectedType)); } else { return(SerializationStaticHelpers.ReadPrimitive(this._reader, code)); } } }
/// <summary> /// /// </summary> /// <param name="surrogate"></param> /// <param name="obj"></param> /// <param name="firstChild"></param> /// <returns></returns> protected object DeserializeSurrogate(ISerializationSurrogate surrogate, Type objType, int objId, XmlNode firstChild, XmlElement rootElement, object standin) { //NOTE: Technically this isn't necessary because we can be sure it'll //never be called on Components. The GameObject surrogate will handle //deserializing components and any loose references will be skipped //until the deference phase at the end of deserialization. //However, in case serialization wasn't done properly (components were //serialized in-place rather than defered to GameObject serialization), //then we need to ensure we simply skip this in such a case. if (standin == null) { if (objType.IsSubclassOf(typeof(Component))) { return(null); } if (objType.IsSubclassOf(typeof(Component[]))) { return(null); } if (objType == typeof(Component[])) { return(null); } } SerializationInfo info = new SerializationInfo(objType, new DummyConverter()); DeserializeContext context = new DeserializeContext(); context.Deserializer = this; context.ObjId = objId; context.ElementBeingParsed = rootElement; context.ObjectType = objType; context.deserializationObjCache = this.deserializationObjCache; context.deserializationTypeCache = this.deserializationTypeCache; //float through the xml nodes and see what items we need to collect. for (XmlNode node = firstChild; node != null; node = node.NextSibling) { object val = DeserializeCore((XmlElement)node); if (val != null) { info.AddValue(node.Name, val, val.GetType()); } else { info.AddValue(node.Name, null, typeof(object)); } } //if the standin is null, we need to create an instance. //Otherwise, we were given an instance to work with. object obj = standin; if (obj == null) { if (SerializerBase.IsSameOrSubclass(typeof(MulticastDelegate), objType)) { obj = null; } else { obj = CreateInstanceOfType(objType, false); //if(SerializerBase.IsReferenceNull(obj)) // return null; } } //we pass obj in but we also assign it back from the output, just in case //the surrogate decided to do something funky. There is also the simple //possibility that we couldn't create an instance of the object beforehand //so we are actually passing in 'null'. obj = surrogate.SetObjectData(obj, info, new StreamingContext(StreamingContextStates.File, context), this); if (SerializerBase.IsReferenceNull(obj)) { Debug.LogWarning("The surrogate '" + surrogate.ToString() + "' could not create an instance of '" + objType.Name + "' for the element '" + firstChild.ParentNode.Name + "'."); } CacheObject(obj, objId); return(obj); }
/// <summary> /// Reads an object from the XML and initializes the object. /// </summary> /// <param name="reader">The XmlReader to read from.</param> /// <param name="converter">The converter used to parse the values from the XML.</param> /// <param name="objectType">The type of the object to create.</param> /// <returns>The recreated object.</returns> private object InitializeObject(XmlTextReader reader, FormatterConverter converter, Type objectType) { Type actualType; ISurrogateSelector selector1 = null; ISerializationSurrogate serializationSurrogate = null; SerializationInfo info = null; object initializedObject = null; // check if a type attribute is present if (reader.HasAttributes) { // if so, get the type string actualTypeName = reader.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance"); actualType = Binder.BindToType("", actualTypeName); } else { // passed type is actual type. actualType = objectType; } // check whether a surrogate should be used, iserializable is implemented or reflection is needed. if ((SurrogateSelector != null) && ((serializationSurrogate = SurrogateSelector.GetSurrogate(actualType, Context, out selector1)) != null)) { // use surrogate info = new SerializationInfo(actualType, converter); if (!actualType.IsPrimitive) { // create a instance of the type. initializedObject = FormatterServices.GetUninitializedObject(actualType); // read the first element reader.ReadStartElement(); while (reader.IsStartElement()) { // determine type string typeName = reader.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance"); Type type = Binder.BindToType("", typeName); // using ISerializable info.AddValue(reader.Name, DetermineValue(reader, converter, type)); reader.ReadEndElement(); } // use the surrogate to populate the instance initializedObject = serializationSurrogate.SetObjectData(initializedObject, info, Context, SurrogateSelector); } } else if (typeof(ISerializable).IsAssignableFrom(actualType)) { // The item implements ISerializable. Create a SerializationInfo object info = new SerializationInfo(actualType, converter); // Populate the collection PopulateSerializationInfo(reader, converter, actualType, info); // Get the specialized Serialization Constructor ConstructorInfo ctor = actualType.GetConstructor(new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }); // Create the object initializedObject = ctor.Invoke(new object[] { info, Context }); } else { // The item does not implement ISerializable. Use reflection to get public // fields and properties. initializedObject = FormatterServices.GetUninitializedObject(actualType); List <MemberInfo> memberList = new List <MemberInfo> (); List <object> valuesList = new List <object> (); // read the first element. reader.ReadStartElement(); while (reader.IsStartElement()) { // Get public fields and members of this type. MemberInfo[] possibleMembers = actualType.GetMember(reader.Name, MemberTypes.Property | MemberTypes.Field, BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance); if (possibleMembers == null) { throw new SerializationException(string.Format("Serialization stream contained element not found in type.{0}", reader.Name)); } if (possibleMembers.Length > 1) { throw new SerializationException(string.Format("More than one member found for tag {0}", reader.Name)); } if (typeof(IList).IsAssignableFrom(possibleMembers[0].ReflectedType)) { // the type is a list, get the list from the initialized object. IList list = GetMemberValue(initializedObject, possibleMembers[0]) as IList; if (list == null) { throw new SerializationException(string.Format("List in object is null. {0}, member {1}", possibleMembers[0].DeclaringType.FullName, possibleMembers[0].Name)); } // read the next element reader.ReadStartElement(); while (reader.IsStartElement()) { if (!reader.IsEmptyElement) { // Initialize the object (recursive call) object listItem = InitializeObject(reader, converter, possibleMembers[0].ReflectedType.GetElementType()); list.Add(listItem); reader.ReadEndElement(); } else { reader.ReadStartElement(); } } } else { // determine the value. object value = DetermineValue(reader, converter, possibleMembers[0].ReflectedType); memberList.Add(possibleMembers[0]); valuesList.Add(value); } } if (memberList.Count > 0) { initializedObject = FormatterServices.PopulateObjectMembers(initializedObject, memberList.ToArray(), valuesList.ToArray()); } reader.ReadEndElement(); } if ((initializedObject as IDeserializationCallback) != null) { DeserializationCallBackList.Add(initializedObject); } return(initializedObject); }
/// <inheritdoc/> public object Deserialize(IFudgeFieldContainer msg, IFudgeDeserializer deserializer) { return(helper.Deserialize(msg, deserializer, (obj, si, sc) => { surrogate.SetObjectData(obj, si, sc, selector); })); }