in src/dotnet-svcutil/lib/src/FrameworkFork/Microsoft.Xml/Xml/Serialization/XmlSerializationWriterILGen.cs [2008:2186]
private void WriteElement(SourceInfo source, ElementAccessor element, string arrayName, bool writeAccessor)
{
string name = writeAccessor ? element.Name : element.Mapping.TypeName;
string ns = element.Any && element.Name.Length == 0 ? null : (element.Form == XmlSchemaForm.Qualified ? (writeAccessor ? element.Namespace : element.Mapping.Namespace) : "");
if (element.Mapping is NullableMapping)
{
if (source.Type == element.Mapping.TypeDesc.Type)
{
MethodInfo Nullable_get_HasValue = element.Mapping.TypeDesc.Type.GetMethod(
"get_HasValue",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
source.LoadAddress(element.Mapping.TypeDesc.Type);
ilg.Call(Nullable_get_HasValue);
}
else
{
source.Load(null);
ilg.Load(null);
ilg.Cne();
}
ilg.If();
string fullTypeName = element.Mapping.TypeDesc.BaseTypeDesc.CSharpName;
SourceInfo castedSource = source.CastTo(element.Mapping.TypeDesc.BaseTypeDesc);
ElementAccessor e = element.Clone();
e.Mapping = ((NullableMapping)element.Mapping).BaseMapping;
WriteElement(e.Any ? source : castedSource, e, arrayName, writeAccessor);
if (element.IsNullable)
{
ilg.Else();
WriteLiteralNullTag(element.Name, element.Form == XmlSchemaForm.Qualified ? element.Namespace : "");
}
ilg.EndIf();
}
else if (element.Mapping is ArrayMapping)
{
ArrayMapping mapping = (ArrayMapping)element.Mapping;
if (element.IsUnbounded)
{
throw CodeGenerator.NotSupported("Unreachable: IsUnbounded is never set true!");
}
else
{
ilg.EnterScope();
string fullTypeName = mapping.TypeDesc.CSharpName;
WriteArrayLocalDecl(fullTypeName, arrayName, source, mapping.TypeDesc);
if (element.IsNullable)
{
WriteNullCheckBegin(arrayName, element);
}
else
{
if (mapping.TypeDesc.IsNullable)
{
ilg.Ldloc(ilg.GetLocal(arrayName));
ilg.Load(null);
ilg.If(Cmp.NotEqualTo);
}
}
WriteStartElement(name, ns, false);
WriteArrayItems(mapping.ElementsSortedByDerivation, null, null, mapping.TypeDesc, arrayName, null);
WriteEndElement();
if (element.IsNullable)
{
ilg.EndIf();
}
else
{
if (mapping.TypeDesc.IsNullable)
{
ilg.EndIf();
}
}
ilg.ExitScope();
}
}
else if (element.Mapping is EnumMapping)
{
WritePrimitive("WriteElementString", name, ns, element.Default, source, element.Mapping, false, true, element.IsNullable);
}
else if (element.Mapping is PrimitiveMapping)
{
PrimitiveMapping mapping = (PrimitiveMapping)element.Mapping;
if (mapping.TypeDesc == QnameTypeDesc)
WriteQualifiedNameElement(name, ns, GetConvertedDefaultValue(source.Type, element.Default), source, element.IsNullable, mapping);
else
{
string suffixRaw = mapping.TypeDesc.XmlEncodingNotRequired ? "Raw" : "";
WritePrimitive(element.IsNullable ? ("WriteNullableStringLiteral" + suffixRaw) : ("WriteElementString" + suffixRaw),
name, ns, GetConvertedDefaultValue(source.Type, element.Default), source, mapping, false, true, element.IsNullable);
}
}
else if (element.Mapping is StructMapping)
{
StructMapping mapping = (StructMapping)element.Mapping;
string methodName = ReferenceMapping(mapping);
#if DEBUG
// use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
if (methodName == null) throw new InvalidOperationException(string.Format(ResXml.XmlInternalErrorMethod, mapping.TypeDesc.Name) + Environment.StackTrace);
#endif
List<Type> argTypes = new List<Type>();
ilg.Ldarg(0);
ilg.Ldstr(name);
argTypes.Add(typeof(string));
ilg.Ldstr(ns);
argTypes.Add(typeof(string));
source.Load(mapping.TypeDesc.Type);
argTypes.Add(mapping.TypeDesc.Type);
if (mapping.TypeDesc.IsNullable)
{
ilg.Ldc(element.IsNullable);
argTypes.Add(typeof(Boolean));
}
ilg.Ldc(false);
argTypes.Add(typeof(Boolean));
MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder,
methodName,
CodeGenerator.PrivateMethodAttributes,
typeof(void),
argTypes.ToArray());
ilg.Call(methodBuilder);
}
else if (element.Mapping is SpecialMapping)
{
SpecialMapping mapping = (SpecialMapping)element.Mapping;
TypeDesc td = mapping.TypeDesc;
string fullTypeName = td.CSharpName;
if (element.Mapping is SerializableMapping)
{
WriteElementCall("WriteSerializable", typeof(IXmlSerializable), source, name, ns, element.IsNullable, !element.Any);
}
else
{
// XmlNode, XmlElement
Label ifLabel1 = ilg.DefineLabel();
Label ifLabel2 = ilg.DefineLabel();
source.Load(null);
ilg.IsInst(typeof(XmlNode));
ilg.Brtrue(ifLabel1);
source.Load(null);
ilg.Load(null);
ilg.Ceq();
ilg.Br(ifLabel2);
ilg.MarkLabel(ifLabel1);
ilg.Ldc(true);
ilg.MarkLabel(ifLabel2);
ilg.If();
WriteElementCall("WriteElementLiteral", typeof(XmlNode), source, name, ns, element.IsNullable, element.Any);
ilg.Else();
MethodInfo XmlSerializationWriter_CreateInvalidAnyTypeException = typeof(XmlSerializationWriter).GetMethod(
"CreateInvalidAnyTypeException",
CodeGenerator.InstanceBindingFlags,
null,
new Type[] { typeof(Object) },
null
);
ilg.Ldarg(0);
source.Load(null);
ilg.Call(XmlSerializationWriter_CreateInvalidAnyTypeException);
ilg.Throw();
ilg.EndIf();
}
}
else
{
throw new InvalidOperationException(ResXml.XmlInternalError);
}
}