private void WriteLiteralStructMethod(StructMapping structMapping)
{
string methodName = (string)MethodNames[structMapping];
bool useReflection = structMapping.TypeDesc.UseReflection;
string typeName = useReflection ? "object" : structMapping.TypeDesc.CSharpName;
Writer.WriteLine();
Writer.Write(typeName);
Writer.Write(" ");
Writer.Write(methodName);
Writer.Write("(");
if (structMapping.TypeDesc.IsNullable)
Writer.Write("bool isNullable, ");
Writer.WriteLine("bool checkType) {");
Writer.Indent++;
Writer.Write(typeof(XmlQualifiedName).FullName);
Writer.WriteLine(" xsiType = checkType ? GetXsiType() : null;");
Writer.WriteLine("bool isNull = false;");
if (structMapping.TypeDesc.IsNullable)
Writer.WriteLine("if (isNullable) isNull = ReadNull();");
Writer.WriteLine("if (checkType) {");
if (structMapping.TypeDesc.IsRoot)
{
Writer.Indent++;
Writer.WriteLine("if (isNull) {");
Writer.Indent++;
Writer.WriteLine("if (xsiType != null) return (" + typeName + ")ReadTypedNull(xsiType);");
Writer.Write("else return ");
if (structMapping.TypeDesc.IsValueType)
{
Writer.Write(RaCodeGen.GetStringForCreateInstance(structMapping.TypeDesc.CSharpName, useReflection, false, false));
Writer.WriteLine(";");
}
else
Writer.WriteLine("null;");
Writer.Indent--;
Writer.WriteLine("}");
}
Writer.Write("if (xsiType == null");
if (!structMapping.TypeDesc.IsRoot)
{
Writer.Write(" || ");
WriteQNameEqual("xsiType", structMapping.TypeName, structMapping.Namespace);
}
Writer.WriteLine(") {");
if (structMapping.TypeDesc.IsRoot)
{
Writer.Indent++;
Writer.WriteLine("return ReadTypedPrimitive(new System.Xml.XmlQualifiedName(\"" + Soap.UrType + "\", \"" + XmlSchema.Namespace + "\"));");
Writer.Indent--;
}
Writer.WriteLine("}");
WriteDerivedTypes(structMapping, !useReflection && !structMapping.TypeDesc.IsRoot, typeName);
if (structMapping.TypeDesc.IsRoot) WriteEnumAndArrayTypes();
Writer.WriteLine("else");
Writer.Indent++;
if (structMapping.TypeDesc.IsRoot)
Writer.Write("return ReadTypedPrimitive((");
else
Writer.Write("throw CreateUnknownTypeException((");
Writer.Write(typeof(XmlQualifiedName).FullName);
Writer.WriteLine(")xsiType);");
Writer.Indent--;
Writer.WriteLine("}");
if (structMapping.TypeDesc.IsNullable)
Writer.WriteLine("if (isNull) return null;");
if (structMapping.TypeDesc.IsAbstract)
{
Writer.Write("throw CreateAbstractTypeException(");
WriteQuotedCSharpString(structMapping.TypeName);
Writer.Write(", ");
WriteQuotedCSharpString(structMapping.Namespace);
Writer.WriteLine(");");
}
else
{
if (structMapping.TypeDesc.Type != null && typeof(XmlSchemaObject).IsAssignableFrom(structMapping.TypeDesc.Type))
{
Writer.WriteLine("DecodeName = false;");
}
WriteCreateMapping(structMapping, "o");
MemberMapping[] mappings = TypeScope.GetSettableMembers(structMapping);
Member anyText = null;
Member anyElement = null;
Member anyAttribute = null;
bool isSequence = structMapping.HasExplicitSequence();
ArrayList arraysToDeclareList = new ArrayList(mappings.Length);
ArrayList arraysToSetList = new ArrayList(mappings.Length);
ArrayList allMembersList = new ArrayList(mappings.Length);
for (int i = 0; i < mappings.Length; i++)
{
MemberMapping mapping = mappings[i];
CodeIdentifier.CheckValidIdentifier(mapping.Name);
string source = RaCodeGen.GetStringForMember("o", mapping.Name, structMapping.TypeDesc);
Member member = new Member(this, source, "a", i, mapping, GetChoiceIdentifierSource(mapping, "o", structMapping.TypeDesc));
if (!mapping.IsSequence)
member.ParamsReadSource = "paramsRead[" + i.ToString(CultureInfo.InvariantCulture) + "]";
member.IsNullable = mapping.TypeDesc.IsNullable;
if (mapping.CheckSpecified == SpecifiedAccessor.ReadWrite)
member.CheckSpecifiedSource = RaCodeGen.GetStringForMember("o", mapping.Name + "Specified", structMapping.TypeDesc);
if (mapping.Text != null)
anyText = member;
if (mapping.Attribute != null && mapping.Attribute.Any)
anyAttribute = member;
if (!isSequence)
{
// find anyElement if present.
for (int j = 0; j < mapping.Elements.Length; j++)
{
if (mapping.Elements[j].Any && (mapping.Elements[j].Name == null || mapping.Elements[j].Name.Length == 0))
{
anyElement = member;
break;
}
}
}
else if (mapping.IsParticle && !mapping.IsSequence)
{
StructMapping declaringMapping;
structMapping.FindDeclaringMapping(mapping, out declaringMapping, structMapping.TypeName);
throw new InvalidOperationException(SR.Format(SR.XmlSequenceHierarchy, structMapping.TypeDesc.FullName, mapping.Name, declaringMapping.TypeDesc.FullName, "Order"));
}
if (mapping.Attribute == null && mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping)
{
Member arrayMember = new Member(this, source, source, "a", i, mapping, GetChoiceIdentifierSource(mapping, "o", structMapping.TypeDesc));
arrayMember.CheckSpecifiedSource = member.CheckSpecifiedSource;
allMembersList.Add(arrayMember);
}
else
{
allMembersList.Add(member);
}
if (mapping.TypeDesc.IsArrayLike)
{
arraysToDeclareList.Add(member);
if (mapping.TypeDesc.IsArrayLike && !(mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping))
{
member.ParamsReadSource = null; // flat arrays -- don't want to count params read.
if (member != anyText && member != anyElement)
{
arraysToSetList.Add(member);
}
}
else if (!mapping.TypeDesc.IsArray)
{
member.ParamsReadSource = null; // collection
}
}
}
if (anyElement != null) arraysToSetList.Add(anyElement);
if (anyText != null && anyText != anyElement) arraysToSetList.Add(anyText);
Member[] arraysToDeclare = (Member[])arraysToDeclareList.ToArray(typeof(Member));
Member[] arraysToSet = (Member[])arraysToSetList.ToArray(typeof(Member));
Member[] allMembers = (Member[])allMembersList.ToArray(typeof(Member));
WriteMemberBegin(arraysToDeclare);
WriteParamsRead(mappings.Length);
WriteAttributes(allMembers, anyAttribute, "UnknownNode", "(object)o");
if (anyAttribute != null)
WriteMemberEnd(arraysToDeclare);
Writer.WriteLine("Reader.MoveToElement();");
Writer.WriteLine("if (Reader.IsEmptyElement) {");
Writer.Indent++;
Writer.WriteLine("Reader.Skip();");
WriteMemberEnd(arraysToSet);
Writer.WriteLine("return o;");
Writer.Indent--;
Writer.WriteLine("}");
Writer.WriteLine("Reader.ReadStartElement();");
if (IsSequence(allMembers))
{
Writer.WriteLine("int state = 0;");
}
int loopIndex = WriteWhileNotLoopStart();
Writer.Indent++;
string unknownNode = "UnknownNode((object)o, " + ExpectedElements(allMembers) + ");";
WriteMemberElements(allMembers, unknownNode, unknownNode, anyElement, anyText, null);
Writer.WriteLine("Reader.MoveToContent();");
WriteWhileLoopEnd(loopIndex);
WriteMemberEnd(arraysToSet);
Writer.WriteLine("ReadEndElement();");
Writer.WriteLine("return o;");
}
Writer.Indent--;
Writer.WriteLine("}");
}