string GenerateLiteralMembersElement(XmlMembersMapping xmlMembersMapping) {
ElementAccessor element = xmlMembersMapping.Accessor;
MemberMapping[] mappings = ((MembersMapping)element.Mapping).Members;
bool hasWrapperElement = ((MembersMapping)element.Mapping).HasWrapperElement;
string methodName = NextMethodName(element.Name);
ilg = new CodeGenerator(this.typeBuilder);
ilg.BeginMethod(
typeof(object[]),
methodName,
CodeGenerator.EmptyTypeArray,
CodeGenerator.EmptyStringArray,
CodeGenerator.PublicMethodAttributes
);
ilg.Load(null);
ilg.Stloc(ilg.ReturnLocal);
MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
"get_Reader",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
MethodInfo XmlReader_MoveToContent = typeof(XmlReader).GetMethod(
"MoveToContent",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
ilg.Ldarg(0);
ilg.Call(XmlSerializationReader_get_Reader);
ilg.Call(XmlReader_MoveToContent);
ilg.Pop();
LocalBuilder localP = ilg.DeclareLocal(typeof(object[]), "p");
ilg.NewArray(typeof(object), mappings.Length);
ilg.Stloc(localP);
InitializeValueTypes("p", mappings);
int wrapperLoopIndex = 0;
if (hasWrapperElement) {
wrapperLoopIndex = WriteWhileNotLoopStart();
WriteIsStartTag(element.Name, element.Form == XmlSchemaForm.Qualified ? element.Namespace : "");
}
Member anyText = null;
Member anyElement = null;
Member anyAttribute = null;
ArrayList membersList = new ArrayList();
ArrayList textOrArrayMembersList = new ArrayList();
ArrayList attributeMembersList = new ArrayList();
for (int i = 0; i < mappings.Length; i++) {
MemberMapping mapping = mappings[i];
string source = "p[" + i.ToString(CultureInfo.InvariantCulture) + "]";
string arraySource = source;
if (mapping.Xmlns != null) {
arraySource = "((" + mapping.TypeDesc.CSharpName + ")" + source + ")";
}
string choiceSource = GetChoiceIdentifierSource(mappings, mapping);
Member member = new Member(this, source, arraySource, "a", i, mapping, choiceSource);
Member anyMember = new Member(this, source, null, "a", i, mapping, choiceSource);
if (!mapping.IsSequence)
member.ParamsReadSource = "paramsRead[" + i.ToString(CultureInfo.InvariantCulture) + "]";
if (mapping.CheckSpecified == SpecifiedAccessor.ReadWrite) {
string nameSpecified = mapping.Name + "Specified";
for (int j = 0; j < mappings.Length; j++) {
if (mappings[j].Name == nameSpecified) {
member.CheckSpecifiedSource = "p[" + j.ToString(CultureInfo.InvariantCulture) + "]";
break;
}
}
}
bool foundAnyElement = false;
if (mapping.Text != null) anyText = anyMember;
if (mapping.Attribute != null && mapping.Attribute.Any)
anyAttribute = anyMember;
if (mapping.Attribute != null || mapping.Xmlns != null)
attributeMembersList.Add(member);
else if (mapping.Text != null)
textOrArrayMembersList.Add(member);
if (!mapping.IsSequence) {
for (int j = 0; j < mapping.Elements.Length; j++) {
if (mapping.Elements[j].Any && mapping.Elements[j].Name.Length == 0) {
anyElement = anyMember;
if (mapping.Attribute == null && mapping.Text == null)
textOrArrayMembersList.Add(anyMember);
foundAnyElement = true;
break;
}
}
}
if (mapping.Attribute != null || mapping.Text != null || foundAnyElement)
membersList.Add(anyMember);
else if (mapping.TypeDesc.IsArrayLike && !(mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping)) {
membersList.Add(anyMember);
textOrArrayMembersList.Add(anyMember);
}
else {
if (mapping.TypeDesc.IsArrayLike && !mapping.TypeDesc.IsArray)
member.ParamsReadSource = null; // collection
membersList.Add(member);
}
}
Member[] members = (Member[])membersList.ToArray(typeof(Member));
Member[] textOrArrayMembers = (Member[])textOrArrayMembersList.ToArray(typeof(Member));
if (members.Length > 0 && members[0].Mapping.IsReturnValue) {
MethodInfo XmlSerializationReader_set_IsReturnValue = typeof(XmlSerializationReader).GetMethod(
"set_IsReturnValue",
CodeGenerator.InstanceBindingFlags,
null,
new Type[] { typeof(Boolean) },
null
);
ilg.Ldarg(0);
ilg.Ldc(true);
ilg.Call(XmlSerializationReader_set_IsReturnValue);
}
WriteParamsRead(mappings.Length);
if (attributeMembersList.Count > 0) {
Member[] attributeMembers = (Member[])attributeMembersList.ToArray(typeof(Member));
WriteMemberBegin(attributeMembers);
WriteAttributes(attributeMembers, anyAttribute, "UnknownNode", localP);
WriteMemberEnd(attributeMembers);
MethodInfo XmlReader_MoveToElement = typeof(XmlReader).GetMethod(
"MoveToElement",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
ilg.Ldarg(0);
ilg.Call(XmlSerializationReader_get_Reader);
ilg.Call(XmlReader_MoveToElement);
ilg.Pop();
}
WriteMemberBegin(textOrArrayMembers);
if (hasWrapperElement) {
MethodInfo XmlReader_get_IsEmptyElement = typeof(XmlReader).GetMethod(
"get_IsEmptyElement",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
ilg.Ldarg(0);
ilg.Call(XmlSerializationReader_get_Reader);
ilg.Call(XmlReader_get_IsEmptyElement);
ilg.If();
{
MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod(
"Skip",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
ilg.Ldarg(0);
ilg.Call(XmlSerializationReader_get_Reader);
ilg.Call(XmlReader_Skip);
ilg.Ldarg(0);
ilg.Call(XmlSerializationReader_get_Reader);
ilg.Call(XmlReader_MoveToContent);
ilg.Pop();
ilg.WhileContinue();
}
ilg.EndIf();
MethodInfo XmlReader_ReadStartElement = typeof(XmlReader).GetMethod(
"ReadStartElement",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
ilg.Ldarg(0);
ilg.Call(XmlSerializationReader_get_Reader);
ilg.Call(XmlReader_ReadStartElement);
}
if (IsSequence(members)) {
ilg.Ldc(0);
ilg.Stloc(typeof(Int32), "state");
}
int loopIndex = WriteWhileNotLoopStart();
string unknownNode = "UnknownNode((object)p, " + ExpectedElements(members) + ");";
WriteMemberElements(members, unknownNode, unknownNode, anyElement, anyText);
ilg.Ldarg(0);
ilg.Call(XmlSerializationReader_get_Reader);
ilg.Call(XmlReader_MoveToContent);
ilg.Pop();
WriteWhileLoopEnd(loopIndex);
WriteMemberEnd(textOrArrayMembers);
if (hasWrapperElement) {
MethodInfo XmlSerializationReader_ReadEndElement = typeof(XmlSerializationReader).GetMethod(
"ReadEndElement",
CodeGenerator.InstanceBindingFlags,
null,
CodeGenerator.EmptyTypeArray,
null
);
ilg.Ldarg(0);
ilg.Call(XmlSerializationReader_ReadEndElement);
WriteUnknownNode("UnknownNode", "null", element, true);
ilg.Ldarg(0);
ilg.Call(XmlSerializationReader_get_Reader);
ilg.Call(XmlReader_MoveToContent);
ilg.Pop();
WriteWhileLoopEnd(wrapperLoopIndex);
}
ilg.Ldloc(ilg.GetLocal("p"));
ilg.EndMethod();
return methodName;
}