private void WriteStructMethod(StructMapping mapping)
{
if (mapping.IsSoap && mapping.TypeDesc.IsRoot) return;
string methodName = (string)MethodNames[mapping];
Writer.WriteLine();
Writer.Write("void ");
Writer.Write(methodName);
string fullTypeName = mapping.TypeDesc.CSharpName;
if (mapping.IsSoap)
{
Writer.WriteLine("(object s) {");
Writer.Indent++;
WriteLocalDecl(fullTypeName, "o", "s", mapping.TypeDesc.UseReflection);
}
else
{
Writer.Write("(string n, string ns, ");
Writer.Write(mapping.TypeDesc.UseReflection ? "object" : fullTypeName);
Writer.Write(" o");
if (mapping.TypeDesc.IsNullable)
Writer.Write(", bool isNullable");
Writer.WriteLine(", bool needType) {");
Writer.Indent++;
if (mapping.TypeDesc.IsNullable)
{
Writer.WriteLine("if ((object)o == null) {");
Writer.Indent++;
Writer.WriteLine("if (isNullable) WriteNullTagLiteral(n, ns);");
Writer.WriteLine("return;");
Writer.Indent--;
Writer.WriteLine("}");
}
Writer.WriteLine("if (!needType) {");
Writer.Indent++;
Writer.Write(typeof(Type).FullName);
Writer.WriteLine(" t = o.GetType();");
Writer.Write("if (");
WriteTypeCompare("t", fullTypeName, mapping.TypeDesc.UseReflection);
Writer.WriteLine(") {");
Writer.WriteLine("}");
WriteDerivedTypes(mapping);
if (mapping.TypeDesc.IsRoot)
WriteEnumAndArrayTypes();
Writer.WriteLine("else {");
Writer.Indent++;
if (mapping.TypeDesc.IsRoot)
{
Writer.WriteLine("WriteTypedPrimitive(n, ns, o, true);");
Writer.WriteLine("return;");
}
else
{
Writer.WriteLine("throw CreateUnknownTypeException(o);");
}
Writer.Indent--;
Writer.WriteLine("}");
Writer.Indent--;
Writer.WriteLine("}");
}
if (!mapping.TypeDesc.IsAbstract)
{
if (mapping.TypeDesc.Type != null && typeof(XmlSchemaObject).IsAssignableFrom(mapping.TypeDesc.Type))
{
Writer.WriteLine("EscapeName = false;");
}
string xmlnsSource = null;
MemberMapping[] members = TypeScope.GetAllMembers(mapping);
int xmlnsMember = FindXmlnsIndex(members);
if (xmlnsMember >= 0)
{
MemberMapping member = members[xmlnsMember];
CodeIdentifier.CheckValidIdentifier(member.Name);
xmlnsSource = RaCodeGen.GetStringForMember("o", member.Name, mapping.TypeDesc);
if (mapping.TypeDesc.UseReflection)
{
xmlnsSource = "((" + member.TypeDesc.CSharpName + ")" + xmlnsSource + ")";
}
}
if (!mapping.IsSoap)
{
Writer.Write("WriteStartElement(n, ns, o, false, ");
if (xmlnsSource == null)
Writer.Write("null");
else
Writer.Write(xmlnsSource);
Writer.WriteLine(");");
if (!mapping.TypeDesc.IsRoot)
{
Writer.Write("if (needType) WriteXsiType(");
WriteQuotedCSharpString(mapping.TypeName);
Writer.Write(", ");
WriteQuotedCSharpString(mapping.Namespace);
Writer.WriteLine(");");
}
}
else if (xmlnsSource != null)
{
WriteNamespaces(xmlnsSource);
}
for (int i = 0; i < members.Length; i++)
{
MemberMapping m = members[i];
if (m.Attribute != null)
{
CodeIdentifier.CheckValidIdentifier(m.Name);
if (m.CheckShouldPersist)
{
Writer.Write("if (");
string methodInvoke = RaCodeGen.GetStringForMethodInvoke("o", fullTypeName, "ShouldSerialize" + m.Name, mapping.TypeDesc.UseReflection);
if (mapping.TypeDesc.UseReflection) methodInvoke = "((" + typeof(bool).FullName + ")" + methodInvoke + ")";
Writer.Write(methodInvoke);
Writer.WriteLine(") {");
Writer.Indent++;
}
if (m.CheckSpecified != SpecifiedAccessor.None)
{
Writer.Write("if (");
string memberGet = RaCodeGen.GetStringForMember("o", m.Name + "Specified", mapping.TypeDesc);
if (mapping.TypeDesc.UseReflection) memberGet = "((" + typeof(bool).FullName + ")" + memberGet + ")";
Writer.Write(memberGet);
Writer.WriteLine(") {");
Writer.Indent++;
}
WriteMember(RaCodeGen.GetStringForMember("o", m.Name, mapping.TypeDesc), m.Attribute, m.TypeDesc, "o");
if (m.CheckSpecified != SpecifiedAccessor.None)
{
Writer.Indent--;
Writer.WriteLine("}");
}
if (m.CheckShouldPersist)
{
Writer.Indent--;
Writer.WriteLine("}");
}
}
}
for (int i = 0; i < members.Length; i++)
{
MemberMapping m = members[i];
if (m.Xmlns != null)
continue;
CodeIdentifier.CheckValidIdentifier(m.Name);
bool checkShouldPersist = m.CheckShouldPersist && (m.Elements.Length > 0 || m.Text != null);
if (checkShouldPersist)
{
Writer.Write("if (");
string methodInvoke = RaCodeGen.GetStringForMethodInvoke("o", fullTypeName, "ShouldSerialize" + m.Name, mapping.TypeDesc.UseReflection);
if (mapping.TypeDesc.UseReflection) methodInvoke = "((" + typeof(bool).FullName + ")" + methodInvoke + ")";
Writer.Write(methodInvoke);
Writer.WriteLine(") {");
Writer.Indent++;
}
if (m.CheckSpecified != SpecifiedAccessor.None)
{
Writer.Write("if (");
string memberGet = RaCodeGen.GetStringForMember("o", m.Name + "Specified", mapping.TypeDesc);
if (mapping.TypeDesc.UseReflection) memberGet = "((" + typeof(bool).FullName + ")" + memberGet + ")";
Writer.Write(memberGet);
Writer.WriteLine(") {");
Writer.Indent++;
}
string choiceSource = null;
if (m.ChoiceIdentifier != null)
{
CodeIdentifier.CheckValidIdentifier(m.ChoiceIdentifier.MemberName);
choiceSource = RaCodeGen.GetStringForMember("o", m.ChoiceIdentifier.MemberName, mapping.TypeDesc);
}
WriteMember(RaCodeGen.GetStringForMember("o", m.Name, mapping.TypeDesc), choiceSource, m.ElementsSortedByDerivation, m.Text, m.ChoiceIdentifier, m.TypeDesc, true);
if (m.CheckSpecified != SpecifiedAccessor.None)
{
Writer.Indent--;
Writer.WriteLine("}");
}
if (checkShouldPersist)
{
Writer.Indent--;
Writer.WriteLine("}");
}
}
if (!mapping.IsSoap)
{
WriteEndElement("o");
}
}
Writer.Indent--;
Writer.WriteLine("}");
}