in src/dotnet-svcutil/lib/src/FrameworkFork/Microsoft.Xml/Xml/Serialization/XmlSerializationWriterILGen.cs [1208:1435]
private void WriteMember(SourceInfo source, AttributeAccessor attribute, TypeDesc memberTypeDesc, string parent)
{
if (memberTypeDesc.IsAbstract) return;
if (memberTypeDesc.IsArrayLike)
{
string aVar = "a" + memberTypeDesc.Name;
string aiVar = "ai" + memberTypeDesc.Name;
string iVar = "i";
string fullTypeName = memberTypeDesc.CSharpName;
WriteArrayLocalDecl(fullTypeName, aVar, source, memberTypeDesc);
if (memberTypeDesc.IsNullable)
{
ilg.Ldloc(memberTypeDesc.Type, aVar);
ilg.Load(null);
ilg.If(Cmp.NotEqualTo);
}
if (attribute.IsList)
{
if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc))
{
string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty;
MethodInfo XmlSerializationWriter_get_Writer = typeof(XmlSerializationWriter).GetMethod(
"get_Writer",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
MethodInfo XmlWriter_WriteStartAttribute = typeof(XmlWriter).GetMethod(
"WriteStartAttribute",
CodeGenerator.InstanceBindingFlags,
null,
new Type[] { typeof(String), typeof(String), typeof(String) },
null
);
ilg.Ldarg(0);
ilg.Call(XmlSerializationWriter_get_Writer);
ilg.Load(null);
ilg.Ldstr(attribute.Name);
ilg.Ldstr(ns);
ilg.Call(XmlWriter_WriteStartAttribute);
}
else
{
LocalBuilder sbLoc = ilg.DeclareOrGetLocal(typeof(StringBuilder), "sb");
ConstructorInfo StringBuilder_ctor = typeof(StringBuilder).GetConstructor(CodeGenerator.EmptyTypeArray);
ilg.New(StringBuilder_ctor);
ilg.Stloc(sbLoc);
}
}
TypeDesc arrayElementTypeDesc = memberTypeDesc.ArrayElementTypeDesc;
if (memberTypeDesc.IsEnumerable)
{
throw CodeGenerator.NotSupported("CDF15337, DDB176069: Also fail in whidbey IEnumerable member with XmlAttributeAttribute");
}
else
{
if (memberTypeDesc.IsArray)
{
LocalBuilder localI = ilg.DeclareOrGetLocal(typeof(Int32), iVar);
ilg.For(localI, 0, ilg.GetLocal(aVar));
}
else
{
LocalBuilder localI = ilg.DeclareOrGetLocal(typeof(Int32), iVar);
ilg.For(localI, 0, ilg.GetLocal(aVar));
}
WriteLocalDecl(aiVar, RaCodeGen.GetStringForArrayMember(aVar, iVar, memberTypeDesc), arrayElementTypeDesc.Type);
}
if (attribute.IsList)
{
string methodName;
Type methodType;
Type argType = typeof(string);
// check to see if we can write values of the attribute sequentially
if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc))
{
ilg.Ldloc(iVar);
ilg.Ldc(0);
ilg.If(Cmp.NotEqualTo);
MethodInfo XmlSerializationWriter_get_Writer = typeof(XmlSerializationWriter).GetMethod(
"get_Writer",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
MethodInfo XmlWriter_WriteString = typeof(XmlWriter).GetMethod(
"WriteString",
CodeGenerator.InstanceBindingFlags,
null,
new Type[] { typeof(String) },
null
);
ilg.Ldarg(0);
ilg.Call(XmlSerializationWriter_get_Writer);
ilg.Ldstr(" ");
ilg.Call(XmlWriter_WriteString);
ilg.EndIf();
ilg.Ldarg(0);
methodName = "WriteValue";
methodType = typeof(XmlSerializationWriter);
}
else
{
MethodInfo StringBuilder_Append = typeof(StringBuilder).GetMethod(
"Append",
CodeGenerator.InstanceBindingFlags,
null,
new Type[] { typeof(string) },
null
);
ilg.Ldloc(iVar);
ilg.Ldc(0);
ilg.If(Cmp.NotEqualTo);
ilg.Ldloc("sb");
ilg.Ldstr(" ");
ilg.Call(StringBuilder_Append);
ilg.Pop();
ilg.EndIf();
ilg.Ldloc("sb");
methodName = "Append";
methodType = typeof(StringBuilder);
}
if (attribute.Mapping is EnumMapping)
WriteEnumValue((EnumMapping)attribute.Mapping, new SourceInfo(aiVar, aiVar, null, arrayElementTypeDesc.Type, ilg), out argType);
else
WritePrimitiveValue(arrayElementTypeDesc, new SourceInfo(aiVar, aiVar, null, arrayElementTypeDesc.Type, ilg), out argType);
MethodInfo method = methodType.GetMethod(
methodName,
CodeGenerator.InstanceBindingFlags,
null,
new Type[] { argType },
null
);
ilg.Call(method);
if (method.ReturnType != typeof(void))
ilg.Pop();
}
else
{
WriteAttribute(new SourceInfo(aiVar, aiVar, null, null, ilg), attribute, parent);
}
if (memberTypeDesc.IsEnumerable)
throw CodeGenerator.NotSupported("CDF15337, DDB176069: Also fail in whidbey IEnumerable member with XmlAttributeAttribute");
else
ilg.EndFor();
if (attribute.IsList)
{
// check to see if we can write values of the attribute sequentially
if (CanOptimizeWriteListSequence(memberTypeDesc.ArrayElementTypeDesc))
{
MethodInfo XmlSerializationWriter_get_Writer = typeof(XmlSerializationWriter).GetMethod(
"get_Writer",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
MethodInfo XmlWriter_WriteEndAttribute = typeof(XmlWriter).GetMethod(
"WriteEndAttribute",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
ilg.Ldarg(0);
ilg.Call(XmlSerializationWriter_get_Writer);
ilg.Call(XmlWriter_WriteEndAttribute);
}
else
{
MethodInfo StringBuilder_get_Length = typeof(StringBuilder).GetMethod(
"get_Length",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
ilg.Ldloc("sb");
ilg.Call(StringBuilder_get_Length);
ilg.Ldc(0);
ilg.If(Cmp.NotEqualTo);
List<Type> argTypes = new List<Type>();
ilg.Ldarg(0);
ilg.Ldstr(attribute.Name);
argTypes.Add(typeof(string));
string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty;
if (ns != null)
{
ilg.Ldstr(ns);
argTypes.Add(typeof(string));
}
MethodInfo Object_ToString = typeof(Object).GetMethod(
"ToString",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
ilg.Ldloc("sb");
ilg.Call(Object_ToString);
argTypes.Add(typeof(string));
MethodInfo XmlSerializationWriter_WriteAttribute = typeof(XmlSerializationWriter).GetMethod(
"WriteAttribute",
CodeGenerator.InstanceBindingFlags,
null,
argTypes.ToArray(),
null
);
ilg.Call(XmlSerializationWriter_WriteAttribute);
ilg.EndIf();
}
}
if (memberTypeDesc.IsNullable)
{
ilg.EndIf();
}
}
else
{
WriteAttribute(source, attribute, parent);
}
}