public XmlFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract) { if (DataContractSerializer.Option == SerializationOption.ReflectionOnly) { return(CreateReflectionXmlClassReader(classContract)); } #if uapaot else if (DataContractSerializer.Option == SerializationOption.ReflectionAsBackup) { return(CreateReflectionXmlClassReader(classContract)); } #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 } }
public XmlFormatGetOnlyCollectionReaderDelegate GenerateGetOnlyCollectionReader(CollectionDataContract collectionContract) { ilg = GenerateCollectionReaderHelper(collectionContract, true /*isGetOnlyCollection*/); ReadGetOnlyCollection(collectionContract); return((XmlFormatGetOnlyCollectionReaderDelegate)ilg.EndMethod()); }
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.GetTypeInfo().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.GetTypeInfo().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) { 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()); }