private string GenerateMembersElement(XmlMembersMapping xmlMembersMapping)
{
ElementAccessor element = xmlMembersMapping.Accessor;
MembersMapping mapping = (MembersMapping)element.Mapping;
bool hasWrapperElement = mapping.HasWrapperElement;
bool writeAccessors = mapping.WriteAccessors;
bool isRpc = xmlMembersMapping.IsSoap && writeAccessors;
string methodName = NextMethodName(element.Name);
Writer.WriteLine();
Writer.Write("public void ");
Writer.Write(methodName);
Writer.WriteLine("(object[] p) {");
Writer.Indent++;
Writer.WriteLine("WriteStartDocument();");
if (!mapping.IsSoap)
{
Writer.WriteLine("TopLevelElement();");
}
// in the top-level method add check for the parameters length,
// because visual basic does not have a concept of an <out> parameter it uses <ByRef> instead
// so sometime we think that we have more parameters then supplied
Writer.WriteLine("int pLength = p.Length;");
if (hasWrapperElement)
{
WriteStartElement(element.Name, (element.Form == XmlSchemaForm.Qualified ? element.Namespace : ""), mapping.IsSoap);
int xmlnsMember = FindXmlnsIndex(mapping.Members);
if (xmlnsMember >= 0)
{
MemberMapping member = mapping.Members[xmlnsMember];
string source = "((" + typeof(XmlSerializerNamespaces).FullName + ")p[" + xmlnsMember.ToString(CultureInfo.InvariantCulture) + "])";
Writer.Write("if (pLength > ");
Writer.Write(xmlnsMember.ToString(CultureInfo.InvariantCulture));
Writer.WriteLine(") {");
Writer.Indent++;
WriteNamespaces(source);
Writer.Indent--;
Writer.WriteLine("}");
}
for (int i = 0; i < mapping.Members.Length; i++)
{
MemberMapping member = mapping.Members[i];
if (member.Attribute != null && !member.Ignore)
{
string source = "p[" + i.ToString(CultureInfo.InvariantCulture) + "]";
string specifiedSource = null;
int specifiedPosition = 0;
if (member.CheckSpecified != SpecifiedAccessor.None)
{
string memberNameSpecified = member.Name + "Specified";
for (int j = 0; j < mapping.Members.Length; j++)
{
if (mapping.Members[j].Name == memberNameSpecified)
{
specifiedSource = "((bool) p[" + j.ToString(CultureInfo.InvariantCulture) + "])";
specifiedPosition = j;
break;
}
}
}
Writer.Write("if (pLength > ");
Writer.Write(i.ToString(CultureInfo.InvariantCulture));
Writer.WriteLine(") {");
Writer.Indent++;
if (specifiedSource != null)
{
Writer.Write("if (pLength <= ");
Writer.Write(specifiedPosition.ToString(CultureInfo.InvariantCulture));
Writer.Write(" || ");
Writer.Write(specifiedSource);
Writer.WriteLine(") {");
Writer.Indent++;
}
WriteMember(source, member.Attribute, member.TypeDesc, "p");
if (specifiedSource != null)
{
Writer.Indent--;
Writer.WriteLine("}");
}
Writer.Indent--;
Writer.WriteLine("}");
}
}
}
for (int i = 0; i < mapping.Members.Length; i++)
{
MemberMapping member = mapping.Members[i];
if (member.Xmlns != null)
continue;
if (member.Ignore)
continue;
string specifiedSource = null;
int specifiedPosition = 0;
if (member.CheckSpecified != SpecifiedAccessor.None)
{
string memberNameSpecified = member.Name + "Specified";
for (int j = 0; j < mapping.Members.Length; j++)
{
if (mapping.Members[j].Name == memberNameSpecified)
{
specifiedSource = "((bool) p[" + j.ToString(CultureInfo.InvariantCulture) + "])";
specifiedPosition = j;
break;
}
}
}
Writer.Write("if (pLength > ");
Writer.Write(i.ToString(CultureInfo.InvariantCulture));
Writer.WriteLine(") {");
Writer.Indent++;
if (specifiedSource != null)
{
Writer.Write("if (pLength <= ");
Writer.Write(specifiedPosition.ToString(CultureInfo.InvariantCulture));
Writer.Write(" || ");
Writer.Write(specifiedSource);
Writer.WriteLine(") {");
Writer.Indent++;
}
string source = "p[" + i.ToString(CultureInfo.InvariantCulture) + "]";
string enumSource = null;
if (member.ChoiceIdentifier != null)
{
for (int j = 0; j < mapping.Members.Length; j++)
{
if (mapping.Members[j].Name == member.ChoiceIdentifier.MemberName)
{
if (member.ChoiceIdentifier.Mapping.TypeDesc.UseReflection)
enumSource = "p[" + j.ToString(CultureInfo.InvariantCulture) + "]";
else
enumSource = "((" + mapping.Members[j].TypeDesc.CSharpName + ")p[" + j.ToString(CultureInfo.InvariantCulture) + "]" + ")";
break;
}
}
#if DEBUG
// use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
if (enumSource == null) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorDetails, "Can not find " + member.ChoiceIdentifier.MemberName + " in the members mapping."));
#endif
}
if (isRpc && member.IsReturnValue && member.Elements.Length > 0)
{
Writer.Write("WriteRpcResult(");
WriteQuotedCSharpString(member.Elements[0].Name);
Writer.Write(", ");
WriteQuotedCSharpString("");
Writer.WriteLine(");");
}
// override writeAccessors choice when we've written a wrapper element
WriteMember(source, enumSource, member.ElementsSortedByDerivation, member.Text, member.ChoiceIdentifier, member.TypeDesc, writeAccessors || hasWrapperElement);
if (specifiedSource != null)
{
Writer.Indent--;
Writer.WriteLine("}");
}
Writer.Indent--;
Writer.WriteLine("}");
}
if (hasWrapperElement)
{
WriteEndElement();
}
if (element.IsSoap)
{
if (!hasWrapperElement && !writeAccessors)
{
// doc/bare case -- allow extra members
Writer.Write("if (pLength > ");
Writer.Write(mapping.Members.Length.ToString(CultureInfo.InvariantCulture));
Writer.WriteLine(") {");
Writer.Indent++;
WriteExtraMembers(mapping.Members.Length.ToString(CultureInfo.InvariantCulture), "pLength");
Writer.Indent--;
Writer.WriteLine("}");
}
Writer.WriteLine("WriteReferencedElements();");
}
Writer.Indent--;
Writer.WriteLine("}");
return methodName;
}