FindDeclaringMapping() private method

private FindDeclaringMapping ( MemberMapping member, StructMapping &declaringMapping, string parent ) : MemberMapping
member MemberMapping
declaringMapping StructMapping
parent string
return MemberMapping
        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(Res.GetString(Res.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("}");
        }        
        void WriteLiteralStructMethod(StructMapping structMapping) {
            string methodName = (string)MethodNames[structMapping];
            string typeName = structMapping.TypeDesc.CSharpName;
            ilg = new CodeGenerator(this.typeBuilder);
            List<Type> argTypes = new List<Type>();
            List<string> argNames = new List<string>();
            if (structMapping.TypeDesc.IsNullable) {
                argTypes.Add(typeof(Boolean));
                argNames.Add("isNullable");
            }
            argTypes.Add(typeof(Boolean));
            argNames.Add("checkType");
            ilg.BeginMethod(
                structMapping.TypeDesc.Type,
                GetMethodBuilder(methodName),
                argTypes.ToArray(),
                argNames.ToArray(),
                CodeGenerator.PrivateMethodAttributes);

            LocalBuilder locXsiType = ilg.DeclareLocal(typeof(XmlQualifiedName), "xsiType");
            LocalBuilder locIsNull = ilg.DeclareLocal(typeof(Boolean), "isNull");
            MethodInfo XmlSerializationReader_GetXsiType = typeof(XmlSerializationReader).GetMethod(
                "GetXsiType",
                CodeGenerator.InstanceBindingFlags,
                null,
                CodeGenerator.EmptyTypeArray,
                null
                );
            MethodInfo XmlSerializationReader_ReadNull = typeof(XmlSerializationReader).GetMethod(
                 "ReadNull",
                 CodeGenerator.InstanceBindingFlags,
                 null,
                 CodeGenerator.EmptyTypeArray,
                 null
                 );
            Label labelTrue = ilg.DefineLabel();
            Label labelEnd = ilg.DefineLabel();
            ilg.Ldarg("checkType");
            ilg.Brtrue(labelTrue);
            ilg.Load(null);
            ilg.Br_S(labelEnd);
            ilg.MarkLabel(labelTrue);
            ilg.Ldarg(0);
            ilg.Call(XmlSerializationReader_GetXsiType);
            ilg.MarkLabel(labelEnd);
            ilg.Stloc(locXsiType);
            ilg.Ldc(false);
            ilg.Stloc(locIsNull);
            if (structMapping.TypeDesc.IsNullable) {
                ilg.Ldarg("isNullable");
                ilg.If();
                {
                    ilg.Ldarg(0);
                    ilg.Call(XmlSerializationReader_ReadNull);
                    ilg.Stloc(locIsNull);
                }
                ilg.EndIf();
            }

            ilg.Ldarg("checkType");
            ilg.If(); // if (checkType)
            if (structMapping.TypeDesc.IsRoot) {
                ilg.Ldloc(locIsNull);
                ilg.If();
                ilg.Ldloc(locXsiType);
                ilg.Load(null);
                ilg.If(Cmp.NotEqualTo);
                MethodInfo XmlSerializationReader_ReadTypedNull = typeof(XmlSerializationReader).GetMethod(
                       "ReadTypedNull",
                       CodeGenerator.InstanceBindingFlags,
                       null,
                       new Type[] { locXsiType.LocalType },
                       null
                       );
                ilg.Ldarg(0);
                ilg.Ldloc(locXsiType);
                ilg.Call(XmlSerializationReader_ReadTypedNull);
                ilg.Stloc(ilg.ReturnLocal);
                ilg.Br(ilg.ReturnLabel);
                ilg.Else();
                if (structMapping.TypeDesc.IsValueType) {
                    throw CodeGenerator.NotSupported("Arg_NeverValueType");
                }
                else {
                    ilg.Load(null);
                    ilg.Stloc(ilg.ReturnLocal);
                    ilg.Br(ilg.ReturnLabel);
                }
                ilg.EndIf(); // if (xsiType != null)

                ilg.EndIf(); // if (isNull)
            }
            ilg.Ldloc(typeof(XmlQualifiedName), "xsiType");
            ilg.Load(null);
            ilg.Ceq();
            if (!structMapping.TypeDesc.IsRoot) {
                labelTrue = ilg.DefineLabel();
                labelEnd = ilg.DefineLabel();
                // xsiType == null
                ilg.Brtrue(labelTrue);
                WriteQNameEqual("xsiType", structMapping.TypeName, structMapping.Namespace);
                // Bool result for WriteQNameEqual is on the stack
                ilg.Br_S(labelEnd);
                ilg.MarkLabel(labelTrue);
                ilg.Ldc(true);
                ilg.MarkLabel(labelEnd);
            }
            ilg.If(); // if (xsiType == null
            if (structMapping.TypeDesc.IsRoot) {
                ConstructorInfo XmlQualifiedName_ctor = typeof(XmlQualifiedName).GetConstructor(
                    CodeGenerator.InstanceBindingFlags,
                    null,
                    new Type[] { typeof(String), typeof(String) },
                    null
                    );
                MethodInfo XmlSerializationReader_ReadTypedPrimitive = typeof(XmlSerializationReader).GetMethod(
                    "ReadTypedPrimitive",
                    CodeGenerator.InstanceBindingFlags,
                    null,
                    new Type[] { typeof(XmlQualifiedName) },
                    null
                    );
                ilg.Ldarg(0);
                ilg.Ldstr(Soap.UrType);
                ilg.Ldstr(XmlSchema.Namespace);
                ilg.New(XmlQualifiedName_ctor);
                ilg.Call(XmlSerializationReader_ReadTypedPrimitive);
                ilg.Stloc(ilg.ReturnLocal);
                ilg.Br(ilg.ReturnLabel);
            }
            WriteDerivedTypes(structMapping, !structMapping.TypeDesc.IsRoot, typeName);
            if (structMapping.TypeDesc.IsRoot) WriteEnumAndArrayTypes();
            ilg.Else(); // if (xsiType == null
            if (structMapping.TypeDesc.IsRoot) {
                MethodInfo XmlSerializationReader_ReadTypedPrimitive = typeof(XmlSerializationReader).GetMethod(
                    "ReadTypedPrimitive",
                    CodeGenerator.InstanceBindingFlags,
                    null,
                    new Type[] { locXsiType.LocalType },
                    null
                    );
                ilg.Ldarg(0);
                ilg.Ldloc(locXsiType);
                ilg.Call(XmlSerializationReader_ReadTypedPrimitive);
                ilg.Stloc(ilg.ReturnLocal);
                ilg.Br(ilg.ReturnLabel);
            }
            else {
                MethodInfo XmlSerializationReader_CreateUnknownTypeException = typeof(XmlSerializationReader).GetMethod(
                     "CreateUnknownTypeException",
                     CodeGenerator.InstanceBindingFlags,
                     null,
                     new Type[] { typeof(XmlQualifiedName) },
                     null
                     );
                ilg.Ldarg(0);
                ilg.Ldloc(locXsiType);
                ilg.Call(XmlSerializationReader_CreateUnknownTypeException);
                ilg.Throw();
            }
            ilg.EndIf(); // if (xsiType == null
            ilg.EndIf();  // checkType

            if (structMapping.TypeDesc.IsNullable) {
                ilg.Ldloc(typeof(bool), "isNull");
                ilg.If();
                {
                    ilg.Load(null);
                    ilg.Stloc(ilg.ReturnLocal);
                    ilg.Br(ilg.ReturnLabel);
                }
                ilg.EndIf();
            }

            if (structMapping.TypeDesc.IsAbstract) {
                MethodInfo XmlSerializationReader_CreateAbstractTypeException = typeof(XmlSerializationReader).GetMethod(
                    "CreateAbstractTypeException",
                    CodeGenerator.InstanceBindingFlags,
                    null,
                    new Type[] { typeof(String), typeof(String) },
                    null
                    );
                ilg.Ldarg(0);
                ilg.Ldstr(structMapping.TypeName);
                ilg.Ldstr(structMapping.Namespace);
                ilg.Call(XmlSerializationReader_CreateAbstractTypeException);
                ilg.Throw();
            }
            else {
                if (structMapping.TypeDesc.Type != null && typeof(XmlSchemaObject).IsAssignableFrom(structMapping.TypeDesc.Type)) {
                    MethodInfo XmlSerializationReader_set_DecodeName = typeof(XmlSerializationReader).GetMethod(
                         "set_DecodeName",
                         CodeGenerator.InstanceBindingFlags,
                         null,
                         new Type[] { typeof(Boolean) },
                         null
                         );
                    ilg.Ldarg(0);
                    ilg.Ldc(false);
                    ilg.Call(XmlSerializationReader_set_DecodeName);
                }
                WriteCreateMapping(structMapping, "o");
                LocalBuilder oLoc = ilg.GetLocal("o");

                // this method populates the memberInfos dictionary based on the structMapping
                MemberMapping[] mappings = TypeScope.GetSettableMembers(structMapping, memberInfos);

                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(Res.GetString(Res.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", oLoc);
                if (anyAttribute != null)
                    WriteMemberEnd(arraysToDeclare);

                MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
                    "get_Reader",
                    CodeGenerator.InstanceBindingFlags,
                    null,
                    CodeGenerator.EmptyTypeArray,
                    null
                    );
                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();

                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);
                WriteMemberEnd(arraysToSet);
                ilg.Ldloc(oLoc);
                ilg.Stloc(ilg.ReturnLocal);
                ilg.Br(ilg.ReturnLabel);
                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(allMembers)) {
                    ilg.Ldc(0);
                    ilg.Stloc(typeof(Int32), "state");
                }
                int loopIndex = WriteWhileNotLoopStart();
                string unknownNode = "UnknownNode((object)o, " + ExpectedElements(allMembers) + ");";
                WriteMemberElements(allMembers, unknownNode, unknownNode, anyElement, anyText);
                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();

                WriteWhileLoopEnd(loopIndex);
                WriteMemberEnd(arraysToSet);

                MethodInfo XmlSerializationReader_ReadEndElement = typeof(XmlSerializationReader).GetMethod(
                    "ReadEndElement",
                    CodeGenerator.InstanceBindingFlags,
                    null,
                    CodeGenerator.EmptyTypeArray,
                    null
                    );
                ilg.Ldarg(0);
                ilg.Call(XmlSerializationReader_ReadEndElement);
                ilg.Ldloc(structMapping.TypeDesc.Type, "o");
                ilg.Stloc(ilg.ReturnLocal);
            }
            ilg.MarkLabel(ilg.ReturnLabel);
            ilg.Ldloc(ilg.ReturnLocal);
            ilg.EndMethod();
        }
