private void ReadClass(ClassDataContract classContract) { if (classContract.HasExtensionData) { LocalBuilder extensionDataLocal = _ilg.DeclareLocal(Globals.TypeOfExtensionDataObject, "extensionData"); _ilg.New(XmlFormatGeneratorStatics.ExtensionDataObjectCtor); _ilg.Store(extensionDataLocal); ReadMembers(classContract, extensionDataLocal); ClassDataContract?currentContract = classContract; while (currentContract != null) { MethodInfo?extensionDataSetMethod = currentContract.ExtensionDataSetMethod; if (extensionDataSetMethod != null) { _ilg.Call(_objectLocal, extensionDataSetMethod, extensionDataLocal); } currentContract = currentContract.BaseContract; } } else { ReadMembers(classContract, null /*extensionDataLocal*/); } }
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); }
private void CreateObject(ClassDataContract classContract) { Type type = _objectType = classContract.UnderlyingType; if (type.GetTypeInfo().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.GetTypeInfo().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); } }
internal System.Runtime.Serialization.CreateXmlSerializableDelegate GenerateCreateXmlSerializableDelegate() { Type underlyingType = base.UnderlyingType; CodeGenerator generator = new CodeGenerator(); bool allowPrivateMemberAccess = this.RequiresMemberAccessForCreate(null); try { generator.BeginMethod("Create" + DataContract.GetClrTypeFullName(underlyingType), typeof(System.Runtime.Serialization.CreateXmlSerializableDelegate), allowPrivateMemberAccess); } catch (SecurityException exception) { if (!allowPrivateMemberAccess || !exception.PermissionType.Equals(typeof(ReflectionPermission))) { throw; } this.RequiresMemberAccessForCreate(exception); } if (underlyingType.IsValueType) { LocalBuilder localBuilder = generator.DeclareLocal(underlyingType, underlyingType.Name + "Value"); generator.Ldloca(localBuilder); generator.InitObj(underlyingType); generator.Ldloc(localBuilder); } else { generator.New(this.GetConstructor()); } generator.ConvertValue(base.UnderlyingType, Globals.TypeOfIXmlSerializable); generator.Ret(); return((System.Runtime.Serialization.CreateXmlSerializableDelegate)generator.EndMethod()); }
internal CreateXmlSerializableDelegate GenerateCreateXmlSerializableDelegate() { Type type = this.UnderlyingType; CodeGenerator ilg = new CodeGenerator(); bool memberAccessFlag = RequiresMemberAccessForCreate(null); try { ilg.BeginMethod("Create" + DataContract.GetClrTypeFullName(type), typeof(CreateXmlSerializableDelegate), memberAccessFlag); } catch (SecurityException securityException) { if (memberAccessFlag && securityException.PermissionType.Equals(typeof(ReflectionPermission))) { 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 { ilg.New(GetConstructor()); } ilg.ConvertValue(this.UnderlyingType, Globals.TypeOfIXmlSerializable); ilg.Ret(); return((CreateXmlSerializableDelegate)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.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()); }
void WriteCollection(CollectionDataContract collectionContract) { LocalBuilder itemNamespace = ilg.DeclareLocal(typeof(XmlDictionaryString), "itemNamespace"); ilg.Load(dataContractArg); ilg.LoadMember(XmlFormatGeneratorStatics.NamespaceProperty); ilg.Store(itemNamespace); LocalBuilder itemName = ilg.DeclareLocal(typeof(XmlDictionaryString), "itemName"); ilg.Load(dataContractArg); ilg.LoadMember(XmlFormatGeneratorStatics.CollectionItemNameProperty); ilg.Store(itemName); if (collectionContract.ChildElementNamespace != null) { ilg.Load(xmlWriterArg); ilg.Load(dataContractArg); ilg.LoadMember(XmlFormatGeneratorStatics.ChildElementNamespaceProperty); ilg.Call(XmlFormatGeneratorStatics.WriteNamespaceDeclMethod); } if (collectionContract.Kind == CollectionKind.Array) { Type itemType = collectionContract.ItemType; LocalBuilder i = ilg.DeclareLocal(Globals.TypeOfInt, "i"); ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementArrayCountMethod, xmlWriterArg, objectLocal); if (!TryWritePrimitiveArray(collectionContract.UnderlyingType, itemType, objectLocal, itemName, itemNamespace)) { ilg.For(i, 0, objectLocal); if (!TryWritePrimitive(itemType, null /*value*/, null /*memberInfo*/, i /*arrayItemIndex*/, itemNamespace, itemName, 0 /*nameIndex*/)) { WriteStartElement(itemType, collectionContract.Namespace, itemNamespace, itemName, 0 /*nameIndex*/); ilg.LoadArrayElement(objectLocal, i); LocalBuilder memberValue = ilg.DeclareLocal(itemType, "memberValue"); ilg.Stloc(memberValue); WriteValue(memberValue, false /*writeXsiType*/); WriteEndElement(); } ilg.EndFor(); } } else { MethodInfo incrementCollectionCountMethod = null; switch (collectionContract.Kind) { case CollectionKind.Collection: case CollectionKind.List: case CollectionKind.Dictionary: incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountMethod; break; case CollectionKind.GenericCollection: case CollectionKind.GenericList: incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(collectionContract.ItemType); break; case CollectionKind.GenericDictionary: incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(Globals.TypeOfKeyValuePair.MakeGenericType(collectionContract.ItemType.GetGenericArguments())); break; } if (incrementCollectionCountMethod != null) { ilg.Call(contextArg, incrementCollectionCountMethod, xmlWriterArg, objectLocal); } bool isDictionary = false, isGenericDictionary = false; Type enumeratorType = null; Type[] keyValueTypes = null; if (collectionContract.Kind == CollectionKind.GenericDictionary) { isGenericDictionary = true; keyValueTypes = collectionContract.ItemType.GetGenericArguments(); enumeratorType = Globals.TypeOfGenericDictionaryEnumerator.MakeGenericType(keyValueTypes); } else if (collectionContract.Kind == CollectionKind.Dictionary) { isDictionary = true; keyValueTypes = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject }; enumeratorType = Globals.TypeOfDictionaryEnumerator; } else { enumeratorType = collectionContract.GetEnumeratorMethod.ReturnType; } MethodInfo moveNextMethod = enumeratorType.GetMethod(Globals.MoveNextMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null); MethodInfo getCurrentMethod = enumeratorType.GetMethod(Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null); if (moveNextMethod == null || getCurrentMethod == null) { if (enumeratorType.IsInterface) { if (moveNextMethod == null) { moveNextMethod = XmlFormatGeneratorStatics.MoveNextMethod; } if (getCurrentMethod == null) { getCurrentMethod = XmlFormatGeneratorStatics.GetCurrentMethod; } } else { Type ienumeratorInterface = Globals.TypeOfIEnumerator; CollectionKind kind = collectionContract.Kind; if (kind == CollectionKind.GenericDictionary || kind == CollectionKind.GenericCollection || kind == CollectionKind.GenericEnumerable) { Type[] interfaceTypes = enumeratorType.GetInterfaces(); foreach (Type interfaceType in interfaceTypes) { if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == Globals.TypeOfIEnumeratorGeneric && interfaceType.GetGenericArguments()[0] == collectionContract.ItemType) { ienumeratorInterface = interfaceType; break; } } } if (moveNextMethod == null) { moveNextMethod = CollectionDataContract.GetTargetMethodWithName(Globals.MoveNextMethodName, enumeratorType, ienumeratorInterface); } if (getCurrentMethod == null) { getCurrentMethod = CollectionDataContract.GetTargetMethodWithName(Globals.GetCurrentMethodName, enumeratorType, ienumeratorInterface); } } } Type elementType = getCurrentMethod.ReturnType; LocalBuilder currentValue = ilg.DeclareLocal(elementType, "currentValue"); LocalBuilder enumerator = ilg.DeclareLocal(enumeratorType, "enumerator"); ilg.Call(objectLocal, collectionContract.GetEnumeratorMethod); if (isDictionary) { ilg.ConvertValue(collectionContract.GetEnumeratorMethod.ReturnType, Globals.TypeOfIDictionaryEnumerator); ilg.New(XmlFormatGeneratorStatics.DictionaryEnumeratorCtor); } else if (isGenericDictionary) { Type ctorParam = Globals.TypeOfIEnumeratorGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(keyValueTypes)); ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, null, new Type[] { ctorParam }, null); ilg.ConvertValue(collectionContract.GetEnumeratorMethod.ReturnType, ctorParam); ilg.New(dictEnumCtor); } ilg.Stloc(enumerator); ilg.ForEach(currentValue, elementType, enumeratorType, enumerator, getCurrentMethod); if (incrementCollectionCountMethod == null) { ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1); } if (!TryWritePrimitive(elementType, currentValue, null /*memberInfo*/, null /*arrayItemIndex*/, itemNamespace, itemName, 0 /*nameIndex*/)) { WriteStartElement(elementType, collectionContract.Namespace, itemNamespace, itemName, 0 /*nameIndex*/); if (isGenericDictionary || isDictionary) { ilg.Call(dataContractArg, XmlFormatGeneratorStatics.GetItemContractMethod); ilg.Load(xmlWriterArg); ilg.Load(currentValue); ilg.ConvertValue(currentValue.LocalType, Globals.TypeOfObject); ilg.Load(contextArg); ilg.Call(XmlFormatGeneratorStatics.WriteXmlValueMethod); } else { WriteValue(currentValue, false /*writeXsiType*/); } WriteEndElement(); } ilg.EndForEach(moveNextMethod); } }