public XmlFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract) { _ilg = new CodeGenerator(); bool memberAccessFlag = classContract.RequiresMemberAccessForRead(null); try { _ilg.BeginMethod("Read" + classContract.StableName.Name + "FromXml", Globals.TypeOfXmlFormatClassReaderDelegate, memberAccessFlag); } catch (SecurityException securityException) { if (memberAccessFlag) { classContract.RequiresMemberAccessForRead(securityException); } else { throw; } } InitArgs(); CreateObject(classContract); _ilg.Call(_contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, _objectLocal); InvokeOnDeserializing(classContract); LocalBuilder objectId = null; ReadClass(classContract); InvokeOnDeserialized(classContract); if (objectId == null) { _ilg.Load(_objectLocal); // Do a conversion back from DateTimeOffsetAdapter to DateTimeOffset after deserialization. // DateTimeOffsetAdapter is used here for deserialization purposes to bypass the ISerializable implementation // on DateTimeOffset; which does not work in partial trust. if (classContract.UnderlyingType == Globals.TypeOfDateTimeOffsetAdapter) { _ilg.ConvertValue(_objectLocal.LocalType, Globals.TypeOfDateTimeOffsetAdapter); _ilg.Call(XmlFormatGeneratorStatics.GetDateTimeOffsetMethod); _ilg.ConvertValue(Globals.TypeOfDateTimeOffset, _ilg.CurrentMethod.ReturnType); } //Copy the KeyValuePairAdapter<K,T> to a KeyValuePair<K,T>. else if (classContract.IsKeyValuePairAdapter) { _ilg.Call(classContract.GetKeyValuePairMethodInfo); _ilg.ConvertValue(Globals.TypeOfKeyValuePair.MakeGenericType(classContract.KeyValuePairGenericArguments), _ilg.CurrentMethod.ReturnType); } else { _ilg.ConvertValue(_objectLocal.LocalType, _ilg.CurrentMethod.ReturnType); } } return((XmlFormatClassReaderDelegate)_ilg.EndMethod()); }
private void InitArgs(Type objType) { _xmlWriterArg = _ilg.GetArg(0); _contextArg = _ilg.GetArg(2); _dataContractArg = _ilg.GetArg(3); _objectLocal = _ilg.DeclareLocal(objType, "objSerialized"); ArgBuilder objectArg = _ilg.GetArg(1); _ilg.Load(objectArg); // Copy the data from the DataTimeOffset object passed in to the DateTimeOffsetAdapter. // DateTimeOffsetAdapter is used here for serialization purposes to bypass the ISerializable implementation // on DateTimeOffset; which does not work in partial trust. if (objType == Globals.TypeOfDateTimeOffsetAdapter) { _ilg.ConvertValue(objectArg.ArgType, Globals.TypeOfDateTimeOffset); _ilg.Call(XmlFormatGeneratorStatics.GetDateTimeOffsetAdapterMethod); } //Copy the KeyValuePair<K,T> to a KeyValuePairAdapter<K,T>. else if (objType.IsGenericType && objType.GetGenericTypeDefinition() == Globals.TypeOfKeyValuePairAdapter) { ClassDataContract dc = (ClassDataContract)DataContract.GetDataContract(objType); _ilg.ConvertValue(objectArg.ArgType, Globals.TypeOfKeyValuePair.MakeGenericType(dc.KeyValuePairGenericArguments !)); _ilg.New(dc.KeyValuePairAdapterConstructorInfo !); } else { _ilg.ConvertValue(objectArg.ArgType, objType); } _ilg.Stloc(_objectLocal); }
internal CreateXmlSerializableDelegate GenerateCreateXmlSerializableDelegate() { Type type = this.UnderlyingType; CodeGenerator ilg = new CodeGenerator(); bool memberAccessFlag = RequiresMemberAccessForCreate(null) && !(type.FullName == "System.Xml.Linq.XElement"); try { ilg.BeginMethod("Create" + DataContract.GetClrTypeFullName(type), typeof(CreateXmlSerializableDelegate), memberAccessFlag); } catch (SecurityException securityException) { if (memberAccessFlag) { RequiresMemberAccessForCreate(securityException); } else { throw; } } if (type.IsValueType) { System.Reflection.Emit.LocalBuilder local = ilg.DeclareLocal(type, type.Name + "Value"); ilg.Ldloca(local); ilg.InitObj(type); ilg.Ldloc(local); } else { // Special case XElement // codegen the same as 'internal XElement : this("default") { }' ConstructorInfo ctor = GetConstructor(); if (!ctor.IsPublic && type.FullName == "System.Xml.Linq.XElement") { Type xName = type.Assembly.GetType("System.Xml.Linq.XName"); if (xName != null) { MethodInfo XName_op_Implicit = xName.GetMethod( "op_Implicit", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, new Type[] { typeof(string) } ); ConstructorInfo XElement_ctor = type.GetConstructor( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, new Type[] { xName } ); if (XName_op_Implicit != null && XElement_ctor != null) { ilg.Ldstr("default"); ilg.Call(XName_op_Implicit); ctor = XElement_ctor; } } } ilg.New(ctor); } ilg.ConvertValue(this.UnderlyingType, Globals.TypeOfIXmlSerializable); ilg.Ret(); return((CreateXmlSerializableDelegate)ilg.EndMethod()); }
public XmlFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract) { if (DataContractSerializer.Option == SerializationOption.ReflectionOnly) { return(new ReflectionXmlClassReader(classContract).ReflectionReadClass); } #if uapaot else if (DataContractSerializer.Option == SerializationOption.ReflectionAsBackup) { return(new ReflectionXmlClassReader(classContract).ReflectionReadClass); } #endif else { #if uapaot throw new InvalidOperationException("Cannot generate class reader"); #else _ilg = new CodeGenerator(); bool memberAccessFlag = classContract.RequiresMemberAccessForRead(null); try { _ilg.BeginMethod("Read" + classContract.StableName.Name + "FromXml", Globals.TypeOfXmlFormatClassReaderDelegate, memberAccessFlag); } catch (SecurityException securityException) { if (memberAccessFlag) { classContract.RequiresMemberAccessForRead(securityException); } else { throw; } } InitArgs(); CreateObject(classContract); _ilg.Call(_contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, _objectLocal); InvokeOnDeserializing(classContract); LocalBuilder objectId = null; if (HasFactoryMethod(classContract)) { objectId = _ilg.DeclareLocal(Globals.TypeOfString, "objectIdRead"); _ilg.Call(_contextArg, XmlFormatGeneratorStatics.GetObjectIdMethod); _ilg.Stloc(objectId); } if (classContract.IsISerializable) { ReadISerializable(classContract); } else { ReadClass(classContract); } bool isFactoryType = InvokeFactoryMethod(classContract, objectId); if (Globals.TypeOfIDeserializationCallback.IsAssignableFrom(classContract.UnderlyingType)) { _ilg.Call(_objectLocal, XmlFormatGeneratorStatics.OnDeserializationMethod, null); } InvokeOnDeserialized(classContract); if (objectId == null) { _ilg.Load(_objectLocal); // Do a conversion back from DateTimeOffsetAdapter to DateTimeOffset after deserialization. // DateTimeOffsetAdapter is used here for deserialization purposes to bypass the ISerializable implementation // on DateTimeOffset; which does not work in partial trust. if (classContract.UnderlyingType == Globals.TypeOfDateTimeOffsetAdapter) { _ilg.ConvertValue(_objectLocal.LocalType, Globals.TypeOfDateTimeOffsetAdapter); _ilg.Call(XmlFormatGeneratorStatics.GetDateTimeOffsetMethod); _ilg.ConvertValue(Globals.TypeOfDateTimeOffset, _ilg.CurrentMethod.ReturnType); } //Copy the KeyValuePairAdapter<K,T> to a KeyValuePair<K,T>. else if (classContract.IsKeyValuePairAdapter) { _ilg.Call(classContract.GetKeyValuePairMethodInfo); _ilg.ConvertValue(Globals.TypeOfKeyValuePair.MakeGenericType(classContract.KeyValuePairGenericArguments), _ilg.CurrentMethod.ReturnType); } else { _ilg.ConvertValue(_objectLocal.LocalType, _ilg.CurrentMethod.ReturnType); } } return((XmlFormatClassReaderDelegate)_ilg.EndMethod()); #endif } }
private void CreateObject(ClassDataContract classContract) { Type type = _objectType = classContract.UnderlyingType; if (type.IsValueType && !classContract.IsNonAttributedType) { type = Globals.TypeOfValueType; } _objectLocal = _ilg.DeclareLocal(type, "objectDeserialized"); if (classContract.UnderlyingType == Globals.TypeOfDBNull) { _ilg.LoadMember(Globals.TypeOfDBNull.GetField("Value")); _ilg.Stloc(_objectLocal); } else if (classContract.IsNonAttributedType) { if (type.IsValueType) { _ilg.Ldloca(_objectLocal); _ilg.InitObj(type); } else { _ilg.New(classContract.GetNonAttributedTypeConstructor()); _ilg.Stloc(_objectLocal); } } else { _ilg.Call(null, XmlFormatGeneratorStatics.GetUninitializedObjectMethod, DataContract.GetIdForInitialization(classContract)); _ilg.ConvertValue(Globals.TypeOfObject, type); _ilg.Stloc(_objectLocal); } }
void DemandMemberAccessPermission(bool memberAccessFlag) { if (memberAccessFlag) { ilg.Call(contextArg, XmlFormatGeneratorStatics.DemandMemberAccessPermissionMethod); } }
public XmlFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract) { ilg = new CodeGenerator(); bool memberAccessFlag = classContract.RequiresMemberAccessForRead(null); try { ilg.BeginMethod("Read" + classContract.StableName.Name + "FromXml", Globals.TypeOfXmlFormatClassReaderDelegate, memberAccessFlag); } catch (SecurityException securityException) { if (memberAccessFlag && securityException.PermissionType.Equals(typeof(ReflectionPermission))) { classContract.RequiresMemberAccessForRead(securityException); } else { throw; } } InitArgs(); DemandSerializationFormatterPermission(classContract); DemandMemberAccessPermission(memberAccessFlag); CreateObject(classContract); ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, objectLocal); InvokeOnDeserializing(classContract); LocalBuilder objectId = null; if (HasFactoryMethod(classContract)) { objectId = ilg.DeclareLocal(Globals.TypeOfString, "objectIdRead"); ilg.Call(contextArg, XmlFormatGeneratorStatics.GetObjectIdMethod); ilg.Stloc(objectId); } if (classContract.IsISerializable) { ReadISerializable(classContract); } else { ReadClass(classContract); } bool isFactoryType = InvokeFactoryMethod(classContract, objectId); if (Globals.TypeOfIDeserializationCallback.IsAssignableFrom(classContract.UnderlyingType)) { ilg.Call(objectLocal, XmlFormatGeneratorStatics.OnDeserializationMethod, null); } InvokeOnDeserialized(classContract); if (objectId == null || !isFactoryType) { ilg.Load(objectLocal); // Do a conversion back from DateTimeOffsetAdapter to DateTimeOffset after deserialization. // DateTimeOffsetAdapter is used here for deserialization purposes to bypass the ISerializable implementation // on DateTimeOffset; which does not work in partial trust. if (classContract.UnderlyingType == Globals.TypeOfDateTimeOffsetAdapter) { ilg.ConvertValue(objectLocal.LocalType, Globals.TypeOfDateTimeOffsetAdapter); ilg.Call(XmlFormatGeneratorStatics.GetDateTimeOffsetMethod); ilg.ConvertValue(Globals.TypeOfDateTimeOffset, ilg.CurrentMethod.ReturnType); } else { ilg.ConvertValue(objectLocal.LocalType, ilg.CurrentMethod.ReturnType); } } return((XmlFormatClassReaderDelegate)ilg.EndMethod()); }
void InitArgs(Type objType) { xmlWriterArg = ilg.GetArg(0); contextArg = ilg.GetArg(2); dataContractArg = ilg.GetArg(3); objectLocal = ilg.DeclareLocal(objType, "objSerialized"); ArgBuilder objectArg = ilg.GetArg(1); ilg.Load(objectArg); // Copy the data from the DataTimeOffset object passed in to the DateTimeOffsetAdapter. // DateTimeOffsetAdapter is used here for serialization purposes to bypass the ISerializable implementation // on DateTimeOffset; which does not work in partial trust. if (objType == Globals.TypeOfDateTimeOffsetAdapter) { ilg.ConvertValue(objectArg.ArgType, Globals.TypeOfDateTimeOffset); ilg.Call(XmlFormatGeneratorStatics.GetDateTimeOffsetAdapterMethod); } else { ilg.ConvertValue(objectArg.ArgType, objType); } ilg.Stloc(objectLocal); }