private void WriteElement(string source, string arrayName, string choiceSource, ElementAccessor element, ChoiceIdentifierAccessor choice, string checkSpecified, bool checkForNull, bool readOnly, int fixupIndex, int elementIndex)
{
if (checkSpecified != null && checkSpecified.Length > 0)
{
Writer.Write(checkSpecified);
Writer.WriteLine(" = true;");
}
if (element.Mapping is ArrayMapping)
{
WriteArray(source, arrayName, (ArrayMapping)element.Mapping, readOnly, element.IsNullable, fixupIndex);
}
else if (element.Mapping is NullableMapping)
{
string methodName = ReferenceMapping(element.Mapping);
#if DEBUG
// use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
if (methodName == null) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorMethod, element.Mapping.TypeDesc.Name));
#endif
WriteSourceBegin(source);
Writer.Write(methodName);
Writer.Write("(true)");
WriteSourceEnd(source);
Writer.WriteLine(";");
}
else if (!element.Mapping.IsSoap && (element.Mapping is PrimitiveMapping))
{
if (element.IsNullable)
{
Writer.WriteLine("if (ReadNull()) {");
Writer.Indent++;
WriteSourceBegin(source);
if (element.Mapping.TypeDesc.IsValueType)
{
Writer.Write(RaCodeGen.GetStringForCreateInstance(element.Mapping.TypeDesc.CSharpName, element.Mapping.TypeDesc.UseReflection, false, false));
}
else
{
Writer.Write("null");
}
WriteSourceEnd(source);
Writer.WriteLine(";");
Writer.Indent--;
Writer.WriteLine("}");
Writer.Write("else ");
}
if (element.Default != null && element.Default != DBNull.Value && element.Mapping.TypeDesc.IsValueType)
{
Writer.WriteLine("if (Reader.IsEmptyElement) {");
Writer.Indent++;
Writer.WriteLine("Reader.Skip();");
Writer.Indent--;
Writer.WriteLine("}");
Writer.WriteLine("else {");
}
else
{
Writer.WriteLine("{");
}
Writer.Indent++;
WriteSourceBegin(source);
if (element.Mapping.TypeDesc == QnameTypeDesc)
Writer.Write("ReadElementQualifiedName()");
else
{
string readFunc;
switch (element.Mapping.TypeDesc.FormatterName)
{
case "ByteArrayBase64":
case "ByteArrayHex":
readFunc = "false";
break;
default:
readFunc = "Reader.ReadElementString()";
break;
}
WritePrimitive(element.Mapping, readFunc);
}
WriteSourceEnd(source);
Writer.WriteLine(";");
Writer.Indent--;
Writer.WriteLine("}");
}
else if (element.Mapping is StructMapping || (element.Mapping.IsSoap && element.Mapping is PrimitiveMapping))
{
TypeMapping mapping = element.Mapping;
if (mapping.IsSoap)
{
Writer.Write("object rre = ");
Writer.Write(fixupIndex >= 0 ? "ReadReferencingElement" : "ReadReferencedElement");
Writer.Write("(");
WriteID(mapping.TypeName);
Writer.Write(", ");
WriteID(mapping.Namespace);
if (fixupIndex >= 0)
{
Writer.Write(", out fixup.Ids[");
Writer.Write((fixupIndex).ToString(CultureInfo.InvariantCulture));
Writer.Write("]");
}
Writer.Write(")");
WriteSourceEnd(source);
Writer.WriteLine(";");
if (mapping.TypeDesc.IsValueType)
{
Writer.WriteLine("if (rre != null) {");
Writer.Indent++;
}
Writer.WriteLine("try {");
Writer.Indent++;
WriteSourceBeginTyped(source, mapping.TypeDesc);
Writer.Write("rre");
WriteSourceEnd(source);
Writer.WriteLine(";");
WriteCatchCastException(mapping.TypeDesc, "rre", null);
Writer.Write("Referenced(");
Writer.Write(source);
Writer.WriteLine(");");
if (mapping.TypeDesc.IsValueType)
{
Writer.Indent--;
Writer.WriteLine("}");
}
}
else
{
string methodName = ReferenceMapping(mapping);
#if DEBUG
// use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
if (methodName == null) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorMethod, mapping.TypeDesc.Name));
#endif
if (checkForNull)
{
Writer.Write("if ((object)(");
Writer.Write(arrayName);
Writer.Write(") == null) Reader.Skip(); else ");
}
WriteSourceBegin(source);
Writer.Write(methodName);
Writer.Write("(");
if (mapping.TypeDesc.IsNullable)
{
WriteBooleanValue(element.IsNullable);
Writer.Write(", ");
}
Writer.Write("true");
Writer.Write(")");
WriteSourceEnd(source);
Writer.WriteLine(";");
}
}
else if (element.Mapping is SpecialMapping)
{
SpecialMapping special = (SpecialMapping)element.Mapping;
switch (special.TypeDesc.Kind)
{
case TypeKind.Node:
bool isDoc = special.TypeDesc.FullName == typeof(XmlDocument).FullName;
WriteSourceBeginTyped(source, special.TypeDesc);
Writer.Write(isDoc ? "ReadXmlDocument(" : "ReadXmlNode(");
Writer.Write(element.Any ? "false" : "true");
Writer.Write(")");
WriteSourceEnd(source);
Writer.WriteLine(";");
break;
case TypeKind.Serializable:
SerializableMapping sm = (SerializableMapping)element.Mapping;
// check to see if we need to do the derivation
if (sm.DerivedMappings != null)
{
Writer.Write(typeof(XmlQualifiedName).FullName);
Writer.WriteLine(" tser = GetXsiType();");
Writer.Write("if (tser == null");
Writer.Write(" || ");
WriteQNameEqual("tser", sm.XsiType.Name, sm.XsiType.Namespace);
Writer.WriteLine(") {");
Writer.Indent++;
}
WriteSourceBeginTyped(source, sm.TypeDesc);
Writer.Write("ReadSerializable(( ");
Writer.Write(typeof(IXmlSerializable).FullName);
Writer.Write(")");
Writer.Write(RaCodeGen.GetStringForCreateInstance(sm.TypeDesc.CSharpName, sm.TypeDesc.UseReflection, sm.TypeDesc.CannotNew, false));
bool isWrappedAny = !element.Any && IsWildcard(sm);
if (isWrappedAny)
{
Writer.WriteLine(", true");
}
Writer.Write(")");
WriteSourceEnd(source);
Writer.WriteLine(";");
if (sm.DerivedMappings != null)
{
Writer.Indent--;
Writer.WriteLine("}");
WriteDerivedSerializable(sm, sm, source, isWrappedAny);
WriteUnknownNode("UnknownNode", "null", null, true);
}
break;
default:
throw new InvalidOperationException(SR.XmlInternalError);
}
}
else
{
throw new InvalidOperationException(SR.XmlInternalError);
}
if (choice != null)
{
#if DEBUG
// use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
if (choiceSource == null) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorDetails, "need parent for the " + source));
#endif
string enumTypeName = choice.Mapping.TypeDesc.CSharpName;
Writer.Write(choiceSource);
Writer.Write(" = ");
CodeIdentifier.CheckValidIdentifier(choice.MemberIds[elementIndex]);
Writer.Write(RaCodeGen.GetStringForEnumMember(enumTypeName, choice.MemberIds[elementIndex], choice.Mapping.TypeDesc.UseReflection));
Writer.WriteLine(";");
}
}