Br_S() private method

private Br_S ( Label label ) : void
label System.Reflection.Emit.Label
return void
        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();
        }
        private string GenerateMembersElement(XmlMembersMapping xmlMembersMapping)
        {
            ElementAccessor element = xmlMembersMapping.Accessor;
            MembersMapping mapping = (MembersMapping)element.Mapping;
            bool hasWrapperElement = mapping.HasWrapperElement;
            bool writeAccessors = mapping.WriteAccessors;
            string methodName = NextMethodName(element.Name);
            ilg = new CodeGenerator(this.typeBuilder);
            ilg.BeginMethod(
                typeof(void),
                methodName,
                new Type[] { typeof(object[]) },
                new string[] { "p" },
                CodeGenerator.PublicMethodAttributes
                );

            MethodInfo XmlSerializationWriter_WriteStartDocument = typeof(XmlSerializationWriter).GetMethod(
                "WriteStartDocument",
                CodeGenerator.InstanceBindingFlags,
                Array.Empty<Type>()
                );
            ilg.Ldarg(0);
            ilg.Call(XmlSerializationWriter_WriteStartDocument);

            MethodInfo XmlSerializationWriter_TopLevelElement = typeof(XmlSerializationWriter).GetMethod(
                "TopLevelElement",
                CodeGenerator.InstanceBindingFlags,
                Array.Empty<Type>()
                );
            ilg.Ldarg(0);
            ilg.Call(XmlSerializationWriter_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
            LocalBuilder pLengthLoc = ilg.DeclareLocal(typeof(int), "pLength");
            ilg.Ldarg("p");
            ilg.Ldlen();
            ilg.Stloc(pLengthLoc);

            if (hasWrapperElement)
            {
                WriteStartElement(element.Name, (element.Form == XmlSchemaForm.Qualified ? element.Namespace : ""), false);

                int xmlnsMember = FindXmlnsIndex(mapping.Members);
                if (xmlnsMember >= 0)
                {
                    MemberMapping member = mapping.Members[xmlnsMember];
                    string source = "((" + typeof(XmlSerializerNamespaces).FullName + ")p[" + xmlnsMember.ToString(CultureInfo.InvariantCulture) + "])";

                    ilg.Ldloc(pLengthLoc);
                    ilg.Ldc(xmlnsMember);
                    ilg.If(Cmp.GreaterThan);
                    WriteNamespaces(source);
                    ilg.EndIf();
                }

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

                    if (member.Attribute != null && !member.Ignore)
                    {
                        SourceInfo source = new SourceInfo("p[" + i.ToString(CultureInfo.InvariantCulture) + "]", null, null, pLengthLoc.LocalType.GetElementType(), ilg);

                        SourceInfo 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 = new SourceInfo("((bool)p[" + j.ToString(CultureInfo.InvariantCulture) + "])", null, null, typeof(bool), ilg);
                                    specifiedPosition = j;
                                    break;
                                }
                            }
                        }

                        ilg.Ldloc(pLengthLoc);
                        ilg.Ldc(i);
                        ilg.If(Cmp.GreaterThan);

                        if (specifiedSource != null)
                        {
                            Label labelTrue = ilg.DefineLabel();
                            Label labelEnd = ilg.DefineLabel();
                            ilg.Ldloc(pLengthLoc);
                            ilg.Ldc(specifiedPosition);
                            ilg.Ble(labelTrue);
                            specifiedSource.Load(typeof(bool));
                            ilg.Br_S(labelEnd);
                            ilg.MarkLabel(labelTrue);
                            ilg.Ldc(true);
                            ilg.MarkLabel(labelEnd);
                            ilg.If();
                        }

                        WriteMember(source, member.Attribute, member.TypeDesc, "p");

                        if (specifiedSource != null)
                        {
                            ilg.EndIf();
                        }

                        ilg.EndIf();
                    }
                }
            }

            for (int i = 0; i < mapping.Members.Length; i++)
            {
                MemberMapping member = mapping.Members[i];
                if (member.Xmlns != null)
                    continue;
                if (member.Ignore)
                    continue;

                SourceInfo 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 = new SourceInfo("((bool)p[" + j.ToString(CultureInfo.InvariantCulture) + "])", null, null, typeof(bool), ilg);
                            specifiedPosition = j;
                            break;
                        }
                    }
                }

                ilg.Ldloc(pLengthLoc);
                ilg.Ldc(i);
                ilg.If(Cmp.GreaterThan);

                if (specifiedSource != null)
                {
                    Label labelTrue = ilg.DefineLabel();
                    Label labelEnd = ilg.DefineLabel();
                    ilg.Ldloc(pLengthLoc);
                    ilg.Ldc(specifiedPosition);
                    ilg.Ble(labelTrue);
                    specifiedSource.Load(typeof(bool));
                    ilg.Br_S(labelEnd);
                    ilg.MarkLabel(labelTrue);
                    ilg.Ldc(true);
                    ilg.MarkLabel(labelEnd);
                    ilg.If();
                }

                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)
                        {
                            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

                }

                // override writeAccessors choice when we've written a wrapper element
                WriteMember(new SourceInfo(source, source, null, null, ilg), enumSource, member.ElementsSortedByDerivation, member.Text, member.ChoiceIdentifier, member.TypeDesc, writeAccessors || hasWrapperElement);

                if (specifiedSource != null)
                {
                    ilg.EndIf();
                }

                ilg.EndIf();
            }

            if (hasWrapperElement)
            {
                WriteEndElement();
            }
            ilg.EndMethod();
            return methodName;
        }