Example #3
0
        private object WriteLiteralStructMethod(StructMapping structMapping, bool isNullable, bool checkType, string defaultNamespace)
        {
            XmlQualifiedName xsiType = checkType ? GetXsiType() : null;
            bool             isNull  = false;

            if (isNullable)
            {
                isNull = ReadNull();
            }

            if (checkType)
            {
                if (structMapping.TypeDesc.IsRoot && isNull)
                {
                    if (xsiType != null)
                    {
                        return(ReadTypedNull(xsiType));
                    }

                    else
                    {
                        if (structMapping.TypeDesc.IsValueType)
                        {
                            return(ReflectionCreateObject(structMapping.TypeDesc.Type));
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }

                object o = null;
                if (xsiType == null || (!structMapping.TypeDesc.IsRoot && QNameEqual(xsiType, structMapping.TypeName, structMapping.Namespace, defaultNamespace)))
                {
                    if (structMapping.TypeDesc.IsRoot)
                    {
                        return(ReadTypedPrimitive(new XmlQualifiedName(Soap.UrType, XmlSchemaConstants.Namespace)));
                    }
                }
                else if (WriteDerivedTypes(out o, structMapping, xsiType, defaultNamespace, checkType, isNullable))
                {
                    return(o);
                }
                else if (structMapping.TypeDesc.IsRoot && WriteEnumAndArrayTypes(out o, structMapping, xsiType, defaultNamespace))
                {
                    return(o);
                }
                else
                {
                    if (structMapping.TypeDesc.IsRoot)
                    {
                        return(ReadTypedPrimitive(xsiType));
                    }
                    else
                    {
                        throw CreateUnknownTypeException(xsiType);
                    }
                }
            }

            if (structMapping.TypeDesc.IsNullable && isNull)
            {
                return(null);
            }
            else if (structMapping.TypeDesc.IsAbstract)
            {
                throw CreateAbstractTypeException(structMapping.TypeName, structMapping.Namespace);
            }
            else
            {
                if (structMapping.TypeDesc.Type != null && typeof(XmlSchemaObject).IsAssignableFrom(structMapping.TypeDesc.Type))
                {
                    // #10589: To Support Serializing XmlSchemaObject
                    throw new NotImplementedException("typeof(XmlSchemaObject)");
                }

                object o = ReflectionCreateObject(structMapping.TypeDesc.Type);

                MemberMapping[] mappings         = TypeScope.GetSettableMembers(structMapping);
                MemberMapping   anyText          = null;
                MemberMapping   anyElement       = null;
                MemberMapping   anyAttribute     = null;
                Member          anyElementMember = null;
                Member          anyTextMember    = null;

                bool isSequence = structMapping.HasExplicitSequence();

                if (isSequence)
                {
                    // #10586: Currently the reflection based method treat this kind of type as normal types.
                    // But potentially we can do some optimization for types that have ordered properties.
                }

                var allMembersList       = new List <Member>(mappings.Length);
                var allMemberMappingList = new List <MemberMapping>(mappings.Length);

                for (int i = 0; i < mappings.Length; i++)
                {
                    MemberMapping mapping = mappings[i];

                    if (mapping.Text != null)
                    {
                        anyText = mapping;
                    }
                    if (mapping.Attribute != null && mapping.Attribute.Any)
                    {
                        anyAttribute = mapping;
                    }
                    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 = mapping;
                                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"));
                    }

                    var member = new Member(mapping);
                    if (mapping.TypeDesc.IsArrayLike)
                    {
                        if (mapping.TypeDesc.IsArrayLike && !(mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping))
                        {
                            member.Collection = new CollectionMember();
                        }
                        else if (!mapping.TypeDesc.IsArray)
                        {
                        }
                    }

                    allMemberMappingList.Add(mapping);
                    allMembersList.Add(member);

                    if (mapping == anyElement)
                    {
                        anyElementMember = member;
                    }
                    else if (mapping == anyText)
                    {
                        anyTextMember = member;
                    }
                }

                var allMembers        = allMembersList.ToArray();
                var allMemberMappings = allMemberMappingList.ToArray();

                Action <object> unknownNodeAction = (n) => UnknownNode(n);
                WriteAttributes(allMemberMappings, anyAttribute, unknownNodeAction, ref o);

                Reader.MoveToElement();
                if (Reader.IsEmptyElement)
                {
                    Reader.Skip();
                    return(o);
                }

                Reader.ReadStartElement();
                bool IsSequenceAllMembers = IsSequence(allMembers);
                if (IsSequenceAllMembers)
                {
                    // #10586: Currently the reflection based method treat this kind of type as normal types.
                    // But potentially we can do some optimization for types that have ordered properties.
                }

                UnknownNodeAction unknownNode = UnknownNodeAction.ReadUnknownNode;
                WriteMembers(ref o, allMembers, unknownNode, unknownNode, anyElementMember, anyTextMember);

                ReadEndElement();
                return(o);
            }
        }
 private void WriteLiteralStructMethod(StructMapping structMapping)
 {
     string s = (string) base.MethodNames[structMapping];
     bool useReflection = structMapping.TypeDesc.UseReflection;
     string str2 = useReflection ? "object" : structMapping.TypeDesc.CSharpName;
     base.Writer.WriteLine();
     base.Writer.Write(str2);
     base.Writer.Write(" ");
     base.Writer.Write(s);
     base.Writer.Write("(");
     if (structMapping.TypeDesc.IsNullable)
     {
         base.Writer.Write("bool isNullable, ");
     }
     base.Writer.WriteLine("bool checkType) {");
     IndentedWriter writer = base.Writer;
     writer.Indent++;
     base.Writer.Write(typeof(XmlQualifiedName).FullName);
     base.Writer.WriteLine(" xsiType = checkType ? GetXsiType() : null;");
     base.Writer.WriteLine("bool isNull = false;");
     if (structMapping.TypeDesc.IsNullable)
     {
         base.Writer.WriteLine("if (isNullable) isNull = ReadNull();");
     }
     base.Writer.WriteLine("if (checkType) {");
     if (structMapping.TypeDesc.IsRoot)
     {
         IndentedWriter writer2 = base.Writer;
         writer2.Indent++;
         base.Writer.WriteLine("if (isNull) {");
         IndentedWriter writer3 = base.Writer;
         writer3.Indent++;
         base.Writer.WriteLine("if (xsiType != null) return (" + str2 + ")ReadTypedNull(xsiType);");
         base.Writer.Write("else return ");
         if (structMapping.TypeDesc.IsValueType)
         {
             base.Writer.Write(base.RaCodeGen.GetStringForCreateInstance(structMapping.TypeDesc.CSharpName, useReflection, false, false));
             base.Writer.WriteLine(";");
         }
         else
         {
             base.Writer.WriteLine("null;");
         }
         IndentedWriter writer4 = base.Writer;
         writer4.Indent--;
         base.Writer.WriteLine("}");
     }
     base.Writer.Write("if (xsiType == null");
     if (!structMapping.TypeDesc.IsRoot)
     {
         base.Writer.Write(" || ");
         this.WriteQNameEqual("xsiType", structMapping.TypeName, structMapping.Namespace);
     }
     base.Writer.WriteLine(") {");
     if (structMapping.TypeDesc.IsRoot)
     {
         IndentedWriter writer5 = base.Writer;
         writer5.Indent++;
         base.Writer.WriteLine("return ReadTypedPrimitive(new System.Xml.XmlQualifiedName(\"anyType\", \"http://www.w3.org/2001/XMLSchema\"));");
         IndentedWriter writer6 = base.Writer;
         writer6.Indent--;
     }
     base.Writer.WriteLine("}");
     this.WriteDerivedTypes(structMapping, !useReflection && !structMapping.TypeDesc.IsRoot, str2);
     if (structMapping.TypeDesc.IsRoot)
     {
         this.WriteEnumAndArrayTypes();
     }
     base.Writer.WriteLine("else");
     IndentedWriter writer7 = base.Writer;
     writer7.Indent++;
     if (structMapping.TypeDesc.IsRoot)
     {
         base.Writer.Write("return ReadTypedPrimitive((");
     }
     else
     {
         base.Writer.Write("throw CreateUnknownTypeException((");
     }
     base.Writer.Write(typeof(XmlQualifiedName).FullName);
     base.Writer.WriteLine(")xsiType);");
     IndentedWriter writer8 = base.Writer;
     writer8.Indent--;
     base.Writer.WriteLine("}");
     if (structMapping.TypeDesc.IsNullable)
     {
         base.Writer.WriteLine("if (isNull) return null;");
     }
     if (structMapping.TypeDesc.IsAbstract)
     {
         base.Writer.Write("throw CreateAbstractTypeException(");
         base.WriteQuotedCSharpString(structMapping.TypeName);
         base.Writer.Write(", ");
         base.WriteQuotedCSharpString(structMapping.Namespace);
         base.Writer.WriteLine(");");
     }
     else
     {
         if ((structMapping.TypeDesc.Type != null) && typeof(XmlSchemaObject).IsAssignableFrom(structMapping.TypeDesc.Type))
         {
             base.Writer.WriteLine("DecodeName = false;");
         }
         this.WriteCreateMapping(structMapping, "o");
         MemberMapping[] allMembers = TypeScope.GetAllMembers(structMapping);
         Member member = null;
         Member member2 = null;
         Member anyAttribute = null;
         bool flag2 = structMapping.HasExplicitSequence();
         ArrayList list = new ArrayList(allMembers.Length);
         ArrayList list2 = new ArrayList(allMembers.Length);
         ArrayList list3 = new ArrayList(allMembers.Length);
         for (int i = 0; i < allMembers.Length; i++)
         {
             MemberMapping mapping = allMembers[i];
             CodeIdentifier.CheckValidIdentifier(mapping.Name);
             string source = base.RaCodeGen.GetStringForMember("o", mapping.Name, structMapping.TypeDesc);
             Member member4 = new Member(this, source, "a", i, mapping, this.GetChoiceIdentifierSource(mapping, "o", structMapping.TypeDesc));
             if (!mapping.IsSequence)
             {
                 member4.ParamsReadSource = "paramsRead[" + i.ToString(CultureInfo.InvariantCulture) + "]";
             }
             member4.IsNullable = mapping.TypeDesc.IsNullable;
             if (mapping.CheckSpecified == SpecifiedAccessor.ReadWrite)
             {
                 member4.CheckSpecifiedSource = base.RaCodeGen.GetStringForMember("o", mapping.Name + "Specified", structMapping.TypeDesc);
             }
             if (mapping.Text != null)
             {
                 member = member4;
             }
             if ((mapping.Attribute != null) && mapping.Attribute.Any)
             {
                 anyAttribute = member4;
             }
             if (!flag2)
             {
                 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)))
                     {
                         member2 = member4;
                         break;
                     }
                 }
             }
             else if (mapping.IsParticle && !mapping.IsSequence)
             {
                 StructMapping mapping2;
                 structMapping.FindDeclaringMapping(mapping, out mapping2, structMapping.TypeName);
                 throw new InvalidOperationException(Res.GetString("XmlSequenceHierarchy", new object[] { structMapping.TypeDesc.FullName, mapping.Name, mapping2.TypeDesc.FullName, "Order" }));
             }
             if (((mapping.Attribute == null) && (mapping.Elements.Length == 1)) && (mapping.Elements[0].Mapping is ArrayMapping))
             {
                 Member member5 = new Member(this, source, source, "a", i, mapping, this.GetChoiceIdentifierSource(mapping, "o", structMapping.TypeDesc)) {
                     CheckSpecifiedSource = member4.CheckSpecifiedSource
                 };
                 list3.Add(member5);
             }
             else
             {
                 list3.Add(member4);
             }
             if (mapping.TypeDesc.IsArrayLike)
             {
                 list.Add(member4);
                 if (mapping.TypeDesc.IsArrayLike && ((mapping.Elements.Length != 1) || !(mapping.Elements[0].Mapping is ArrayMapping)))
                 {
                     member4.ParamsReadSource = null;
                     if ((member4 != member) && (member4 != member2))
                     {
                         list2.Add(member4);
                     }
                 }
                 else if (!mapping.TypeDesc.IsArray)
                 {
                     member4.ParamsReadSource = null;
                 }
             }
         }
         if (member2 != null)
         {
             list2.Add(member2);
         }
         if ((member != null) && (member != member2))
         {
             list2.Add(member);
         }
         Member[] members = (Member[]) list.ToArray(typeof(Member));
         Member[] memberArray2 = (Member[]) list2.ToArray(typeof(Member));
         Member[] memberArray3 = (Member[]) list3.ToArray(typeof(Member));
         this.WriteMemberBegin(members);
         this.WriteParamsRead(allMembers.Length);
         this.WriteAttributes(memberArray3, anyAttribute, "UnknownNode", "(object)o");
         if (anyAttribute != null)
         {
             this.WriteMemberEnd(members);
         }
         base.Writer.WriteLine("Reader.MoveToElement();");
         base.Writer.WriteLine("if (Reader.IsEmptyElement) {");
         IndentedWriter writer9 = base.Writer;
         writer9.Indent++;
         base.Writer.WriteLine("Reader.Skip();");
         this.WriteMemberEnd(memberArray2);
         base.Writer.WriteLine("return o;");
         IndentedWriter writer10 = base.Writer;
         writer10.Indent--;
         base.Writer.WriteLine("}");
         base.Writer.WriteLine("Reader.ReadStartElement();");
         if (this.IsSequence(memberArray3))
         {
             base.Writer.WriteLine("int state = 0;");
         }
         int loopIndex = this.WriteWhileNotLoopStart();
         IndentedWriter writer11 = base.Writer;
         writer11.Indent++;
         string elementElseString = "UnknownNode((object)o, " + this.ExpectedElements(memberArray3) + ");";
         this.WriteMemberElements(memberArray3, elementElseString, elementElseString, member2, member, null);
         base.Writer.WriteLine("Reader.MoveToContent();");
         this.WriteWhileLoopEnd(loopIndex);
         this.WriteMemberEnd(memberArray2);
         base.Writer.WriteLine("ReadEndElement();");
         base.Writer.WriteLine("return o;");
     }
     IndentedWriter writer12 = base.Writer;
     writer12.Indent--;
     base.Writer.WriteLine("}");
 }